def __init__(self, pestr=None, loadfrommem=False, parse_resources=True, parse_delay=True, parse_reloc=True, wsize=32): self._rva = ContectRva(self) self._virt = ContentVirtual(self) self.img_rva = StrPatchwork() if pestr is None: self._content = StrPatchwork() self._sex = 0 self._wsize = wsize self.Doshdr = pe.Doshdr(self) self.NTsig = pe.NTsig(self) self.Coffhdr = pe.Coffhdr(self) if self._wsize == 32: Opthdr = pe.Opthdr32 else: Opthdr = pe.Opthdr64 self.Opthdr = Opthdr(self) self.NThdr = pe.NThdr(self) self.NThdr.optentries = [pe.Optehdr(self) for _ in range(0x10)] self.NThdr.CheckSum = 0 self.SHList = pe.SHList(self) self.SHList.shlist = [] self.NThdr.sizeofheaders = 0x1000 self.DirImport = pe.DirImport(self) self.DirExport = pe.DirExport(self) self.DirDelay = pe.DirDelay(self) self.DirReloc = pe.DirReloc(self) self.DirRes = pe.DirRes(self) self.Doshdr.magic = 0x5a4d self.Doshdr.lfanew = 0xe0 self.NTsig.signature = 0x4550 if wsize == 32: self.Opthdr.magic = 0x10b elif wsize == 64: self.Opthdr.magic = 0x20b else: raise ValueError('unknown pe size %r' % wsize) self.Opthdr.majorlinkerversion = 0x7 self.Opthdr.minorlinkerversion = 0x0 self.NThdr.filealignment = 0x1000 self.NThdr.sectionalignment = 0x1000 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 if wsize == 32: self.NThdr.dllcharacteristics = 0x8000 else: self.NThdr.dllcharacteristics = 0x8000 # for createthread self.NThdr.sizeofstackreserve = 0x200000 self.NThdr.sizeofstackcommit = 0x1000 self.NThdr.sizeofheapreserve = 0x100000 self.NThdr.sizeofheapcommit = 0x1000 self.NThdr.ImageBase = 0x400000 self.NThdr.sizeofheaders = 0x1000 self.NThdr.numberofrvaandsizes = 0x10 self.NTsig.signature = 0x4550 if wsize == 32: self.Coffhdr.machine = 0x14c elif wsize == 64: self.Coffhdr.machine = 0x8664 else: raise ValueError('unknown pe size %r' % wsize) if wsize == 32: self.Coffhdr.characteristics = 0x10f self.Coffhdr.sizeofoptionalheader = 0xe0 else: self.Coffhdr.characteristics = 0x22 # 0x2f self.Coffhdr.sizeofoptionalheader = 0xf0 else: self._content = StrPatchwork(pestr) self.loadfrommem = loadfrommem self.parse_content(parse_resources=parse_resources, parse_delay=parse_delay, parse_reloc=parse_reloc)
def parse_content(self, parse_resources=True, parse_delay=True, parse_reloc=True): off = 0 self._sex = 0 self._wsize = 32 self.Doshdr = pe.Doshdr.unpack(self.content, off, self) off = self.Doshdr.lfanew if off > len(self.content): log.warn('ntsig after eof!') self.NTsig = None return self.NTsig = pe.NTsig.unpack(self.content, off, self) self.DirImport = None self.DirExport = None self.DirDelay = None self.DirReloc = None self.DirRes = None if self.NTsig.signature != 0x4550: log.warn('not a valid pe!') return off += len(self.NTsig) self.Coffhdr, length = pe.Coffhdr.unpack_l(self.content, off, self) off += length self._wsize = ord(self.content[off + 1]) * 32 if self._wsize == 32: Opthdr = pe.Opthdr32 else: Opthdr = pe.Opthdr64 if len(self.content) < 0x200: # Fix for very little PE self.content += (0x200 - len(self.content)) * b'\x00' self.Opthdr, length = Opthdr.unpack_l(self.content, off, self) self.NThdr = pe.NThdr.unpack(self.content, off + length, self) self.img_rva[0] = self.content[:self.NThdr.sizeofheaders] off += self.Coffhdr.sizeofoptionalheader self.SHList = pe.SHList.unpack(self.content, off, self) # load section data filealignment = self.NThdr.filealignment sectionalignment = self.NThdr.sectionalignment for section in self.SHList.shlist: virt_size = (section.size // sectionalignment + 1) * sectionalignment if self.loadfrommem: section.offset = section.addr if self.NThdr.sectionalignment > 0x1000: raw_off = 0x200 * (section.offset // 0x200) else: raw_off = section.offset if raw_off != section.offset: log.warn('unaligned raw section (%x %x)!', raw_off, section.offset) section.data = StrPatchwork() if section.rawsize == 0: rounded_size = 0 else: if section.rawsize % filealignment: rs = (section.rawsize // filealignment + 1) * filealignment else: rs = section.rawsize rounded_size = rs if rounded_size > virt_size: rounded_size = min(rounded_size, section.size) data = self.content[raw_off:raw_off + rounded_size] section.data = data # Pad data to page size 0x1000 length = len(data) data += b"\x00" * ((((length + 0xfff)) & 0xFFFFF000) - length) self.img_rva[section.addr] = data # Fix img_rva self.img_rva = self.img_rva try: self.DirImport = pe.DirImport.unpack( self.img_rva, self.NThdr.optentries[pe.DIRECTORY_ENTRY_IMPORT].rva, self) except pe.InvalidOffset: log.warning('cannot parse DirImport, skipping') self.DirImport = pe.DirImport(self) try: self.DirExport = pe.DirExport.unpack( self.img_rva, self.NThdr.optentries[pe.DIRECTORY_ENTRY_EXPORT].rva, self) except pe.InvalidOffset: log.warning('cannot parse DirExport, skipping') self.DirExport = pe.DirExport(self) if len(self.NThdr.optentries) > pe.DIRECTORY_ENTRY_DELAY_IMPORT: self.DirDelay = pe.DirDelay(self) if parse_delay: try: self.DirDelay = pe.DirDelay.unpack( self.img_rva, self.NThdr.optentries[ pe.DIRECTORY_ENTRY_DELAY_IMPORT].rva, self) except pe.InvalidOffset: log.warning('cannot parse DirDelay, skipping') if len(self.NThdr.optentries) > pe.DIRECTORY_ENTRY_BASERELOC: self.DirReloc = pe.DirReloc(self) if parse_reloc: try: self.DirReloc = pe.DirReloc.unpack( self.img_rva, self.NThdr.optentries[ pe.DIRECTORY_ENTRY_BASERELOC].rva, self) except pe.InvalidOffset: log.warning('cannot parse DirReloc, skipping') if len(self.NThdr.optentries) > pe.DIRECTORY_ENTRY_RESOURCE: self.DirRes = pe.DirRes(self) if parse_resources: self.DirRes = pe.DirRes(self) try: self.DirRes = pe.DirRes.unpack( self.img_rva, self.NThdr.optentries[pe.DIRECTORY_ENTRY_RESOURCE].rva, self) except pe.InvalidOffset: log.warning('cannot parse DirRes, skipping')
# Set callbacks sb.jitter.add_breakpoint(end_offset, update_binary) # Run sb.run() # Rebuild PE # Alternative solution: miasm.jitter.loader.pe.vm2pe(sb.jitter, out_fname, # libs=sb.libs, e_orig=sb.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 bname, fname = os.path.split(options.filename) fname = os.path.join(bname, fname.replace('.', '_'))