NationalSecurityAgency / ghidra

Ghidra is a software reverse engineering (SRE) framework
https://www.nsa.gov/ghidra
Apache License 2.0
50.69k stars 5.78k forks source link

currentProgram.setImageBase() behavior vs Memory Map -> set image base #4172

Open wburton-intel opened 2 years ago

wburton-intel commented 2 years ago

When using the API to process windows drivers (I assume this is true for user space DLLs as well but haven't tested) running currentProgram.setImageBase() is limited to just rebasing the program.

When using the GUI and going to Memory Map -> Set Image Base the program will be rebased, but in addition other required addresses are updated such as the location of _guard_dispatch_icall and _guard_check_icall as pointed to by PTR__guard_dispatch_icall_xxx and PTR__guard_check_icall_xxx. Other updates to the base address are missing as well, such as those in WDF structs, but these are buried a bit more deeply.

I would like to achieve the latter behavior through the API. Is there any way of achieving this? Should it be a bug that the API doesn't do this by default, since it makes it an invalid executable?

ryanmkurtz commented 2 years ago

I think this is a duplicate of #329. @wburton-intel, do you agree?

wburton-intel commented 2 years ago

Hmm, probably. The situation is slightly different as I'm not creating a custom RelocationFixupHandler, but it seems likely that it's the same root cause. I'd suggest an update to the documentation for the different setImageBase() API calls to indicate that there may be issues if it is called after auto-analysis has been triggered and that the relocation fixup handlers won't be automatically called. I'll work round it and use -loader-imagebase from the command line or possibly rebase in the pre-script since I'm using the headless analyzer.

ghidra1 commented 2 years ago

It is always best to establish the desired image base at time of import for the best results. Results and side-affects of changing the image base can vary widely and is not well supported.

The current relocation-fixup mechanism relies on a GUI plugin which is absent when operating headless. This plugin reacts to the image base change event. There is a RelocationFixupCommand which could be invoked after changing the image base in a headless environment. You would need to be careful in a GUI tool environment since you would not want both the plugin and your script to initiate such a fixup. Your script could check for an active tool and/or the RelocationFixupPlugin. The plugin's response is slightly delayed after an image base change due to its use of events - this is another reason changing the image base via a script is discouraged.

wburton-intel commented 2 years ago

I've gone back to look at the ways I'd intended to set the image base when importing it and I haven't been able to get any of them to work. The ElfLoader and BinaryLoader have options to set the image base, but neither the PeLoader or MachoLoader seem to have any options to allow this. This seems to be true when importing in the GUI or command line.

I can import the file with the BinaryLoader with a supplied base address, but I don't then see any way of triggering it to be re-imported as a PE file. I can import as a PE file then use a pre-analysis script to alter the base address, but in spite of this being pre-analysis I'm still unable to trigger the relocation fixup handling.

I've looked at the RelocationFixupCommand and it doesn't appear to be a simple task to obtain all the required objects when calling it from a script, and I haven't found any examples of other people trying to do it.

If you've got any pointers to routes I've not considered to get a PE file to load with a supplied base address that would be great. I'll be hacking around the problem in my script for the time being so this will mean I can neaten things up in the future.

ryanmkurtz commented 2 years ago

The ElfLoader and BinaryLoader have options to set the image base, but neither the PeLoader or MachoLoader seem to have any options to allow this.

Yes, unfortunately only those 2 loaders support a loader image base option.