Search code examples
pythonwindbgpykd

How to read heap using PYKD


In this question, I wanted to replace DbgCommand("dt ...") by an API call, and the PYKD command typedVar() came to the rescue.

As a result, my heap_stat script (extended with m_nSize and m_nCount information) is running three times faster now.

For your information, I've done this replacement for calculating the amount of members in an STL collection:

Replace: collection_Size = dbgCommand(("dt 0x" + pointer_format + " %s m_nSize") % (ptr,type_name)).split(' : ').[-1].split('\n')[0]
By:      collection_Size = typedVar(type_name, ptr).m_nSize

As a result of this success, I'd like to replace other DbgCommand requests by API calls.

For the case of dbgCommand('!heap -h 0'), this seems not to be that simple (some examples):

>>> for t in targetHeapIterator():
...   print t
... 
Traceback (most recent call last):
  File "<console>", line 1, in <module>
RuntimeError: This class cannot be instantiated from Python

>>> for t in targetHeap().entries:
...   print t
... 
Traceback (most recent call last):
  File "<console>", line 1, in <module>
RuntimeError: This class cannot be instantiated from Python

>>> for t in targetProcess().getManagedHeap().entries:
...   print t
... 
Traceback (most recent call last):
  File "<console>", line 1, in <module>
TypeError: 'instancemethod' object is not iterable

How can I iterate over the heap of my process (replacing !heap -h 0)?

P.S. Even if targetHeap() can't be used as a replacement for !heap -h 0, I'd still like to know how to use it, for investigation purposes.


Solution

  • targetHeapIterator() - only for managed heap and it cannot be created directly, only through special class.

    for entry in targetProcess.getManagedHeap().entries():
        pass # enumerate managed heap
    

    For enumerating native heap, you need write your own script.

    Maybe it will be useful for you: https://githomelab.ru/pykd/pykdwin

    This package has heap enumeartor but with restrictions:

    • does not support LFH
    • does not support Segment Heap

    Sample from doc:

    from pykdwin.heap import *
    for heap in get_heaps():
        for entry in heap.entries():
            print( hex(entry.address), entry.size )