diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/long_mode/mod.rs | 67 | ||||
| -rw-r--r-- | src/protected_mode/mod.rs | 56 | ||||
| -rw-r--r-- | src/real_mode/mod.rs | 25 | 
3 files changed, 125 insertions, 23 deletions
diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs index e967f4b..72ec802 100644 --- a/src/long_mode/mod.rs +++ b/src/long_mode/mod.rs @@ -382,6 +382,18 @@ impl RegSpec {          RegSpec { bank: RegisterBank::D, num: 3 }      } +    // TODO: make pub in the 1.1 version bump +    #[inline] +    const fn esi() -> RegSpec { +        RegSpec { bank: RegisterBank::D, num: 6 } +    } + +    // TODO: make pub in the 1.1 version bump +    #[inline] +    const fn edi() -> RegSpec { +        RegSpec { bank: RegisterBank::D, num: 7 } +    } +      #[inline]      pub const fn ax() -> RegSpec {          RegSpec { bank: RegisterBank::W, num: 0 } @@ -582,6 +594,8 @@ impl OperandSpec {              OperandSpec::DispU32 |              OperandSpec::DispU64 |              OperandSpec::Deref | +            OperandSpec::Deref_esi | +            OperandSpec::Deref_edi |              OperandSpec::Deref_rsi |              OperandSpec::Deref_rdi |              OperandSpec::RegDisp | @@ -760,6 +774,12 @@ impl Operand {              OperandSpec::Deref => {                  Operand::RegDeref(inst.regs[1])              } +            OperandSpec::Deref_esi => { +                Operand::RegDeref(RegSpec::esi()) +            } +            OperandSpec::Deref_edi => { +                Operand::RegDeref(RegSpec::edi()) +            }              OperandSpec::Deref_rsi => {                  Operand::RegDeref(RegSpec::rsi())              } @@ -2782,6 +2802,8 @@ enum OperandSpec {      DispU32,      DispU64,      Deref, +    Deref_esi, +    Deref_edi,      Deref_rsi,      Deref_rdi,      RegDisp, @@ -4415,7 +4437,8 @@ impl Instruction {      /// prefixes.      pub fn segment_override_for_op(&self, op: u8) -> Option<Segment> {          match self.opcode { -            Opcode::STOS => { +            Opcode::STOS | +            Opcode::SCAS => {                  if op == 0 {                      Some(Segment::ES)                  } else { @@ -9122,21 +9145,34 @@ fn unlikely_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y          // sure hope these aren't backwards huh          OperandCode::AL_Xb => {              instruction.regs[0] = RegSpec::al(); -            instruction.regs[1] = RegSpec::rsi(); +            if instruction.prefixes.address_size() { +                instruction.regs[1] = RegSpec::esi(); +            } else { +                instruction.regs[1] = RegSpec::rsi(); +            }              instruction.operands[0] = OperandSpec::RegRRR;              instruction.operands[1] = OperandSpec::Deref;              instruction.mem_size = 1;              instruction.operand_count = 2;          }          OperandCode::Yb_Xb => { -            instruction.operands[0] = OperandSpec::Deref_rdi; -            instruction.operands[1] = OperandSpec::Deref_rsi; +            if instruction.prefixes.address_size() { +                instruction.operands[0] = OperandSpec::Deref_edi; +                instruction.operands[1] = OperandSpec::Deref_esi; +            } else { +                instruction.operands[0] = OperandSpec::Deref_rdi; +                instruction.operands[1] = OperandSpec::Deref_rsi; +            }              instruction.mem_size = 1;              instruction.operand_count = 2;          }          OperandCode::Yb_AL => {              instruction.regs[0] = RegSpec::al(); -            instruction.regs[1] = RegSpec::rsi(); +            if instruction.prefixes.address_size() { +                instruction.regs[1] = RegSpec::edi(); +            } else { +                instruction.regs[1] = RegSpec::rdi(); +            }              instruction.operands[0] = OperandSpec::Deref;              instruction.operands[1] = OperandSpec::RegRRR;              instruction.mem_size = 1; @@ -9150,7 +9186,11 @@ fn unlikely_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y                  8 => RegSpec::rax(),                  _ => { unreachable!(); }              }; -            instruction.regs[1] = RegSpec::rsi(); +            if instruction.prefixes.address_size() { +                instruction.regs[1] = RegSpec::esi(); +            } else { +                instruction.regs[1] = RegSpec::rsi(); +            }              instruction.operands[1] = OperandSpec::Deref;              instruction.mem_size = opwidth;          } @@ -9162,7 +9202,11 @@ fn unlikely_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y                  8 => RegSpec::rax(),                  _ => { unreachable!(); }              }; -            instruction.regs[1] = RegSpec::rdi(); +            if instruction.prefixes.address_size() { +                instruction.regs[1] = RegSpec::edi(); +            } else { +                instruction.regs[1] = RegSpec::rdi(); +            }              instruction.operands[0] = OperandSpec::Deref;              instruction.operands[1] = OperandSpec::RegRRR;              instruction.mem_size = opwidth; @@ -9170,8 +9214,13 @@ fn unlikely_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y          OperandCode::Yv_Xv => {              let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes);              instruction.mem_size = opwidth; -            instruction.operands[0] = OperandSpec::Deref_rdi; -            instruction.operands[1] = OperandSpec::Deref_rsi; +            if instruction.prefixes.address_size() { +                instruction.operands[0] = OperandSpec::Deref_edi; +                instruction.operands[1] = OperandSpec::Deref_esi; +            } else { +                instruction.operands[0] = OperandSpec::Deref_rdi; +                instruction.operands[1] = OperandSpec::Deref_rsi; +            }          }          OperandCode::ModRM_0x0f12 => {              instruction.regs[0].bank = RegisterBank::X; diff --git a/src/protected_mode/mod.rs b/src/protected_mode/mod.rs index 6e503a0..19fe881 100644 --- a/src/protected_mode/mod.rs +++ b/src/protected_mode/mod.rs @@ -525,6 +525,8 @@ impl OperandSpec {              OperandSpec::DispU16 |              OperandSpec::DispU32 |              OperandSpec::Deref | +            OperandSpec::Deref_si | +            OperandSpec::Deref_di |              OperandSpec::Deref_esi |              OperandSpec::Deref_edi |              OperandSpec::RegDisp | @@ -704,6 +706,12 @@ impl Operand {              OperandSpec::Deref => {                  Operand::RegDeref(inst.regs[1])              } +            OperandSpec::Deref_si => { +                Operand::RegDeref(RegSpec::si()) +            } +            OperandSpec::Deref_di => { +                Operand::RegDeref(RegSpec::di()) +            }              OperandSpec::Deref_esi => {                  Operand::RegDeref(RegSpec::esi())              } @@ -2720,6 +2728,8 @@ enum OperandSpec {      DispU16,      DispU32,      Deref, +    Deref_si, +    Deref_di,      Deref_esi,      Deref_edi,      RegDisp, @@ -4357,7 +4367,8 @@ impl Instruction {      /// prefixes.      pub fn segment_override_for_op(&self, op: u8) -> Option<Segment> {          match self.opcode { -            Opcode::STOS => { +            Opcode::STOS | +            Opcode::SCAS => {                  if op == 0 {                      Some(Segment::ES)                  } else { @@ -5748,6 +5759,7 @@ fn read_M_16bit<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpea      let modbits = modrm >> 6;      let mmm = modrm & 7;      if modbits == 0b00 && mmm == 0b110 { +        instr.disp = read_num(words, 2)? as u16 as u32;          return Ok(OperandSpec::DispU16);      }      match mmm { @@ -8975,21 +8987,34 @@ fn unlikely_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y          // sure hope these aren't backwards huh          OperandCode::AL_Xb => {              instruction.regs[0] = RegSpec::al(); -            instruction.regs[1] = RegSpec::esi(); +            if instruction.prefixes.address_size() { +                instruction.regs[1] = RegSpec::si(); +            } else { +                instruction.regs[1] = RegSpec::esi(); +            }              instruction.operands[0] = OperandSpec::RegRRR;              instruction.operands[1] = OperandSpec::Deref;              instruction.mem_size = 1;              instruction.operand_count = 2;          }          OperandCode::Yb_Xb => { -            instruction.operands[0] = OperandSpec::Deref_edi; -            instruction.operands[1] = OperandSpec::Deref_esi; +            if instruction.prefixes.address_size() { +                instruction.operands[0] = OperandSpec::Deref_di; +                instruction.operands[1] = OperandSpec::Deref_si; +            } else { +                instruction.operands[0] = OperandSpec::Deref_edi; +                instruction.operands[1] = OperandSpec::Deref_esi; +            }              instruction.mem_size = 1;              instruction.operand_count = 2;          }          OperandCode::Yb_AL => {              instruction.regs[0] = RegSpec::al(); -            instruction.regs[1] = RegSpec::esi(); +            if instruction.prefixes.address_size() { +                instruction.regs[1] = RegSpec::di(); +            } else { +                instruction.regs[1] = RegSpec::edi(); +            }              instruction.operands[0] = OperandSpec::Deref;              instruction.operands[1] = OperandSpec::RegRRR;              instruction.mem_size = 1; @@ -9003,7 +9028,11 @@ fn unlikely_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y                  instruction.mem_size = 4;                  RegSpec::eax()              }; -            instruction.regs[1] = RegSpec::esi(); +            if instruction.prefixes.address_size() { +                instruction.regs[1] = RegSpec::si(); +            } else { +                instruction.regs[1] = RegSpec::esi(); +            }              instruction.operands[1] = OperandSpec::Deref;          }          OperandCode::Yv_AX => { @@ -9014,7 +9043,11 @@ fn unlikely_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y                  instruction.mem_size = 4;                  RegSpec::eax()              }; -            instruction.regs[1] = RegSpec::edi(); +            if instruction.prefixes.address_size() { +                instruction.regs[1] = RegSpec::di(); +            } else { +                instruction.regs[1] = RegSpec::edi(); +            }              instruction.operands[0] = OperandSpec::Deref;              instruction.operands[1] = OperandSpec::RegRRR;          } @@ -9024,8 +9057,13 @@ fn unlikely_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y              } else {                  4              }; -            instruction.operands[0] = OperandSpec::Deref_edi; -            instruction.operands[1] = OperandSpec::Deref_esi; +            if instruction.prefixes.address_size() { +                instruction.operands[0] = OperandSpec::Deref_di; +                instruction.operands[1] = OperandSpec::Deref_si; +            } else { +                instruction.operands[0] = OperandSpec::Deref_edi; +                instruction.operands[1] = OperandSpec::Deref_esi; +            }          }          OperandCode::ModRM_0x0f12 => {              instruction.regs[0].bank = RegisterBank::X; diff --git a/src/real_mode/mod.rs b/src/real_mode/mod.rs index 6913fb4..3c9c279 100644 --- a/src/real_mode/mod.rs +++ b/src/real_mode/mod.rs @@ -4367,7 +4367,8 @@ impl Instruction {      /// prefixes.      pub fn segment_override_for_op(&self, op: u8) -> Option<Segment> {          match self.opcode { -            Opcode::STOS => { +            Opcode::STOS | +            Opcode::SCAS => {                  if op == 0 {                      Some(Segment::ES)                  } else { @@ -5758,6 +5759,7 @@ fn read_M_16bit<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpea      let modbits = modrm >> 6;      let mmm = modrm & 7;      if modbits == 0b00 && mmm == 0b110 { +        instr.disp = read_num(words, 2)? as u16 as u32;          return Ok(OperandSpec::DispU16);      }      match mmm { @@ -8994,21 +8996,34 @@ fn unlikely_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y          // sure hope these aren't backwards huh          OperandCode::AL_Xb => {              instruction.regs[0] = RegSpec::al(); -            instruction.regs[1] = RegSpec::esi(); +            if instruction.prefixes.address_size() { +                instruction.regs[1] = RegSpec::esi(); +            } else { +                instruction.regs[1] = RegSpec::si(); +            }              instruction.operands[0] = OperandSpec::RegRRR;              instruction.operands[1] = OperandSpec::Deref;              instruction.mem_size = 1;              instruction.operand_count = 2;          }          OperandCode::Yb_Xb => { -            instruction.operands[0] = OperandSpec::Deref_edi; -            instruction.operands[1] = OperandSpec::Deref_esi; +            if instruction.prefixes.address_size() { +                instruction.operands[0] = OperandSpec::Deref_edi; +                instruction.operands[1] = OperandSpec::Deref_esi; +            } else { +                instruction.operands[0] = OperandSpec::Deref_di; +                instruction.operands[1] = OperandSpec::Deref_si; +            }              instruction.mem_size = 1;              instruction.operand_count = 2;          }          OperandCode::Yb_AL => {              instruction.regs[0] = RegSpec::al(); -            instruction.regs[1] = RegSpec::esi(); +            if instruction.prefixes.address_size() { +                instruction.regs[1] = RegSpec::edi(); +            } else { +                instruction.regs[1] = RegSpec::di(); +            }              instruction.operands[0] = OperandSpec::Deref;              instruction.operands[1] = OperandSpec::RegRRR;              instruction.mem_size = 1;  | 
