aboutsummaryrefslogtreecommitdiff
path: root/src
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 /src
parente15ef43a243ae0e0db369cead1786f4f2c4e690e (diff)
handle vzeroupper/vzeroall, reject vzero* with nonzero vvvv
Diffstat (limited to 'src')
-rw-r--r--src/long_mode/vex.rs12
-rw-r--r--src/protected_mode/vex.rs12
-rw-r--r--src/real_mode/vex.rs12
3 files changed, 33 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 {