-
Notifications
You must be signed in to change notification settings - Fork 7.1k
Description
Describe the bug
In 32-bit x86 code, instruction CALL rel16 (66 e8 cw) zeroes out the high bytes of EIP[1], making it suitable only for calls to code in 0x00000000-0000ffff. However, patching a CALL instruction will suggest it even for destinations outside that range, creating faulty binaries that will most likely crash if executed. The disassembler will also erroneously display the intended destination as the instruction's target, making the bug nontrivial to identify.
To Reproduce
- Open an x86 binary
- Locate a CALL instruction
- Patch the instruction to target an address less than 0x7000 away in either direction and higher than 0xffff
66 e8 ####will be suggested, which is incorrect
Expected behavior
CALL rel16 is not suggested outside of its real target range, and usages are correctly disassembled to destinations within said range.
Attachments
I was going to include a sample ELF, but not a valid attachment
Environment:
- OS: Ubuntu 22.04.5 LTS
- Java Version: 17.0.13
- Ghidra Version: 11.0
- Ghidra Origin: Official GitHub distro
Additional context
[1]Intel® 64 and IA-32 Architectures Software Developer’s Manual, volume 2A, chapter 3, page 143:
IF near call THEN IF near relative call THEN [...] IF OperandSize = 16 THEN tempEIP := (EIP + DEST) AND 0000FFFFH; (* DEST is rel16 *) [...]
