From 6b397ce0fc555bc3b4fe328b637cb514f3859420 Mon Sep 17 00:00:00 2001 From: nullableVoidPtr <30564701+nullableVoidPtr@users.noreply.github.com> Date: Tue, 18 Feb 2025 03:32:06 +1100 Subject: [PATCH 1/2] [arch/x86] WIP: initial Intel APX impl. --- arch/x86/CMakeLists.txt | 2 +- arch/x86/arch_x86.cpp | 79 +++ arch/x86/il.cpp | 1120 +++++++++++++++++++++++++++++++++------ 3 files changed, 1024 insertions(+), 177 deletions(-) diff --git a/arch/x86/CMakeLists.txt b/arch/x86/CMakeLists.txt index 3b2b9a69a..2e8ef897e 100644 --- a/arch/x86/CMakeLists.txt +++ b/arch/x86/CMakeLists.txt @@ -47,7 +47,7 @@ target_include_directories(arch_x86 PRIVATE ${PROJECT_BINARY_DIR}/obj/include-private) add_compile_definitions(XED_DECODER XED_AMD_ENABLED XED_VIA_ENABLED XED_AVX XED_SUPPORTS_AVX512 - XED_MPX XED_CET XED_SUPPORTS_SHA XED_SUPPORTS_WBNOINVD) + XED_MPX XED_CET XED_SUPPORTS_SHA XED_SUPPORTS_WBNOINVD XED_APX) target_link_libraries(arch_x86 binaryninjaapi) diff --git a/arch/x86/arch_x86.cpp b/arch/x86/arch_x86.cpp index 8c4469722..548721d19 100644 --- a/arch/x86/arch_x86.cpp +++ b/arch/x86/arch_x86.cpp @@ -1423,6 +1423,7 @@ void X86CommonArchitecture::GetOperandTextBNIntel(const xed_decoded_inst_t* cons break; } case XED_OPERAND_PTR: + case XED_OPERAND_ABSBR: { stringstream sstream; sstream << "0x" << hex; @@ -3281,6 +3282,8 @@ class X64Architecture: public X86CommonArchitecture XED_REG_RAX, XED_REG_RCX, XED_REG_RDX, XED_REG_RBX, // 64+ XED_REG_R8, XED_REG_R9, XED_REG_R10, XED_REG_R11, XED_REG_R12, XED_REG_R13, XED_REG_R14, XED_REG_R15, // 64+ + XED_REG_R16, XED_REG_R17, XED_REG_R18, XED_REG_R19, XED_REG_R20, XED_REG_R21, XED_REG_R22, XED_REG_R23, // APX + XED_REG_R24, XED_REG_R25, XED_REG_R26, XED_REG_R27, XED_REG_R28, XED_REG_R29, XED_REG_R30, XED_REG_R31, // APX XED_REG_BNDCFGU, XED_REG_BNDSTATUS, // 64 briefly. MPX control registers XED_REG_K0, XED_REG_K1, XED_REG_K2, XED_REG_K3, XED_REG_K4, XED_REG_K5, XED_REG_K6, XED_REG_K7, // 64+ AVX bit-masking registers (also not confident in size) @@ -3309,6 +3312,8 @@ class X64Architecture: public X86CommonArchitecture XED_REG_AH, XED_REG_CH, XED_REG_DH, XED_REG_BH, XED_REG_AL, XED_REG_CL, XED_REG_DL, XED_REG_BL, // 16+ XED_REG_SPL, XED_REG_BPL, XED_REG_SIL, XED_REG_DIL, // 64+ XED_REG_R8B, XED_REG_R9B, XED_REG_R10B, XED_REG_R11B, XED_REG_R12B, XED_REG_R13B, XED_REG_R14B, XED_REG_R15B, // 64+ + XED_REG_R16B, XED_REG_R17B, XED_REG_R18B, XED_REG_R19B, XED_REG_R20B, XED_REG_R21B, XED_REG_R22B, XED_REG_R23B, // APX + XED_REG_R24B, XED_REG_R25B, XED_REG_R26B, XED_REG_R27B, XED_REG_R28B, XED_REG_R29B, XED_REG_R30B, XED_REG_R31B, // APX // 16-Bit XED_REG_IP, // 16+ @@ -3322,6 +3327,8 @@ class X64Architecture: public X86CommonArchitecture XED_REG_AX, XED_REG_CX, XED_REG_DX, XED_REG_BX, // 16+ XED_REG_R8W, XED_REG_R9W, XED_REG_R10W, XED_REG_R11W, XED_REG_R12W, XED_REG_R13W, XED_REG_R14W, XED_REG_R15W, // 64+ + XED_REG_R16W, XED_REG_R17W, XED_REG_R18W, XED_REG_R19W, XED_REG_R20W, XED_REG_R21W, XED_REG_R22W, XED_REG_R23W, // APX + XED_REG_R24W, XED_REG_R25W, XED_REG_R26W, XED_REG_R27W, XED_REG_R28W, XED_REG_R29W, XED_REG_R30W, XED_REG_R31W, // APX // 32-Bit XED_REG_EIP, // 32+ @@ -3330,6 +3337,8 @@ class X64Architecture: public X86CommonArchitecture XED_REG_EAX, XED_REG_ECX, XED_REG_EDX, XED_REG_EBX, // 32+ XED_REG_R8D, XED_REG_R9D, XED_REG_R10D, XED_REG_R11D, XED_REG_R12D, XED_REG_R13D, XED_REG_R14D, XED_REG_R15D, // 64+ + XED_REG_R16D, XED_REG_R17D, XED_REG_R18D, XED_REG_R19D, XED_REG_R20D, XED_REG_R21D, XED_REG_R22D, XED_REG_R23D, // APX + XED_REG_R24D, XED_REG_R25D, XED_REG_R26D, XED_REG_R27D, XED_REG_R28D, XED_REG_R29D, XED_REG_R30D, XED_REG_R31D, // APX // 48-Bit (All 32+) XED_REG_GDTR, // Global Descriptor Table Register @@ -3349,6 +3358,8 @@ class X64Architecture: public X86CommonArchitecture XED_REG_RAX, XED_REG_RCX, XED_REG_RDX, XED_REG_RBX, // 64+ XED_REG_R8, XED_REG_R9, XED_REG_R10, XED_REG_R11, XED_REG_R12, XED_REG_R13, XED_REG_R14, XED_REG_R15, // 64+ + XED_REG_R16, XED_REG_R17, XED_REG_R18, XED_REG_R19, XED_REG_R20, XED_REG_R21, XED_REG_R22, XED_REG_R23, // APX + XED_REG_R24, XED_REG_R25, XED_REG_R26, XED_REG_R27, XED_REG_R28, XED_REG_R29, XED_REG_R30, XED_REG_R31, // APX XED_REG_BNDCFGU, XED_REG_BNDSTATUS, // 64 briefly. MPX control registers XED_REG_K0, XED_REG_K1, XED_REG_K2, XED_REG_K3, XED_REG_K4, XED_REG_K5, XED_REG_K6, XED_REG_K7, // 64+ AVX bit-masking registers (also not confident in size) @@ -3404,6 +3415,23 @@ class X64Architecture: public X86CommonArchitecture case XED_REG_R14B: return RegisterInfo(XED_REG_R14, 0, 1); case XED_REG_R15B: return RegisterInfo(XED_REG_R15, 0, 1); + case XED_REG_R16B: return RegisterInfo(XED_REG_R16, 0, 1); + case XED_REG_R17B: return RegisterInfo(XED_REG_R17, 0, 1); + case XED_REG_R18B: return RegisterInfo(XED_REG_R18, 0, 1); + case XED_REG_R19B: return RegisterInfo(XED_REG_R19, 0, 1); + case XED_REG_R20B: return RegisterInfo(XED_REG_R20, 0, 1); + case XED_REG_R21B: return RegisterInfo(XED_REG_R21, 0, 1); + case XED_REG_R22B: return RegisterInfo(XED_REG_R22, 0, 1); + case XED_REG_R23B: return RegisterInfo(XED_REG_R23, 0, 1); + case XED_REG_R24B: return RegisterInfo(XED_REG_R24, 0, 1); + case XED_REG_R25B: return RegisterInfo(XED_REG_R25, 0, 1); + case XED_REG_R26B: return RegisterInfo(XED_REG_R26, 0, 1); + case XED_REG_R27B: return RegisterInfo(XED_REG_R27, 0, 1); + case XED_REG_R28B: return RegisterInfo(XED_REG_R28, 0, 1); + case XED_REG_R29B: return RegisterInfo(XED_REG_R29, 0, 1); + case XED_REG_R30B: return RegisterInfo(XED_REG_R30, 0, 1); + case XED_REG_R31B: return RegisterInfo(XED_REG_R31, 0, 1); + // 16-Bit case XED_REG_IP: return RegisterInfo(XED_REG_RIP, 0, 2); @@ -3434,6 +3462,23 @@ class X64Architecture: public X86CommonArchitecture case XED_REG_R14W: return RegisterInfo(XED_REG_R14, 0, 2); case XED_REG_R15W: return RegisterInfo(XED_REG_R15, 0, 2); + case XED_REG_R16W: return RegisterInfo(XED_REG_R16, 0, 1); + case XED_REG_R17W: return RegisterInfo(XED_REG_R17, 0, 1); + case XED_REG_R18W: return RegisterInfo(XED_REG_R18, 0, 1); + case XED_REG_R19W: return RegisterInfo(XED_REG_R19, 0, 1); + case XED_REG_R20W: return RegisterInfo(XED_REG_R20, 0, 1); + case XED_REG_R21W: return RegisterInfo(XED_REG_R21, 0, 1); + case XED_REG_R22W: return RegisterInfo(XED_REG_R22, 0, 1); + case XED_REG_R23W: return RegisterInfo(XED_REG_R23, 0, 1); + case XED_REG_R24W: return RegisterInfo(XED_REG_R24, 0, 1); + case XED_REG_R25W: return RegisterInfo(XED_REG_R25, 0, 1); + case XED_REG_R26W: return RegisterInfo(XED_REG_R26, 0, 1); + case XED_REG_R27W: return RegisterInfo(XED_REG_R27, 0, 1); + case XED_REG_R28W: return RegisterInfo(XED_REG_R28, 0, 1); + case XED_REG_R29W: return RegisterInfo(XED_REG_R29, 0, 1); + case XED_REG_R30W: return RegisterInfo(XED_REG_R30, 0, 1); + case XED_REG_R31W: return RegisterInfo(XED_REG_R31, 0, 1); + // 32-Bit case XED_REG_EIP: return RegisterInfo(XED_REG_RIP, 0, 4); @@ -3471,6 +3516,23 @@ class X64Architecture: public X86CommonArchitecture case XED_REG_R14D: return RegisterInfo(XED_REG_R14, 0, 4, true); case XED_REG_R15D: return RegisterInfo(XED_REG_R15, 0, 4, true); + case XED_REG_R16D: return RegisterInfo(XED_REG_R16, 0, 1); + case XED_REG_R17D: return RegisterInfo(XED_REG_R17, 0, 1); + case XED_REG_R18D: return RegisterInfo(XED_REG_R18, 0, 1); + case XED_REG_R19D: return RegisterInfo(XED_REG_R19, 0, 1); + case XED_REG_R20D: return RegisterInfo(XED_REG_R20, 0, 1); + case XED_REG_R21D: return RegisterInfo(XED_REG_R21, 0, 1); + case XED_REG_R22D: return RegisterInfo(XED_REG_R22, 0, 1); + case XED_REG_R23D: return RegisterInfo(XED_REG_R23, 0, 1); + case XED_REG_R24D: return RegisterInfo(XED_REG_R24, 0, 1); + case XED_REG_R25D: return RegisterInfo(XED_REG_R25, 0, 1); + case XED_REG_R26D: return RegisterInfo(XED_REG_R26, 0, 1); + case XED_REG_R27D: return RegisterInfo(XED_REG_R27, 0, 1); + case XED_REG_R28D: return RegisterInfo(XED_REG_R28, 0, 1); + case XED_REG_R29D: return RegisterInfo(XED_REG_R29, 0, 1); + case XED_REG_R30D: return RegisterInfo(XED_REG_R30, 0, 1); + case XED_REG_R31D: return RegisterInfo(XED_REG_R31, 0, 1); + // 48-Bit case XED_REG_GDTR: return RegisterInfo(XED_REG_GDTR, 0, 6); case XED_REG_LDTR: return RegisterInfo(XED_REG_LDTR, 0, 6); @@ -3517,6 +3579,23 @@ class X64Architecture: public X86CommonArchitecture case XED_REG_R13: return RegisterInfo(XED_REG_R13, 0, 8); case XED_REG_R14: return RegisterInfo(XED_REG_R14, 0, 8); case XED_REG_R15: return RegisterInfo(XED_REG_R15, 0, 8); + case XED_REG_R16: return RegisterInfo(XED_REG_R16, 0, 1); + case XED_REG_R17: return RegisterInfo(XED_REG_R17, 0, 1); + case XED_REG_R18: return RegisterInfo(XED_REG_R18, 0, 1); + case XED_REG_R19: return RegisterInfo(XED_REG_R19, 0, 1); + case XED_REG_R20: return RegisterInfo(XED_REG_R20, 0, 1); + case XED_REG_R21: return RegisterInfo(XED_REG_R21, 0, 1); + case XED_REG_R22: return RegisterInfo(XED_REG_R22, 0, 1); + case XED_REG_R23: return RegisterInfo(XED_REG_R23, 0, 1); + case XED_REG_R24: return RegisterInfo(XED_REG_R24, 0, 1); + case XED_REG_R25: return RegisterInfo(XED_REG_R25, 0, 1); + case XED_REG_R26: return RegisterInfo(XED_REG_R26, 0, 1); + case XED_REG_R27: return RegisterInfo(XED_REG_R27, 0, 1); + case XED_REG_R28: return RegisterInfo(XED_REG_R28, 0, 1); + case XED_REG_R29: return RegisterInfo(XED_REG_R29, 0, 1); + case XED_REG_R30: return RegisterInfo(XED_REG_R30, 0, 1); + case XED_REG_R31: return RegisterInfo(XED_REG_R31, 0, 1); + case XED_REG_BNDCFGU: return RegisterInfo(XED_REG_BNDCFGU, 0, 8); case XED_REG_BNDSTATUS: return RegisterInfo(XED_REG_BNDSTATUS, 0, 8); diff --git a/arch/x86/il.cpp b/arch/x86/il.cpp index 3dd9f87a7..46e485f2f 100644 --- a/arch/x86/il.cpp +++ b/arch/x86/il.cpp @@ -198,6 +198,7 @@ static size_t ReadILOperand(LowLevelILFunction& il, const xed_decoded_inst_t* co sizeToRead = xed_decoded_inst_operand_length_bits(xedd, (unsigned)operand_index) / 8; const unsigned int immediateSize = xed_decoded_inst_get_operand_width(xedd) / 8; const int64_t relbr = xed_decoded_inst_get_branch_displacement(xedd) + addr + xed_decoded_inst_get_length(xedd); + const int64_t absbr = xed_decoded_inst_get_branch_displacement(xedd); const xed_operand_enum_t op_name = xed_operand_name(xed_inst_operand(xed_decoded_inst_inst(xedd), (unsigned)operand_index)); const auto reg1 = xed_decoded_inst_get_reg(xedd, op_name); const size_t addrSize = xed_decoded_inst_get_machine_mode_bits(xedd) / 8; @@ -235,6 +236,8 @@ static size_t ReadILOperand(LowLevelILFunction& il, const xed_decoded_inst_t* co case XED_OPERAND_PTR: case XED_OPERAND_RELBR: return il.Operand(instruction_index, il.ConstPointer(addrSize, relbr)); + case XED_OPERAND_ABSBR: + return il.Operand(instruction_index, il.ConstPointer(addrSize, absbr)); // Memory Acesses case XED_OPERAND_AGEN: @@ -275,6 +278,7 @@ static size_t ReadFloatILOperand(LowLevelILFunction& il, const xed_decoded_inst_ // Immediates case XED_OPERAND_IMM0: case XED_OPERAND_PTR: + case XED_OPERAND_ABSBR: case XED_OPERAND_RELBR: if (xed_decoded_inst_get_immediate_is_signed(xedd)) return il.Operand(instruction_index, il.FloatConvert(opLen, il.FloatConstRaw(operandSize, xed_decoded_inst_get_signed_immediate(xedd)))); @@ -446,13 +450,60 @@ static void Repeat( static void CMovFlagCond(const int64_t addr, const xed_decoded_inst_t* xedd, LowLevelILFunction& il, BNLowLevelILFlagCondition flag) { - // keep the true branch but let the false branch goto doneLabel directly - LowLevelILLabel trueLabel, doneLabel; + bool isCondFault = false; + bool isNdd = false; + + switch (xed_decoded_inst_get_iclass(xedd)) { + case XED_ICLASS_CFCMOVB: + case XED_ICLASS_CFCMOVBE: + case XED_ICLASS_CFCMOVL: + case XED_ICLASS_CFCMOVLE: + case XED_ICLASS_CFCMOVNB: + case XED_ICLASS_CFCMOVNBE: + case XED_ICLASS_CFCMOVNL: + case XED_ICLASS_CFCMOVNLE: + case XED_ICLASS_CFCMOVNO: + case XED_ICLASS_CFCMOVNP: + case XED_ICLASS_CFCMOVNS: + case XED_ICLASS_CFCMOVNZ: + case XED_ICLASS_CFCMOVO: + case XED_ICLASS_CFCMOVP: + case XED_ICLASS_CFCMOVS: + case XED_ICLASS_CFCMOVZ: + isCondFault = true; + case XED_ICLASS_CMOVB: + case XED_ICLASS_CMOVBE: + case XED_ICLASS_CMOVL: + case XED_ICLASS_CMOVLE: + case XED_ICLASS_CMOVNB: + case XED_ICLASS_CMOVNBE: + case XED_ICLASS_CMOVNL: + case XED_ICLASS_CMOVNLE: + case XED_ICLASS_CMOVNO: + case XED_ICLASS_CMOVNP: + case XED_ICLASS_CMOVNS: + case XED_ICLASS_CMOVNZ: + case XED_ICLASS_CMOVO: + case XED_ICLASS_CMOVP: + case XED_ICLASS_CMOVS: + case XED_ICLASS_CMOVZ: + { + size_t noperands = xed_inst_noperands(xed_decoded_inst_inst(xedd)); + if (noperands == 3) { + isNdd = true; + break; + } + } + default: + break; + } + + LowLevelILLabel trueLabel, falseLabel, doneLabel; il.AddInstruction( il.If( il.FlagCondition(flag), - trueLabel, doneLabel)); + trueLabel, falseLabel)); il.MarkLabel(trueLabel); @@ -461,14 +512,100 @@ static void CMovFlagCond(const int64_t addr, const xed_decoded_inst_t* xedd, Low ReadILOperand(il, xedd, addr, 1, 1))); il.AddInstruction(il.Goto(doneLabel)); + + il.MarkLabel(falseLabel); + + if (isNdd) { + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + ReadILOperand(il, xedd, addr, 2, 2))); + } else if (isCondFault) { + const xed_operand_enum_t op_name = xed_operand_name(xed_inst_operand(xed_decoded_inst_inst(xedd), 0)); + + switch (op_name) + { + // Register cases + case XED_OPERAND_REG0: + case XED_OPERAND_REG1: + case XED_OPERAND_REG2: + case XED_OPERAND_REG3: + case XED_OPERAND_REG4: + case XED_OPERAND_REG5: + case XED_OPERAND_REG6: + case XED_OPERAND_REG7: + case XED_OPERAND_REG8: + case XED_OPERAND_BASE0: + case XED_OPERAND_BASE1: + { + size_t addrSize = xed_decoded_inst_get_machine_mode_bits(xedd) / 8; + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.Const(addrSize, 0))); + break; + } + default: + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + ReadILOperand(il, xedd, addr, 1, 1))); + break; + } + } + il.MarkLabel(doneLabel); } static void CMovFlagGroup(const int64_t addr, const xed_decoded_inst_t* xedd, LowLevelILFunction& il, uint32_t flag) { - // keep the true branch but let the false branch goto doneLabel directly - LowLevelILLabel trueLabel, doneLabel; + bool isCondFault = false; + bool isNdd = false; + + switch (xed_decoded_inst_get_iclass(xedd)) { + case XED_ICLASS_CFCMOVB: + case XED_ICLASS_CFCMOVBE: + case XED_ICLASS_CFCMOVL: + case XED_ICLASS_CFCMOVLE: + case XED_ICLASS_CFCMOVNB: + case XED_ICLASS_CFCMOVNBE: + case XED_ICLASS_CFCMOVNL: + case XED_ICLASS_CFCMOVNLE: + case XED_ICLASS_CFCMOVNO: + case XED_ICLASS_CFCMOVNP: + case XED_ICLASS_CFCMOVNS: + case XED_ICLASS_CFCMOVNZ: + case XED_ICLASS_CFCMOVO: + case XED_ICLASS_CFCMOVP: + case XED_ICLASS_CFCMOVS: + case XED_ICLASS_CFCMOVZ: + isCondFault = true; + case XED_ICLASS_CMOVB: + case XED_ICLASS_CMOVBE: + case XED_ICLASS_CMOVL: + case XED_ICLASS_CMOVLE: + case XED_ICLASS_CMOVNB: + case XED_ICLASS_CMOVNBE: + case XED_ICLASS_CMOVNL: + case XED_ICLASS_CMOVNLE: + case XED_ICLASS_CMOVNO: + case XED_ICLASS_CMOVNP: + case XED_ICLASS_CMOVNS: + case XED_ICLASS_CMOVNZ: + case XED_ICLASS_CMOVO: + case XED_ICLASS_CMOVP: + case XED_ICLASS_CMOVS: + case XED_ICLASS_CMOVZ: + { + size_t noperands = xed_inst_noperands(xed_decoded_inst_inst(xedd)); + if (noperands == 3) { + isNdd = true; + break; + } + } + default: + break; + } + + LowLevelILLabel trueLabel, falseLabel, doneLabel; il.AddInstruction( il.If( @@ -484,6 +621,128 @@ static void CMovFlagGroup(const int64_t addr, const xed_decoded_inst_t* xedd, Lo ReadILOperand(il, xedd, addr, 1, 1))); il.AddInstruction(il.Goto(doneLabel)); + + il.MarkLabel(falseLabel); + + if (isNdd) { + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + ReadILOperand(il, xedd, addr, 2, 2))); + } else if (isCondFault) { + const xed_operand_enum_t op_name = xed_operand_name(xed_inst_operand(xed_decoded_inst_inst(xedd), 0)); + + switch (op_name) + { + // Register cases + case XED_OPERAND_REG0: + case XED_OPERAND_REG1: + case XED_OPERAND_REG2: + case XED_OPERAND_REG3: + case XED_OPERAND_REG4: + case XED_OPERAND_REG5: + case XED_OPERAND_REG6: + case XED_OPERAND_REG7: + case XED_OPERAND_REG8: + case XED_OPERAND_BASE0: + case XED_OPERAND_BASE1: + { + size_t addrSize = xed_decoded_inst_get_machine_mode_bits(xedd) / 8; + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.Const(addrSize, 0))); + break; + } + default: + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + ReadILOperand(il, xedd, addr, 1, 1))); + break; + } + } + + il.MarkLabel(doneLabel); +} + +static void AssignEvexDfv(const xed_decoded_inst_t* xedd, LowLevelILFunction& il) { + xed_flag_dfv_t defaultFlagValues; + if (!xed_flag_dfv_get_default_flags_values( + xed_decoded_inst_get_dfv_reg(xedd), &defaultFlagValues)) { + // TODO: better error handling + il.AddInstruction(il.Undefined()); + return; + } + + il.AddInstruction( + il.SetFlag(IL_FLAG_O, + il.Const(1, defaultFlagValues.s.of))); + il.AddInstruction( + il.SetFlag(IL_FLAG_S, + il.Const(1, defaultFlagValues.s.sf))); + il.AddInstruction( + il.SetFlag(IL_FLAG_Z, + il.Const(1, defaultFlagValues.s.zf))); + il.AddInstruction( + il.SetFlag(IL_FLAG_C, + il.Const(1, defaultFlagValues.s.cf))); + il.AddInstruction( + il.SetFlag(IL_FLAG_P, + il.Const(1, defaultFlagValues.s.cf))); + il.AddInstruction( + il.SetFlag(IL_FLAG_A, + il.Const(1, 0))); +} + + +static void ConditionalCmp(const int64_t addr, const xed_decoded_inst_t* xedd, LowLevelILFunction& il, uint32_t size, ExprId cond) +{ + LowLevelILLabel trueLabel, falseLabel, doneLabel; + + il.AddInstruction( + il.If( + cond, + trueLabel, falseLabel + ) + ); + + il.MarkLabel(trueLabel); + + il.AddInstruction( + il.Sub(size, + ReadILOperand(il, xedd, addr, 0, 0), + ReadILOperand(il, xedd, addr, 1, 1), + IL_FLAGWRITE_ALL)); + il.AddInstruction(il.Goto(doneLabel)); + + il.MarkLabel(falseLabel); + AssignEvexDfv(xedd, il); + + il.MarkLabel(doneLabel); +} + + +static void ConditionalTest(const int64_t addr, const xed_decoded_inst_t* xedd, LowLevelILFunction& il, uint32_t size, ExprId cond) +{ + LowLevelILLabel trueLabel, falseLabel, doneLabel; + + il.AddInstruction( + il.If( + cond, + trueLabel, falseLabel + ) + ); + + il.MarkLabel(trueLabel); + + il.AddInstruction( + il.And(size, + ReadILOperand(il, xedd, addr, 0, 0), + ReadILOperand(il, xedd, addr, 1, 1), + IL_FLAGWRITE_ALL)); + il.AddInstruction(il.Goto(doneLabel)); + + il.MarkLabel(falseLabel); + AssignEvexDfv(xedd, il); + il.MarkLabel(doneLabel); } @@ -525,6 +784,9 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev const uint64_t immediateOne = xed_decoded_inst_get_unsigned_immediate(xedd); const int64_t branchDestination = xed_decoded_inst_get_branch_displacement(xedd) + addr + instLen; + const bool noFlags = xed_decoded_inst_get_attribute(xedd, XED_ATTRIBUTE_APX_NF); + const bool zeroUpper = xed_decoded_inst_is_apx_zu(xedd); + auto LiftAsIntrinsic = [& il, xi, xedd, addr, xedd_iForm] () mutable { typedef struct @@ -635,51 +897,121 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev { case XED_ICLASS_ADC_LOCK: // TODO: Add Lock construct case XED_ICLASS_ADC: - il.AddInstruction( - WriteILOperand(il, xedd, addr, 0, 0, - il.AddCarry(opOneLen, - ReadILOperand(il, xedd, addr, 0, 0), - ReadILOperand(il, xedd, addr, 1, 1), - il.Flag(IL_FLAG_C), IL_FLAGWRITE_ALL))); + { + uint32_t noperands = xed_inst_noperands(xi); + if (noperands == 2) { + // nothing special + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.AddCarry(opOneLen, + ReadILOperand(il, xedd, addr, 0, 0), + ReadILOperand(il, xedd, addr, 1, 1), + il.Flag(IL_FLAG_C), IL_FLAGWRITE_ALL))); + } else if (noperands == 3) { + // new data destination + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.AddCarry(opTwoLen, + ReadILOperand(il, xedd, addr, 1, 1), + ReadILOperand(il, xedd, addr, 2, 2), + il.Flag(IL_FLAG_C), IL_FLAGWRITE_ALL))); + } break; + } case XED_ICLASS_ADCX: - il.AddInstruction( - WriteILOperand(il, xedd, addr, 0, 0, - il.AddCarry(opOneLen, - ReadILOperand(il, xedd, addr, 0, 0), - ReadILOperand(il, xedd, addr, 1, 1), - il.Flag(IL_FLAG_C), IL_FLAG_C))); + { + uint32_t noperands = xed_inst_noperands(xi); + if (noperands == 2) { + // nothing special + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.AddCarry(opOneLen, + ReadILOperand(il, xedd, addr, 0, 0), + ReadILOperand(il, xedd, addr, 1, 1), + il.Flag(IL_FLAG_C), IL_FLAG_C))); + } else if (noperands == 3) { + // new data destination + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.AddCarry(opTwoLen, + ReadILOperand(il, xedd, addr, 1, 1), + ReadILOperand(il, xedd, addr, 2, 2), + il.Flag(IL_FLAG_C), IL_FLAG_C))); + } break; + } case XED_ICLASS_ADOX: - il.AddInstruction( - WriteILOperand(il, xedd, addr, 0, 0, - il.AddCarry(opOneLen, - ReadILOperand(il, xedd, addr, 0, 0), - ReadILOperand(il, xedd, addr, 1, 1), - il.Flag(IL_FLAG_O), IL_FLAG_O))); + { + uint32_t noperands = xed_inst_noperands(xi); + if (noperands == 2) { + // nothing special + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.AddCarry(opOneLen, + ReadILOperand(il, xedd, addr, 0, 0), + ReadILOperand(il, xedd, addr, 1, 1), + il.Flag(IL_FLAG_O), IL_FLAG_O))); + } else if (noperands == 3) { + // new data destination + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.AddCarry(opOneLen, + ReadILOperand(il, xedd, addr, 1, 1), + ReadILOperand(il, xedd, addr, 2, 2), + il.Flag(IL_FLAG_O), IL_FLAG_O))); + } break; + } case XED_ICLASS_ADD_LOCK: // TODO: Add Lock construct case XED_ICLASS_ADD: - il.AddInstruction( - WriteILOperand(il, xedd, addr, 0, 0, - il.Add(opOneLen, - ReadILOperand(il, xedd, addr, 0, 0), - ReadILOperand(il, xedd, addr, 1, 1), - IL_FLAGWRITE_ALL))); + { + uint32_t noperands = xed_inst_noperands(xi); + if (noperands == 2) { + // nothing special + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.Add(opOneLen, + ReadILOperand(il, xedd, addr, 0, 0), + ReadILOperand(il, xedd, addr, 1, 1), + noFlags ? 0 : IL_FLAGWRITE_ALL))); + } else if (noperands == 3) { + // new data destination + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.Add(opTwoLen, + ReadILOperand(il, xedd, addr, 1, 1), + ReadILOperand(il, xedd, addr, 2, 2), + noFlags ? 0 : IL_FLAGWRITE_ALL))); + } break; + } case XED_ICLASS_AND_LOCK: // TODO: Add Lock construct case XED_ICLASS_AND: - il.AddInstruction( - WriteILOperand(il, xedd, addr, 0, 0, - il.And(opOneLen, - ReadILOperand(il, xedd, addr, 0, 0), - ReadILOperand(il, xedd, addr, 1, 1), - IL_FLAGWRITE_ALL))); + { + uint32_t noperands = xed_inst_noperands(xi); + if (noperands == 2) { + // nothing special + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.And(opOneLen, + ReadILOperand(il, xedd, addr, 0, 0), + ReadILOperand(il, xedd, addr, 1, 1), + noFlags ? 0 : IL_FLAGWRITE_ALL))); + } else if (noperands == 3) { + // new data destination + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.And(opTwoLen, + ReadILOperand(il, xedd, addr, 1, 1), + ReadILOperand(il, xedd, addr, 2, 2), + noFlags ? 0 : IL_FLAGWRITE_ALL))); + } break; + } case XED_ICLASS_PAND: il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -1267,78 +1599,95 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev break; case XED_ICLASS_CMOVO: + case XED_ICLASS_CFCMOVO: CMovFlagCond(addr, xedd, il, LLFC_O); break; case XED_ICLASS_CMOVNO: + case XED_ICLASS_CFCMOVNO: CMovFlagCond(addr, xedd, il, LLFC_NO); break; case XED_ICLASS_CMOVB: case XED_ICLASS_FCMOVB: + case XED_ICLASS_CFCMOVB: CMovFlagGroup(addr, xedd, il, IL_FLAG_GROUP_LT); break; case XED_ICLASS_CMOVNB: case XED_ICLASS_FCMOVNB: + case XED_ICLASS_CFCMOVNB: CMovFlagGroup(addr, xedd, il, IL_FLAG_GROUP_GE); break; case XED_ICLASS_CMOVZ: case XED_ICLASS_FCMOVE: + case XED_ICLASS_CFCMOVZ: CMovFlagGroup(addr, xedd, il, IL_FLAG_GROUP_E); break; case XED_ICLASS_CMOVNZ: case XED_ICLASS_FCMOVNE: + case XED_ICLASS_CFCMOVNZ: CMovFlagGroup(addr, xedd, il, IL_FLAG_GROUP_NE); break; case XED_ICLASS_CMOVBE: case XED_ICLASS_FCMOVBE: + case XED_ICLASS_CFCMOVBE: CMovFlagGroup(addr, xedd, il, IL_FLAG_GROUP_LE); break; case XED_ICLASS_CMOVNBE: case XED_ICLASS_FCMOVNBE: + case XED_ICLASS_CFCMOVNBE: CMovFlagGroup(addr, xedd, il, IL_FLAG_GROUP_GT); break; case XED_ICLASS_CMOVS: + case XED_ICLASS_CFCMOVS: CMovFlagCond(addr, xedd, il, LLFC_NEG); break; case XED_ICLASS_CMOVNS: + case XED_ICLASS_CFCMOVNS: CMovFlagCond(addr, xedd, il, LLFC_POS); break; case XED_ICLASS_CMOVP: case XED_ICLASS_FCMOVU: + case XED_ICLASS_CFCMOVP: CMovFlagGroup(addr, xedd, il, IL_FLAG_GROUP_PE); break; case XED_ICLASS_CMOVNP: case XED_ICLASS_FCMOVNU: + case XED_ICLASS_CFCMOVNP: CMovFlagGroup(addr, xedd, il, IL_FLAG_GROUP_PO); break; case XED_ICLASS_CMOVL: + case XED_ICLASS_CFCMOVL: CMovFlagCond(addr, xedd, il, LLFC_SLT); break; case XED_ICLASS_CMOVNL: + case XED_ICLASS_CFCMOVNL: CMovFlagCond(addr, xedd, il, LLFC_SGE); break; case XED_ICLASS_CMOVLE: + case XED_ICLASS_CFCMOVLE: CMovFlagCond(addr, xedd, il, LLFC_SLE); break; case XED_ICLASS_CMOVNLE: + case XED_ICLASS_CFCMOVNLE: CMovFlagCond(addr, xedd, il, LLFC_SGT); break; case XED_ICLASS_CMP: + case XED_ICLASS_CCMPT: il.AddInstruction( il.Sub(opOneLen, ReadILOperand(il, xedd, addr, 0, 0), @@ -1346,6 +1695,66 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev IL_FLAGWRITE_ALL)); break; + case XED_ICLASS_CCMPO: + ConditionalCmp(addr, xedd, il, opOneLen, il.FlagCondition(LLFC_O)); + break; + + case XED_ICLASS_CCMPNO: + ConditionalCmp(addr, xedd, il, opOneLen, il.FlagCondition(LLFC_NO)); + break; + + case XED_ICLASS_CCMPB: + ConditionalCmp(addr, xedd, il, opOneLen, il.FlagGroup(IL_FLAG_GROUP_LT)); + break; + + case XED_ICLASS_CCMPNB: + ConditionalCmp(addr, xedd, il, opOneLen, il.FlagGroup(IL_FLAG_GROUP_GE)); + break; + + case XED_ICLASS_CCMPZ: + ConditionalCmp(addr, xedd, il, opOneLen, il.FlagGroup(IL_FLAG_GROUP_E)); + break; + + case XED_ICLASS_CCMPNZ: + ConditionalCmp(addr, xedd, il, opOneLen, il.FlagGroup(IL_FLAG_GROUP_NE)); + break; + + case XED_ICLASS_CCMPBE: + ConditionalCmp(addr, xedd, il, opOneLen, il.FlagGroup(IL_FLAG_GROUP_LE)); + break; + + case XED_ICLASS_CCMPNBE: + ConditionalCmp(addr, xedd, il, opOneLen, il.FlagGroup(IL_FLAG_GROUP_GT)); + break; + + case XED_ICLASS_CCMPS: + ConditionalCmp(addr, xedd, il, opOneLen, il.FlagCondition(LLFC_NEG)); + break; + + case XED_ICLASS_CCMPNS: + ConditionalCmp(addr, xedd, il, opOneLen, il.FlagCondition(LLFC_POS)); + break; + + case XED_ICLASS_CCMPL: + ConditionalCmp(addr, xedd, il, opOneLen, il.FlagCondition(LLFC_SLT)); + break; + + case XED_ICLASS_CCMPNL: + ConditionalCmp(addr, xedd, il, opOneLen, il.FlagCondition(LLFC_SLT)); + break; + + case XED_ICLASS_CCMPLE: + ConditionalCmp(addr, xedd, il, opOneLen, il.FlagCondition(LLFC_SLE)); + break; + + case XED_ICLASS_CCMPNLE: + ConditionalCmp(addr, xedd, il, opOneLen, il.FlagCondition(LLFC_SGT)); + break; + + case XED_ICLASS_CCMPF: + AssignEvexDfv(xedd, il); + break; + case XED_ICLASS_REPE_CMPSQ: case XED_ICLASS_REPNE_CMPSQ: case XED_ICLASS_CMPSQ: @@ -1470,15 +1879,31 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev case XED_ICLASS_DEC_LOCK: // TODO: Handle lock prefix case XED_ICLASS_DEC: - il.AddInstruction( - WriteILOperand(il, xedd, addr, 0, 0, - il.Sub(opOneLen, - ReadILOperand(il, xedd, addr, 0, 0), - il.Const(opOneLen, 1), - IL_FLAGWRITE_NOCARRY) - ) - ); + { + uint32_t noperands = xed_inst_noperands(xi); + if (noperands == 1) { + // nothing special + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.Sub(opOneLen, + ReadILOperand(il, xedd, addr, 0, 0), + il.Const(opOneLen, 1), + noFlags ? 0 : IL_FLAGWRITE_NOCARRY) + ) + ); + } else if (noperands == 2) { + // new data destination + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.Sub(opTwoLen, + ReadILOperand(il, xedd, addr, 1, 1), + il.Const(opTwoLen, 1), + noFlags ? 0 : IL_FLAGWRITE_NOCARRY) + ) + ); + } break; + } case XED_ICLASS_DIV: il.AddInstruction( @@ -1765,7 +2190,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev il.MultDoublePrecSigned(1, il.Register(1, XED_REG_AL), ReadILOperand(il, xedd, addr, 0, 0), - IL_FLAGWRITE_CO))); + noFlags ? 0 : IL_FLAGWRITE_CO))); break; case 2: il.AddInstruction( @@ -1775,7 +2200,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev il.MultDoublePrecSigned(2, il.Register(2, XED_REG_AX), ReadILOperand(il, xedd, addr, 0, 0), - IL_FLAGWRITE_CO))); + noFlags ? 0 : IL_FLAGWRITE_CO))); break; case 4: il.AddInstruction( @@ -1785,7 +2210,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev il.MultDoublePrecSigned(4, il.Register(4, XED_REG_EAX), ReadILOperand(il, xedd, addr, 0, 0), - IL_FLAGWRITE_CO))); + noFlags ? 0 : IL_FLAGWRITE_CO))); break; case 8: il.AddInstruction( @@ -1795,7 +2220,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev il.MultDoublePrecSigned(8, il.Register(8, XED_REG_RAX), ReadILOperand(il, xedd, addr, 0, 0), - IL_FLAGWRITE_CO))); + noFlags ? 0 : IL_FLAGWRITE_CO))); break; default: il.AddInstruction(il.Undefined()); @@ -1805,38 +2230,76 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev case XED_IFORM_IMUL_GPRv_GPRv: case XED_IFORM_IMUL_GPRv_MEMv: - il.AddInstruction( - WriteILOperand(il, xedd, addr, 0, 0, - il.Mult(opOneLen, - ReadILOperand(il, xedd, addr, 0, 0), - ReadILOperand(il, xedd, addr, 1, 1), - IL_FLAGWRITE_CO))); - break; - - case XED_IFORM_IMUL_GPRv_GPRv_IMMb: - case XED_IFORM_IMUL_GPRv_GPRv_IMMz: - case XED_IFORM_IMUL_GPRv_MEMv_IMMb: - case XED_IFORM_IMUL_GPRv_MEMv_IMMz: - default: - il.AddInstruction( - WriteILOperand(il, xedd, addr, 0, 0, - il.Mult(opOneLen, - ReadILOperand(il, xedd, addr, 1, 1), - ReadILOperand(il, xedd, addr, 2, 2), - IL_FLAGWRITE_CO))); + { + uint32_t noperands = xed_inst_noperands(xi); + if (noperands == 2) { + // nothing special + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.Mult(opOneLen, + ReadILOperand(il, xedd, addr, 0, 0), + ReadILOperand(il, xedd, addr, 1, 1), + IL_FLAGWRITE_CO))); + } else if (noperands == 3) { + // new data destination + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.Mult(opOneLen, + ReadILOperand(il, xedd, addr, 1, 1), + ReadILOperand(il, xedd, addr, 2, 2), + IL_FLAGWRITE_CO))); + } + break; + } + case XED_IFORM_IMUL_GPRv_GPRv_IMMb: + case XED_IFORM_IMUL_GPRv_GPRv_IMMz: + case XED_IFORM_IMUL_GPRv_MEMv_IMMb: + case XED_IFORM_IMUL_GPRv_MEMv_IMMz: + default: + if (!zeroUpper || !(opOneLen == 1 || opOneLen == 2)) { + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.Mult(opOneLen, + ReadILOperand(il, xedd, addr, 1, 1), + ReadILOperand(il, xedd, addr, 2, 2), + IL_FLAGWRITE_CO))); + } else { + // TODO: test this + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.ZeroExtend(8, + il.Mult(opOneLen, + ReadILOperand(il, xedd, addr, 1, 1), + ReadILOperand(il, xedd, addr, 2, 2), + IL_FLAGWRITE_CO)))); + } } break; case XED_ICLASS_INC_LOCK: // TODO: Handle lock prefix case XED_ICLASS_INC: - il.AddInstruction( - WriteILOperand(il, xedd, addr, 0, 0, - il.Add(opOneLen, - ReadILOperand(il, xedd, addr, 0, 0), - il.Const(opOneLen, 1), - IL_FLAGWRITE_NOCARRY))); + { + uint32_t noperands = xed_inst_noperands(xi); + if (noperands == 1) { + // nothing special + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.Add(opOneLen, + ReadILOperand(il, xedd, addr, 0, 0), + il.Const(opOneLen, 1), + noFlags ? 0 : IL_FLAGWRITE_NOCARRY))); + } else if (noperands == 2) { + // new data destination + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.Add(opTwoLen, + ReadILOperand(il, xedd, addr, 1, 1), + il.Const(opTwoLen, 1), + noFlags ? 0 : IL_FLAGWRITE_NOCARRY))); + } break; + } case XED_ICLASS_INT: switch (immediateOne) @@ -1870,6 +2333,10 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev il.AddInstruction(il.Jump(ReadILOperand(il, xedd, addr, 0, 0))); return false; + case XED_ICLASS_JMPABS: + il.AddInstruction(il.Jump(ReadILOperand(il, xedd, addr, 0, 0))); + return false; + case XED_ICLASS_JO: ConditionalJump(arch, il, il.FlagCondition(LLFC_O), addrSize, branchDestination, addr + instLen); return false; @@ -2606,7 +3073,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev il.MultDoublePrecUnsigned(1, il.Register(1, XED_REG_AL), ReadILOperand(il, xedd, addr, 0, 0), - IL_FLAGWRITE_CO))); + noFlags ? 0 : IL_FLAGWRITE_CO))); break; case 2: il.AddInstruction( @@ -2616,7 +3083,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev il.MultDoublePrecUnsigned(2, il.Register(2, XED_REG_AX), ReadILOperand(il, xedd, addr, 0, 0), - IL_FLAGWRITE_CO))); + noFlags ? 0 : IL_FLAGWRITE_CO))); break; case 4: il.AddInstruction( @@ -2626,7 +3093,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev il.MultDoublePrecUnsigned(4, il.Register(4, XED_REG_EAX), ReadILOperand(il, xedd, addr, 0, 0), - IL_FLAGWRITE_CO))); + noFlags ? 0 : IL_FLAGWRITE_CO))); break; case 8: il.AddInstruction( @@ -2636,7 +3103,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev il.MultDoublePrecUnsigned(8, il.Register(8, XED_REG_RAX), ReadILOperand(il, xedd, addr, 0, 0), - IL_FLAGWRITE_CO))); + noFlags ? 0 : IL_FLAGWRITE_CO))); break; default: il.AddInstruction(il.Undefined()); @@ -2646,12 +3113,25 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev case XED_ICLASS_NEG_LOCK: // TODO: Handle lock prefix case XED_ICLASS_NEG: - il.AddInstruction( - WriteILOperand(il, xedd, addr, 0, 0, - il.Neg(opOneLen, - ReadILOperand(il, xedd, addr, 0, 0), - IL_FLAGWRITE_ALL))); + { + uint32_t noperands = xed_inst_noperands(xi); + if (noperands == 1) { + // nothing special + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.Neg(opOneLen, + ReadILOperand(il, xedd, addr, 0, 0), + noFlags ? 0 : IL_FLAGWRITE_ALL))); + } else if (noperands == 2) { + // new data destination + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.Neg(opTwoLen, + ReadILOperand(il, xedd, addr, 1, 1), + noFlags ? 0 : IL_FLAGWRITE_ALL))); + } break; + } case XED_ICLASS_NOP: case XED_ICLASS_NOP2: @@ -2691,21 +3171,47 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev case XED_ICLASS_NOT_LOCK: // TODO: Handle lock prefix case XED_ICLASS_NOT: - il.AddInstruction( - WriteILOperand(il, xedd, addr, 0, 0, - il.Not(opOneLen, - ReadILOperand(il, xedd, addr, 0, 0)))); + { + uint32_t noperands = xed_inst_noperands(xi); + if (noperands == 1) { + // nothing special + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.Not(opOneLen, + ReadILOperand(il, xedd, addr, 0, 0)))); + } else if (noperands == 2) { + // new data destination + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.Not(opTwoLen, + ReadILOperand(il, xedd, addr, 1, 1)))); + } break; + } case XED_ICLASS_OR_LOCK: // TODO: Handle lock prefix case XED_ICLASS_OR: - il.AddInstruction( - WriteILOperand(il, xedd, addr, 0, 0, - il.Or(opOneLen, - ReadILOperand(il, xedd, addr, 0, 0), - ReadILOperand(il, xedd, addr, 1, 1), - IL_FLAGWRITE_ALL))); + { + uint32_t noperands = xed_inst_noperands(xi); + if (noperands == 2) { + // nothing special + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.Or(opOneLen, + ReadILOperand(il, xedd, addr, 0, 0), + ReadILOperand(il, xedd, addr, 1, 1), + noFlags ? 0 : IL_FLAGWRITE_ALL))); + } else if (noperands == 3) { + // new data destination + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.Or(opTwoLen, + ReadILOperand(il, xedd, addr, 1, 1), + ReadILOperand(il, xedd, addr, 2, 2), + noFlags ? 0 : IL_FLAGWRITE_ALL))); + } break; + } case XED_ICLASS_POR: il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -2728,7 +3234,18 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev 0))); // VPOR doesn't modify flags break; + case XED_ICLASS_POP2: + case XED_ICLASS_POP2P: + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.Pop(8))); + il.AddInstruction( + WriteILOperand(il, xedd, addr, 1, 1, + il.Pop(8))); + break; + case XED_ICLASS_POP: + case XED_ICLASS_POPP: il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, il.Pop(opOneLen))); @@ -2859,7 +3376,14 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev ); break; + case XED_ICLASS_PUSH2: + case XED_ICLASS_PUSH2P: + il.AddInstruction(il.Push(8, ReadILOperand(il, xedd, addr, 0, 0))); + il.AddInstruction(il.Push(8, ReadILOperand(il, xedd, addr, 1, 1))); + break; + case XED_ICLASS_PUSH: + case XED_ICLASS_PUSHP: { // 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 @@ -2882,22 +3406,50 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev } case XED_ICLASS_RCL: - il.AddInstruction( - WriteILOperand(il, xedd, addr, 0, 0, - il.RotateLeftCarry(opOneLen, - ReadILOperand(il, xedd, addr, 0, 0), - ReadILOperand(il, xedd, addr, 1, 1), - il.Flag(IL_FLAG_C), IL_FLAGWRITE_ALL))); + { + uint32_t noperands = xed_inst_noperands(xi); + if (noperands == 2) { + // nothing special + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.RotateLeftCarry(opOneLen, + ReadILOperand(il, xedd, addr, 0, 0), + ReadILOperand(il, xedd, addr, 1, 1), + il.Flag(IL_FLAG_C), IL_FLAGWRITE_ALL))); + } else if (noperands == 3) { + // new data destination + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.RotateLeftCarry(opTwoLen, + ReadILOperand(il, xedd, addr, 1, 1), + ReadILOperand(il, xedd, addr, 2, 2), + il.Flag(IL_FLAG_C), IL_FLAGWRITE_ALL))); + } break; + } case XED_ICLASS_RCR: - il.AddInstruction( - WriteILOperand(il, xedd, addr, 0, 0, - il.RotateRightCarry(opOneLen, - ReadILOperand(il, xedd, addr, 0, 0), - ReadILOperand(il, xedd, addr, 1, 1), - il.Flag(IL_FLAG_C), IL_FLAGWRITE_ALL))); + { + uint32_t noperands = xed_inst_noperands(xi); + if (noperands == 2) { + // nothing special + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.RotateRightCarry(opOneLen, + ReadILOperand(il, xedd, addr, 0, 0), + ReadILOperand(il, xedd, addr, 1, 1), + il.Flag(IL_FLAG_C), IL_FLAGWRITE_ALL))); + } else if (noperands == 3) { + // new data destination + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.RotateRightCarry(opTwoLen, + ReadILOperand(il, xedd, addr, 1, 1), + ReadILOperand(il, xedd, addr, 2, 2), + il.Flag(IL_FLAG_C), IL_FLAGWRITE_ALL))); + } break; + } case XED_ICLASS_RET_NEAR: if ((opOne_name != XED_OPERAND_IMM0) || (immediateOne == 0)) @@ -2917,22 +3469,50 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev break; case XED_ICLASS_ROL: - il.AddInstruction( - WriteILOperand(il, xedd, addr, 0, 0, - il.RotateLeft(opOneLen, - ReadILOperand(il, xedd, addr, 0, 0), - ReadILOperand(il, xedd, addr, 1, 1), - IL_FLAGWRITE_ALL))); + { + uint32_t noperands = xed_inst_noperands(xi); + if (noperands == 2) { + // nothing special + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.RotateLeft(opOneLen, + ReadILOperand(il, xedd, addr, 0, 0), + ReadILOperand(il, xedd, addr, 1, 1), + noFlags ? 0 : IL_FLAGWRITE_ALL))); + } else if (noperands == 3) { + // new data destination + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.RotateLeft(opTwoLen, + ReadILOperand(il, xedd, addr, 1, 1), + ReadILOperand(il, xedd, addr, 2, 2), + noFlags ? 0 : IL_FLAGWRITE_ALL))); + } break; + } case XED_ICLASS_ROR: - il.AddInstruction( - WriteILOperand(il, xedd, addr, 0, 0, - il.RotateRight(opOneLen, - ReadILOperand(il, xedd, addr, 0, 0), - ReadILOperand(il, xedd, addr, 1, 1), - IL_FLAGWRITE_ALL))); + { + uint32_t noperands = xed_inst_noperands(xi); + if (noperands == 2) { + // nothing special + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.RotateRight(opOneLen, + ReadILOperand(il, xedd, addr, 0, 0), + ReadILOperand(il, xedd, addr, 1, 1), + noFlags ? 0 : IL_FLAGWRITE_ALL))); + } else if (noperands == 3) { + // new data destination + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.RotateRight(opTwoLen, + ReadILOperand(il, xedd, addr, 1, 1), + ReadILOperand(il, xedd, addr, 2, 2), + noFlags ? 0 : IL_FLAGWRITE_ALL))); + } break; + } // there is no ROLX instruciton case XED_ICLASS_RORX: @@ -2945,13 +3525,27 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev break; case XED_ICLASS_SAR: - il.AddInstruction( - WriteILOperand(il, xedd, addr, 0, 0, - il.ArithShiftRight(opOneLen, - ReadILOperand(il, xedd, addr, 0, 0), - ReadILOperand(il, xedd, addr, 1, 1), - IL_FLAGWRITE_ALL))); + { + uint32_t noperands = xed_inst_noperands(xi); + if (noperands == 2) { + // nothing special + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.ArithShiftRight(opOneLen, + ReadILOperand(il, xedd, addr, 0, 0), + ReadILOperand(il, xedd, addr, 1, 1), + noFlags ? 0 : IL_FLAGWRITE_ALL))); + } else if (noperands == 3) { + // new data destination + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.ArithShiftRight(opTwoLen, + ReadILOperand(il, xedd, addr, 1, 1), + ReadILOperand(il, xedd, addr, 2, 2), + noFlags ? 0 : IL_FLAGWRITE_ALL))); + } break; + } case XED_ICLASS_SARX: il.AddInstruction( @@ -2972,13 +3566,27 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev case XED_ICLASS_SBB_LOCK: // TODO: Handle lock prefix case XED_ICLASS_SBB: - il.AddInstruction( - WriteILOperand(il, xedd, addr, 0, 0, - il.SubBorrow(opOneLen, - ReadILOperand(il, xedd, addr, 0, 0), - ReadILOperand(il, xedd, addr, 1, 1), - il.Flag(IL_FLAG_C), IL_FLAGWRITE_ALL))); + { + uint32_t noperands = xed_inst_noperands(xi); + if (noperands == 2) { + // nothing special + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.SubBorrow(opOneLen, + ReadILOperand(il, xedd, addr, 0, 0), + ReadILOperand(il, xedd, addr, 1, 1), + il.Flag(IL_FLAG_C), IL_FLAGWRITE_ALL))); + } else if (noperands == 3) { + // new data destination + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.SubBorrow(opTwoLen, + ReadILOperand(il, xedd, addr, 1, 1), + ReadILOperand(il, xedd, addr, 2, 2), + il.Flag(IL_FLAG_C), IL_FLAGWRITE_ALL))); + } break; + } case XED_ICLASS_REPE_SCASB: case XED_ICLASS_REPE_SCASD: @@ -3040,6 +3648,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev break; } + // TODO: ZU flag case XED_ICLASS_SETO: il.AddInstruction(WriteILOperand(il, xedd, addr, 0, 0, il.Flag(IL_FLAG_O))); break; @@ -3105,24 +3714,52 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev break; case XED_ICLASS_SHL: - il.AddInstruction( - WriteILOperand(il, xedd, addr, 0, 0, - il.ShiftLeft(opOneLen, - ReadILOperand(il, xedd, addr, 0, 0), - ReadILOperand(il, xedd, addr, 1, 1), - IL_FLAGWRITE_ALL))); + { + uint32_t noperands = xed_inst_noperands(xi); + if (noperands == 2) { + // nothing special + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.ShiftLeft(opOneLen, + ReadILOperand(il, xedd, addr, 0, 0), + ReadILOperand(il, xedd, addr, 1, 1), + noFlags ? 0 : IL_FLAGWRITE_ALL))); + } else if (noperands == 3) { + // new data destination + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.ShiftLeft(opTwoLen, + ReadILOperand(il, xedd, addr, 1, 1), + ReadILOperand(il, xedd, addr, 2, 2), + noFlags ? 0 : IL_FLAGWRITE_ALL))); + } break; + } // This is imprecise since it does NOT move the last shifted bit into CF // the same problem also happens on SHL, SAR case XED_ICLASS_SHR: - il.AddInstruction( - WriteILOperand(il, xedd, addr, 0, 0, - il.LogicalShiftRight(opOneLen, - ReadILOperand(il, xedd, addr, 0, 0), - ReadILOperand(il, xedd, addr, 1, 1), - IL_FLAGWRITE_ALL))); + { + uint32_t noperands = xed_inst_noperands(xi); + if (noperands == 2) { + // nothing special + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.LogicalShiftRight(opOneLen, + ReadILOperand(il, xedd, addr, 0, 0), + ReadILOperand(il, xedd, addr, 1, 1), + noFlags ? 0 : IL_FLAGWRITE_ALL))); + } else if (noperands == 3) { + // new data destination + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.LogicalShiftRight(opTwoLen, + ReadILOperand(il, xedd, addr, 1, 1), + ReadILOperand(il, xedd, addr, 2, 2), + noFlags ? 0 : IL_FLAGWRITE_ALL))); + } break; + } case XED_ICLASS_SHLX: il.AddInstruction( @@ -3146,52 +3783,94 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev { size_t opSize = opOneLen; size_t mask = opSize == 4 ? 31 : 63; + uint32_t noperands = xed_inst_noperands(xi); // Shift left double: operand[0] = operand[0]:operand[1] << operand[3] // this since we can't easily operation on a combined register we do it like this // operand[0] = (operand[0] << operand[3]) | (operand[1] >> (63|32 - operand[3])) // One final cevate operand[3] must be masked with 63|32 - il.AddInstruction(WriteILOperand(il, xedd, addr, 0, 0, - il.Or(opSize, - il.ShiftLeft(opSize, - ReadILOperand(il, xedd, addr, 0, 0), - il.And(opSize, - il.Const(1, mask), - ReadILOperand(il, xedd, addr, 2, 2)), - IL_FLAGWRITE_ALL), - il.LogicalShiftRight(opSize, - ReadILOperand(il, xedd, addr, 1, 1), - il.Sub(opSize, + if (noperands == 2) { + // nothing special + il.AddInstruction(WriteILOperand(il, xedd, addr, 0, 0, + il.Or(opSize, + il.ShiftLeft(opSize, + ReadILOperand(il, xedd, addr, 0, 0), il.And(opSize, il.Const(1, mask), ReadILOperand(il, xedd, addr, 2, 2)), - il.Const(1, opSize * 8)))))); + noFlags ? 0 : IL_FLAGWRITE_ALL), + il.LogicalShiftRight(opSize, + ReadILOperand(il, xedd, addr, 1, 1), + il.Sub(opSize, + il.And(opSize, + il.Const(1, mask), + ReadILOperand(il, xedd, addr, 2, 2)), + il.Const(1, opSize * 8)))))); + } else if (noperands == 3) { + // new data destination + il.AddInstruction(WriteILOperand(il, xedd, addr, 0, 0, + il.Or(opSize, + il.ShiftLeft(opSize, + ReadILOperand(il, xedd, addr, 1, 1), + il.And(opSize, + il.Const(1, mask), + ReadILOperand(il, xedd, addr, 3, 3)), + noFlags ? 0 : IL_FLAGWRITE_ALL), + il.LogicalShiftRight(opSize, + ReadILOperand(il, xedd, addr, 2, 2), + il.Sub(opSize, + il.And(opSize, + il.Const(1, mask), + ReadILOperand(il, xedd, addr, 3, 3)), + il.Const(1, opSize * 8)))))); + } break; } case XED_ICLASS_SHRD: { size_t opSize = opOneLen; size_t mask = opSize == 4 ? 31 : 63; + uint32_t noperands = xed_inst_noperands(xi); // Shift right double: operand[0] = operand[0]:operand[1] >> operand[3] // this since we can't easily operation on a combined register we do it like this // operand[0] = (operand[0] >> operand[3]) | (operand[1] << (63|31 - operand[3])) // One final cevate operand[3] must be masked with 63|31 - il.AddInstruction(WriteILOperand(il, xedd, addr, 0, 0, - il.Or(opSize, - il.LogicalShiftRight(opSize, - ReadILOperand(il, xedd, addr, 0, 0), - il.And(opSize, - il.Const(1, mask), - ReadILOperand(il, xedd, addr, 2, 2)), - IL_FLAGWRITE_ALL), - il.ShiftLeft(opSize, - ReadILOperand(il, xedd, addr, 1, 1), - il.Sub(opSize, - il.Const(1, opSize * 8), + if (noperands == 2) { + // nothing special + il.AddInstruction(WriteILOperand(il, xedd, addr, 0, 0, + il.Or(opSize, + il.LogicalShiftRight(opSize, + ReadILOperand(il, xedd, addr, 0, 0), + il.And(opSize, + il.Const(1, mask), + ReadILOperand(il, xedd, addr, 2, 2)), + noFlags ? 0 : IL_FLAGWRITE_ALL), + il.ShiftLeft(opSize, + ReadILOperand(il, xedd, addr, 1, 1), + il.Sub(opSize, + il.Const(1, opSize * 8), + il.And(opSize, + il.Const(1, mask), + ReadILOperand(il, xedd, addr, 2, 2))))))); + } else if (noperands == 3) { + // new data destination + il.AddInstruction(WriteILOperand(il, xedd, addr, 0, 0, + il.Or(opSize, + il.LogicalShiftRight(opSize, + ReadILOperand(il, xedd, addr, 1, 1), il.And(opSize, il.Const(1, mask), - ReadILOperand(il, xedd, addr, 2, 2))))))); + ReadILOperand(il, xedd, addr, 3, 3)), + noFlags ? 0 : IL_FLAGWRITE_ALL), + il.ShiftLeft(opSize, + ReadILOperand(il, xedd, addr, 2, 2), + il.Sub(opSize, + il.Const(1, opSize * 8), + il.And(opSize, + il.Const(1, mask), + ReadILOperand(il, xedd, addr, 3, 3))))))); + } break; } case XED_ICLASS_STOSB: @@ -3313,15 +3992,30 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev case XED_ICLASS_SUB_LOCK: // TODO: Handle lock prefix case XED_ICLASS_SUB: - il.AddInstruction( - WriteILOperand(il, xedd, addr, 0, 0, - il.Sub(opOneLen, - ReadILOperand(il, xedd, addr, 0, 0), - ReadILOperand(il, xedd, addr, 1, 1), - IL_FLAGWRITE_ALL))); + { + uint32_t noperands = xed_inst_noperands(xi); + if (noperands == 2) { + // nothing special + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.Sub(opOneLen, + ReadILOperand(il, xedd, addr, 0, 0), + ReadILOperand(il, xedd, addr, 1, 1), + noFlags ? 0 : IL_FLAGWRITE_ALL))); + } else if (noperands == 3) { + // new data destination + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.Sub(opTwoLen, + ReadILOperand(il, xedd, addr, 1, 1), + ReadILOperand(il, xedd, addr, 2, 2), + noFlags ? 0 : IL_FLAGWRITE_ALL))); + } break; + } case XED_ICLASS_TEST: + case XED_ICLASS_CTESTT: il.AddInstruction( il.And(opOneLen, ReadILOperand(il, xedd, addr, 0, 0), @@ -3367,6 +4061,66 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev ); break; + case XED_ICLASS_CTESTO: + ConditionalTest(addr, xedd, il, opOneLen, il.FlagCondition(LLFC_O)); + break; + + case XED_ICLASS_CTESTNO: + ConditionalTest(addr, xedd, il, opOneLen, il.FlagCondition(LLFC_NO)); + break; + + case XED_ICLASS_CTESTB: + ConditionalTest(addr, xedd, il, opOneLen, il.FlagGroup(IL_FLAG_GROUP_LT)); + break; + + case XED_ICLASS_CTESTNB: + ConditionalTest(addr, xedd, il, opOneLen, il.FlagGroup(IL_FLAG_GROUP_GE)); + break; + + case XED_ICLASS_CTESTZ: + ConditionalTest(addr, xedd, il, opOneLen, il.FlagGroup(IL_FLAG_GROUP_E)); + break; + + case XED_ICLASS_CTESTNZ: + ConditionalTest(addr, xedd, il, opOneLen, il.FlagGroup(IL_FLAG_GROUP_NE)); + break; + + case XED_ICLASS_CTESTBE: + ConditionalTest(addr, xedd, il, opOneLen, il.FlagGroup(IL_FLAG_GROUP_LE)); + break; + + case XED_ICLASS_CTESTNBE: + ConditionalTest(addr, xedd, il, opOneLen, il.FlagGroup(IL_FLAG_GROUP_GT)); + break; + + case XED_ICLASS_CTESTS: + ConditionalTest(addr, xedd, il, opOneLen, il.FlagCondition(LLFC_NEG)); + break; + + case XED_ICLASS_CTESTNS: + ConditionalTest(addr, xedd, il, opOneLen, il.FlagCondition(LLFC_POS)); + break; + + case XED_ICLASS_CTESTL: + ConditionalTest(addr, xedd, il, opOneLen, il.FlagCondition(LLFC_SLT)); + break; + + case XED_ICLASS_CTESTNL: + ConditionalTest(addr, xedd, il, opOneLen, il.FlagCondition(LLFC_SLT)); + break; + + case XED_ICLASS_CTESTLE: + ConditionalTest(addr, xedd, il, opOneLen, il.FlagCondition(LLFC_SLE)); + break; + + case XED_ICLASS_CTESTNLE: + ConditionalTest(addr, xedd, il, opOneLen, il.FlagCondition(LLFC_SGT)); + break; + + case XED_ICLASS_CTESTF: + AssignEvexDfv(xedd, il); + break; + case XED_ICLASS_XCHG: il.AddInstruction(il.SetRegister(opOneLen, LLIL_TEMP(0), ReadILOperand(il, xedd, addr, 0, 0))); il.AddInstruction(WriteILOperand(il, xedd, addr, 0, 0, ReadILOperand(il, xedd, addr, 1, 1))); @@ -3500,13 +4254,27 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev break; case XED_ICLASS_XOR_LOCK: // TODO: Handle lock prefix case XED_ICLASS_XOR: - il.AddInstruction( - WriteILOperand(il, xedd, addr, 0, 0, - il.Xor(opOneLen, - ReadILOperand(il, xedd, addr, 0, 0), - ReadILOperand(il, xedd, addr, 1, 1), - IL_FLAGWRITE_ALL))); + { + uint32_t noperands = xed_inst_noperands(xi); + if (noperands == 2) { + // nothing special + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.Xor(opOneLen, + ReadILOperand(il, xedd, addr, 0, 0), + ReadILOperand(il, xedd, addr, 1, 1), + noFlags ? 0 : IL_FLAGWRITE_ALL))); + } else if (noperands == 3) { + // new data destination + il.AddInstruction( + WriteILOperand(il, xedd, addr, 0, 0, + il.Xor(opTwoLen, + ReadILOperand(il, xedd, addr, 1, 1), + ReadILOperand(il, xedd, addr, 2, 2), + noFlags ? 0 : IL_FLAGWRITE_ALL))); + } break; + } case XED_ICLASS_VPXOR: if (xed_classify_avx512(xedd)) { From 90d2968adf38d4d60c10fd65c29dfdce92c48027 Mon Sep 17 00:00:00 2001 From: nullableVoidPtr <30564701+nullableVoidPtr@users.noreply.github.com> Date: Tue, 18 Feb 2025 22:26:21 +1100 Subject: [PATCH 2/2] [arch/x86] fix: Intel APX NDD --- arch/x86/il.cpp | 209 ++++++++++++------------------------------------ 1 file changed, 50 insertions(+), 159 deletions(-) diff --git a/arch/x86/il.cpp b/arch/x86/il.cpp index 46e485f2f..e8ae28471 100644 --- a/arch/x86/il.cpp +++ b/arch/x86/il.cpp @@ -451,7 +451,7 @@ static void Repeat( static void CMovFlagCond(const int64_t addr, const xed_decoded_inst_t* xedd, LowLevelILFunction& il, BNLowLevelILFlagCondition flag) { bool isCondFault = false; - bool isNdd = false; + bool isNdd = xed_decoded_inst_get_attribute(xedd, XED_ATTRIBUTE_APX_NDD); switch (xed_decoded_inst_get_iclass(xedd)) { case XED_ICLASS_CFCMOVB: @@ -471,29 +471,6 @@ static void CMovFlagCond(const int64_t addr, const xed_decoded_inst_t* xedd, Low case XED_ICLASS_CFCMOVS: case XED_ICLASS_CFCMOVZ: isCondFault = true; - case XED_ICLASS_CMOVB: - case XED_ICLASS_CMOVBE: - case XED_ICLASS_CMOVL: - case XED_ICLASS_CMOVLE: - case XED_ICLASS_CMOVNB: - case XED_ICLASS_CMOVNBE: - case XED_ICLASS_CMOVNL: - case XED_ICLASS_CMOVNLE: - case XED_ICLASS_CMOVNO: - case XED_ICLASS_CMOVNP: - case XED_ICLASS_CMOVNS: - case XED_ICLASS_CMOVNZ: - case XED_ICLASS_CMOVO: - case XED_ICLASS_CMOVP: - case XED_ICLASS_CMOVS: - case XED_ICLASS_CMOVZ: - { - size_t noperands = xed_inst_noperands(xed_decoded_inst_inst(xedd)); - if (noperands == 3) { - isNdd = true; - break; - } - } default: break; } @@ -558,7 +535,7 @@ static void CMovFlagCond(const int64_t addr, const xed_decoded_inst_t* xedd, Low static void CMovFlagGroup(const int64_t addr, const xed_decoded_inst_t* xedd, LowLevelILFunction& il, uint32_t flag) { bool isCondFault = false; - bool isNdd = false; + bool isNdd = xed_decoded_inst_get_attribute(xedd, XED_ATTRIBUTE_APX_NDD); switch (xed_decoded_inst_get_iclass(xedd)) { case XED_ICLASS_CFCMOVB: @@ -578,29 +555,6 @@ static void CMovFlagGroup(const int64_t addr, const xed_decoded_inst_t* xedd, Lo case XED_ICLASS_CFCMOVS: case XED_ICLASS_CFCMOVZ: isCondFault = true; - case XED_ICLASS_CMOVB: - case XED_ICLASS_CMOVBE: - case XED_ICLASS_CMOVL: - case XED_ICLASS_CMOVLE: - case XED_ICLASS_CMOVNB: - case XED_ICLASS_CMOVNBE: - case XED_ICLASS_CMOVNL: - case XED_ICLASS_CMOVNLE: - case XED_ICLASS_CMOVNO: - case XED_ICLASS_CMOVNP: - case XED_ICLASS_CMOVNS: - case XED_ICLASS_CMOVNZ: - case XED_ICLASS_CMOVO: - case XED_ICLASS_CMOVP: - case XED_ICLASS_CMOVS: - case XED_ICLASS_CMOVZ: - { - size_t noperands = xed_inst_noperands(xed_decoded_inst_inst(xedd)); - if (noperands == 3) { - isNdd = true; - break; - } - } default: break; } @@ -784,6 +738,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev const uint64_t immediateOne = xed_decoded_inst_get_unsigned_immediate(xedd); const int64_t branchDestination = xed_decoded_inst_get_branch_displacement(xedd) + addr + instLen; + const bool newDataDestination = xed_decoded_inst_get_attribute(xedd, XED_ATTRIBUTE_APX_NDD); const bool noFlags = xed_decoded_inst_get_attribute(xedd, XED_ATTRIBUTE_APX_NF); const bool zeroUpper = xed_decoded_inst_is_apx_zu(xedd); @@ -897,9 +852,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev { case XED_ICLASS_ADC_LOCK: // TODO: Add Lock construct case XED_ICLASS_ADC: - { - uint32_t noperands = xed_inst_noperands(xi); - if (noperands == 2) { + if (!newDataDestination) { // nothing special il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -907,7 +860,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev ReadILOperand(il, xedd, addr, 0, 0), ReadILOperand(il, xedd, addr, 1, 1), il.Flag(IL_FLAG_C), IL_FLAGWRITE_ALL))); - } else if (noperands == 3) { + } else { // new data destination il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -917,12 +870,9 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev il.Flag(IL_FLAG_C), IL_FLAGWRITE_ALL))); } break; - } case XED_ICLASS_ADCX: - { - uint32_t noperands = xed_inst_noperands(xi); - if (noperands == 2) { + if (!newDataDestination) { // nothing special il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -930,7 +880,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev ReadILOperand(il, xedd, addr, 0, 0), ReadILOperand(il, xedd, addr, 1, 1), il.Flag(IL_FLAG_C), IL_FLAG_C))); - } else if (noperands == 3) { + } else { // new data destination il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -940,12 +890,9 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev il.Flag(IL_FLAG_C), IL_FLAG_C))); } break; - } case XED_ICLASS_ADOX: - { - uint32_t noperands = xed_inst_noperands(xi); - if (noperands == 2) { + if (!newDataDestination) { // nothing special il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -953,7 +900,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev ReadILOperand(il, xedd, addr, 0, 0), ReadILOperand(il, xedd, addr, 1, 1), il.Flag(IL_FLAG_O), IL_FLAG_O))); - } else if (noperands == 3) { + } else { // new data destination il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -963,13 +910,10 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev il.Flag(IL_FLAG_O), IL_FLAG_O))); } break; - } case XED_ICLASS_ADD_LOCK: // TODO: Add Lock construct case XED_ICLASS_ADD: - { - uint32_t noperands = xed_inst_noperands(xi); - if (noperands == 2) { + if (!newDataDestination) { // nothing special il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -977,7 +921,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev ReadILOperand(il, xedd, addr, 0, 0), ReadILOperand(il, xedd, addr, 1, 1), noFlags ? 0 : IL_FLAGWRITE_ALL))); - } else if (noperands == 3) { + } else { // new data destination il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -987,13 +931,10 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev noFlags ? 0 : IL_FLAGWRITE_ALL))); } break; - } case XED_ICLASS_AND_LOCK: // TODO: Add Lock construct case XED_ICLASS_AND: - { - uint32_t noperands = xed_inst_noperands(xi); - if (noperands == 2) { + if (!newDataDestination) { // nothing special il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -1001,7 +942,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev ReadILOperand(il, xedd, addr, 0, 0), ReadILOperand(il, xedd, addr, 1, 1), noFlags ? 0 : IL_FLAGWRITE_ALL))); - } else if (noperands == 3) { + } else { // new data destination il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -1011,7 +952,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev noFlags ? 0 : IL_FLAGWRITE_ALL))); } break; - } + case XED_ICLASS_PAND: il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -1879,9 +1820,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev case XED_ICLASS_DEC_LOCK: // TODO: Handle lock prefix case XED_ICLASS_DEC: - { - uint32_t noperands = xed_inst_noperands(xi); - if (noperands == 1) { + if (!newDataDestination) { // nothing special il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -1891,7 +1830,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev noFlags ? 0 : IL_FLAGWRITE_NOCARRY) ) ); - } else if (noperands == 2) { + } else { // new data destination il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -1903,7 +1842,6 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev ); } break; - } case XED_ICLASS_DIV: il.AddInstruction( @@ -2230,9 +2168,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev case XED_IFORM_IMUL_GPRv_GPRv: case XED_IFORM_IMUL_GPRv_MEMv: - { - uint32_t noperands = xed_inst_noperands(xi); - if (noperands == 2) { + if (!newDataDestination) { // nothing special il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -2240,7 +2176,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev ReadILOperand(il, xedd, addr, 0, 0), ReadILOperand(il, xedd, addr, 1, 1), IL_FLAGWRITE_CO))); - } else if (noperands == 3) { + } else { // new data destination il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -2250,7 +2186,6 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev IL_FLAGWRITE_CO))); } break; - } case XED_IFORM_IMUL_GPRv_GPRv_IMMb: case XED_IFORM_IMUL_GPRv_GPRv_IMMz: case XED_IFORM_IMUL_GPRv_MEMv_IMMb: @@ -2279,9 +2214,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev case XED_ICLASS_INC_LOCK: // TODO: Handle lock prefix case XED_ICLASS_INC: - { - uint32_t noperands = xed_inst_noperands(xi); - if (noperands == 1) { + if (!newDataDestination) { // nothing special il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -2289,7 +2222,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev ReadILOperand(il, xedd, addr, 0, 0), il.Const(opOneLen, 1), noFlags ? 0 : IL_FLAGWRITE_NOCARRY))); - } else if (noperands == 2) { + } else { // new data destination il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -2299,7 +2232,6 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev noFlags ? 0 : IL_FLAGWRITE_NOCARRY))); } break; - } case XED_ICLASS_INT: switch (immediateOne) @@ -3113,16 +3045,14 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev case XED_ICLASS_NEG_LOCK: // TODO: Handle lock prefix case XED_ICLASS_NEG: - { - uint32_t noperands = xed_inst_noperands(xi); - if (noperands == 1) { + if (!newDataDestination) { // nothing special il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, il.Neg(opOneLen, ReadILOperand(il, xedd, addr, 0, 0), noFlags ? 0 : IL_FLAGWRITE_ALL))); - } else if (noperands == 2) { + } else { // new data destination il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -3131,7 +3061,6 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev noFlags ? 0 : IL_FLAGWRITE_ALL))); } break; - } case XED_ICLASS_NOP: case XED_ICLASS_NOP2: @@ -3171,15 +3100,13 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev case XED_ICLASS_NOT_LOCK: // TODO: Handle lock prefix case XED_ICLASS_NOT: - { - uint32_t noperands = xed_inst_noperands(xi); - if (noperands == 1) { + if (!newDataDestination) { // nothing special il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, il.Not(opOneLen, ReadILOperand(il, xedd, addr, 0, 0)))); - } else if (noperands == 2) { + } else { // new data destination il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -3187,13 +3114,10 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev ReadILOperand(il, xedd, addr, 1, 1)))); } break; - } case XED_ICLASS_OR_LOCK: // TODO: Handle lock prefix case XED_ICLASS_OR: - { - uint32_t noperands = xed_inst_noperands(xi); - if (noperands == 2) { + if (!newDataDestination) { // nothing special il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -3201,7 +3125,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev ReadILOperand(il, xedd, addr, 0, 0), ReadILOperand(il, xedd, addr, 1, 1), noFlags ? 0 : IL_FLAGWRITE_ALL))); - } else if (noperands == 3) { + } else { // new data destination il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -3211,7 +3135,6 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev noFlags ? 0 : IL_FLAGWRITE_ALL))); } break; - } case XED_ICLASS_POR: il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -3406,9 +3329,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev } case XED_ICLASS_RCL: - { - uint32_t noperands = xed_inst_noperands(xi); - if (noperands == 2) { + if (!newDataDestination) { // nothing special il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -3416,7 +3337,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev ReadILOperand(il, xedd, addr, 0, 0), ReadILOperand(il, xedd, addr, 1, 1), il.Flag(IL_FLAG_C), IL_FLAGWRITE_ALL))); - } else if (noperands == 3) { + } else { // new data destination il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -3426,12 +3347,9 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev il.Flag(IL_FLAG_C), IL_FLAGWRITE_ALL))); } break; - } case XED_ICLASS_RCR: - { - uint32_t noperands = xed_inst_noperands(xi); - if (noperands == 2) { + if (!newDataDestination) { // nothing special il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -3439,7 +3357,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev ReadILOperand(il, xedd, addr, 0, 0), ReadILOperand(il, xedd, addr, 1, 1), il.Flag(IL_FLAG_C), IL_FLAGWRITE_ALL))); - } else if (noperands == 3) { + } else { // new data destination il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -3449,7 +3367,6 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev il.Flag(IL_FLAG_C), IL_FLAGWRITE_ALL))); } break; - } case XED_ICLASS_RET_NEAR: if ((opOne_name != XED_OPERAND_IMM0) || (immediateOne == 0)) @@ -3469,9 +3386,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev break; case XED_ICLASS_ROL: - { - uint32_t noperands = xed_inst_noperands(xi); - if (noperands == 2) { + if (!newDataDestination) { // nothing special il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -3479,7 +3394,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev ReadILOperand(il, xedd, addr, 0, 0), ReadILOperand(il, xedd, addr, 1, 1), noFlags ? 0 : IL_FLAGWRITE_ALL))); - } else if (noperands == 3) { + } else { // new data destination il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -3489,12 +3404,9 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev noFlags ? 0 : IL_FLAGWRITE_ALL))); } break; - } case XED_ICLASS_ROR: - { - uint32_t noperands = xed_inst_noperands(xi); - if (noperands == 2) { + if (!newDataDestination) { // nothing special il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -3502,7 +3414,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev ReadILOperand(il, xedd, addr, 0, 0), ReadILOperand(il, xedd, addr, 1, 1), noFlags ? 0 : IL_FLAGWRITE_ALL))); - } else if (noperands == 3) { + } else { // new data destination il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -3512,7 +3424,6 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev noFlags ? 0 : IL_FLAGWRITE_ALL))); } break; - } // there is no ROLX instruciton case XED_ICLASS_RORX: @@ -3525,9 +3436,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev break; case XED_ICLASS_SAR: - { - uint32_t noperands = xed_inst_noperands(xi); - if (noperands == 2) { + if (!newDataDestination) { // nothing special il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -3535,7 +3444,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev ReadILOperand(il, xedd, addr, 0, 0), ReadILOperand(il, xedd, addr, 1, 1), noFlags ? 0 : IL_FLAGWRITE_ALL))); - } else if (noperands == 3) { + } else { // new data destination il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -3545,7 +3454,6 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev noFlags ? 0 : IL_FLAGWRITE_ALL))); } break; - } case XED_ICLASS_SARX: il.AddInstruction( @@ -3566,9 +3474,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev case XED_ICLASS_SBB_LOCK: // TODO: Handle lock prefix case XED_ICLASS_SBB: - { - uint32_t noperands = xed_inst_noperands(xi); - if (noperands == 2) { + if (!newDataDestination) { // nothing special il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -3576,7 +3482,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev ReadILOperand(il, xedd, addr, 0, 0), ReadILOperand(il, xedd, addr, 1, 1), il.Flag(IL_FLAG_C), IL_FLAGWRITE_ALL))); - } else if (noperands == 3) { + } else { // new data destination il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -3586,7 +3492,6 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev il.Flag(IL_FLAG_C), IL_FLAGWRITE_ALL))); } break; - } case XED_ICLASS_REPE_SCASB: case XED_ICLASS_REPE_SCASD: @@ -3714,9 +3619,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev break; case XED_ICLASS_SHL: - { - uint32_t noperands = xed_inst_noperands(xi); - if (noperands == 2) { + if (!newDataDestination) { // nothing special il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -3724,7 +3627,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev ReadILOperand(il, xedd, addr, 0, 0), ReadILOperand(il, xedd, addr, 1, 1), noFlags ? 0 : IL_FLAGWRITE_ALL))); - } else if (noperands == 3) { + } else { // new data destination il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -3734,14 +3637,11 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev noFlags ? 0 : IL_FLAGWRITE_ALL))); } break; - } // This is imprecise since it does NOT move the last shifted bit into CF // the same problem also happens on SHL, SAR case XED_ICLASS_SHR: - { - uint32_t noperands = xed_inst_noperands(xi); - if (noperands == 2) { + if (!newDataDestination) { // nothing special il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -3749,7 +3649,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev ReadILOperand(il, xedd, addr, 0, 0), ReadILOperand(il, xedd, addr, 1, 1), noFlags ? 0 : IL_FLAGWRITE_ALL))); - } else if (noperands == 3) { + } else { // new data destination il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -3759,7 +3659,6 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev noFlags ? 0 : IL_FLAGWRITE_ALL))); } break; - } case XED_ICLASS_SHLX: il.AddInstruction( @@ -3783,13 +3682,12 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev { size_t opSize = opOneLen; size_t mask = opSize == 4 ? 31 : 63; - uint32_t noperands = xed_inst_noperands(xi); // Shift left double: operand[0] = operand[0]:operand[1] << operand[3] // this since we can't easily operation on a combined register we do it like this // operand[0] = (operand[0] << operand[3]) | (operand[1] >> (63|32 - operand[3])) // One final cevate operand[3] must be masked with 63|32 - if (noperands == 2) { + if (!newDataDestination) { // nothing special il.AddInstruction(WriteILOperand(il, xedd, addr, 0, 0, il.Or(opSize, @@ -3806,7 +3704,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev il.Const(1, mask), ReadILOperand(il, xedd, addr, 2, 2)), il.Const(1, opSize * 8)))))); - } else if (noperands == 3) { + } else { // new data destination il.AddInstruction(WriteILOperand(il, xedd, addr, 0, 0, il.Or(opSize, @@ -3830,13 +3728,12 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev { size_t opSize = opOneLen; size_t mask = opSize == 4 ? 31 : 63; - uint32_t noperands = xed_inst_noperands(xi); // Shift right double: operand[0] = operand[0]:operand[1] >> operand[3] // this since we can't easily operation on a combined register we do it like this // operand[0] = (operand[0] >> operand[3]) | (operand[1] << (63|31 - operand[3])) // One final cevate operand[3] must be masked with 63|31 - if (noperands == 2) { + if (!newDataDestination) { // nothing special il.AddInstruction(WriteILOperand(il, xedd, addr, 0, 0, il.Or(opSize, @@ -3853,7 +3750,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev il.And(opSize, il.Const(1, mask), ReadILOperand(il, xedd, addr, 2, 2))))))); - } else if (noperands == 3) { + } else { // new data destination il.AddInstruction(WriteILOperand(il, xedd, addr, 0, 0, il.Or(opSize, @@ -3992,9 +3889,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev case XED_ICLASS_SUB_LOCK: // TODO: Handle lock prefix case XED_ICLASS_SUB: - { - uint32_t noperands = xed_inst_noperands(xi); - if (noperands == 2) { + if (!newDataDestination) { // nothing special il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -4002,7 +3897,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev ReadILOperand(il, xedd, addr, 0, 0), ReadILOperand(il, xedd, addr, 1, 1), noFlags ? 0 : IL_FLAGWRITE_ALL))); - } else if (noperands == 3) { + } else { // new data destination il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -4012,7 +3907,6 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev noFlags ? 0 : IL_FLAGWRITE_ALL))); } break; - } case XED_ICLASS_TEST: case XED_ICLASS_CTESTT: @@ -4254,9 +4148,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev break; case XED_ICLASS_XOR_LOCK: // TODO: Handle lock prefix case XED_ICLASS_XOR: - { - uint32_t noperands = xed_inst_noperands(xi); - if (noperands == 2) { + if (!newDataDestination) { // nothing special il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -4264,7 +4156,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev ReadILOperand(il, xedd, addr, 0, 0), ReadILOperand(il, xedd, addr, 1, 1), noFlags ? 0 : IL_FLAGWRITE_ALL))); - } else if (noperands == 3) { + } else { // new data destination il.AddInstruction( WriteILOperand(il, xedd, addr, 0, 0, @@ -4274,7 +4166,6 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev noFlags ? 0 : IL_FLAGWRITE_ALL))); } break; - } case XED_ICLASS_VPXOR: if (xed_classify_avx512(xedd)) {