From 06b9d518496b90e83ad8b9857973442b978ed3e6 Mon Sep 17 00:00:00 2001 From: iximeow Date: Sun, 23 Jun 2019 16:09:26 -0700 Subject: begin supporting f30f instructions fix issue where non-relevant prefixes on 0f opcodes may cause incorrect invalid decodes --- src/display.rs | 22 +++++++++++ src/lib.rs | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 130 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/display.rs b/src/display.rs index 7dba44d..ca2b2f7 100644 --- a/src/display.rs +++ b/src/display.rs @@ -184,6 +184,13 @@ impl fmt::Display for Opcode { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { &Opcode::MOVSS => write!(f, "{}", "movss"), + &Opcode::SQRTSS => write!(f, "{}", "sqrtss"), + &Opcode::ADDSS => write!(f, "{}", "addss"), + &Opcode::SUBSS => write!(f, "{}", "subss"), + &Opcode::MULSS => write!(f, "{}", "mulss"), + &Opcode::DIVSS => write!(f, "{}", "divss"), + &Opcode::MINSS => write!(f, "{}", "minss"), + &Opcode::MAXSS => write!(f, "{}", "maxss"), &Opcode::MOVSD => write!(f, "{}", "movsd"), &Opcode::SQRTSD => write!(f, "{}", "sqrtsd"), &Opcode::ADDSD => write!(f, "{}", "addsd"), @@ -193,6 +200,7 @@ impl fmt::Display for Opcode { &Opcode::MINSD => write!(f, "{}", "minsd"), &Opcode::MAXSD => write!(f, "{}", "maxsd"), &Opcode::MOVDDUP => write!(f, "{}", "movddup"), + &Opcode::MOVSLDUP => write!(f, "{}", "movsldup"), &Opcode::HADDPS => write!(f, "{}", "haddps"), &Opcode::HSUBPS => write!(f, "{}", "hsubps"), &Opcode::ADDSUBPS => write!(f, "{}", "addsubps"), @@ -201,6 +209,9 @@ impl fmt::Display for Opcode { &Opcode::CVTTSD2SI => write!(f, "{}", "cvttsd2si"), &Opcode::CVTSD2SI => write!(f, "{}", "cvtsd2si"), &Opcode::CVTSD2SS => write!(f, "{}", "cvtsd2ss"), + &Opcode::CVTTSS2SI => write!(f, "{}", "cvttss2si"), + &Opcode::CVTSS2SI => write!(f, "{}", "cvtss2si"), + &Opcode::CVTSS2SD => write!(f, "{}", "cvtss2sd"), &Opcode::LDDQU => write!(f, "{}", "lddqu"), &Opcode::STI => write!(f, "{}", "sti"), &Opcode::STD => write!(f, "{}", "std"), @@ -371,7 +382,13 @@ impl Colorize for Opcode { Opcode::SUBSD | Opcode::MULSD | Opcode::DIVSD | + Opcode::SQRTSS | + Opcode::ADDSS | + Opcode::SUBSS | + Opcode::MULSS | + Opcode::DIVSS | Opcode::MOVDDUP | + Opcode::MOVSLDUP | Opcode::HADDPS | Opcode::HSUBPS | Opcode::ADDSUBPS | @@ -444,6 +461,9 @@ impl Colorize for Opcode { Opcode::CVTTSD2SI | Opcode::CVTSD2SI | Opcode::CVTSD2SS | + Opcode::CVTTSS2SI | + Opcode::CVTSS2SI | + Opcode::CVTSS2SD | Opcode::LDDQU | Opcode::CLC | Opcode::CLI | @@ -501,6 +521,8 @@ impl Colorize for Opcode { Opcode::MINSD | Opcode::MAXSD | + Opcode::MINSS | + Opcode::MAXSS | Opcode::CMPS | Opcode::SCAS | Opcode::TEST | diff --git a/src/lib.rs b/src/lib.rs index a935e91..bee1173 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -235,8 +235,15 @@ pub enum Segment { #[allow(non_camel_case_types)] #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum Opcode { - MOVSD, MOVSS, + ADDSS, + SUBSS, + MULSS, + DIVSS, + MINSS, + MAXSS, + SQRTSS, + MOVSD, SQRTSD, ADDSD, SUBSD, @@ -244,6 +251,7 @@ pub enum Opcode { DIVSD, MINSD, MAXSD, + MOVSLDUP, MOVDDUP, HADDPS, HSUBPS, @@ -253,6 +261,9 @@ pub enum Opcode { CVTTSD2SI, CVTSD2SI, CVTSD2SS, + CVTTSS2SI, + CVTSS2SI, + CVTSS2SD, LDDQU, MOVZX_b, MOVZX_w, @@ -862,7 +873,91 @@ fn read_opcode_f20f_map>(bytes_iter: &mut T, instruction: & } } fn read_opcode_f30f_map>(bytes_iter: &mut T, instruction: &mut Instruction, prefixes: Prefixes, length: &mut u8) -> Result { - Err("f30f opcode map unsupported".to_string()) + match bytes_iter.next() { + Some(b) => { + *length += 1; + match b { + 0x10 => { + instruction.prefixes = prefixes; + instruction.opcode = Opcode::MOVSS; + Ok(OperandCode::G_E_xmm) + }, + 0x11 => { + instruction.prefixes = prefixes; + instruction.opcode = Opcode::MOVSS; + Ok(OperandCode::E_G_xmm) + }, + 0x12 => { + instruction.prefixes = prefixes; + instruction.opcode = Opcode::MOVSLDUP; + Ok(OperandCode::G_E_xmm) + }, + 0x2a => { + instruction.prefixes = prefixes; + instruction.opcode = Opcode::CVTSI2SS; + Ok(OperandCode::G_E_xmm) + }, + 0x2c => { + instruction.prefixes = prefixes; + instruction.opcode = Opcode::CVTTSS2SI; + Ok(OperandCode::G_E_xmm) + }, + 0x2d => { + instruction.prefixes = prefixes; + instruction.opcode = Opcode::CVTSS2SI; + Ok(OperandCode::G_E_xmm) + }, + 0x51 => { + instruction.prefixes = prefixes; + instruction.opcode = Opcode::SQRTSS; + Ok(OperandCode::G_E_xmm) + }, + 0x58 => { + instruction.prefixes = prefixes; + instruction.opcode = Opcode::ADDSS; + Ok(OperandCode::G_E_xmm) + }, + 0x59 => { + instruction.prefixes = prefixes; + instruction.opcode = Opcode::MULSS; + Ok(OperandCode::G_E_xmm) + }, + 0x5a => { + instruction.prefixes = prefixes; + instruction.opcode = Opcode::CVTSS2SD; + Ok(OperandCode::G_E_xmm) + }, + 0x5c => { + instruction.prefixes = prefixes; + instruction.opcode = Opcode::SUBSS; + Ok(OperandCode::G_E_xmm) + }, + 0x5d => { + instruction.prefixes = prefixes; + instruction.opcode = Opcode::MINSS; + Ok(OperandCode::G_E_xmm) + }, + 0x5e => { + instruction.prefixes = prefixes; + instruction.opcode = Opcode::DIVSS; + Ok(OperandCode::G_E_xmm) + }, + 0x5f => { + instruction.prefixes = prefixes; + instruction.opcode = Opcode::MAXSS; + Ok(OperandCode::G_E_xmm) + }, + _ => { + instruction.prefixes = prefixes; + instruction.opcode = Opcode::Invalid; + Err("Invalid opcode".to_string()) + } + } + } + None => { + Err("No more bytes".to_owned()) + } + } } fn read_opcode_0f_map>(bytes_iter: &mut T, instruction: &mut Instruction, prefixes: Prefixes, length: &mut u8) -> Result { match bytes_iter.next() { @@ -1236,16 +1331,20 @@ fn read_opcode>(bytes_iter: &mut T, instruction: &mut Instr }; }, 0x26 => { - prefixes.set_es() + prefixes.set_es(); + alternate_opcode_map = None; }, 0x2e => { - prefixes.set_cs() + prefixes.set_cs(); + alternate_opcode_map = None; }, 0x36 => { - prefixes.set_ss() + prefixes.set_ss(); + alternate_opcode_map = None; }, 0x3e => { - prefixes.set_ds() + prefixes.set_ds(); + alternate_opcode_map = None; }, 0x06 | 0x07 @@ -1293,9 +1392,11 @@ fn read_opcode>(bytes_iter: &mut T, instruction: &mut Instr }, 0x64 => { prefixes.set_fs(); + alternate_opcode_map = None; }, 0x65 => { prefixes.set_gs(); + alternate_opcode_map = None; }, 0x66 => { prefixes.set_operand_size(); @@ -1303,6 +1404,7 @@ fn read_opcode>(bytes_iter: &mut T, instruction: &mut Instr }, 0x67 => { prefixes.set_address_size(); + alternate_opcode_map = None; }, 0x68 => { instruction.prefixes = prefixes; -- cgit v1.1