diff options
author | iximeow <me@iximeow.net> | 2021-08-21 14:03:08 -0700 |
---|---|---|
committer | iximeow <me@iximeow.net> | 2021-08-21 14:03:08 -0700 |
commit | d7208834963c46a6da74a3837d9e82bad33dfd7f (patch) | |
tree | 6df2525647cc29b719ce1db376d271b801c47371 /src/long_mode | |
parent | e4131e4eb64595d9b24493eb31a9af4c5e21b1eb (diff) |
fix incorrect decoding of 0x9*-series instructions with rex.b
Diffstat (limited to 'src/long_mode')
-rw-r--r-- | src/long_mode/mod.rs | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs index a01e854..22b6a99 100644 --- a/src/long_mode/mod.rs +++ b/src/long_mode/mod.rs @@ -5118,7 +5118,7 @@ enum OperandCode { Zv_R5 = OperandCodeBuilder::new().op0_is_rrr_and_Z_operand(ZOperandCategory::Zv_R, 5).bits(), Zv_R6 = OperandCodeBuilder::new().op0_is_rrr_and_Z_operand(ZOperandCategory::Zv_R, 6).bits(), Zv_R7 = OperandCodeBuilder::new().op0_is_rrr_and_Z_operand(ZOperandCategory::Zv_R, 7).bits(), - // Zv_AX_R0 = 0x48, + Zv_AX_R0 = OperandCodeBuilder::new().op0_is_rrr_and_Z_operand(ZOperandCategory::Zv_AX, 0).bits(), Zv_AX_R1 = OperandCodeBuilder::new().op0_is_rrr_and_Z_operand(ZOperandCategory::Zv_AX, 1).bits(), Zv_AX_R2 = OperandCodeBuilder::new().op0_is_rrr_and_Z_operand(ZOperandCategory::Zv_AX, 2).bits(), Zv_AX_R3 = OperandCodeBuilder::new().op0_is_rrr_and_Z_operand(ZOperandCategory::Zv_AX, 3).bits(), @@ -5447,7 +5447,7 @@ const OPCODES: [OpcodeRecord; 256] = [ OpcodeRecord(Interpretation::Instruction(Opcode::LEA), OperandCode::Gv_M), OpcodeRecord(Interpretation::Instruction(Opcode::MOV), OperandCode::Sw_Ew), OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x8f_Ev), - OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::XCHG), OperandCode::Zv_AX_R0), OpcodeRecord(Interpretation::Instruction(Opcode::XCHG), OperandCode::Zv_AX_R1), OpcodeRecord(Interpretation::Instruction(Opcode::XCHG), OperandCode::Zv_AX_R2), OpcodeRecord(Interpretation::Instruction(Opcode::XCHG), OperandCode::Zv_AX_R3), @@ -7428,6 +7428,13 @@ fn read_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpe } 1 => { // Zv_AX + // in 64-bit mode, rex.b is able to make "nop" into an `xchg`, as in `4190` + // aka `xchg eax, r8d. + if reg == 0 && !instruction.prefixes.rex_unchecked().b() { + instruction.opcode = Opcode::NOP; + instruction.operand_count = 0; + return Ok(()); + } let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes); let bank = if opwidth == 4 { RegisterBank::D @@ -7436,8 +7443,9 @@ fn read_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpe } else { RegisterBank::Q }; + // always *ax, but size is determined by prefixes (or lack thereof) instruction.regs[0] = - RegSpec::from_parts(0, instruction.prefixes.rex_unchecked().b(), bank); + RegSpec::from_parts(0, false, bank); instruction.operands[1] = OperandSpec::RegMMM; instruction.regs[1] = RegSpec::from_parts(reg, instruction.prefixes.rex_unchecked().b(), bank); |