diff options
| -rw-r--r-- | src/long_mode/vex.rs | 12 | ||||
| -rw-r--r-- | src/protected_mode/vex.rs | 12 | ||||
| -rw-r--r-- | src/real_mode/vex.rs | 12 | ||||
| -rw-r--r-- | test/long_mode/mod.rs | 1 | ||||
| -rw-r--r-- | test/protected_mode/mod.rs | 1 | ||||
| -rw-r--r-- | test/real_mode/mod.rs | 1 | 
6 files changed, 36 insertions, 3 deletions
diff --git a/src/long_mode/vex.rs b/src/long_mode/vex.rs index 5695b17..9649e72 100644 --- a/src/long_mode/vex.rs +++ b/src/long_mode/vex.rs @@ -439,6 +439,12 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y              Ok(())          }          VEXOperandCode::Nothing => { +            if instruction.opcode == Opcode::VZEROUPPER || instruction.opcode == Opcode::VZEROALL { +                if instruction.regs[3].num != 0 { +                    instruction.opcode = Opcode::Invalid; +                    return Err(DecodeError::InvalidOperand); +                } +            }              instruction.operand_count = 0;              Ok(())          }, @@ -1541,7 +1547,11 @@ fn read_vex_instruction<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch a                          } else {                              VEXOperandCode::G_V_E_xmm                          }), -                        0x77 => (Opcode::VZEROUPPER, VEXOperandCode::Nothing), +                        0x77 => if L { +                            (Opcode::VZEROALL, VEXOperandCode::Nothing) +                        } else { +                            (Opcode::VZEROUPPER, VEXOperandCode::Nothing) +                        },                          0xAE => (Opcode::Invalid, if L {                              return Err(DecodeError::InvalidOpcode);                          } else { diff --git a/src/protected_mode/vex.rs b/src/protected_mode/vex.rs index 3550f77..54c9d23 100644 --- a/src/protected_mode/vex.rs +++ b/src/protected_mode/vex.rs @@ -440,6 +440,12 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y              Ok(())          }          VEXOperandCode::Nothing => { +            if instruction.opcode == Opcode::VZEROUPPER || instruction.opcode == Opcode::VZEROALL { +                if instruction.regs[3].num != 0 { +                    instruction.opcode = Opcode::Invalid; +                    return Err(DecodeError::InvalidOperand); +                } +            }              instruction.operand_count = 0;              Ok(())          }, @@ -1470,7 +1476,11 @@ fn read_vex_instruction<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch a                          } else {                              VEXOperandCode::G_V_E_xmm                          }), -                        0x77 => (Opcode::VZEROUPPER, VEXOperandCode::Nothing), +                        0x77 => if L { +                            (Opcode::VZEROALL, VEXOperandCode::Nothing) +                        } else { +                            (Opcode::VZEROUPPER, VEXOperandCode::Nothing) +                        },                          0xAE => (Opcode::Invalid, if L {                              return Err(DecodeError::InvalidOpcode);                          } else { diff --git a/src/real_mode/vex.rs b/src/real_mode/vex.rs index 8e69032..56eb48f 100644 --- a/src/real_mode/vex.rs +++ b/src/real_mode/vex.rs @@ -440,6 +440,12 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y              Ok(())          }          VEXOperandCode::Nothing => { +            if instruction.opcode == Opcode::VZEROUPPER || instruction.opcode == Opcode::VZEROALL { +                if instruction.regs[3].num != 0 { +                    instruction.opcode = Opcode::Invalid; +                    return Err(DecodeError::InvalidOperand); +                } +            }              instruction.operand_count = 0;              Ok(())          }, @@ -1470,7 +1476,11 @@ fn read_vex_instruction<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch a                          } else {                              VEXOperandCode::G_V_E_xmm                          }), -                        0x77 => (Opcode::VZEROUPPER, VEXOperandCode::Nothing), +                        0x77 => if L { +                            (Opcode::VZEROALL, VEXOperandCode::Nothing) +                        } else { +                            (Opcode::VZEROUPPER, VEXOperandCode::Nothing) +                        },                          0xAE => (Opcode::Invalid, if L {                              return Err(DecodeError::InvalidOpcode);                          } else { diff --git a/test/long_mode/mod.rs b/test/long_mode/mod.rs index 1573580..de65a97 100644 --- a/test/long_mode/mod.rs +++ b/test/long_mode/mod.rs @@ -3161,6 +3161,7 @@ fn test_x87() {  #[test]  fn test_mishegos_finds() { +    test_invalid(&[0xc5, 0x8c, 0x77]);      test_display(&[0x0f, 0xfc, 0xaf, 0x40, 0x38, 0x25, 0xbf], "paddb mm5, qword [rdi - 0x40dac7c0]");      test_invalid(&[0xc5, 0x4d, 0x16, 0x0f]);      test_invalid(&[0xf3, 0x67, 0x0f, 0x3a, 0xf0, 0xfb, 0xb4]); diff --git a/test/protected_mode/mod.rs b/test/protected_mode/mod.rs index 65e112f..28682ef 100644 --- a/test/protected_mode/mod.rs +++ b/test/protected_mode/mod.rs @@ -2881,6 +2881,7 @@ fn test_x87() {  #[test]  fn test_mishegos_finds() { +    test_invalid(&[0xc5, 0x8c, 0x77]);      test_display(&[0x0f, 0xfc, 0xaf, 0x40, 0x38, 0x25, 0xbf], "paddb mm5, qword [edi - 0x40dac7c0]");      test_invalid(&[0xf3, 0x67, 0x0f, 0x3a, 0xf0, 0xfb, 0xb4]);      test_display(&[0x65, 0x66, 0x0f, 0x01, 0xdc], "stgi"); diff --git a/test/real_mode/mod.rs b/test/real_mode/mod.rs index 54bae05..23744e1 100644 --- a/test/real_mode/mod.rs +++ b/test/real_mode/mod.rs @@ -18189,6 +18189,7 @@ fn test_invalid_sequences() {      test_invalid(&[0xc4, 0b110_00011, 0b1_1111_101, 0x19, 0b11_001_010, 0x77]);      test_invalid(&[0xc4, 0b110_00011, 0b1_1111_101, 0x46, 0b11_001_010, 0x77]);      test_invalid(&[0xc5, 0b1_1111_111, 0x2f, 0b11_001_010]); +    test_invalid(&[0xc5, 0x8c, 0x77]);      test_invalid(&[0xd9, 0x08]);      test_invalid(&[0xd9, 0x09]);      test_invalid(&[0xd9, 0x0a]);  | 
