0

Does WinDBG provide a way of displaying type information (dt?) for a plain heap address?

I am looking at a scenario where paged heap and user mode stack traces are not available. While analysing the heap I was tracking down excessive heap usage and I found various objects in the heap that were referencing a certain memory address. Mainly !heap -srch [UserPtr] +0x30 returned objects like this:

0:004> !heap -srch 00000224ceade3a0+30
    _HEAP @ 224ceaa0000
              HEAP_ENTRY Size Prev Flags            UserPtr UserSize - state
        00000224ceae3ac0 045c 0000  [00]   00000224ceae3ad0    045ac - (busy)
    _HEAP @ 224ceaa0000
              HEAP_ENTRY Size Prev Flags            UserPtr UserSize - state
        00000224ceae8080 0346 045c  [00]   00000224ceae8090    03454 - (busy)

Now due to missing user mode stack traces !heap -p -a [UserPtr] returns nothing.

So here I am, I know that actually 0x00000224ceae3ad0 and 0x00000224ceae8090 are the culprits. Well actually [UserPtr]+0x30 (48 bytes) for a reason I yet have to find out but I am stuck here. (I created a small sample where I was able to verify the address, so at least in the sample I am quite sure that the address are correct)

Is there something useful I can do at this point to gain more information about those address beside !address [Addr] which does not really help much.

Since I know size and address I could wade around in the heap and see what I can find but that seems random.

Any hints on how to get more data would be great.

For what it is worth: I am on a NT Heap with LFH.

Edit: In my sample I of course know the data types but in the real world scenario I am facing these types are unknown to me, even with access to code it might be not obvious which instance of what objects points to this address beside coincidental matches of sizes.

Samuel
  • 6,126
  • 35
  • 70
  • You didn't provide any information about what `00000224ceade3a0+30` is, or how your program uses the heap, so it's hard to provide any specific guidance. In the absence of any other information, you'll just have to dump the memory blocks at `0x00000224ceae3ad0` and `0x00000224ceae8090` and look for circumstantial evidence as to their identity. Maybe there is a vtable or pointer in them. Maybe there are other heap blocks with known identity that point to them. – Raymond Chen Nov 10 '19 at 18:42
  • @RaymondChen I updated the entry but very little is known about the object. How would I spot a vtable? How would you dump those blocks? Some `d*` command? – Samuel Nov 10 '19 at 18:58
  • 1
    You can use `dps` to dump an address as if it were a vtable. You can see whether the result is a bunch of virtual function pointers. – Raymond Chen Nov 10 '19 at 19:06
  • Unlike .NET, C++ does not maintain type information along with objects. So in general, it's not possible to figure out the type for a heap block – Thomas Weller Nov 11 '19 at 20:12
  • @ThomasWeller are you aware how the runtime stores their type information when I enable Runtime Type information with `/GR` in visual studio? – Samuel Nov 12 '19 at 18:09
  • @Samuel: sorry, I don't know. I never noticed this command line switch. Perhaps it's worth its own question. – Thomas Weller Nov 13 '19 at 08:07

1 Answers1

3

if the UserPtr contained a vftable windbg will normally decode it in the output as below

HEAP_ENTRY Size Prev Flags    UserPtr UserSize - state
        029b1428 0030 0007  [00]   029b1430    00168 - (busy)
          dbgeng!Debugger::DataModel::Host::HostModule::`vftable'

as raymond commented you can use dps like dps poi(UserPtr) or print individual entries

0:004> .printf "%y\n" , poi(029b1430)
dbgeng!Debugger::DataModel::Host::HostModule::`vftable' (59cde364)
0:004> .printf "%y\n" , poi(poi(029b1430)+2c)
dbgeng!Debugger::DataModel::Host::BaseSymbol::GetFullyQualifiedName (59f79670)
0:004> .printf "%y\n" , poi(poi(029b1430)+28)
dbgeng!Debugger::DataModel::Host::HostModule::IsEqual (59f77680)
blabb
  • 8,674
  • 1
  • 18
  • 27