ghidra
ghidra copied to clipboard
Fix segment table generation and rel16 offsets for DOS MZ executables
Two small fixes for DOS MZ executables:
- MZ files don't have a formal list of segment bounds, you instead work it out from addresses in the relocation table. There were two lines which added segments based on the address of the relocation table entry itself; for pretty much every multisegment DOS EXE I tried this would create additional segment boundaries that didn't match with other tools. Removing these two lines fixes the segment list.
- Originally, rel16 offset arguments to instructions would be rigged to remain in the same segment. This holds true for protected mode, but in real mode it's possible to jump segment boundaries. This was fixed by adding a conditional in the .sinc file for real mode to use a normal offset calculation. Tested and confirmed to be working with real mode MZ and protected mode NE executables.
Should fix #981 .
I tried in the past to do the same thing to fix rel16 calculation and it didnt work well at all: https://github.com/NationalSecurityAgency/ghidra/issues/981#issuecomment-1076724273
SLEIGH unfortunately only has access to the linear address, and in real mode its impossible to generally recover the correct segment from just the linear address. So the SLEiGH code here will fix some cases but break others, as would any alternative.
In general, users should probably analyze their 16-bit executables using the "Protected Mode" language variant, even for MZ executables, if it all possible.