From 98fcbbcb92554090651a15460319ce7ae4038c6a Mon Sep 17 00:00:00 2001 From: iximeow Date: Sat, 19 Oct 2019 22:59:58 -0700 Subject: decode shift-by-cl and fix error decoding sign-extending operands --- src/display.rs | 17 ++++++++++++++++- src/lib.rs | 23 ++++++++++++++++------- test/test.rs | 1 + 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/display.rs b/src/display.rs index 2a1dcc2..fc3f1bd 100644 --- a/src/display.rs +++ b/src/display.rs @@ -6,7 +6,22 @@ use std::fmt; use yaxpeax_arch::{Colorize, ColorSettings, ShowContextual, YaxColors}; use yaxpeax_arch::display::*; -use ::{RegSpec, RegisterBank, Opcode, Operand, Instruction, Segment}; +use ::{RegSpec, RegisterBank, Opcode, Operand, Instruction, Segment, PrefixRex}; + +impl fmt::Display for PrefixRex { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if self.present() { + write!(f, "rex:{}{}{}{}", + if self.w() { "w" } else { "-" }, + if self.r() { "r" } else { "-" }, + if self.x() { "x" } else { "-" }, + if self.b() { "b" } else { "-" }, + ) + } else { + write!(f, "rex:none") + } + } +} impl fmt::Display for Segment { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { diff --git a/src/lib.rs b/src/lib.rs index 7dcd0a2..38619b7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -772,7 +772,7 @@ pub enum OperandCode { Fw, Gv_Eb, Gv_Ew, - Gv_Ed, + Gdq_Ed, G_E_xmm, G_E_xmm_Ib, Gv_M, @@ -1266,7 +1266,7 @@ const OPCODE_F30F_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::MOVDQU), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::MOVDQU), OperandCode::G_E_xmm), // 0x70 OpcodeRecord(Interpretation::Instruction(Opcode::PSHUFHW), OperandCode::G_E_xmm_Ib), OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), @@ -1885,7 +1885,7 @@ const OPCODES: [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::MOVSXD), OperandCode::Gv_Ed), + OpcodeRecord(Interpretation::Instruction(Opcode::MOVSXD), OperandCode::Gdq_Ed), OpcodeRecord(Interpretation::Prefix, OperandCode::Nothing), OpcodeRecord(Interpretation::Prefix, OperandCode::Nothing), OpcodeRecord(Interpretation::Prefix, OperandCode::Nothing), @@ -2519,6 +2519,16 @@ pub fn read_operands>(mut bytes_iter: T, instruction: &mut instruction.opcode = BITWISE_OPCODE_MAP[((modrm >> 3) & 7) as usize].clone(); instruction.operands[1] = Operand::ImmediateI8(1); }, + OperandCode::ModRM_0xd3_Ev_CL => { + let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let (mod_bits, r, m) = octets_of(modrm); + + read_E(&mut bytes_iter, instruction, modrm, opwidth, 0).unwrap(); + let opcode = BITWISE_OPCODE_MAP[r as usize].clone(); + instruction.opcode = opcode; + instruction.operands[1] = Operand::Register(RegSpec::cl()); + } OperandCode::ModRM_0xf6 => { let opwidth = 1; let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); @@ -2723,13 +2733,12 @@ pub fn read_operands>(mut bytes_iter: T, instruction: &mut read_E(&mut bytes_iter, instruction, modrm, opwidth, 1).unwrap(); } }, - // TODO: verify M - OperandCode::Gv_Ed => { - let opwidth = 4; + OperandCode::Gdq_Ed => { + let opwidth = 8; let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); // println!("mod_bits: {:2b}, r: {:3b}, m: {:3b}", mod_bits, r, m); - read_E(&mut bytes_iter, instruction, modrm, opwidth, 1).unwrap(); + read_E(&mut bytes_iter, instruction, modrm, 4 /* opwidth */, 1).unwrap(); instruction.operands[0] = Operand::Register(RegSpec::gp_from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present())); }, diff --git a/test/test.rs b/test/test.rs index df0e1343..cd28685 100644 --- a/test/test.rs +++ b/test/test.rs @@ -107,6 +107,7 @@ fn test_mov() { test_display(&[0x89, 0x55, 0x94], "mov [rbp - 0x6c], edx"); test_display(&[0x65, 0x4c, 0x89, 0x04, 0x25, 0xa8, 0x01, 0x00, 0x00], "mov gs:[0x1a8], r8"); test_display(&[0x0f, 0xbe, 0x83, 0xb4, 0x00, 0x00, 0x00], "movsx eax, byte [rbx + 0xb4]"); + 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, xmmword [rdi]"); test_display(&[0xf3, 0x0f, 0x7f, 0x45, 0x00], "movdqu xmmword [rbp], xmm0"); -- cgit v1.1