aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2019-03-30 20:02:20 -0700
committeriximeow <me@iximeow.net>2020-01-12 16:10:13 -0800
commit7a45abbef5a1158e3ab676e666cbe69a2d57e36a (patch)
treedeac9cc0078e44d7003861b6314d95dfcd076b18 /src
parentf1c54efa783918bd300f894958ad48026afc7e1e (diff)
fix incorrectly showing decode errors, add more system instructions
Diffstat (limited to 'src')
-rw-r--r--src/display.rs14
-rw-r--r--src/lib.rs49
2 files changed, 62 insertions, 1 deletions
diff --git a/src/display.rs b/src/display.rs
index 3a73225..b500992 100644
--- a/src/display.rs
+++ b/src/display.rs
@@ -174,6 +174,13 @@ impl <T: std::fmt::Write> Colorize<T> for Operand {
impl fmt::Display for Opcode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
+ &Opcode::SLDT => write!(f, "{}", "sldt"),
+ &Opcode::STR => write!(f, "{}", "str"),
+ &Opcode::LLDT => write!(f, "{}", "lldt"),
+ &Opcode::LTR => write!(f, "{}", "ltr"),
+ &Opcode::VERR => write!(f, "{}", "verr"),
+ &Opcode::VERW => write!(f, "{}", "verw"),
+ &Opcode::JMPE => write!(f, "{}", "jmpe"),
&Opcode::WRMSR => write!(f, "{}", "wrmsr"),
&Opcode::RDMSR => write!(f, "{}", "rdmsr"),
&Opcode::RDTSC => write!(f, "{}", "rdtsc"),
@@ -470,6 +477,13 @@ impl <T: std::fmt::Write> Colorize<T> for Opcode {
Opcode::CLTS |
Opcode::SYSCALL |
Opcode::LSL |
+ Opcode::SLDT |
+ Opcode::STR |
+ Opcode::LLDT |
+ Opcode::LTR |
+ Opcode::VERR |
+ Opcode::VERW |
+ Opcode::JMPE |
Opcode::LAR => { write!(out, "{}", colors.platform_op(self)) }
Opcode::UD2 |
diff --git a/src/lib.rs b/src/lib.rs
index d693ee4..d0dbba3 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -316,6 +316,13 @@ pub enum Opcode {
RDTSC,
RDMSR,
RDPMC,
+ SLDT,
+ STR,
+ LLDT,
+ LTR,
+ VERR,
+ VERW,
+ JMPE,
Invalid
}
#[derive(Debug)]
@@ -2336,7 +2343,45 @@ fn read_operands<T: Iterator<Item=u8>>(
Ok(())
}
OperandCode::ModRM_0x0f00 => {
- Ok(())
+ let modrm = match bytes_iter.next() {
+ Some(b) => b,
+ None => return Err("Out of bytes".to_string())
+ };
+ *length += 1;
+ let (mod_bits, r, m) = octets_of(modrm);
+ if r == 0 {
+ instruction.opcode = Opcode::SLDT;
+ instruction.operands[1] = Operand::Nothing;
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 2, &mut instruction.operands[0], length)
+ } else if r == 1 {
+ instruction.opcode = Opcode::STR;
+ instruction.operands[1] = Operand::Nothing;
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 2, &mut instruction.operands[0], length)
+ } else if r == 2 {
+ instruction.opcode = Opcode::LLDT;
+ instruction.operands[1] = Operand::Nothing;
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 2, &mut instruction.operands[0], length)
+ } else if r == 3 {
+ instruction.opcode = Opcode::LTR;
+ instruction.operands[1] = Operand::Nothing;
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 2, &mut instruction.operands[0], length)
+ } else if r == 4 {
+ instruction.opcode = Opcode::VERR;
+ instruction.operands[1] = Operand::Nothing;
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 2, &mut instruction.operands[0], length)
+ } else if r == 5 {
+ instruction.opcode = Opcode::VERW;
+ instruction.operands[1] = Operand::Nothing;
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 2, &mut instruction.operands[0], length)
+ } else if r == 6 {
+ instruction.opcode = Opcode::JMPE;
+ instruction.operands = [Operand::Nothing, Operand::Nothing];
+ Ok(())
+ } else if r == 7 {
+ Err("Invalid modr/m bits".to_owned())
+ } else {
+ unreachable!("r <= 8");
+ }
}
OperandCode::ModRM_0x0f01 => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vq, &instruction.prefixes);
@@ -2599,6 +2644,8 @@ fn read_operands<T: Iterator<Item=u8>>(
Ok(())
}
_ => {
+ instruction.operands = [Operand::Nothing, Operand::Nothing];
+ instruction.opcode = Opcode::Invalid;
// use std::hint::unreachable_unchecked;
Err(format!("unsupported operand code: {:?}", operand_code))
// unsafe { unreachable_unchecked(); }