def parse_content(self, parse_resources=True, parse_delay=True, parse_reloc=True): h = struct.unpack("BB", self.content[:2]) if h != (0x4d, 0x5a): # magic number, MZ raise ValueError("Not a PE, no MZ magic number") of = 0 self.sex = '<' self.wsize = 32 self.DOShdr = pe.DOShdr(parent=self, content=self.content, start=of) of = self.DOShdr.lfanew if of > len(self.content): raise ValueError('Not a PE, NTsig offset after eof %#x', of) self.NTsig = pe.NTsig(parent=self, content=self.content, start=of) if self.NTsig.signature != 0x4550: # PE\0\0 raise ValueError('Not a PE, NTsig is %#x', self.NTsig.signature) of += self.NTsig.bytelen self.COFFhdr = pe.COFFhdr(parent=self, content=self.content, start=of) of += self.COFFhdr.bytelen magic, = struct.unpack('H', self.content[of:of + 2]) self.wsize = (magic >> 8) * 32 if not magic in (0x10b, 0x20b): # e.g. Ange Albertini's d_nonnull.dll d_tiny.dll log.warning('Opthdr magic %#x', magic) self.wsize = 32 self.Opthdr = { 32: pe.Opthdr32, 64: pe.Opthdr64 }[self.wsize](parent=self, content=self.content, start=of) l = self.Opthdr.bytelen self.NThdr = pe.NThdr(parent=self, content=self.content, start=of + l) of += self.COFFhdr.sizeofoptionalheader if self.NThdr.numberofrvaandsizes < 13: log.warning('Windows 8 needs at least 13 directories, %d found', self.NThdr.numberofrvaandsizes) # Even if the NT header has 64-bit pointers, in 64-bit PE files # the Section headers have 32-bit pointers (it is a 32-bit COFF # in a 64-bit PE). self.SHList = pe.SHList(parent=self, content=self.content, start=of, wsize=32) # Directory parsing. # 'start' is None, because the offset is computed from the RVA # in the NT header kargs = {'parent': self, 'content': self.content, 'start': None} self.DirImport = pe.DirImport(**kargs) self.DirExport = pe.DirExport(**kargs) if parse_delay: self.DirDelay = pe.DirDelay(**kargs) if parse_reloc: self.DirReloc = pe.DirReloc(**kargs) if parse_resources: self.DirRes = pe.DirRes(**kargs) if self.COFFhdr.pointertosymboltable != 0: if self.COFFhdr.pointertosymboltable + 18 * self.COFFhdr.numberofsymbols > len( self.content): log.warning('Too many symbols: %d', self.COFFhdr.numberofsymbols) self.Symbols = pe.CoffSymbols(**kargs) if hasattr(self, 'Symbols'): of = self.COFFhdr.pointertosymboltable + self.Symbols.bytelen sz, = struct.unpack(self.sex + 'I', self.content[of:of + 4]) if len(self.content) < of + sz: log.warning('File too short for StrTable %#x != %#x' % (len(self.content) - of, sz)) sz = len(self.content) - of self.SymbolStrings = StrTable(self.content[of:of + sz])
sb.pe.virt[sb.pe.rva2virt(s.addr)] = sdata # Set callbacks sb.jitter.add_breakpoint(end_label, update_binary) # Run sb.run() # Rebuild PE new_dll = [] sb.pe.SHList.align_sections(0x1000, 0x1000) logging.info(repr(sb.pe.SHList)) sb.pe.DirRes = pe.DirRes(sb.pe) sb.pe.DirImport.impdesc = None logging.info(repr(sb.pe.DirImport.impdesc)) new_dll = sb.libs.gen_new_lib(sb.pe) logging.info(new_dll) sb.pe.DirImport.impdesc = [] sb.pe.DirImport.add_dlldesc(new_dll) s_myimp = sb.pe.SHList.add_section(name="myimp", rawsize=len(sb.pe.DirImport)) logging.info(repr(sb.pe.SHList)) sb.pe.DirImport.set_rva(s_myimp.addr) # XXXX TODO sb.pe.NThdr.optentries[pe.DIRECTORY_ENTRY_DELAY_IMPORT].rva = 0 sb.pe.Opthdr.AddressOfEntryPoint = sb.pe.virt2rva(end_label) bname, fname = os.path.split(options.filename)
def __init__(self, pestr=None, parse_resources=True, parse_delay=True, parse_reloc=True, wsize=32): self._rva = ContentRVA(self) self._virt = ContentVirtual(self) if pestr == None: self.sex = '<' self.wsize = wsize self.DOShdr = pe.DOShdr(parent=self, wsize=32) self.NTsig = pe.NTsig(parent=self, wsize=32) self.COFFhdr = pe.COFFhdr(parent=self, wsize=32) self.Opthdr = { 32: pe.Opthdr32, 64: pe.Opthdr64 }[wsize](parent=self) self.NThdr = pe.NThdr(parent=self) self.SHList = pe.SHList(parent=self, wsize=32) self.DirImport = pe.DirImport(parent=self) self.DirExport = pe.DirExport(parent=self) self.DirDelay = pe.DirDelay(parent=self) self.DirReloc = pe.DirReloc(parent=self) self.DirRes = pe.DirRes(parent=self) self.DOShdr.magic = 0x5a4d self.DOShdr.lfanew = 0xe0 if wsize == 32: self.COFFhdr.machine = pe.IMAGE_FILE_MACHINE_I386 self.COFFhdr.characteristics = 0x10f self.COFFhdr.sizeofoptionalheader = 0xe0 self.Opthdr.magic = pe.IMAGE_NT_OPTIONAL_HDR32_MAGIC elif wsize == 64: self.COFFhdr.machine = pe.IMAGE_FILE_MACHINE_AMD64 self.COFFhdr.characteristics = 0x22 self.COFFhdr.sizeofoptionalheader = 0xf0 self.Opthdr.magic = pe.IMAGE_NT_OPTIONAL_HDR64_MAGIC self.Opthdr.majorlinkerversion = 0x7 self.Opthdr.minorlinkerversion = 0x0 self.NThdr.ImageBase = 0x400000 self.NThdr.sectionalignment = 0x1000 self.NThdr.filealignment = 0x200 self.NThdr.filealignment = 0x1000 # previous versions of elfesteem self.NThdr.majoroperatingsystemversion = 0x5 self.NThdr.minoroperatingsystemversion = 0x1 self.NThdr.MajorImageVersion = 0x5 self.NThdr.MinorImageVersion = 0x1 self.NThdr.majorsubsystemversion = 0x4 self.NThdr.minorsubsystemversion = 0x0 self.NThdr.subsystem = 0x3 self.NThdr.dllcharacteristics = 0x8000 self.NThdr.sizeofstackreserve = 0x200000 self.NThdr.sizeofstackcommit = 0x1000 self.NThdr.sizeofheapreserve = 0x100000 self.NThdr.sizeofheapcommit = 0x1000 self.NThdr.sizeofheaders = 0x1000 self.NThdr.numberofrvaandsizes = 0x10 self.NThdr.optentries = pe.OptNThdrs(parent=self.NThdr) for _ in range(self.NThdr.numberofrvaandsizes): self.NThdr.optentries.append( pe.OptNThdr(parent=self.NThdr.optentries)) self.NThdr._size += self.NThdr.optentries.bytelen self.NThdr.CheckSum = 0 self.NTsig.signature = 0x4550 self.content = StrPatchwork(self.pack()) else: self.content = StrPatchwork(pestr) self.parse_content(parse_resources=parse_resources, parse_delay=parse_delay, parse_reloc=parse_reloc) # For API compatibility with previous versions of elfesteem self._sex = '<>'.index(self.sex) self._wsize = self.wsize