I came across this technique, leveraging the HPA feature (Heap Page Allocator, known as PageHeap) in gflags from Windows debugging tools, to find the size of a heap allocation:
Lets say you have found a use-after-free on program X where at some point it is dereferencing a register plus an offset.
1) Open IDA an lookup where the object got created to see the size of the allocation.
2) Use page heap, windbg and take a look to the allocation stack trace
3) Windbg !heap -p -a
Or... a quick trick I used today, taking advantage of page heap placing the object at the end of a page for catching buffer overflows.
1:022:x86> ? 0x1000-(ebx&0x00000FFF) Evaluate expression: 88 = 00000058 <--- size of chunk 1:022:x86>
Fermin J. Serna - @fjserna
Why does it work?
This is what I understand:
- Each page is 0x1000 bytes (4kb).
- Each block smaller than 0x1000 would be allocated from the end of the page backwards.
- Therefore, by taking the page size and subtracting the block size from it, retrieved from the block's address last 3 digits that we get using the & operator, you get its actual size.
It seems a bit voodoo, because:
In order for the subtraction to work, the inspected allocated block address must be aligned with 1000. Does HPA align everything in pages somehow? I didn't find any resource with enough information about it. Is there any other way that HPA makes this formula work with?
How does the AND operator actually makes the value return only the last 3 digits? I don't get its logic.
Could anyone be kind enough to explain these things for us?