aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2021-07-04 14:23:45 -0700
committeriximeow <me@iximeow.net>2021-07-04 14:23:45 -0700
commitff9760b94936de929777f9730ac1568ac26bf4d5 (patch)
tree53be09b02c0f3e3c7edcfe02038cd31f3dbc0883
parente15ef43a243ae0e0db369cead1786f4f2c4e690e (diff)
handle vzeroupper/vzeroall, reject vzero* with nonzero vvvv
-rw-r--r--src/long_mode/vex.rs12
-rw-r--r--src/protected_mode/vex.rs12
-rw-r--r--src/real_mode/vex.rs12
-rw-r--r--test/long_mode/mod.rs1
-rw-r--r--test/protected_mode/mod.rs1
-rw-r--r--test/real_mode/mod.rs1
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]);