hex_patch/app/
instruction.rs1use std::{collections::HashMap, fmt::Display};
2
3use capstone::Insn;
4
5#[derive(Debug, Clone, PartialEq, Eq)]
6pub struct Instruction {
7 pub(super) mnemonic: String,
8 pub(super) operands: String,
9 pub(super) virtual_address: u64,
10 pub(super) bytes: Vec<u8>,
11}
12
13impl Instruction {
14 pub fn new(instruction: &Insn, symbols: Option<&HashMap<u64, String>>) -> Self {
15 let mnemonic = instruction
16 .mnemonic()
17 .expect(&t!("errors.instruction_no_mnemonic"));
18 let operands = instruction
19 .op_str()
20 .expect(&t!("errors.instruction_no_operands"));
21 let operands = operands.split(", ").collect::<Vec<_>>();
22 let mut operands_string = String::new();
23 for (i, operand) in operands.iter().enumerate() {
24 let mut found_symbol = false;
25 if let Some(symbols) = &symbols {
26 if let Some(operand) = operand.strip_prefix("0x") {
27 if let Ok(operand_address) = u64::from_str_radix(operand, 16) {
28 if let Some(symbol) = symbols.get(&operand_address) {
29 found_symbol = true;
30 operands_string.push_str(symbol);
31 }
32 }
33 }
34 if let Some(operand) = operand.strip_prefix("#0x") {
35 if let Ok(operand_address) = u64::from_str_radix(operand, 16) {
36 if let Some(symbol) = symbols.get(&operand_address) {
37 found_symbol = true;
38 operands_string.push_str(symbol);
39 }
40 }
41 }
42 }
43 if !found_symbol {
44 operands_string.push_str(operand);
45 }
46 if i < operands.len() - 1 {
47 operands_string.push_str(", ");
48 }
49 }
50 let virtual_address = instruction.address();
51 let bytes = instruction.bytes().to_vec();
52 Instruction {
53 mnemonic: mnemonic.to_string(),
54 operands: operands_string,
55 virtual_address,
56 bytes,
57 }
58 }
59
60 pub fn mnemonic(&self) -> &str {
61 &self.mnemonic
62 }
63
64 pub fn operands(&self) -> &str {
65 &self.operands
66 }
67
68 pub fn ip(&self) -> u64 {
69 self.virtual_address
70 }
71
72 pub fn len(&self) -> usize {
73 self.bytes.len()
74 }
75
76 pub fn is_empty(&self) -> bool {
77 self.bytes.is_empty()
78 }
79}
80
81impl Display for Instruction {
82 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
83 write!(f, "{} {}", self.mnemonic, self.operands)
84 }
85}