rendered paste bodyimport syssys.path.append('..\\..')from PyStand import Structuint16 = Struct.uint16uint32 = Struct.uint32import XBECODE = 0x00000020INITDATA = 0x00000040UNINITDATA = 0x00000080COMMENTS = 0x00000200NOFINAL = 0x00000800DISCARD = 0x02000000SHAREABLE = 0x10000000EXECUTABLE = 0x20000000READABLE = 0x40000000WRITABLE = 0x80000000class ImageFileHeader(Struct): __endian__ = Struct.LE def __format__(self): self.machine, self.numberOfSections = uint16[2] self.timestamp, self.symtab, self.numsyms = uint32[3] self.optHdrSize, self.characteristics = uint16[2]class ImageOptionalHeader(Struct): __endian__ = Struct.LE def __format__(self): self.Magic = uint16 self.LinkerVersion = Struct.uint8[2] self.SizeOfCode, self.SizeOfInitializedData = uint32[2] self.SizeOfUninitializedData = uint32 self.AddressOfEntryPoint = uint32 self.BaseOfCode, self.BaseOfData = uint32[2] self.ImageBase, self.SectionAlignment, self.FileAlignment = uint32[3] self.OperatingSystemVersion = uint16[2] self.ImageVersion = uint16[2] self.SubsystemVersion = uint16[2] self.Reserved = uint32 self.SizeOfImage, self.SizeOfHeaders, self.Checksum = uint32[3] self.Subsystem, self.DllCharacteristics = uint16[2] self.SizeOfStackReserve, self.SizeOfStackCommit = uint32[2] self.SizeOfHeapReserve, self.SizeOfHeapCommit = uint32[2] self.LoaderFlags, self.NumberOfRvaAndSizes = uint32[2] self.DataDirectory = uint32[32] class ImageSectionHeader(Struct): __endian__ = Struct.LE def __format__(self): self.Name = Struct.string(8, stripNulls=True) self.VirtualSize, self.VirtualAddress = uint32[2] self.SizeOfRawData, self.RawData = uint32[2] self.Relocations, self.Linenumbers = uint32[2] self.NumRelocations, self.NumLinenumbers = uint16[2] self.Characteristics = uint32class ImageImportDirectory(Struct): __endian__ = Struct.LE def __format__(self): self.RVAFunctionNameList = uint32 self.useless = uint32[2] self.RVAModuleName = uint32 self.RVAFunctionAddressList = uint32# This is neither an XBE or PE structure, just a convenience structclass XBEPEImportDirectory(Struct): __endian__ = Struct.LE def __format__(self): self.kernel32, self.sclera = ImageImportDirectory()[2] # 0000 self.dllname1 = Struct.string(16, value='kernel32.dll\0\0\0\0') # 0014 self.dllname2 = Struct.string(12, value='sclera.dll\0\0') # 0024 self.emptylist = self.uint32 # 0030class PE(object): def __init__(self, xbe): self.xbe = xbe def write(self, fp): fp.write('MZ') fp.write('\0' * 58) fp.write(uint32(64)) imgheader = ImageFileHeader() imgheader.machine = 0x14C # x86 imgheader.numberOfSections = len(self.xbe.sections) + 1 # +1 for import directory imgheader.timestamp = 0 imgheader.symtab = 0 imgheader.numsyms = 0 imgheader.characteristics = 0x0003 # No relocations and executable imgoptheader = ImageOptionalHeader() imgheader.optHdrSize = len(imgoptheader) imgoptheader.Magic = 0x010B imgoptheader.AddressOfEntryPoint = self.xbe.entry - self.xbe.base imgoptheader.ImageBase = self.xbe.base imgoptheader.SectionAlignment = 1 imgoptheader.FileAlignment = 1 imgoptheader.OperatingSystemVersion[0] = 1 imgoptheader.SubsystemVersion = [3, 1] imgoptheader.SizeOfImage = 0 imgoptheader.Subsystem = 2 # Windows GUI imgoptheader.DllCharacteristics = 0xF imgoptheader.SizeOfStackReserve = 0x100000 imgoptheader.SizeOfStackCommit = 0x100000 imgoptheader.SizeOfHeapReserve = 0x100000 imgoptheader.SizeOfHeapCommit = 0x001000 imgoptheader.NumberOfRvaAndSizes = 0 imgsectheader = ImageSectionHeader() imgoptheader.SizeOfHeaders = 64 + 4 + len(imgheader) + len(imgoptheader) imgoptheader.SizeOfHeaders += (len(imgsectheader) * len(self.xbe.sections)) dirBase = max(sect.addr + sect.size for sect in self.xbe.sections.values()) imgoptheader.DataDirectory[2] = dirBase - self.xbe.base imgimpdirectory = XBEPEImportDirectory() imgimpdirectory.kernel32.RVAModuleName = dirBase + 0x14 - self.xbe.base # Offset to 'kernel32.dll\0\0\0\0' imgimpdirectory.sclera.RVAModuleName = dirBase + 0x24 - self.xbe.base # Offset to 'sclera.dll\0\0' imgimpdirectory.kernel32.RVAFunctionNameList = dirBase + 0x30 - self.xbe.base # Offset to ending uint32 imgimpdirectory.kernel32.RVAFunctionAddressList = dirBase + 0x30 - self.xbe.base # Offset to ending uint32 imgimpdirectory.sclera.RVAFunctionNameList = dirBase + 0x30 - self.xbe.base # Offset to ending uint32 imgimpdirectory.sclera.RVAFunctionAddressList = dirBase + 0x30 - self.xbe.base # Offset to ending uint32 imgimplen = len(imgimpdirectory) imgoptheader.DataDirectory[3] = imgimplen fp.write('PE\0\0') fp.write(imgheader.pack()) fp.write(imgoptheader.pack()) sectpos = fp.tell() + (len(imgsectheader) * len(self.xbe.sections)) for sect in self.xbe.sections.values(): imgsectheader.Name = sect.name imgsectheader.VirtualSize = sect.size imgsectheader.VirtualAddress = sect.addr - self.xbe.base imgsectheader.SizeOfRawData = len(sect.data) imgsectheader.RawData = sectpos imgsectheader.Characteristics = READABLE imgsectheader.Characteristics |= (sect.flags & XBE.EXECUTABLE and EXECUTABLE) or 0 imgsectheader.Characteristics |= (sect.flags & XBE.WRITABLE and WRITABLE) or 0 imgsectheader.Characteristics |= (sect.flags & XBE.PRELOAD and INITDATA) or 0 fp.write(imgsectheader.pack()) sectpos += len(sect.data) imgsectheader.Name = '.idata' imgsectheader.VirtualSize = imgimplen imgsectheader.VirtualAddress = dirBase imgsectheader.SizeOfRawData = imgimplen imgsectheader.RawData = sectpos imgsectheader.Characteristics = READABLE | INITDATA fp.write(imgsectheader.pack()) sectpos += imgimplen for sect in self.xbe.sections.values(): fp.write(sect.data) fp.write(imgimpdirectory.pack())