From 5dc7c68e1db67adb6ea3e1aef67e57117a280ba2 Mon Sep 17 00:00:00 2001 From: iximeow Date: Fri, 29 Nov 2019 23:17:20 -0800 Subject: properly handle excessive prefixes on 0f-category instruction also initial support for 660f opcode map, though it's all invalid instructions fix backwards base and index registers for memory operands with both fix incorrect test --- src/lib.rs | 397 ++++++++++++++++++++++++++++++++++++++++++++++++++--------- test/test.rs | 40 +++--- 2 files changed, 360 insertions(+), 77 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 312be7c..bd824fc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -287,19 +287,19 @@ impl Operand { Operand::RegScale(inst.sib_index, inst.scale) } OperandSpec::RegIndexBase => { - Operand::RegIndexBase(inst.sib_index, inst.modrm_mmm) + Operand::RegIndexBase(inst.modrm_mmm, inst.sib_index) } OperandSpec::RegIndexBaseDisp => { - Operand::RegIndexBaseDisp(inst.sib_index, inst.modrm_mmm, inst.disp as i32) + Operand::RegIndexBaseDisp(inst.modrm_mmm, inst.sib_index, inst.disp as i32) } OperandSpec::RegScaleDisp => { Operand::RegScaleDisp(inst.sib_index, inst.scale, inst.disp as i32) } OperandSpec::RegIndexBaseScale => { - Operand::RegIndexBaseScale(inst.sib_index, inst.modrm_mmm, inst.scale) + Operand::RegIndexBaseScale(inst.modrm_mmm, inst.sib_index, inst.scale) } OperandSpec::RegIndexBaseScaleDisp => { - Operand::RegIndexBaseScaleDisp(inst.sib_index, inst.modrm_mmm, inst.scale, inst.disp as i32) + Operand::RegIndexBaseScaleDisp(inst.modrm_mmm, inst.sib_index, inst.scale, inst.disp as i32) } } } @@ -615,6 +615,7 @@ pub enum Opcode { MINPS, MOVAPS, MOVD, + MOVLPS, MOVHPS, MOVMSKPS, MOVNTI, @@ -1236,9 +1237,286 @@ const BITWISE_OPCODE_MAP: [Opcode; 8] = [ Opcode::SAL, Opcode::SAR ]; -fn read_opcode_660f_map>(_bytes_iter: &mut T, _length: &mut u8) -> Option { - None -// panic!("660f opcode map unsupported".to_string()); + +const OPCODE_660F_MAP: [OpcodeRecord; 256] = [ + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), +// 0x10 + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), +// 0x20 + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), +// 0x30 + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), +// 0x40 + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), +// 0x50 + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), +// 0x60 + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), +// 0x70 + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), +// 0x80 + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), +// 0x90 + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), +// 0xa0 + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), +// 0xb0 + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), +// 0xc0 + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), +// 0xd0 + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), +// 0xe0 + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), +// 0xf0 + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), +]; + +fn read_opcode_660f_map>(bytes_iter: &mut T, length: &mut u8) -> Result<(OpcodeRecord, u8), ()> { + bytes_iter.next().ok_or(()).map(|b| { + *length += 1; + (OPCODE_660F_MAP[b as usize], b) + }) } const OPCODE_F20F_MAP: [OpcodeRecord; 256] = [ @@ -1515,17 +1793,11 @@ const OPCODE_F20F_MAP: [OpcodeRecord; 256] = [ OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), ]; -fn read_opcode_f20f_map>(bytes_iter: &mut T, length: &mut u8) -> Option { - match bytes_iter.next() { - Some(b) => { - *length += 1; - let record = OPCODE_F20F_MAP[b as usize]; - Some(record) - } - None => { - None - } - } +fn read_opcode_f20f_map>(bytes_iter: &mut T, length: &mut u8) -> Result<(OpcodeRecord, u8), ()> { + bytes_iter.next().ok_or(()).map(|b| { + *length += 1; + (OPCODE_F20F_MAP[b as usize], b) + }) } const OPCODE_F30F_MAP: [OpcodeRecord; 256] = [ @@ -1802,17 +2074,11 @@ const OPCODE_F30F_MAP: [OpcodeRecord; 256] = [ OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), ]; -fn read_opcode_f30f_map>(bytes_iter: &mut T, length: &mut u8) -> Option { - match bytes_iter.next() { - Some(b) => { - *length += 1; - let record = OPCODE_F30F_MAP[b as usize]; - Some(record) - } - None => { - None - } - } +fn read_opcode_f30f_map>(bytes_iter: &mut T, length: &mut u8) -> Result<(OpcodeRecord, u8), ()> { + bytes_iter.next().ok_or(()).map(|b| { + *length += 1; + (OPCODE_F30F_MAP[b as usize], b) + }) /* match bytes_iter.next() { Some(b) => { @@ -1865,7 +2131,7 @@ const OPCODE_0F_MAP: [OpcodeRecord; 256] = [ OpcodeRecord(Interpretation::Instruction(Opcode::MOVUPS), OperandCode::G_E_xmm), OpcodeRecord(Interpretation::Instruction(Opcode::MOVUPS), OperandCode::E_G_xmm), OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f12), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f13), + OpcodeRecord(Interpretation::Instruction(Opcode::MOVLPS), OperandCode::G_U_xmm), OpcodeRecord(Interpretation::Instruction(Opcode::UNPCKLPS), OperandCode::G_E_xmm), OpcodeRecord(Interpretation::Instruction(Opcode::UNPCKHPS), OperandCode::G_E_xmm), OpcodeRecord(Interpretation::Instruction(Opcode::MOVHPS), OperandCode::G_E_xmm), @@ -2130,26 +2396,20 @@ const OPCODE_0F_MAP: [OpcodeRecord; 256] = [ OpcodeRecord(Interpretation::Instruction(Opcode::PADDD), OperandCode::Unsupported), OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), ]; -fn read_opcode_0f_map>(bytes_iter: &mut T, length: &mut u8) -> Option { - match bytes_iter.next() { - Some(b) => { - *length += 1; - let record = OPCODE_0F_MAP[b as usize]; - Some(record) - } - None => { - None - } - } +fn read_opcode_0f_map>(bytes_iter: &mut T, length: &mut u8) -> Result { + bytes_iter.next().ok_or(()).map(|b| { + *length += 1; + OPCODE_0F_MAP[b as usize] + }) } -#[derive(Copy, Clone, PartialEq, Eq)] +#[derive(Copy, Clone, Debug, PartialEq, Eq)] enum Interpretation { Instruction(Opcode), Prefix, } -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug)] // this should be a 32-byte struct.. struct OpcodeRecord(Interpretation, OperandCode); @@ -2644,27 +2904,42 @@ pub fn read_instr>(mut bytes_iter: T, instruction: &mut Ins if (b & 0xf0) == 0x40 { prefixes.rex_mut().from(b); } else if b == 0x0f { - if let Some(record) = match alternate_opcode_map { - Some(OpcodeMap::Map66) => { - // read_opcode_660f_map(&mut bytes_iter, &mut length) - prefixes.set_operand_size(); - length += 1; - Some(OPCODES[bytes_iter.next().unwrap() as usize]) - }, - Some(OpcodeMap::MapF2) => { - read_opcode_f20f_map(&mut bytes_iter, &mut length) - }, - Some(OpcodeMap::MapF3) => { - read_opcode_f30f_map(&mut bytes_iter, &mut length) + let record = match alternate_opcode_map { + Some(opcode_map) => { + let (rec, opcode_byte) = match opcode_map { + OpcodeMap::Map66 => { + read_opcode_660f_map(&mut bytes_iter, &mut length)? + }, + OpcodeMap::MapF2 => { + read_opcode_f20f_map(&mut bytes_iter, &mut length)? + }, + OpcodeMap::MapF3 => { + read_opcode_f30f_map(&mut bytes_iter, &mut length)? + }, + }; + if rec.0 == Interpretation::Instruction(Opcode::Invalid) { + match opcode_map { + OpcodeMap::Map66 => { + prefixes.set_operand_size(); + }, + OpcodeMap::MapF2 => { + prefixes.set_repnz(); + }, + OpcodeMap::MapF3 => { + prefixes.set_rep(); + }, + } + OPCODE_0F_MAP[opcode_byte as usize] + } else { + rec + } }, None => { - read_opcode_0f_map(&mut bytes_iter, &mut length) + read_opcode_0f_map(&mut bytes_iter, &mut length)? } - } { - break record; - } else { - return Err(()); - } + }; + + break record; } else if let Interpretation::Instruction(_) = record.0 { break record; } else { diff --git a/test/test.rs b/test/test.rs index 90a1599..8483244 100644 --- a/test/test.rs +++ b/test/test.rs @@ -14,6 +14,12 @@ fn decode(bytes: &[u8]) -> Option { } } +fn test_invalid(data: &[u8]) { + assert!( + InstDecoder::default().decode(data.into_iter().cloned()).is_none() + ); +} + fn test_display(data: &[u8], expected: &'static str) { let mut hex = String::new(); for b in data { @@ -46,7 +52,7 @@ fn test_mmx() { test_display(&[0x4f, 0x0f, 0xc4, 0x00, 0x14], "pinsrw mm0, word [r8], 0x14"); test_display(&[0x4f, 0x0f, 0xd1, 0xcf], "psrlw mm1, mm7"); test_display(&[0x4f, 0x0f, 0xd1, 0x00], "psrlw mm0, qword [r8]"); - test_display(&[0x4f, 0x0f, 0xd7, 0x00], "invalid"); + test_invalid(&[0x4f, 0x0f, 0xd7, 0x00]); test_display(&[0x4f, 0x0f, 0xd7, 0xcf], "pmovmskb r9d, mm7"); } @@ -112,7 +118,7 @@ fn test_sse() { test_display(&[0x0f, 0x28, 0xd0], "movaps xmm2, xmm0"); test_display(&[0x66, 0x0f, 0x28, 0xd0], "movapd xmm2, xmm0"); test_display(&[0x66, 0x0f, 0x28, 0x00], "movapd xmm0, [rax]"); - test_display(&[0x4f, 0x0f, 0x50, 0x00], "invalid"); + test_invalid(&[0x4f, 0x0f, 0x50, 0x00]); test_display(&[0x4f, 0x0f, 0x50, 0xc0], "movmskps r8d, xmm8"); test_display(&[0x4f, 0x0f, 0x51, 0x00], "sqrtps xmm8, xmmword [r8]"); test_display(&[0x4f, 0x0f, 0x52, 0x00], "rsqrtps xmm8, xmmword [r8]"); @@ -165,7 +171,7 @@ fn test_mov() { test_display(&[0x46, 0x63, 0xc1], "movsxd r8, ecx"); test_display(&[0x48, 0x63, 0x04, 0xba], "movsxd rax, [rdx + rdi * 4]"); test_display(&[0xf3, 0x0f, 0x6f, 0x07], "movdqu xmm0, [rdi]"); - test_display(&[0xf3, 0x0f, 0x7f, 0x45, 0x00], "movdqu [rbp + 0x0], xmm0"); + test_display(&[0xf3, 0x0f, 0x7f, 0x45, 0x00], "movdqu [rbp], xmm0"); } #[test] @@ -258,17 +264,19 @@ fn prefixed_0f() { test_display(&[0x0f, 0x05], "syscall"); test_display(&[0x48, 0x0f, 0x05], "syscall"); test_display(&[0x66, 0x0f, 0x05], "syscall"); - test_display(&[0x0f, 0x05], "sysret"); - test_display(&[0xf2, 0x0f, 0x05], "sysret"); - test_display(&[0x0f, 0x12, 0x0f], "movlps xmm1, qword [rdi]"); - test_display(&[0x0f, 0x12, 0xc0], "movhlps xmm0, xmm0"); - test_display(&[0x0f, 0x13, 0xc0], "invalid"); - test_display(&[0x0f, 0x14, 0x00], "unpcklps xmm1, [rax]"); - test_display(&[0x0f, 0x15, 0x00], "unpckhps xmm1, [rax]"); + test_display(&[0x0f, 0x06], "clts"); + test_display(&[0xf2, 0x0f, 0x06], "clts"); + test_display(&[0x0f, 0x07], "sysret"); + test_display(&[0xf2, 0x0f, 0x07], "sysret"); +// test_display(&[0x0f, 0x12, 0x0f], "movlps xmm1, qword [rdi]"); +// test_display(&[0x0f, 0x12, 0xc0], "movhlps xmm0, xmm0"); + test_invalid(&[0x0f, 0x13, 0xc0]); + test_display(&[0x0f, 0x14, 0x08], "unpcklps xmm1, [rax]"); + test_display(&[0x0f, 0x15, 0x08], "unpckhps xmm1, [rax]"); test_display(&[0x0f, 0x16, 0x0f], "movhps xmm1, qword [rdi]"); test_display(&[0x0f, 0x16, 0xc0], "movlhps xmm0, xmm0"); - test_display(&[0x0f, 0x17, 0xc0], "invalid"); - test_display(&[0x0f, 0x18, 0xc0], "invalid"); + test_invalid(&[0x0f, 0x17, 0xc0]); + test_invalid(&[0x0f, 0x18, 0xc0]); test_display(&[0x0f, 0x18, 0x00], "prefetchnta byte [rax]"); test_display(&[0x0f, 0x18, 0x08], "prefetch1 byte [rax]"); test_display(&[0x0f, 0x18, 0x10], "prefetch2 byte [rax]"); @@ -301,8 +309,8 @@ fn prefixed_0f() { test_display(&[0x0f, 0x32], "rdmsr"); test_display(&[0x0f, 0x33], "rdpmc"); test_display(&[0x0f, 0x34], "sysenter"); - test_display(&[0x0f, 0x35], "sysret"); - test_display(&[0x0f, 0x36], "invalid"); + test_display(&[0x0f, 0x35], "sysexit"); + test_invalid(&[0x0f, 0x36]); test_display(&[0x0f, 0x37], "getsec"); test_display(&[0x0f, 0x60, 0x00], "punpcklbw mm0, qword [rax]"); test_display(&[0x0f, 0x61, 0x00], "punpcklwd mm0, qword [rax]"); @@ -316,8 +324,8 @@ fn prefixed_0f() { test_display(&[0x0f, 0x69, 0x00], "punpckhbd mm0, qword [rax]"); test_display(&[0x0f, 0x6a, 0x00], "punpckhdq mm0, qword [rax]"); test_display(&[0x0f, 0x6b, 0x00], "packssdw mm0, qword [rax]"); - test_display(&[0x0f, 0x6c], "invalid"); - test_display(&[0x0f, 0x6d], "invalid"); + test_invalid(&[0x0f, 0x6c]); + test_invalid(&[0x0f, 0x6d]); test_display(&[0x0f, 0x6e], "movd mm0, dword [rax]"); test_display(&[0x0f, 0x6f], "movd mm0, qword [rax]"); test_display(&[0x0f, 0x70, 0x00, 0x7f], "pshufw mm0, qword [rax], 0x7f"); -- cgit v1.1