imports = { "kernel32.dll": { "GetStdHandle": 0, "WriteFile": 0, "ReadFile": 0, "WinExec": 0, }, } data = { welcome: 0, test: 0, } binary32 = PE.Binary("pwn.exe", PE.PE_TYPE.PE32) # Start with 0x100 bytes of \cc section_text = PE.Section(".text") section_text.content = tobytes(x86.Int3().get_code() * 0x100) section_text.virtual_address = 0x1000 # Init data section data_raw = '' for obj in data.keys(): data[obj] = binary32.optional_header.imagebase + len(data_raw) + 0x2000 data_raw += obj section_data = PE.Section(".data") section_data.content = tobytes(data_raw) section_data.virtual_address = 0x2000
def build_pe_executable(asm_code: bytearray, memory_layout: List[MemorySection], arch: Architecture) -> str: """ Uses LIEF to build a standalone binary. Upon success, return the path to the file generated """ if not is_x86_32(arch) and not is_x86_64(arch): raise ValueError("Unsupported architecture for PE generation") is_x64 = is_x86_64(arch) if is_x64: basename = "cemu-pe-amd64-{:s}".format(generate_random_string(5)) pe = PE.Binary(basename, PE.PE_TYPE.PE32_PLUS) else: basename = "cemu-pe-i386-{:s}".format(generate_random_string(5)) pe = PE.Binary(basename, PE.PE_TYPE.PE32) # adding sections sections = {} reladdr = 0x1000 for mem in memory_layout: name, base_address, size, permission = mem.name, mem.address, mem.size, mem.permission if name in (".stack", ): continue sect = PE.Section(name) if name == ".text": # .text section: copy our code and set the entrypoint to the # beginning VA sect.content = asm_code sect.virtual_address = reladdr sect.characteristics = parse_as_lief_pe_permission( permission, "code") sections["text"] = pe.add_section(sect, PE.SECTION_TYPES.TEXT) elif name == ".data": # .data is also sure to exist sect.content = b"\x00" sect.virtual_address = reladdr sect.characteristics = parse_as_lief_pe_permission( permission, "udata") sections["data"] = pe.add_section(sect, PE.SECTION_TYPES.DATA) reladdr += size # fixing pe header pe.header.add_characteristic(PE.HEADER_CHARACTERISTICS.EXECUTABLE_IMAGE) pe.header.add_characteristic(PE.HEADER_CHARACTERISTICS.DEBUG_STRIPPED) if is_x64: pe.header.add_characteristic( PE.HEADER_CHARACTERISTICS.LARGE_ADDRESS_AWARE) else: pe.header.add_characteristic( PE.HEADER_CHARACTERISTICS.CHARA_32BIT_MACHINE) # fixing pe optional header pe.optional_header.addressof_entrypoint = sections["text"].virtual_address pe.optional_header.major_operating_system_version = 0x04 pe.optional_header.minor_operating_system_version = 0x00 pe.optional_header.major_subsystem_version = 0x05 pe.optional_header.minor_subsystem_version = 0x02 pe.optional_header.major_linker_version = 0x02 pe.optional_header.minor_linker_version = 0x1e pe.optional_header.remove(PE.DLL_CHARACTERISTICS.NX_COMPAT) pe.optional_header.add(PE.DLL_CHARACTERISTICS.NO_SEH) # pe.add_library("ntdll.dll") #building exe to disk outfile = f"{tempfile.gettempdir()}{os.path.sep:s}{basename:s}.exe" builder = PE.Builder(pe) builder.build_imports(True) builder.build() builder.write(outfile) return outfile
#!/usr/bin/env python # -*- coding: utf-8 -*- # Description: # Create a PE which pop a MessageBox # with the message "Hello World" # fetch detail : https://lief.quarkslab.com/doc/tutorials/02_pe_from_scratch.html from lief import PE # First we have to create a Binary : binary32 = PE.Binary("pe_from_scratch", PE.PE_TYPE.PE32) # The first parameter is the binary’s name and the second one # is the type: PE32 or PE64 (see PE_TYPE). The Binary‘s constructor # creates automatically DosHeader, Header, OptionalHeader an empty DataDirectory. # # Now that we have a minimal binary, we have to add sections. # We will have a first section holding assembly code (.text) # and a second one containing strings (.data): # A MessageBoxA is composed of a title and a message. # These two strings will be stored in the .data as follows: title = "LIEF is awesome\0" message = "Hello World\0" data = list(map(ord, title)) data += list(map(ord, message)) code = [ 0x6a, 0x00, # push 0x00 uType
from lief import PE a = "tinyPE\0" code = [ 0x6A, 0x00, # push 0 uExitCode 0xFF, 0x15, 0x4C, 0x30, 0x40, 0x00 # call ExitProcess ] data = list(map(ord, a)) binary32 = PE.Binary("testpe", PE.PE_TYPE.PE32) section_text = PE.Section(".text") section_text.content = code section_text.virtual_address = 0x1000 section_data = PE.Section(".data") section_data.content = data section_data.virtual_address = 0x2000 section_text = binary32.add_section(section_text, PE.SECTION_TYPES.TEXT) section_data = binary32.add_section(section_data, PE.SECTION_TYPES.DATA) binary32.optional_header.addressof_entrypoint = section_text.virtual_address # kernel32 = binary32.add_library("kernel32.dll") kernel32.add_entry("ExitProcess") ExitProcess_addr = binary32.predict_function_rva("kernel32.dll", "ExitProcess") #