Added fake_fast_chunks command (#204)

* New command for finding fake fast chunks for House of Spirit and
Fastbit Dup

* fixed isort
pull/205/head
nilch 9 years ago committed by Zach Riggle
parent 9de6345a83
commit 9ba992d69d

@ -58,6 +58,7 @@ Pwndbg enables introspection of the glibc allocator, ptmalloc2, via a handful of
![](caps/heap_heap2.png)
![](caps/heap_mallocchunk.png)
![](caps/heap_topchunk.png)
![](caps/fake_fast.png)
## IDA Pro Integration

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB

@ -5,6 +5,8 @@ from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import struct
import gdb
import six
@ -259,3 +261,34 @@ def largebins(addr=None, verbose=False):
print(underline(yellow('largebins')))
for node in formatted_bins:
print(node)
@pwndbg.commands.ParsedCommand
@pwndbg.commands.OnlyWhenRunning
def find_fake_fast(addr, size):
"""
Finds candidate fake fast chunks that will overlap with the specified
address. Used for fastbin dups and house of spirit
"""
main_heap = pwndbg.heap.current
fastbin = main_heap.fastbin_index(int(size))
max_fast = main_heap.global_max_fast
start = int(addr) - int(max_fast)
mem = pwndbg.memory.read(start, max_fast, partial=True)
fmt = {
'little': '<',
'big': '>'
}[pwndbg.arch.endian] + {
4: 'I',
8: 'Q'
}[pwndbg.arch.ptrsize]
print(red("FAKE CHUNKS"))
for offset in range(max_fast - pwndbg.arch.ptrsize):
candidate = mem[offset:offset + pwndbg.arch.ptrsize]
if len(candidate) == pwndbg.arch.ptrsize:
value = struct.unpack(fmt, candidate)[0]
if main_heap.fastbin_index(value) == fastbin:
malloc_chunk(start+offset-pwndbg.arch.ptrsize)

@ -46,6 +46,11 @@ class Heap(pwndbg.heap.heap.BaseHeap):
return self._mp
@property
def global_max_fast(self):
return pwndbg.symbol.address('global_max_fast')
@property
@pwndbg.memoize.reset_on_objfile
def malloc_chunk(self):
@ -114,6 +119,16 @@ class Heap(pwndbg.heap.heap.BaseHeap):
def chunk_key_offset(self, key):
"""
Finds the index of a field in the malloc_chunk struct.
64 bit example.)
prev_size == 0
size == 8
fd == 16
bk == 24
...
"""
chunk_keys = self.malloc_chunk.keys()
try:
@ -154,9 +169,15 @@ class Heap(pwndbg.heap.heap.BaseHeap):
return (None, None)
def fastbin_index(self, size):
if pwndbg.arch.ptrsize == 8:
return (size >> 4) - 2
else:
return (size >> 3) - 2
def fastbins(self, arena_addr=None):
arena = self.get_arena(arena_addr)
arena = self.get_arena(arena_addr)
if arena is None:
return

Loading…
Cancel
Save