def heap_allocations(addr, free): while addr and pwndbg.memory.peek(addr): size = pwndbg.memory.u64(addr) in_use = size & 1 flags = size & 3 done = not (size & 2) size &= ~3 if size > 0x1000: print(red(bold("FOUND CORRUPTION OR END OF DATA"))) data = '' if not in_use or addr in free: print(blue(bold("%#016x - usersize=%#x - [FREE %i]" % (addr, size, flags)))) linkedlist = (addr + 8 + size - 0x10) & pwndbg.arch.ptrmask if not pwndbg.memory.peek(linkedlist): print('Corrupted? (%#x)' % linkedlist) bk = pwndbg.memory.u64(linkedlist) fd = pwndbg.memory.u64(linkedlist+8) print(" @ %#x" % linkedlist) print(" bk: %#x" % bk) print(" fd: %#x" % fd) else: print(green(bold("%#016x - usersize=%#x" % (addr, size)))) pwndbg.commands.hexdump.hexdump(addr+8, size) addr += size + 8 print()
def heap(addr=None): """ Prints out all chunks in the main_arena, or the arena specified by `addr`. """ main_arena = get_main_arena(addr) if main_arena == None: return heap_base = get_heap_bounds()[0] if heap_base == None: print(red('Could not find the heap')) return top = main_arena['top'] last_remainder = main_arena['last_remainder'] print(bold('Top Chunk: ') + M.get(top)) print(bold('Last Remainder: ') + M.get(last_remainder)) print() # Print out all chunks on the heap # TODO: Add an option to print out only free or allocated chunks addr = heap_base while addr <= top: chunk = malloc_chunk(addr) size = int(chunk['size']) # Clear the bottom 3 bits size &= ~7 addr += size
def heap(addr=None): """ Prints out all chunks in the main_arena, or the arena specified by `addr`. """ main_arena = get_main_arena(addr) if main_arena == None: return heap_base = get_heap_bounds()[0] if heap_base == None: print(red('Could not find the heap')) return top = main_arena['top'] last_remainder = main_arena['last_remainder'] print(bold('Top Chunk: ') + pwndbg.color.get(top)) print(bold('Last Remainder: ') + pwndbg.color.get(last_remainder)) print() # Print out all chunks on the heap # TODO: Add an option to print out only free or allocated chunks addr = heap_base while addr <= top: chunk = malloc_chunk(addr) size = int(chunk['size']) # Clear the bottom 3 bits size &= ~7 addr += size
def heap_freebins(addr=0x0602558): print(bold('Linked List')) # addr = 0x0602558 # addr = 0x060E360 print(' ' + hex(addr)) addr = pwndbg.memory.u64(addr) free = [] while addr and pwndbg.memory.peek(addr): free.append(addr) size = pwndbg.memory.u64(addr) in_use = size & 1 size &= ~3 linkedlist = (addr + 8 + size - 0x10) & pwndbg.arch.ptrmask try: bk = pwndbg.memory.u64(linkedlist) except: bk = None try: fd = pwndbg.memory.u64(linkedlist + 8) except: fd = None print(' %#x %#x %s' % (addr, size, '*' if in_use else '')) addr = bk print() return free
def heap_freebins(addr=0x0602558): print(bold('Linked List')) # addr = 0x0602558 # addr = 0x060E360 print(' ' + hex(addr)) addr = pwndbg.memory.u64(addr) free = [] while addr and pwndbg.memory.peek(addr): free.append(addr) size = pwndbg.memory.u64(addr) in_use = size & 1 size &= ~3 linkedlist = (addr + 8 + size - 0x10) & pwndbg.arch.ptrmask try: bk = pwndbg.memory.u64(linkedlist) except: bk = None try: fd = pwndbg.memory.u64(linkedlist+8) except: fd = None print(' %#x %#x %s' % (addr, size, '*' if in_use else '')) addr = bk print() return free
def format_bin(bins, verbose=False): main_heap = pwndbg.heap.current fd_offset = main_heap.chunk_key_offset('fd') result = [] for size in bins: chain = bins[size] if not verbose and chain == [0]: continue formatted_chain = pwndbg.chain.format(chain, offset=fd_offset) if isinstance(size, int): size = hex(size) result.append((bold(size) + ': ').ljust(13) + formatted_chain) if not result: result.append(bold('empty')) return result
def main_arena(self): main_arena_addr = pwndbg.symbol.address('main_arena') if main_arena_addr is not None: self._main_arena = pwndbg.memory.poi(self.malloc_state, main_arena_addr) else: print( bold( red('Symbol \'main arena\' not found. Try installing libc ' 'debugging symbols and try again.'))) return self._main_arena
def heap_allocations(addr, free): while addr and pwndbg.memory.peek(addr): size = pwndbg.memory.u64(addr) in_use = size & 1 flags = size & 3 done = not (size & 2) size &= ~3 if size > 0x1000: print(red(bold("FOUND CORRUPTION OR END OF DATA"))) data = '' if not in_use or addr in free: print( blue( bold("%#016x - usersize=%#x - [FREE %i]" % (addr, size, flags)))) linkedlist = (addr + 8 + size - 0x10) & pwndbg.arch.ptrmask if not pwndbg.memory.peek(linkedlist): print('Corrupted? (%#x)' % linkedlist) bk = pwndbg.memory.u64(linkedlist) fd = pwndbg.memory.u64(linkedlist + 8) print(" @ %#x" % linkedlist) print(" bk: %#x" % bk) print(" fd: %#x" % fd) else: print(green(bold("%#016x - usersize=%#x" % (addr, size)))) pwndbg.commands.hexdump.hexdump(addr + 8, size) addr += size + 8 print()
def heap(addr=None): """ Prints out all chunks in the main_arena, or the arena specified by `addr`. """ main_heap = pwndbg.heap.current main_arena = main_heap.get_arena(addr) if main_arena is None: return heap_region = main_heap.get_region(addr) if heap_region is None: print(red('Could not find the heap')) return top = main_arena['top'] last_remainder = main_arena['last_remainder'] print(bold('Top Chunk: ') + M.get(top)) print(bold('Last Remainder: ') + M.get(last_remainder)) print() # Print out all chunks on the heap # TODO: Add an option to print out only free or allocated chunks addr = heap_region.vaddr while addr <= top: chunk = malloc_chunk(addr) size = int(chunk['size']) # Clear the bottom 3 bits size &= ~7 if size == 0: break addr += size
def arenas(): """ Prints out allocated arenas """ heap = pwndbg.heap.current addr = None arena = heap.get_arena(addr) main_arena_addr = int(arena.address) fmt = '[%%%ds]' % (pwndbg.arch.ptrsize * 2) while addr != main_arena_addr: h = heap.get_region(addr) if not h: print(red('Could not find the heap')) return hdr = bold(fmt % (hex(addr) if addr else 'main')) print(hdr, M.heap(str(h))) addr = int(arena['next']) arena = heap.get_arena(addr)
def bins(addr=None): """ Prints out the contents of the fastbins of the main arena or the arena at the specified address. """ main_arena = get_main_arena(addr) if main_arena == None: return fastbins = main_arena['fastbinsY'] bins = main_arena['bins'] size_t_size = pwndbg.typeinfo.load('size_t').sizeof num_fastbins = int(fastbins.type.sizeof / fastbins.type.target().sizeof) num_bins = int(bins.type.sizeof / bins.type.target().sizeof) fd_field_offset = 2 * size_t_size print(underline(yellow('fastbins'))) for i in range(num_fastbins): size = 2 * size_t_size * (i + 1) chain = pwndbg.chain.format(int(fastbins[i]), offset=fd_field_offset) print((bold(size) + ': ').ljust(13) + chain)