Find all instances that inherit from a base class
I wish there was a simple answer and someone else could solve it easier than this.
Background information
-
dump all objects so that you can get addresses from the output:
!dumpheap -short
-
loop over all these objects
.foreach ( adr {!dumpheap -short}) { ... }
-
The method table will be the first byte of the pointer size at the object address, so instead of
!do <address>
finding the method table, you can also do? poi(<address>)
.!dumpmt
does not list the base class, so you have to find it yourself. In a 64 bit class, the base class is 16 bytes, so to get the type of the base class from the object address you can do!dumpmt poi(poi(<address>)+0x10)
. You can repeat this to get the base class:!dumpmt poi(poi(<address>)+0x10)+0x10)
.You can repeat this until the pointer is 0x00000000, which means you have reached System.Object and the base class is gone.
Since you want to automate this process, you need to insert it into the loop as well:
r$t0 =poi(<address>); .while(@$t0) { .if(@$t0 == <basemt>) {...}; r$t0=poi(@$t0+0x10);}
-
Do whatever you want with an address for example. just list him
.echo ${adr}
or unload him!do ${adr}
. -
Put it all together.
Example
Since I don't know what you are looking for, I am using it Exception
as an example. And as it always is StackOverflowException
, OutOfMemoryException
and ExecutionEngineException
in any .NET program, it should at least find three objects if you try it.
0:021> !name2ee *!System.Exception
Module: 000007fef2091000
Assembly: mscorlib.dll
Token: 0000000002000005
MethodTable: 000007fef2776738
EEClass: 000007fef214d7b0
Name: System.Exception
So, the parameter <basemt>
I'm looking for is this 000007fef2776738
.
Now the complete statement (formatted for readability):
.foreach ( adr {!dumpheap -short}) {
r$t0 =poi(${adr});
.while(@$t0) {
.if(@$t0 == 000007fef2776738) {!do ${adr}};
r$t0=poi(@$t0+0x10);
}
}
or (formatted for copy and paste):
.foreach ( adr {!dumpheap -short}) { r$t0 =poi(${adr}); .while(@$t0) { .if(@$t0 == 000007fef2776738) {!do ${adr}}; r$t0=poi(@$t0+0x10);} }
source to share