aboutsummaryrefslogtreecommitdiff
path: root/src/long_mode/mod.rs
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2021-08-21 12:13:01 -0700
committeriximeow <me@iximeow.net>2021-08-21 12:13:01 -0700
commitcef4feeaf9c64e03a6728f267750ac2fb32eb9ff (patch)
treedcfc974ad5d1beffe629138aebdfa92fbf7f90a5 /src/long_mode/mod.rs
parent4612215ddc98dabaffedc36f6fe402bb9f04119a (diff)
report memory sizes for push, pop, call, ret
these instructions had memory sizes reported for the operand, if it was a memory operand, but for versions with non-memory operands the decoded `Instruction` would imply that non memory access would happen at all. now, decoded instructions in these cases will report a more useful memory size.
Diffstat (limited to 'src/long_mode/mod.rs')
-rw-r--r--src/long_mode/mod.rs32
1 files changed, 31 insertions, 1 deletions
diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs
index 039d550..a01e854 100644
--- a/src/long_mode/mod.rs
+++ b/src/long_mode/mod.rs
@@ -7396,6 +7396,9 @@ fn read_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpe
if immsz == 0 {
instruction.operands[0] = OperandSpec::ImmI8;
} else {
+ if instruction.opcode == Opcode::CALL {
+ instruction.mem_size = 8;
+ }
instruction.operands[0] = OperandSpec::ImmI32;
}
instruction.operand_count = 1;
@@ -7420,6 +7423,7 @@ fn read_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpe
};
instruction.regs[0] =
RegSpec::from_parts(reg, instruction.prefixes.rex_unchecked().b(), bank);
+ instruction.mem_size = 8;
instruction.operand_count = 1;
}
1 => {
@@ -7615,12 +7619,27 @@ fn read_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpe
if instruction.operands[0] == OperandSpec::RegMMM {
if opcode == Opcode::CALL || opcode == Opcode::JMP {
instruction.regs[1].bank = RegisterBank::Q;
+ if opcode == Opcode::CALL {
+ instruction.mem_size = 8;
+ }
+ } else if opcode == Opcode::PUSH || opcode == Opcode::POP {
+ if instruction.prefixes.operand_size() {
+ instruction.mem_size = 2;
+ } else {
+ instruction.mem_size = 8;
+ }
} else if opcode == Opcode::CALLF || opcode == Opcode::JMPF {
return Err(DecodeError::InvalidOperand);
}
} else {
- if opcode == Opcode::CALL || opcode == Opcode::JMP || opcode == Opcode::PUSH || opcode == Opcode::POP {
+ if opcode == Opcode::CALL || opcode == Opcode::JMP {
instruction.mem_size = 8;
+ } else if opcode == Opcode::PUSH || opcode == Opcode::POP {
+ if instruction.prefixes.operand_size() {
+ instruction.mem_size = 2;
+ } else {
+ instruction.mem_size = 8;
+ }
} else if opcode == Opcode::CALLF || opcode == Opcode::JMPF {
instruction.mem_size = 10;
}
@@ -7749,6 +7768,12 @@ fn read_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpe
if instruction.opcode == Opcode::Invalid {
return Err(DecodeError::InvalidOpcode);
}
+ if instruction.opcode == Opcode::RETURN {
+ instruction.mem_size = 8;
+ } else if instruction.opcode == Opcode::RETF {
+ instruction.mem_size = 10;
+ }
+ // TODO: leave?
instruction.operands[0] = OperandSpec::Nothing;
instruction.operand_count = 0;
return Ok(());
@@ -9273,6 +9298,11 @@ fn unlikely_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
instruction.imm =
read_imm_unsigned(words, 2)?;
instruction.operands[0] = OperandSpec::ImmU16;
+ if instruction.opcode == Opcode::RETURN {
+ instruction.mem_size = 8;
+ } else {
+ instruction.mem_size = 10;
+ }
instruction.operand_count = 1;
}
OperandCode::ModRM_0x0f00 => {