diff options
| -rw-r--r-- | CHANGELOG | 5 | ||||
| -rw-r--r-- | src/long_mode/display.rs | 4 | ||||
| -rw-r--r-- | src/long_mode/mod.rs | 36 | ||||
| -rw-r--r-- | src/protected_mode/display.rs | 4 | ||||
| -rw-r--r-- | src/protected_mode/mod.rs | 33 | ||||
| -rw-r--r-- | src/real_mode/display.rs | 4 | ||||
| -rw-r--r-- | src/real_mode/mod.rs | 33 | ||||
| -rw-r--r-- | test/long_mode/mod.rs | 3 | ||||
| -rw-r--r-- | test/protected_mode/mod.rs | 3 | ||||
| -rw-r--r-- | test/real_mode/mod.rs | 3 | 
10 files changed, 116 insertions, 12 deletions
@@ -1,3 +1,8 @@ +## 1.1.1 +* support `endbr64` and `endbr32` +  - these are interpretations of `nop` (`0f1e` wide nop), so the only issue +  with for users <1.1.1 will be `yaxpeax-86` decoding `nop` instead. +  ## 1.1.0  * implement `AnnotatingDecoder` from `yaxpeax-arch=0.2.6` and later. diff --git a/src/long_mode/display.rs b/src/long_mode/display.rs index 7c344b7..35b9c1f 100644 --- a/src/long_mode/display.rs +++ b/src/long_mode/display.rs @@ -1405,6 +1405,8 @@ const MNEMONICS: &[&'static str] = &[      "setssbsy",      "clrssbsy",      "rstorssp", +    "endbr64", +    "endbr32",      // TDX      "tdcall", @@ -3220,6 +3222,8 @@ impl <T: fmt::Write, Y: YaxColors> Colorize<T, Y> for Opcode {              Opcode::SETSSBSY |              Opcode::CLRSSBSY |              Opcode::RSTORSSP | +            Opcode::ENDBR64 | +            Opcode::ENDBR32 |              Opcode::AESDEC |              Opcode::AESDECLAST |              Opcode::AESENC | diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs index 3d6d977..866eb8f 100644 --- a/src/long_mode/mod.rs +++ b/src/long_mode/mod.rs @@ -2139,6 +2139,8 @@ pub enum Opcode {      SETSSBSY,      CLRSSBSY,      RSTORSSP, +    ENDBR64, +    ENDBR32,      // TDX      TDCALL, @@ -4986,9 +4988,7 @@ enum OperandCode {      ModRM_0x0f73 = OperandCodeBuilder::new().read_modrm().special_case(57).bits(),      ModRM_0xf20f78 = OperandCodeBuilder::new().read_modrm().special_case(58).bits(),      ModRM_0x660f78 = OperandCodeBuilder::new().read_modrm().special_case(59).bits(), -//    ModRM_0x660f12 = OperandCodeBuilder::new().read_modrm().special_case(58).bits(), -//    ModRM_0x660f16 = OperandCodeBuilder::new().read_modrm().special_case(59).bits(), -//    ModRM_0x660f71 = OperandCodeBuilder::new().read_modrm().special_case(60).bits(), +    ModRM_0xf30f1e = OperandCodeBuilder::new().special_case(60).bits(),  //    ModRM_0x660f72 = OperandCodeBuilder::new().read_modrm().special_case(61).bits(),  //    ModRM_0x660f73 = OperandCodeBuilder::new().read_modrm().special_case(62).bits(),  //    ModRM_0x660fc7 = OperandCodeBuilder::new().read_modrm().special_case(63).bits(), @@ -6372,7 +6372,7 @@ fn read_0f_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord {              0x1b => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev),              0x1c => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev),              0x1d => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), -            0x1e => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), +            0x1e => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::ModRM_0xf30f1e),              0x1f => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev),              0x20 => OpcodeRecord(Interpretation::Instruction(Opcode::MOV), OperandCode::Rq_Cq_0), @@ -8833,6 +8833,34 @@ fn unlikely_operands<              instruction.operand_count = 3;          } +        OperandCode::ModRM_0xf30f1e => { +            let modrm = read_modrm(words)?; +            match modrm { +                0xfa => { +                    instruction.opcode = Opcode::ENDBR64; +                    instruction.operand_count = 0; +                }, +                0xfb => { +                    instruction.opcode = Opcode::ENDBR32; +                    instruction.operand_count = 0; +                }, +                _ => { +                    let (sz, bank) = if instruction.prefixes.rex_unchecked().w() { +                        (8, RegisterBank::Q) +                    } else if !instruction.prefixes.operand_size() { +                        (4, RegisterBank::D) +                    } else { +                        (2, RegisterBank::W) +                    }; +                    instruction.operands[1] = OperandSpec::RegRRR; +                    instruction.operands[0] = read_E(words, instruction, modrm, sz, sink)?; +                    instruction.regs[0] = +                        RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex_unchecked().r(), bank); +                    instruction.operand_count = 2; + +                } +            }; +        }          OperandCode::G_E_xmm_Ub => {              let modrm = read_modrm(words)?; diff --git a/src/protected_mode/display.rs b/src/protected_mode/display.rs index 275a61d..f545111 100644 --- a/src/protected_mode/display.rs +++ b/src/protected_mode/display.rs @@ -1406,6 +1406,8 @@ const MNEMONICS: &[&'static str] = &[      "setssbsy",      "clrssbsy",      "rstorssp", +    "endbr64", +    "endbr32",      // TDX      "tdcall", @@ -3233,6 +3235,8 @@ impl <T: fmt::Write, Y: YaxColors> Colorize<T, Y> for Opcode {              Opcode::SETSSBSY |              Opcode::CLRSSBSY |              Opcode::RSTORSSP | +            Opcode::ENDBR64 | +            Opcode::ENDBR32 |              Opcode::AESDEC |              Opcode::AESDECLAST |              Opcode::AESENC | diff --git a/src/protected_mode/mod.rs b/src/protected_mode/mod.rs index fef1807..232284d 100644 --- a/src/protected_mode/mod.rs +++ b/src/protected_mode/mod.rs @@ -2077,6 +2077,8 @@ pub enum Opcode {      SETSSBSY,      CLRSSBSY,      RSTORSSP, +    ENDBR64, +    ENDBR32,      // TDX      TDCALL, @@ -4905,9 +4907,7 @@ enum OperandCode {      ModRM_0x0f73 = OperandCodeBuilder::new().read_modrm().special_case(57).bits(),      ModRM_0xf20f78 = OperandCodeBuilder::new().read_modrm().special_case(58).bits(),      ModRM_0x660f78 = OperandCodeBuilder::new().read_modrm().special_case(59).bits(), -//    ModRM_0x660f12 = OperandCodeBuilder::new().read_modrm().special_case(58).bits(), -//    ModRM_0x660f16 = OperandCodeBuilder::new().read_modrm().special_case(59).bits(), -//    ModRM_0x660f71 = OperandCodeBuilder::new().read_modrm().special_case(60).bits(), +    ModRM_0xf30f1e = OperandCodeBuilder::new().special_case(60).bits(),  //    ModRM_0x660f72 = OperandCodeBuilder::new().read_modrm().special_case(61).bits(),  //    ModRM_0x660f73 = OperandCodeBuilder::new().read_modrm().special_case(62).bits(),  //    ModRM_0x660fc7 = OperandCodeBuilder::new().read_modrm().special_case(63).bits(), @@ -6393,7 +6393,7 @@ fn read_0f_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord {              0x1b => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev),              0x1c => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev),              0x1d => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), -            0x1e => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), +            0x1e => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::ModRM_0xf30f1e),              0x1f => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev),              0x20 => OpcodeRecord(Interpretation::Instruction(Opcode::MOV), OperandCode::Rq_Cq_0), @@ -8781,6 +8781,31 @@ fn unlikely_operands<              instruction.operand_count = 3;          } +        OperandCode::ModRM_0xf30f1e => { +            let modrm = read_modrm(words)?; +            match modrm { +                0xfa => { +                    instruction.opcode = Opcode::ENDBR64; +                    instruction.operand_count = 0; +                }, +                0xfb => { +                    instruction.opcode = Opcode::ENDBR32; +                    instruction.operand_count = 0; +                }, +                _ => { +                    let (sz, bank) = if !instruction.prefixes.operand_size() { +                        (4, RegisterBank::D) +                    } else { +                        (2, RegisterBank::W) +                    }; +                    instruction.operands[1] = OperandSpec::RegRRR; +                    instruction.operands[0] = read_E(words, instruction, modrm, sz, sink)?; +                    instruction.regs[0] = +                        RegSpec::from_parts((modrm >> 3) & 7, bank); +                    instruction.operand_count = 2; +                } +            }; +        }          OperandCode::G_E_xmm_Ub => {              let modrm = read_modrm(words)?; diff --git a/src/real_mode/display.rs b/src/real_mode/display.rs index 10640a4..258f5d9 100644 --- a/src/real_mode/display.rs +++ b/src/real_mode/display.rs @@ -1406,6 +1406,8 @@ const MNEMONICS: &[&'static str] = &[      "setssbsy",      "clrssbsy",      "rstorssp", +    "endbr64", +    "endbr32",      // TDX      "tdcall", @@ -3233,6 +3235,8 @@ impl <T: fmt::Write, Y: YaxColors> Colorize<T, Y> for Opcode {              Opcode::SETSSBSY |              Opcode::CLRSSBSY |              Opcode::RSTORSSP | +            Opcode::ENDBR64 | +            Opcode::ENDBR32 |              Opcode::AESDEC |              Opcode::AESDECLAST |              Opcode::AESENC | diff --git a/src/real_mode/mod.rs b/src/real_mode/mod.rs index 45dd7a3..92c0592 100644 --- a/src/real_mode/mod.rs +++ b/src/real_mode/mod.rs @@ -2077,6 +2077,8 @@ pub enum Opcode {      SETSSBSY,      CLRSSBSY,      RSTORSSP, +    ENDBR64, +    ENDBR32,      // TDX      TDCALL, @@ -4905,9 +4907,7 @@ enum OperandCode {      ModRM_0x0f73 = OperandCodeBuilder::new().read_modrm().special_case(57).bits(),      ModRM_0xf20f78 = OperandCodeBuilder::new().read_modrm().special_case(58).bits(),      ModRM_0x660f78 = OperandCodeBuilder::new().read_modrm().special_case(59).bits(), -//    ModRM_0x660f12 = OperandCodeBuilder::new().read_modrm().special_case(58).bits(), -//    ModRM_0x660f16 = OperandCodeBuilder::new().read_modrm().special_case(59).bits(), -//    ModRM_0x660f71 = OperandCodeBuilder::new().read_modrm().special_case(60).bits(), +    ModRM_0xf30f1e = OperandCodeBuilder::new().special_case(60).bits(),  //    ModRM_0x660f72 = OperandCodeBuilder::new().read_modrm().special_case(61).bits(),  //    ModRM_0x660f73 = OperandCodeBuilder::new().read_modrm().special_case(62).bits(),  //    ModRM_0x660fc7 = OperandCodeBuilder::new().read_modrm().special_case(63).bits(), @@ -6395,7 +6395,7 @@ fn read_0f_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord {              0x1b => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev),              0x1c => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev),              0x1d => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), -            0x1e => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), +            0x1e => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::ModRM_0xf30f1e),              0x1f => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev),              0x20 => OpcodeRecord(Interpretation::Instruction(Opcode::MOV), OperandCode::Rq_Cq_0), @@ -8785,6 +8785,31 @@ fn unlikely_operands<              instruction.operand_count = 3;          } +        OperandCode::ModRM_0xf30f1e => { +            let modrm = read_modrm(words)?; +            match modrm { +                0xfa => { +                    instruction.opcode = Opcode::ENDBR64; +                    instruction.operand_count = 0; +                }, +                0xfb => { +                    instruction.opcode = Opcode::ENDBR32; +                    instruction.operand_count = 0; +                }, +                _ => { +                    let (sz, bank) = if instruction.prefixes.operand_size() { +                        (4, RegisterBank::D) +                    } else { +                        (2, RegisterBank::W) +                    }; +                    instruction.operands[1] = OperandSpec::RegRRR; +                    instruction.operands[0] = read_E(words, instruction, modrm, sz, sink)?; +                    instruction.regs[0] = +                        RegSpec::from_parts((modrm >> 3) & 7, bank); +                    instruction.operand_count = 2; +                } +            }; +        }          OperandCode::G_E_xmm_Ub => {              let modrm = read_modrm(words)?; diff --git a/test/long_mode/mod.rs b/test/long_mode/mod.rs index dab4e91..1efa74e 100644 --- a/test/long_mode/mod.rs +++ b/test/long_mode/mod.rs @@ -2677,6 +2677,9 @@ fn prefixed_f20f() {  fn prefixed_f30f() {      test_display(&[0xf3, 0x0f, 0x16, 0xcf], "movshdup xmm1, xmm7");      test_display(&[0xf3, 0x4d, 0x0f, 0x16, 0xcf], "movshdup xmm9, xmm15"); +    test_display(&[0xf3, 0x0f, 0x1e, 0xfa], "endbr64"); +    test_display(&[0xf3, 0x0f, 0x1e, 0xfb], "endbr32"); +    test_display(&[0xf3, 0x0f, 0x1e, 0xfc], "nop esp, edi");  }  #[test] diff --git a/test/protected_mode/mod.rs b/test/protected_mode/mod.rs index 41ecbb7..4b8ca8d 100644 --- a/test/protected_mode/mod.rs +++ b/test/protected_mode/mod.rs @@ -2361,6 +2361,9 @@ fn prefixed_f20f() {  #[test]  fn prefixed_f30f() {      test_display(&[0xf3, 0x0f, 0x16, 0xcf], "movshdup xmm1, xmm7"); +    test_display(&[0xf3, 0x0f, 0x1e, 0xfa], "endbr64"); +    test_display(&[0xf3, 0x0f, 0x1e, 0xfb], "endbr32"); +    test_display(&[0xf3, 0x0f, 0x1e, 0xfc], "nop esp, edi");  }  #[test] diff --git a/test/real_mode/mod.rs b/test/real_mode/mod.rs index dfbe4e8..6dcc3a2 100644 --- a/test/real_mode/mod.rs +++ b/test/real_mode/mod.rs @@ -17828,6 +17828,9 @@ fn test_real_mode() {      test_display(&[0xf3, 0x0f, 0x16, 0x0f], "movshdup xmm1, xmmword [bx]");      test_display(&[0xf3, 0x0f, 0x16, 0xcf], "movshdup xmm1, xmm7");      test_display(&[0xf3, 0x0f, 0x16, 0xcf], "movshdup xmm1, xmm7"); +    test_display(&[0xf3, 0x0f, 0x1e, 0xfa], "endbr64"); +    test_display(&[0xf3, 0x0f, 0x1e, 0xfb], "endbr32"); +    test_display(&[0xf3, 0x0f, 0x1e, 0xfc], "nop sp, di");      test_display(&[0xf3, 0x0f, 0x21, 0xc8], "mov eax, dr1");      test_display(&[0xf3, 0x0f, 0x2a, 0x00], "cvtsi2ss xmm0, dword [bx + si]");      test_display(&[0xf3, 0x0f, 0x2a, 0x01], "cvtsi2ss xmm0, dword [bx + di]");  | 
