04 May 2019
Using Python module pefile to rewrite a Windows PE/PE+ file (I think both 32-bit and 64-bit are supported, tested 64-bit only). The goal is to append a new section, change the executable's entry point to the new section, jump back to the original entry point (OEP).
#!/usr/env python3 import pefile def adjust_SectionSize(sz, align): if sz % align: sz = ((sz + align) // align) * align return sz pe = pefile.PE('../hello.exe') last_section = pe.sections[-1] new_section = pefile.SectionStructure(pe.__IMAGE_SECTION_HEADER_format__) # fill with zeros new_section.__unpack__(bytearray(new_section.sizeof())) # place section header after last section header (assume there is enough room) new_section.set_file_offset(last_section.get_file_offset() + last_section.sizeof()) new_section.Name = b'.test' new_section_size = 100 new_section.SizeOfRawData = adjust_SectionSize(new_section_size, pe.OPTIONAL_HEADER.FileAlignment) new_section.PointerToRawData = len(pe.__data__) new_section.Misc = new_section.Misc_PhysicalAddress = new_section.Misc_VirtualSize = new_section_size new_section.VirtualAddress = last_section.VirtualAddress + adjust_SectionSize(last_section.Misc_VirtualSize, pe.OPTIONAL_HEADER.SectionAlignment) new_section.Characteristics = 0x40000000 | 0x20000000 | 0x20 # read | execute | code # create new section data containing jump to OEP reljmp = pe.OPTIONAL_HEADER.AddressOfEntryPoint - (new_section.VirtualAddress + 5) print('rel jmp %08x' % (reljmp)) new_section_data = bytearray(new_section.SizeOfRawData) new_section_data[0] = 0xe9 new_section_data[1:4] = reljmp.to_bytes(4, byteorder='little', signed=True) # change address of entry point to beginning of new section pe.OPTIONAL_HEADER.AddressOfEntryPoint = new_section.VirtualAddress # increase size of image pe.OPTIONAL_HEADER.SizeOfImage += adjust_SectionSize(new_section_size, pe.OPTIONAL_HEADER.SectionAlignment) # increase number of sections pe.FILE_HEADER.NumberOfSections += 1 # append new section to structures pe.sections.append(new_section) pe.__structures__.append(new_section) # add new section data to file pe.__data__ = bytearray(pe.__data__) + new_section_data pe.write('../hello_patched.exe')
posted at: 10:33 | path: /programming | permanent link