def disasm(self, src, args): """Use pwntools to disassemble a given piece of bytecode.""" try: res = pwn.disasm(args[0].decode('string_escape')) for line in res.split('\n'): self.send(src, line) except Exception, e: self.send(src, e)
def examine(self, cmd): """examine memory. (use of $reg is possible) formatting options: b,w,h,g""" size_modifiers = dict([("b", (1, "B")), ("h", (2, "H")), ("w", (4, "L")), ("g", (8, "Q"))]) instr, _, cmd = cmd.partition(" ") try: address = parseInteger(cmd, self) # make sure adress is in virtual adress space where_symbol, where_ad = self.programinfo.where(address) except ValueError as e: return str(e) except FileNotFoundError: # happens if we inspect something that is not an ELF file where_symbol, where_ad = "", address # check if user specified some special formatting if "/" in instr: _, _, instr = instr.partition("/") args = PRINT_ARGS_REGEX.match(instr) count = int(args.group(1)) if args.group(1) else 1 fmt = args.group(2) if fmt not in size_modifiers.keys() and fmt is not "i": if fmt: print("fmt %s is not an option" % fmt) fmt = "w" else: count = 1 fmt = "w" # special case, disassemble and return early if fmt == "i": count_read = count grow_factor = .5 while True: count_read = int(count_read * (1 + grow_factor)) try: bytesread = self.ptraceProcess.readBytes( address, count_read) except PtraceError as e: # incase we cant read count*1.5 bytes because memory isnt mapped print( e ) # this is shitty code, but it should almost never occur if grow_factor <= .5**(2 * 6): count //= 2 grow_factor = 0.5 count_read = count grow_factor = grow_factor**2 continue lines = pwn.disasm(bytesread, byte=False, vma=address).splitlines(keepends=True) # keep reading more bytes until we cleanly disassemlbe COUNT instructions if any(".byte" in line for line in lines[:count]): continue else: return "".join(lines) # regular case size, unpack_fmt = size_modifiers[fmt] unpack_fmt = "<" + unpack_fmt # read data from memory and print it accordingly try: bytesread = self.ptraceProcess.readBytes(address, size * count) except PtraceError as e: return str(e) # to print offset symbol_delta = address - where_ad line_pref = lambda offset: where_symbol + "+%#x" % (symbol_delta + offset) format_str = " %0" + "%d" % (size * 2) + "x" # to pad with zeros newLineAfter = 16 // size result = "" for i, value in enumerate(iter_unpack(unpack_fmt, bytesread)): if i % newLineAfter == 0: result += "\n" + line_pref(i) result += format_str % value return result[1:] # remove first newline
def get_ASM_instructions(self, start_address, size=30, offset=0): blob = self.pe.get_data(start_address, size) return disasm(blob, arch="i386", offset=offset)
#!/usr/bin/env python3 import sys import pwn def parse_sexpr(s): '''Parse an s-expr of the form (= foobarF3 0b0001) to a tuple of the form ('=', 0xf3, 1)''' toks = s[1:-2].split() return (toks[0], int(toks[1][len('bytecode'):], 16) if toks[1].startswith('bytecode') else toks[1], int(toks[2], 2)) def sexprs_to_bytes(sexprs): num_instrs = list(filter(lambda sexpr: sexpr[1] == 'NumInstrs', sexprs))[0][2] sexprs = filter(lambda sexpr: sexpr[1] != 'NumInstrs', sexprs) sexprs = sorted(sexprs, key=lambda sexpr: sexpr[1]) return num_instrs, bytes(map(lambda sexpr: sexpr[2], sexprs)) if __name__ == '__main__': sexprs = list(map(parse_sexpr, sys.stdin.readlines()[1:])) num_instrs, b = sexprs_to_bytes(sexprs) print(f'num_instrs = {num_instrs}') print(repr(b)) print(pwn.disasm(b))
import pwn import re import sys with open('./stuck_in_the_past.exe', 'rb') as f: binary = f.read() code = binary[0x7DE:0x3EC8] code = pwn.disasm(code, byte=False, offset=False) instr_dict = { 'nop': '', 'xchg ax, ax': '', 'push 0x1\npush 0x0\nmov eax, 0x4010f6\njmp eax': '>', 'push 0x1\npush 0x21\nmov eax, 0x4010f6\njmp eax': '<', 'push 0x1\npush 0x42\nmov eax, 0x4010f6\njmp eax': 'v', 'push 0x1\npush 0x63\nmov eax, 0x4010f6\njmp eax': '^', 'push 0x1\npush 0x70\nmov eax, 0x4010f6\njmp eax': '#', 'push 0x2\npush 0x70\nmov eax, 0x4010f6\njmp eax': '#', 'push 0x0\nmov eax, 0x401124\njmp eax': '+', 'push 0x4\nmov eax, 0x401124\njmp eax': '-', 'push 0x8\nmov eax, 0x401124\njmp eax': '*', 'push 0xc\nmov eax, 0x401124\njmp eax': '/', 'push 0x15\nmov eax, 0x401124\njmp eax': '%', 'mov eax, 0x4010fe\njmp eax': '_', 'mov eax, 0x401111\njmp eax': '|', 'mov eax, 0x401153\njmp eax': '!', 'mov eax, 0x40115f\njmp eax': ':', 'mov eax, 0x401167\njmp eax': '\\', 'mov eax, 0x401170\njmp eax': '$', 'mov eax, 0x401176\njmp eax': '?',
def parse_command(self): """ Arguments pc: current pc address handler: process an instruction, argument is pc address. """ pc = self.getpc() def check_breakpoint(pc): if not self.breakpoints.has_key(pc): return False elif self.breakpoints[pc] is True: return True return False if self.stopped or check_breakpoint(pc): if self.last_cmd in ['ni', 'c']: print '-' * 25 + ' register ' + '-' * 25 self.show_register() print '-' * 25 + ' code ' + '-' * 25 opcode = self.getMemory(pc, 32) lines = disasm(opcode).splitlines() for i in range(5): line = lines[i] addr, disasm_code = line[:line.index(":")], line[ line.index(":"):] new_addr = pc + int(addr, 16) print hex(new_addr) + disasm_code print '-' * 25 + ' stack ' + '-' * 25 self.show_stack() if check_breakpoint(pc): print 'Breakpoint at ' + hex(pc).strip('L') self.stopped = True cmd = raw_input("> ").strip('\n') if not cmd: if self.last_cmd: cmd = self.last_cmd else: while not cmd: cmd = raw_input("> ").strip('\n') cmd = new_cmd self.last_cmd = cmd.split(' ')[0] if cmd.startswith('b ') or cmd.startswith('break '): addr = int(cmd.split(' ')[1], 16) self.set_breakpoint(addr) return pc elif cmd in ['continue', 'c']: self.stopped = False return self.process() elif cmd.startswith('db'): self.del_breakpoint(cmd) return pc elif cmd in ['listbreak', 'lb']: self.list_breakpoint() return pc elif cmd in ['next', 'n', 'ni']: return self.process() elif cmd in ['reg', 're', 'r']: self.show_register() return pc elif cmd == 'stack': self.show_stack() return pc elif cmd.startswith('x '): self.memory_x(cmd) return pc else: print 'unknown command' return pc else: return self.process()
import pwn import code alphabet = ['A', 'A#', 'B', 'C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#'] def word2note(n): import math new_n = float(n / 27.5) res = int((math.log(new_n, 2) * 12.0 + 0.5)) return '{}{}'.format(alphabet[res % 12], res / 12) print word2note(0x71) print word2note(0x67de) conv = dict() for i in xrange(0x1b, 0x67de + 1): conv[pwn.disasm(word2note(i), arch='i386')] = i code.interact(local=locals()) print len(conv) print conv
def shellcode_to_asm(shellcode, byte=True, offset=True): 'Convert shellcode into x86 asm code.' return disasm(shellcode, byte=byte, offset=offset).split('\n')
box[i], box[x] = box[x], box[i] x = y = 0 out = [] for char in data: x = (x + 1) % 256 y = (y + box[x]) % 256 box[x], box[y] = box[y], box[x] out.append(char ^ box[(box[x] + box[y]) % 256]) return bytes(out) with open('./chall.hbt', 'rb') as f: hbt = f.read() key1 = hbt[0x8:0x18] key2 = hbt[0x18:0x28] data = crypt(hbt[0x40:0x80], key1) code = pwn.disasm(crypt(hbt[0x80:], key2)) pwn.log.info(code) flag = bytearray(data[0x19:0x19 + 0x27]) for i in range(len(flag)): flag[i] ^= (0x27 - i) flag = bytes(flag).decode() pwn.log.info(flag)
return None except KeyboardInterrupt: raise except EOFError: pwn.log.debug("got EOF for leaking addr 0x{:x}".format(addr)) pass except Exception: pwn.log.warning("got exception...", exc_info=sys.exc_info()) finally: if vp: vp.close() return None leaked = "" base_addr = 0x400000 if __name__ == "__main__": while len(leaked) < 32000: addr = base_addr + len(leaked) x = fmtleaker(addr) if x: leaked += x else: leaked += "\xff" if len(leaked) % 128 == 0: with open("out.elf", "wb") as f: f.write(leaked) pwn.disasm(data, arch='amd64')