summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXusheng <xusheng@vector35.com>2024-08-02 14:04:12 +0800
committerXusheng <xusheng@vector35.com>2024-08-02 16:10:31 +0800
commita9a3f1ab55e18b345be37001c66cfa9455494b4a (patch)
tree1554d9bc345482bb4a49b7927773c790196df252
parent351238c300838d39ca896eeb7d180a35cc12998f (diff)
Properly lift push r16 instructions in x86. Fix https://github.com/Vector35/binaryninja-api/issues/4028
-rw-r--r--arch/x86/il.cpp9
1 files changed, 7 insertions, 2 deletions
diff --git a/arch/x86/il.cpp b/arch/x86/il.cpp
index 6046f274..e6d704a6 100644
--- a/arch/x86/il.cpp
+++ b/arch/x86/il.cpp
@@ -2861,8 +2861,13 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev
case XED_ICLASS_PUSH:
{
- const unsigned int stackAdjustment = xed_decoded_inst_get_memop_address_width(xedd, 0) / 8;
- if (opOneLen != stackAdjustment) // 32-bit push on 64-bit pushes a 64-bit value
+ // Whe the stack adjustment is different from the operand one size, zero-extend it. Note, a "push r16" in either
+ // x86 or x64 pushes the 2-byte register onto the stack, and there is no need to extend. See
+ // https://github.com/Vector35/binaryninja-api/issues/4028 and
+ // https://stackoverflow.com/questions/43435764/64-bit-mode-does-not-support-32-bit-push-and-pop-instructions
+ // for more details
+ const unsigned int stackAdjustment = xed_decoded_inst_get_memory_operand_length(xedd, 0);
+ if (opOneLen != stackAdjustment)
{
il.AddInstruction(
il.Push(stackAdjustment,