Tho*_*ler 10
我希望有一个简单的答案,其他人可以比这更容易解决.
以一种可以从输出中获取地址的方式转储所有对象: !dumpheap -short
遍历所有这些对象 .foreach ( adr {!dumpheap -short}) { ... }
方法表将是对象地址处的第一个指针大小字节,因此!do <address>您也可以这样做而不是查找方法表? poi(<address>).
!dumpmt没有列出基类,所以你需要自己找到它.在64位上,基类是16字节,所以要从对象地址获取基类的类型,你可以这样做!dumpmt poi(poi(<address>)+0x10).你可以重复一遍来获得基础类:!dumpmt poi(poi(<address>)+0x10)+0x10).
您可以重复此操作,直到指针为0x00000000,这意味着您已到达System.Object并且没有更多基类.
由于您希望自动执行此过程,因此您还需要将其置于循环中:
r$t0 =poi(<address>);
.while(@$t0) { .if(@$t0 == <basemt>) {...}; r$t0=poi(@$t0+0x10);}
用地址做任何你想要的事情,例如只列出它:.echo ${adr}或者转储它:!do ${adr}.
把它们放在一起.
由于我不知道你在寻找什么,我将Exception以此为例.并且因为总有一个StackOverflowException,OutOfMemoryException并且ExecutionEngineException在任何.NET程序中,如果你尝试它,它至少应该找到三个对象.
0:021> !name2ee *!System.Exception
Module: 000007fef2091000
Assembly: mscorlib.dll
Token: 0000000002000005
MethodTable: 000007fef2776738
EEClass: 000007fef214d7b0
Name: System.Exception
Run Code Online (Sandbox Code Playgroud)
所以<basemt>我正在寻找的参数是000007fef2776738.
完整语句现在(格式化为可读性):
.foreach ( adr {!dumpheap -short}) {
r$t0 =poi(${adr});
.while(@$t0) {
.if(@$t0 == 000007fef2776738) {!do ${adr}};
r$t0=poi(@$t0+0x10);
}
}
Run Code Online (Sandbox Code Playgroud)
或(格式化为复制和粘贴):
.foreach ( adr {!dumpheap -short}) { r$t0 =poi(${adr}); .while(@$t0) { .if(@$t0 == 000007fef2776738) {!do ${adr}}; r$t0=poi(@$t0+0x10);} }
Run Code Online (Sandbox Code Playgroud)