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.
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 before0x10000because it's based on the PE being loaded at0. It then tries to apply a type before the base of the PE raising an exception that resembles the following: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.javaand rebase to 0x0 automatically, or add Ghidra's0x10000default base address to resolve the correct location of global variables.