ghidra-firmware-utils icon indicating copy to clipboard operation
ghidra-firmware-utils copied to clipboard

UEFIHelper.java exception with position-independent PE32's

Open zznop opened this issue 3 years ago • 3 comments

If a UEFI PE32 module is built position-independent, Ghidra loads it at 0x10000. When it searches for global assignments, it finds the SystemTable->BootServices, which in almost every case is somewhere before 0x10000 because it's based on the PE being loaded at 0. It then tries to apply a type before the base of the PE raising an exception that resembles the following:

> Error running script: UEFIHelper.java
ghidra.program.model.util.CodeUnitInsertionException: Insufficent memory at address 0000146c (length: 4 bytes)
        at ghidra.program.database.code.CodeManager.checkValidAddressRange(CodeManager.java:1916)
        ...
        UEFIHelper.defineData(UEFIHelper.java:138)
        ...

There is a simple workaround: upon loading the PE32 click the Memory Map and rebase the binary to 0x0. However, I think you can also address this in code by detecting if the PE32 is position-independent in UEFIHelper.java and rebase to 0x0 automatically, or add Ghidra's 0x10000 default base address to resolve the correct location of global variables.

zznop avatar Apr 09 '21 13:04 zznop

Thanks for reporting this. Do you have an example binary which reproduces this issue?

al3xtjames avatar Apr 10 '21 05:04 al3xtjames

Unfortunately, I don't have a binary that I can share at the moment. When I have the time, I'll look through online firmware samples or try to build a module from edk2 and report back.

zznop avatar Apr 10 '21 13:04 zznop

I think the issue only effects x86 PE32's, not x86-64. A position-independent x86-64 PE32 loads fine in my testing. Unfortunately, the only firmware samples I can find online only contain 32-bit UEFI modules.

zznop avatar Apr 11 '21 03:04 zznop