diff options
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | src/long_mode/display.rs | 8 | ||||
| -rw-r--r-- | src/long_mode/mod.rs | 37 | ||||
| -rw-r--r-- | src/protected_mode/display.rs | 8 | ||||
| -rw-r--r-- | src/protected_mode/mod.rs | 37 | ||||
| -rw-r--r-- | test/long_mode/mod.rs | 8 | ||||
| -rw-r--r-- | test/protected_mode/mod.rs | 8 | 
7 files changed, 103 insertions, 5 deletions
@@ -21,7 +21,7 @@ the decoders provided by `yaxpeax-x86` are designed to be usable in a `no_std` s  yaxpeax-x86 decodes long-mode (`amd64`/`x86_64`), protected-mode (`x86`/`x86_32`), and real-mode (`x86_16`) instructions. the most part, ISA extensions decode equivalently across modes; this is the full list of extensions that are supported: -`3dnow`\*, `sse`\*, `sse2`\*, `sse3`, `ssse3`, `sse4.1`, `sse4.2`, `sse4a`, `avx`, `avx2`, `avx512`\*\*, `syscall`, `cmpxchg16b`, `fma3`, `aesni`, `popcnt`, `rdrand`, `xsave`, `sgx`, `monitor`, `movbe`, `sgx`, `bmi1`, `bmi2`, `invpcid`, `mpx`, `adx`, `clflushopt`, `pcommit`, `sha`, `gfni`, `pclmulqdq`, `rdtscp`, `abm`, `xop`, `skinit`, `tbm`, `svm`, `f16c`, `fma4`, `tsx`, `enqcmd`\*\*\*, `uintr`\*\*\*, `keylocker`\*\*\*, `store_direct`\*\*\*, `cet`\*\*\* +`3dnow`\*, `sse`\*, `sse2`\*, `sse3`, `ssse3`, `sse4.1`, `sse4.2`, `sse4a`, `avx`, `avx2`, `avx512`\*\*, `syscall`, `cmpxchg16b`, `fma3`, `aesni`, `popcnt`, `rdrand`, `xsave`, `sgx`, `monitor`, `movbe`, `sgx`, `bmi1`, `bmi2`, `invpcid`, `mpx`, `adx`, `clflushopt`, `pcommit`, `sha`, `gfni`, `pclmulqdq`, `rdtscp`, `abm`, `xop`, `skinit`, `tbm`, `svm`, `f16c`, `fma4`, `tsx`, `enqcmd`\*\*\*, `uintr`\*\*\*, `keylocker`\*\*\*, `store_direct`\*\*\*, `cet`\*\*\*, `sev/snp`\*\*\*  \*: `3dnow`, `sse`, and `sse2` are non-optional in `x86_64`, so it is not permitted to construct a decoder that rejects them. `x86_32` and `x86_16` could have features to reject these instructions for true `8086` and `i386` compatibility, but currently do not. diff --git a/src/long_mode/display.rs b/src/long_mode/display.rs index b9e4a92..b1fb7f8 100644 --- a/src/long_mode/display.rs +++ b/src/long_mode/display.rs @@ -1800,6 +1800,10 @@ const MNEMONICS: &[&'static str] = &[      "vpandnq",      "vpandd",      "vpandq", +    "psmash", +    "pvalidate", +    "rmpadjust", +    "rmpupdate",  ];  impl Opcode { @@ -3091,6 +3095,10 @@ impl <T: fmt::Write, Y: YaxColors> Colorize<T, Y> for Opcode {              Opcode::INVLPGA |              Opcode::INVLPGB |              Opcode::TLBSYNC | +            Opcode::PSMASH | +            Opcode::PVALIDATE | +            Opcode::RMPADJUST | +            Opcode::RMPUPDATE |              Opcode::CPUID |              Opcode::WBINVD |              Opcode::INVD | diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs index 8ed68fb..9111faa 100644 --- a/src/long_mode/mod.rs +++ b/src/long_mode/mod.rs @@ -2515,6 +2515,11 @@ pub enum Opcode {      VPANDNQ,      VPANDD,      VPANDQ, + +    PSMASH, +    PVALIDATE, +    RMPADJUST, +    RMPUPDATE,  }  impl PartialEq for Instruction { @@ -9502,7 +9507,21 @@ fn unlikely_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y                          instruction.regs[0] = RegSpec::ecx();                          instruction.operand_count = 1;                      } else if m == 6 { -                        if instruction.prefixes.rep() || instruction.prefixes.repnz() || instruction.prefixes.operand_size() { +                        if instruction.prefixes.rep() { +                            if instruction.prefixes.repnz() || instruction.prefixes.operand_size() { +                                return Err(DecodeError::InvalidOperand); +                            } +                            instruction.opcode = Opcode::RMPADJUST; +                            instruction.operand_count = 0; +                            return Ok(()); +                        } else if instruction.prefixes.repnz() { +                            if instruction.prefixes.rep() || instruction.prefixes.operand_size() { +                                return Err(DecodeError::InvalidOperand); +                            } +                            instruction.opcode = Opcode::RMPUPDATE; +                            instruction.operand_count = 0; +                            return Ok(()); +                        } else if instruction.prefixes.operand_size() {                              return Err(DecodeError::InvalidOperand);                          } @@ -9515,7 +9534,21 @@ fn unlikely_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y                          instruction.regs[1] = RegSpec::edx();                          instruction.regs[3] = RegSpec::ecx();                      } else if m == 7 { -                        if instruction.prefixes.rep() || instruction.prefixes.repnz() || instruction.prefixes.operand_size() { +                        if instruction.prefixes.rep() { +                            if instruction.prefixes.repnz() || instruction.prefixes.operand_size() { +                                return Err(DecodeError::InvalidOperand); +                            } +                            instruction.opcode = Opcode::PSMASH; +                            instruction.operand_count = 0; +                            return Ok(()); +                        } else if instruction.prefixes.repnz() { +                            if instruction.prefixes.rep() || instruction.prefixes.operand_size() { +                                return Err(DecodeError::InvalidOperand); +                            } +                            instruction.opcode = Opcode::PVALIDATE; +                            instruction.operand_count = 0; +                            return Ok(()); +                        } else if instruction.prefixes.operand_size() {                              return Err(DecodeError::InvalidOperand);                          } diff --git a/src/protected_mode/display.rs b/src/protected_mode/display.rs index 3e0079e..ac869aa 100644 --- a/src/protected_mode/display.rs +++ b/src/protected_mode/display.rs @@ -1801,6 +1801,10 @@ const MNEMONICS: &[&'static str] = &[      "vpandnq",      "vpandd",      "vpandq", +    "psmash", +    "pvalidate", +    "rmpadjust", +    "rmpupdate",  ];  impl Opcode { @@ -3102,6 +3106,10 @@ impl <T: fmt::Write, Y: YaxColors> Colorize<T, Y> for Opcode {              Opcode::INVLPGA |              Opcode::INVLPGB |              Opcode::TLBSYNC | +            Opcode::PSMASH | +            Opcode::PVALIDATE | +            Opcode::RMPADJUST | +            Opcode::RMPUPDATE |              Opcode::CPUID |              Opcode::WBINVD |              Opcode::INVD | diff --git a/src/protected_mode/mod.rs b/src/protected_mode/mod.rs index 936dc08..0497db6 100644 --- a/src/protected_mode/mod.rs +++ b/src/protected_mode/mod.rs @@ -2441,6 +2441,11 @@ pub enum Opcode {      VPANDNQ,      VPANDD,      VPANDQ, + +    PSMASH, +    PVALIDATE, +    RMPADJUST, +    RMPUPDATE,  }  impl PartialEq for Instruction { @@ -9322,7 +9327,21 @@ fn unlikely_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y                          instruction.regs[0] = RegSpec::ecx();                          instruction.operand_count = 1;                      } else if m == 6 { -                        if instruction.prefixes.rep() || instruction.prefixes.repnz() || instruction.prefixes.operand_size() { +                        if instruction.prefixes.rep() { +                            if instruction.prefixes.repnz() || instruction.prefixes.operand_size() { +                                return Err(DecodeError::InvalidOperand); +                            } +                            instruction.opcode = Opcode::RMPADJUST; +                            instruction.operand_count = 0; +                            return Ok(()); +                        } else if instruction.prefixes.repnz() { +                            if instruction.prefixes.rep() || instruction.prefixes.operand_size() { +                                return Err(DecodeError::InvalidOperand); +                            } +                            instruction.opcode = Opcode::RMPUPDATE; +                            instruction.operand_count = 0; +                            return Ok(()); +                        } else if instruction.prefixes.operand_size() {                              return Err(DecodeError::InvalidOperand);                          } @@ -9335,7 +9354,21 @@ fn unlikely_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y                          instruction.regs[1] = RegSpec::edx();                          instruction.regs[3] = RegSpec::ecx();                      } else if m == 7 { -                        if instruction.prefixes.rep() || instruction.prefixes.repnz() || instruction.prefixes.operand_size() { +                        if instruction.prefixes.rep() { +                            if instruction.prefixes.repnz() || instruction.prefixes.operand_size() { +                                return Err(DecodeError::InvalidOperand); +                            } +                            instruction.opcode = Opcode::PSMASH; +                            instruction.operand_count = 0; +                            return Ok(()); +                        } else if instruction.prefixes.repnz() { +                            if instruction.prefixes.rep() || instruction.prefixes.operand_size() { +                                return Err(DecodeError::InvalidOperand); +                            } +                            instruction.opcode = Opcode::PVALIDATE; +                            instruction.operand_count = 0; +                            return Ok(()); +                        } else if instruction.prefixes.operand_size() {                              return Err(DecodeError::InvalidOperand);                          } diff --git a/test/long_mode/mod.rs b/test/long_mode/mod.rs index 6a45b38..4d44694 100644 --- a/test/long_mode/mod.rs +++ b/test/long_mode/mod.rs @@ -3329,6 +3329,14 @@ fn test_tsxldtrk() {      test_display(&[0xf2, 0x0f, 0x01, 0xe9], "xresldtrk");  } +#[test] +fn test_sevsnp() { +    test_display(&[0xf3, 0x0f, 0x01, 0xff], "psmash"); +    test_display(&[0xf2, 0x0f, 0x01, 0xff], "pvalidate"); +    test_display(&[0xf3, 0x0f, 0x01, 0xfe], "rmpadjust"); +    test_display(&[0xf2, 0x0f, 0x01, 0xfe], "rmpupdate"); +} +  // some test cases are best just lifted from llvm or gcc.  #[test]  fn from_llvm() { diff --git a/test/protected_mode/mod.rs b/test/protected_mode/mod.rs index 90b53a6..c742516 100644 --- a/test/protected_mode/mod.rs +++ b/test/protected_mode/mod.rs @@ -3026,6 +3026,14 @@ fn test_tsxldtrk() {      test_display(&[0xf2, 0x0f, 0x01, 0xe9], "xresldtrk");  } +#[test] +fn test_sevsnp() { +    test_display(&[0xf3, 0x0f, 0x01, 0xff], "psmash"); +    test_display(&[0xf2, 0x0f, 0x01, 0xff], "pvalidate"); +    test_display(&[0xf3, 0x0f, 0x01, 0xfe], "rmpadjust"); +    test_display(&[0xf2, 0x0f, 0x01, 0xfe], "rmpupdate"); +} +  // some test cases are best just lifted from llvm or gcc.  #[test]  fn from_llvm() {  | 
