Skip to content

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

Closed
@dzervas

Description

@dzervas

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:

  • Parse the exe
  • add_library
  • add_entry
  • create a builder with build_imports and patch_imports
  • execute it

Expected behavior
The executable should execute regularly without any new crashes

Environment (please complete the following information):

  • System and Version : Manjaro with kernel 5.15.60-1-MANJARO
  • Target format (PE, ELF, Mach-O): PE
  • LIEF commit version: python -c "import lief;print(lief.__version__)" or the one from LIEF/config.h: 0.12.1-

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

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions