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 got(name_filter=''): relro_status = pwndbg.wrappers.checksec.relro_status() pie_status = pwndbg.wrappers.checksec.pie_status() jmpslots = list(pwndbg.wrappers.readelf.get_jmpslots()) if not len(jmpslots): print(red("NO JUMP_SLOT entries available in the GOT")) return if "PIE enabled" in pie_status: bin_text_base = pwndbg.memory.page_align(pwndbg.elf.entry()) print("\nGOT protection: %s | GOT functions: %d\n " % (green(relro_status), len(jmpslots))) for line in jmpslots: address, info, rtype, value, name = line.split()[:5] if name_filter not in name: continue address_val = int(address, 16) if "PIE enabled" in pie_status: # if PIE, address is only the offset from the binary base address address_val = bin_text_base + address_val got_address = pwndbg.memory.pvoid(address_val) print("[0x%x] %s -> %s" % (address_val, light_yellow(name), pwndbg.chain.format(got_address)))
def instruction(ins): asm = '%-06s %s' % (ins.mnemonic, ins.op_str) # TODO: detect 'arm', 'x86,64' is only for Intel x86/64 _highlighted, asm = pwndbg.color.syntax_highlight(asm, language='ARM') is_branch = set(ins.groups) & capstone_branch_groups # Highlight the current line if enabled if pwndbg.config.highlight_pc and ins.address == pwndbg.regs.pc: asm = C.highlight(asm) # tl;dr is a branch? if ins.target not in (None, ins.address + ins.size): sym = pwndbg.symbol.get(ins.target) or None target = M.get(ins.target) const = ins.target_const hextarget = hex(ins.target) hexlen = len(hextarget) # If it's a constant expression, color it directly in the asm. if const: asm = asm.replace(hex(ins.target), sym or target) if sym: asm = '%s <%s>' % (ljust_colored(asm, 36), target) # It's not a constant expression, but we've calculated the target # address by emulation. elif sym: asm = '%s <%s; %s>' % (ljust_colored(asm, 36), target, sym) # We were able to calculate the target, but there is no symbol # name for it. else: asm += '<%s>' % (target) # not a branch elif ins.symbol: if is_branch and not ins.target: asm = '%s <%s>' % (asm, ins.symbol) # XXX: not sure when this ever happens asm += '<-- file a pwndbg bug for this' else: asm = asm.replace(hex(ins.symbol_addr), ins.symbol) asm = '%s <%s>' % (ljust_colored(asm, 36), M.get(ins.symbol_addr)) # Style the instruction mnemonic if it's a branch instruction. if is_branch: asm = asm.replace(ins.mnemonic, branch(ins.mnemonic), 1) # If we know the conditional is taken, mark it as green. if ins.condition is None: asm = ' ' + asm elif ins.condition: asm = green('✔ ') + asm else: asm = ' ' + asm return asm
def got(name_filter=''): local_path = pwndbg.file.get_file(pwndbg.proc.exe) cs_out = pwndbg.wrappers.checksec("--file", local_path) file_out = pwndbg.wrappers.file(local_path) if "statically" in file_out: return "Binary is statically linked." readelf_out = pwndbg.wrappers.readelf("-r", local_path) jmpslots = '\n'.join( filter(lambda l: _extract_jumps(l), readelf_out.splitlines())) if not len(jmpslots): return "NO JUMP_SLOT entries available in the GOT" if "PIE enabled" in cs_out: bin_text_base = pwndbg.memory.page_align(pwndbg.elf.entry()) relro_status = "No RELRO" if "Full RELRO" in cs_out: relro_status = "Full RELRO" elif "Partial RELRO" in cs_out: relro_status = "Partial RELRO" print("\nGOT protection: %s | GOT functions: %d\n " % (green(relro_status), len(jmpslots.splitlines()))) for line in jmpslots.splitlines(): address, info, rtype, value, name = line.split()[:5] if name_filter not in name: continue address_val = int(address, 16) if "PIE enabled" in cs_out: # if PIE, address is only the offset from the binary base address address_val = bin_text_base + address_val got_address = pwndbg.memory.pvoid(address_val) print("[%s] %s -> %s" % (address, light_yellow(name), pwndbg.chain.format(got_address)))
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()