diff options
| -rw-r--r-- | CHANGELOG | 5 | ||||
| -rw-r--r-- | fuzz/fuzz_targets/does_not_decode_invalid_registers.rs | 270 | ||||
| -rw-r--r-- | src/long_mode/mod.rs | 8 | 
3 files changed, 278 insertions, 5 deletions
| @@ -1,4 +1,4 @@ -## 1.3.0 +## 1.2.1  * fix incorrect register numbers used in `RegSpec::r12()` and `RegSpec::r13()`    and smaller-size variants (thank you @tokatoka!) @@ -22,6 +22,9 @@    `vpmov*2m` with nonsense `k8..k15` selected. to real hardware, this bit    sequence is an invalid instruction, and so it is now invalid to yaxpeax-x86    as well. +* fix incorrect `RegisterBank` names in `long_mode`. in a previous +  reorganization register bank numbers were changed and the names were updated to +  match for `protected_mode` and `real_mode`, but `long_mode` was overlooked.  ## 1.2.0  * fix incorrect old yaxpeax-arch version selection for ffi crates diff --git a/fuzz/fuzz_targets/does_not_decode_invalid_registers.rs b/fuzz/fuzz_targets/does_not_decode_invalid_registers.rs index 0f32f73..31b1004 100644 --- a/fuzz/fuzz_targets/does_not_decode_invalid_registers.rs +++ b/fuzz/fuzz_targets/does_not_decode_invalid_registers.rs @@ -11,20 +11,290 @@ fuzz_target!(|data: &[u8]| {      let x86_16_decoder = yaxpeax_x86::real_mode::InstDecoder::default();      if let Ok(inst) = x86_64_decoder.decode_slice(data) { +        use yaxpeax_x86::long_mode::Operand;          let mut res = String::new();          inst.write_to(&mut res).expect("format does not panic");          assert!(!res.contains("BUG")); +        for i in 0..inst.operand_count() { +            match inst.operand(i) { +                Operand::Register(reg) => { +                    assert!(!reg.class().name().contains("BUG")); +                } +                Operand::RegisterMaskMerge(r1, r2, _) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegisterMaskMergeSae(r1, r2, _, _) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegisterMaskMergeSaeNoround(r1, r2, _) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegDeref(r1) => { +                    assert!(!r1.class().name().contains("BUG")); +                } +                Operand::RegDisp(r1, _) => { +                    assert!(!r1.class().name().contains("BUG")); +                } +                Operand::RegScale(r1, _) => { +                    assert!(!r1.class().name().contains("BUG")); +                } +                Operand::RegIndexBase(r1, r2) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegIndexBaseDisp(r1, r2, _) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegScaleDisp(r1, _, _) => { +                    assert!(!r1.class().name().contains("BUG")); +                } +                Operand::RegIndexBaseScale(r1, r2, _) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegIndexBaseScaleDisp(r1, r2, _, _) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegDerefMasked(r1, r2) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegDispMasked(r1, _, r2) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegScaleMasked(r1, _, r2) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegIndexBaseMasked(r1, r2, r3) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                    assert!(!r3.class().name().contains("BUG")); +                } +                Operand::RegIndexBaseDispMasked(r1, r2, _, r3) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                    assert!(!r3.class().name().contains("BUG")); +                } +                Operand::RegScaleDispMasked(r1, _, _, r2) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegIndexBaseScaleMasked(r1, r2, _, r3) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                    assert!(!r3.class().name().contains("BUG")); +                } +                Operand::RegIndexBaseScaleDispMasked(r1, r2, _, _, r3) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                    assert!(!r3.class().name().contains("BUG")); +                } +                Operand::Nothing => { +                    panic!("`Nothing` should not be an operand listed in `inst.operand_count()`"); +                } +                _ => { +                    /* operands with no register - immediates or a non-rip-relative displacement */ +                } +            } +        }      };      if let Ok(inst) = x86_32_decoder.decode_slice(data) { +        use yaxpeax_x86::protected_mode::Operand;          let mut res = String::new();          inst.write_to(&mut res).expect("format does not panic");          assert!(!res.contains("BUG")); +        for i in 0..inst.operand_count() { +            match inst.operand(i) { +                Operand::Register(reg) => { +                    assert!(!reg.class().name().contains("BUG")); +                } +                Operand::RegisterMaskMerge(r1, r2, _) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegisterMaskMergeSae(r1, r2, _, _) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegisterMaskMergeSaeNoround(r1, r2, _) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegDeref(r1) => { +                    assert!(!r1.class().name().contains("BUG")); +                } +                Operand::RegDisp(r1, _) => { +                    assert!(!r1.class().name().contains("BUG")); +                } +                Operand::RegScale(r1, _) => { +                    assert!(!r1.class().name().contains("BUG")); +                } +                Operand::RegIndexBase(r1, r2) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegIndexBaseDisp(r1, r2, _) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegScaleDisp(r1, _, _) => { +                    assert!(!r1.class().name().contains("BUG")); +                } +                Operand::RegIndexBaseScale(r1, r2, _) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegIndexBaseScaleDisp(r1, r2, _, _) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegDerefMasked(r1, r2) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegDispMasked(r1, _, r2) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegScaleMasked(r1, _, r2) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegIndexBaseMasked(r1, r2, r3) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                    assert!(!r3.class().name().contains("BUG")); +                } +                Operand::RegIndexBaseDispMasked(r1, r2, _, r3) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                    assert!(!r3.class().name().contains("BUG")); +                } +                Operand::RegScaleDispMasked(r1, _, _, r2) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegIndexBaseScaleMasked(r1, r2, _, r3) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                    assert!(!r3.class().name().contains("BUG")); +                } +                Operand::RegIndexBaseScaleDispMasked(r1, r2, _, _, r3) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                    assert!(!r3.class().name().contains("BUG")); +                } +                Operand::Nothing => { +                    panic!("`Nothing` should not be an operand listed in `inst.operand_count()`"); +                } +                _ => { +                    /* operands with no register - immediates or a non-rip-relative displacement */ +                } +            } +        }      };      if let Ok(inst) = x86_16_decoder.decode_slice(data) { +        use yaxpeax_x86::real_mode::Operand;          let mut res = String::new();          inst.write_to(&mut res).expect("format does not panic");          assert!(!res.contains("BUG")); +        for i in 0..inst.operand_count() { +            match inst.operand(i) { +                Operand::Register(reg) => { +                    assert!(!reg.class().name().contains("BUG")); +                } +                Operand::RegisterMaskMerge(r1, r2, _) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegisterMaskMergeSae(r1, r2, _, _) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegisterMaskMergeSaeNoround(r1, r2, _) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegDeref(r1) => { +                    assert!(!r1.class().name().contains("BUG")); +                } +                Operand::RegDisp(r1, _) => { +                    assert!(!r1.class().name().contains("BUG")); +                } +                Operand::RegScale(r1, _) => { +                    assert!(!r1.class().name().contains("BUG")); +                } +                Operand::RegIndexBase(r1, r2) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegIndexBaseDisp(r1, r2, _) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegScaleDisp(r1, _, _) => { +                    assert!(!r1.class().name().contains("BUG")); +                } +                Operand::RegIndexBaseScale(r1, r2, _) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegIndexBaseScaleDisp(r1, r2, _, _) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegDerefMasked(r1, r2) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegDispMasked(r1, _, r2) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegScaleMasked(r1, _, r2) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegIndexBaseMasked(r1, r2, r3) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                    assert!(!r3.class().name().contains("BUG")); +                } +                Operand::RegIndexBaseDispMasked(r1, r2, _, r3) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                    assert!(!r3.class().name().contains("BUG")); +                } +                Operand::RegScaleDispMasked(r1, _, _, r2) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                } +                Operand::RegIndexBaseScaleMasked(r1, r2, _, r3) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                    assert!(!r3.class().name().contains("BUG")); +                } +                Operand::RegIndexBaseScaleDispMasked(r1, r2, _, _, r3) => { +                    assert!(!r1.class().name().contains("BUG")); +                    assert!(!r2.class().name().contains("BUG")); +                    assert!(!r3.class().name().contains("BUG")); +                } +                Operand::Nothing => { +                    panic!("`Nothing` should not be an operand listed in `inst.operand_count()`"); +                } +                _ => { +                    /* operands with no register - immediates or a non-rip-relative displacement */ +                } +            } +        }      };  }); diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs index 4eb0a36..439417a 100644 --- a/src/long_mode/mod.rs +++ b/src/long_mode/mod.rs @@ -789,16 +789,16 @@ pub struct RegisterClass {  }  const REGISTER_CLASS_NAMES: &[&'static str] = &[ -    "qword", -    "BUG. PLEASE REPORT.", -    "dword",      "BUG. PLEASE REPORT.", +    "byte",      "word",      "BUG. PLEASE REPORT.", -    "byte", +    "dword",      "BUG. PLEASE REPORT.",      "rex-byte",      "BUG. PLEASE REPORT.", +    "qword", +    "BUG. PLEASE REPORT.",      "cr",      "BUG. PLEASE REPORT.",      "dr", | 
