From 81e9b93aab9217cf7cb508f64b19fc1c0df024b5 Mon Sep 17 00:00:00 2001 From: iximeow Date: Thu, 19 Nov 2020 18:13:24 -0800 Subject: fix decoding of rex-prefixed modrm+sib operands selecting index 0b100 and base 0b101 for memory operands with a base, index, and displacement either the wrong base would be selected (register number ignored, so only `*ax` or `r8*` would be reported), or yaxpeax-x86 would report a base register is present when it is not (`RegIndexBaseScaleDisp` when the operand is actually `RegScaleDisp`) thank you to Evan Johnson for catching and reporting this bug! also bump crate version to 0.1.4 as this will be immediately tagged and released. --- src/long_mode/mod.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'src/long_mode') diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs index 363c605..d165e38 100644 --- a/src/long_mode/mod.rs +++ b/src/long_mode/mod.rs @@ -5665,20 +5665,28 @@ fn read_sib>(bytes_iter: &mut T, instr: &mut Instruction, m OperandSpec::DispU32 } else { + instr.modrm_mmm.num |= 0b101; + if instr.prefixes.rex().x() { instr.sib_index.num = 0b1100; let scale = 1u8 << (sibbyte >> 6); instr.scale = scale; if disp == 0 { - OperandSpec::RegIndexBaseScale + if modbits == 0 { + OperandSpec::RegScale + } else { + OperandSpec::RegIndexBaseScale + } } else { instr.disp = disp as i64 as u64; - OperandSpec::RegIndexBaseScaleDisp + if modbits == 0 { + OperandSpec::RegScaleDisp + } else { + OperandSpec::RegIndexBaseScaleDisp + } } } else { - instr.modrm_mmm.num |= 0b101; - if disp == 0 { OperandSpec::Deref } else { -- cgit v1.1