进程堆段及其必要性

2023-12-24

在转储 win32 进程的堆时(主要是在像 IE 这样具有高堆内存消耗的进程中)使用!堆-a 004e0000我发现特定堆的多个段,例如,

Heap entries for Segment00 in Heap 004e0000
Heap entries for Segment01 in Heap 004e0000
Heap entries for Segment02 in Heap 004e0000

我的问题是

问题1。为什么需要将单个堆分成多个段?

问题2。大多数时候我发现两个部分之间有很大的差距。例如,在下图中,Segment00 实际上以 @ 0x005e0000 结束(未提交字节开始的位置),而 Segment01 从 @ 0x05b60000 开始。

为什么会有这样的差距??我们不能使用相同的段(Segment00)来进一步分配吗?

问题3。如何从进程内存或更具体的堆偏移量(例如 heap_handle+0xsomeoffset )中找到特定堆中存在的段数及其地址?


作为问题 3 的答案,我认为,我找到了一种“hacky”方法来从内存中获取段基地址。

0:027> !heap
Index   Address  Name      Debugging options enabled
  1:   00790000                
  2:   004d0000                
  3:   028b0000                
  4:   02a40000                
  5:   02fa0000                
  6:   03b00000                
  7:   02ca0000                
  8:   03ac0000                
  9:   04d80000                
 10:   0a850000                

我们取堆0x00790000并列出其中的所有段。

0:027> !heap 00790000
Index   Address  Name      Debugging options enabled
  1:   00790000 
    Segment at 00790000 to 00890000 (00100000 bytes committed)
    Segment at 053a0000 to 054a0000 (00100000 bytes committed)
    Segment at 05d40000 to 05f40000 (00200000 bytes committed)
    Segment at 063e0000 to 067e0000 (00400000 bytes committed)
    Segment at 09ce0000 to 0a4e0000 (007fa000 bytes committed)

现在是时候从内存中手动获取相同的段基地址了。

0:027> dt _HEAP 00790000 
ntdll!_HEAP
   +0x000 Entry            : _HEAP_ENTRY
   +0x008 SegmentSignature : 0xffeeffee
   +0x00c SegmentFlags     : 0
   +0x010 SegmentListEntry : _LIST_ENTRY [ 0x53a0010 - 0x7900a8 ]
   +0x018 Heap             : 0x00790000 _HEAP
   +0x01c BaseAddress      : 0x00790000 Void
   ..
   ..

我们感兴趣的是段列表条目(这是@偏移0x010)

我们从地址 heap_base + 0x10 转储 2 个 DWORD

0:027> dd 00790000 + 0x10 L2
00790010  053a0010 007900a8

然后我们获取 BLINK(这意味着上面输出的第二个 DWORD,即 0x007900a8)并从那里转储 2 DWROD。我们继续这样做,直到到达与起始位置相同的指针,即 0x007900a8

0:027> dd 007900a8 L2
007900a8  00790010 09ce0010
0:027> dd 09ce0010 L2
09ce0010  007900a8 063e0010
0:027> dd 063e0010 L2
063e0010  09ce0010 05d40010
0:027> dd 05d40010 L2
05d40010  063e0010 053a0010
0:027> dd 053a0010 L2
053a0010  05d40010 00790010
0:027> dd 00790010 L2
00790010  053a0010 007900a8

由于我们到达了与起点相同的点,因此我们可以在这里停下来。

0:027> dd 007900a8 L2
007900a8  00790010 09ce0010

现在看看我们上面得到的值。如果从所有(0x007900a8 和 0x007900a8 除外)中减去 16,您将获得段基地址。

0:027> ? 09ce0000 + 16
Evaluate expression: 164495382 = 09ce0016

哪个是

00790000
053a0000
05d40000
063e0000
09ce0000
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

进程堆段及其必要性 的相关文章

  • 当遇到地址 (ba) 断点时检查 Windbg 中的数据

    我想创建一个断点 这样它将创建另一个一次性断点 当写入该内存时 该断点将 dd 某个内存地址 因此 当断点被击中时 我想运行如下命令 ba w4 ESP 4 1 dd memory address of this breakpoint 由于
  • 虚拟析构函数和内存释放

    我不太确定我是否理解虚拟析构函数和在堆上分配空间的概念 让我们看下面的例子 class Base public int a class Derived public Base public int b 我想如果我做这样的事情 Base o
  • 从调试版本检测发布版本的最佳方法? 。网

    所以我有大约 10 个简短的 css 文件与 mvc 应用程序一起使用 有像 错误 css 登录 css ETC 只是一些非常短的 css 文件 使更新和编辑变得容易 至少对我来说 我想要的是能够优化 if else 分支而不是将其合并到最
  • 如何使用 Visual Studio 2008 调试 CUDA 内核代码?

    嘿 我正在使用带有 CUDA 3 2 的 Visual Studio 2008 我正在尝试调试具有此签名的函数 MatrixMultiplication Kernel lt lt
  • 编写自定义 Eclipse 调试器

    EDIT 一定有某种方法可以解决这个问题 而无需编写全新的调试器 我目前正在研究在现有 java 调试器之上构建的方法 如果有人对如何获取 Java 调试器已有的信息 有关堆栈帧 变量 原始数据等 有任何想法 那将非常有帮助 我想要做的是我
  • 函数的变量存储在哪里?在堆栈或堆上?

    当程序调用函数时 为该函数中的变量分配哪种类型的数据结构内存 堆还是栈 为什么 在我看来 它应该存储在堆栈上 因为它们不一定是引用类型 但在我读到答案的地方 据说它们存储在堆上 并在函数返回值后释放 它比这更复杂一点 事实上使用堆栈和堆实际
  • mscorwks.dll 中的 System.UnauthorizedAccessException 导致应用程序池崩溃

    我的应用程序池在 IIS 6 0 MS 调试诊断每次都指向 kernel32 dll 中不断随机崩溃 入口点始终为 mscorwks CreateApplicationContext bbef 结果始终为 System Unauthoriz
  • 启用 USB 设备进行远程调试在 Firefox 上不起作用

    我使用的firefox版本是106 0 2 我正在尝试连接 oculus quest 2 来调试网站项目 问题是我按下启用 USB 设备按钮 它显示更新状态 然后再次显示相同的按钮 状态保持禁用 有任何想法吗 chrome 的开发工具也不起
  • 调试器:如何在故障转储中获取“Mutex Owned”或“Mutex Free”信息?

    我不知道我没有做什么 但我根本无法让自己的调试器保存正在调试的应用程序的 Mutex Owned 或 Mutex Free 信息 如果我按如下方式调用它 CDB 就可以正常工作 cdb pn test exe c dump f ma u t
  • 从 .NET DLL 文件生成 PDB?

    我需要可以从 DLL 文件 C NET 代码 生成 PDB 的东西 有吗free程序来做到这一点 实际上 从 1 2 版本开始 您也可以使用 dotPeek 来做到这一点 右键单击 Assembly Explorer 中的程序集 然后选择
  • 快速成功退出 C++,分配大量对象

    我正在寻找一种方法来快速退出已使用 C 类在内存中分配大量结构的 C 程序正确完成 但在程序中最后 返回 后 所有自动析构函数都会启动 问题是程序通过大量 C 类结构分配了大约 15GB 内存 并且此自动析构过程需要大约还需要 1 个小时才
  • 附加调试器(使用eclipse)播放框架失败

    我正在使用 Scala 通过 Eclipse IDE 在 Play 框架之上编写一个 Web 我正在尝试调试我的应用程序 但遇到调试附加失败 我尝试使用 Java 而不是 Scala 进行切换 但遇到了同样的错误 这就是我所做的 创建项目并
  • 在 Eclipse 中调试 Android NDK C/C++ 代码 - 未命中断点

    我下载了适用于 Linux 的 Android SDK Bundle 和 Android NDK 安装了ADT 我安装了CDT 我创建了一个 Android 项目并添加了本机支持 jni 然后我用java代码编写了本机函数 并用c 代码导出
  • Java 有没有办法记录*每个*线程中断?

    我想每次都以某种方式记录Thread interrupt 被调用 记录哪个线程发出调用 及其当前堆栈 以及识别有关哪个线程被中断的信息 有没有办法做到这一点 在搜索信息时 我看到有人提到实施安全管理器的可能性 这是可以在运行时完成的事情 例
  • 如何增加STS(Spring Tool Suite)内存大小?

    我正在尝试增加 spring 工具套件的堆大小 内存 因为我的内存不足 如果我将 Xmx 从 768m 增加到 1024m 我会收到错误 无法创建 Java 虚拟机 如果我将 Xmx 恢复为 768m 它可以正常工作 但我会遇到 OOM 内
  • 设置断点时 Visual Studio 中的调试浏览器无法运行

    我在 Win 11 计算机上使用 Visual Studio 2022 自上周以来 当我在代码中设置断点时 Google Chrome 就无法工作了 我将浏览器从 Chrome 更改为 Edge 直到今天它似乎都可以工作 但现在 Edge
  • Visual Studio 如何在调试期间显示 System.Double?

    尝试调试以下简单程序 并将鼠标悬停在x在每个步骤中 或 添加监视 x管他呢 using System using System Globalization static class Program static double x stati
  • Visual Studio 调试器可以显示不加引号/未转义的字符串吗?

    Visual Studio 中的托管调试器 我使用的是 11 0 显示包含双引号和反斜杠的字符串值 如下所示 Text C Temp 有时我想以简单的形式显示像上面这样的转义文本 Text C Temp 我知道可以通过值旁边的放大镜访问文本
  • 如何在GDB中重新运行程序多次?

    我有一个程序偶尔会失败 但出现相同的错误 为了调试它 我想在 GDB 下运行它 直到它失败 设置断点并重新运行它 我该怎么办 gdb args path to program
  • ClojureScript 中的 js/console.log

    我想用 ClojureScript 实现一个函数来简化js console log像这样 defn log args apply js console log args 调用它 log foo bar 抛出 TypeError Illega

随机推荐