Permalink
Browse files

Added fake_fast_chunks command (#204)

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

* fixed isort
  • Loading branch information...
blendin authored and zachriggle committed Apr 4, 2017
1 parent 9de6345 commit 9ba992d69d19480107c6685f8f7f4bc1f9c1cd85
Showing with 56 additions and 1 deletion.
  1. +1 −0 FEATURES.md
  2. BIN caps/fake_fast.png
  3. +33 −0 pwndbg/commands/heap.py
  4. +22 −1 pwndbg/heap/ptmalloc.py
@@ -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
BIN +211 KB caps/fake_fast.png
Binary file not shown.
@@ -5,6 +5,8 @@
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 @@ def mp(self):
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 @@ def chunk_flags(self, size):
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 @@ def get_bounds(self):
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

0 comments on commit 9ba992d

Please sign in to comment.