lief-project / LIEF

LIEF - Library to Instrument Executable Formats (C++, Python, Rust)
https://lief.re
Apache License 2.0
4.48k stars 621 forks source link

Building & patching imports leads to a crash in x64 PE #777

Open dzervas opened 2 years ago

dzervas commented 2 years ago

Describe the bug I'm trying to add a single DLL to the import table of a x64 EXE

To Reproduce Steps to reproduce the behavior:

Expected behavior The executable should execute regularly without any new crashes

Environment (please complete the following information):

Additional context Code used:

def download_libgadget(path=".", bitness="x86"):
    libpath = path + "/libgadget.dll"
    if os.path.isfile(libpath):
        print(f"[+] {libpath} already exists, skipping")
        return None

    latest = requests.get("https://api.github.com/repos/frida/frida/releases/latest").json()

    for a in latest["assets"]:
        if a["name"].startswith("frida-gadget") and a["name"].endswith(f"windows-{bitness}.dll.xz"):
            url = a["browser_download_url"]
            print("[+] Downloading", url)

            r = requests.get(url, allow_redirects=True)
            open(libpath + ".xz", "wb").write(r.content)
            with lzma.open(libpath + ".xz", "rb") as f:
                open(libpath, "wb").write(f.read())

            print("[+] Downloaded", a["name"])

            break

def inject(binary):
    injected = lief.parse(binary)
    bitness = 32

    if injected.header.machine == lief.PE.MACHINE_TYPES.I386:
        print("[+] Detected 32 bit PE")
    elif injected.header.machine == lief.PE.MACHINE_TYPES.AMD64:
        print("[+] Detected 64 bit PE")
        bitness = 64
    else:
        print("[!] Unable to detected binary bitness")
        exit(1)

    download_libgadget(realpath(dirname(binary)), "x86" if bitness == 32 else "x86_64")
    gadget = injected.add_library("libgadget.dll")
    gadget.add_entry("frida_gadget_wait_for_permission_to_resume")

    builder = lief.PE.Builder(injected)
    builder.build_imports(True)
    builder.patch_imports(True)
    builder.build()
    os.rename(binary, binary + ".b-" + str(datetime.now().isoformat()))
    builder.write(binary)

if __name__ == "__main__":
    from sys import argv
    inject(argv[1])

error.txt

Unfortunately I can't freely redistribute the executable so contact me if you need it to send it privately

romainthomas commented 2 years ago

Yes, actually the modification of the import/export table for PE binary is very (very) limited. I'll have to refactor this part around November.

dzervas commented 2 years ago

Are there any other solutions to inject frida into an exe? I don't get why nobody does it and there's literally nothing out there

receiver1 commented 3 months ago

it looks like the refactoring never happened, the crashes are still going on

jclab-joseph commented 3 months ago

+1

Grivus commented 3 months ago

+1

babaee404 commented 3 months ago

this code generate exe file but after run it crash filePath= r"PE64_x86-64_binary_mfc-application.exe" outFile= r"out-1.exe" peFile = lief.parse(filePath)

kernel32_lhs = peFile.add_library("user32.dll") kernel32_lhs.add_entry("UnregisterClassW")

builder = lief.PE.Builder(peFile)

builder.build_imports(True).patch_imports(True) builder.build()

builder.write(outFile)

receiver1 commented 1 month ago

this code generate exe file but after run it crash filePath= r"PE64_x86-64_binary_mfc-application.exe" outFile= r"out-1.exe" peFile = lief.parse(filePath)

kernel32_lhs = peFile.add_library("user32.dll") kernel32_lhs.add_entry("UnregisterClassW")

builder = lief.PE.Builder(peFile)

builder.build_imports(True).patch_imports(True) builder.build()

builder.write(outFile)

Import rebuild is broken for X64.

Redbeanw44602 commented 2 weeks ago

Two years have passed and the crash continues :(

jclab-joseph commented 2 weeks ago

We also needed to add the dll to the import table of the exe.

https://github.com/Snshadow/debug It was a difficult work, but he succeeded! It was made in Go and works well. With this as a reference, someone might be able to fix LIEF too.