def make_writable(self, addr): for prog in self.elf.progs: if elfutil.is_load(prog): if addr in prog and prog.flags & 2 == 0: self.debug('[!] Segment made writable: 0x%x-0x%x' % (prog.vaddr, prog.vaddr + prog.memsz)) prog.flags |= 2
def patch(self): cwd = os.getcwd() try: for path, pathname in self.patchfiles: sys.path.insert(0, os.path.dirname(path)) print '[*]', pathname patchfile = os.path.basename(path).rsplit('.', 1)[0] patch = __import__(patchfile) sys.path.pop(0) # preserve function order try: source, _ = inspect.getsourcelines(patch) order = [] for line in source: if line.startswith('def'): name = line.split(' ', 1)[1].split('(', 1)[0] try: order.append(getattr(patch, name)) except AttributeError: pass except Exception: print 'Warning: could not preserve patch function order' traceback.print_exc() order = vars(patch).values() for func in order: if func.__name__.startswith('_'): # skip "private" functions continue if hasattr(func, '__call__'): print ' [+] %s()' % func.__name__ with self.bin.collect() as patchset: try: func(patchset) except Exception as e: print 'Exception thrown by patch:', path, func.__name__ traceback.print_exc() print 'Memory maps:' for prog in self.bin.elf.progs: if elfutil.is_load(prog): print '0x%x-0x%x' % (prog.vaddr, prog.vaddr + prog.vsize) sys.exit(1) print finally: os.chdir(cwd)
def __init__(self, path): self.path = path self.fileobj = open(path, 'rb') self.elf = elffile.open(fileobj=self.fileobj) self.linker = Linker(self) self.final_hook = [] self.asm_hook = [] self.c_hook = [] self.verbose = False autolink.declare(self.linker) start = 0xFFFFFFFFFFFFFFFF end = 0 # TODO: doesn't handle new mem being mapped or unmapped for ph in reversed(self.elf.progs): if elfutil.is_load(ph): start = min(start, ph.vaddr) end = max(ph.vaddr + ph.vsize, end) # add patch segment def new_segment(addr): align = 0x1000 ph = self.elf.programHeaderClass() ph.data = bytearray() ph.type = PT.byname['PT_LOAD'].code ph.vaddr = (addr + align - 1) & ~(align - 1) ph.paddr = ph.vaddr # TODO: default is RWX?! ph.flags = 7 ph.align = align ph.memsz = 0 ph.filesz = 0 self.elf.progs.append(ph) return ph self.patch = new_segment(end) self.nxpatch = new_segment(end + 0x800000) self.nxpatch.flags = 6 self.linkpatch = new_segment(end + 0x1600000) self.jitpatch = new_segment(end + 0x2400000) self.entry_hooks = []