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.mnemonic().expect("Failed to get mnemonic");
16 let operands = instruction.op_str().expect("Failed to get operands");
17 let operands = operands.split(", ").collect::<Vec<_>>();
18 let mut operands_string = String::new();
19 for (i, operand) in operands.iter().enumerate() {
20 let mut found_symbol = false;
21 if let Some(symbols) = &symbols {
22 if let Some(operand) = operand.strip_prefix("0x") {
23 if let Ok(operand_address) = u64::from_str_radix(operand, 16) {
24 if let Some(symbol) = symbols.get(&operand_address) {
25 found_symbol = true;
26 operands_string.push_str(symbol);
27 }
28 }
29 }
30 if let Some(operand) = operand.strip_prefix("#0x") {
31 if let Ok(operand_address) = u64::from_str_radix(operand, 16) {
32 if let Some(symbol) = symbols.get(&operand_address) {
33 found_symbol = true;
34 operands_string.push_str(symbol);
35 }
36 }
37 }
38 }
39 if !found_symbol {
40 operands_string.push_str(operand);
41 }
42 if i < operands.len() - 1 {
43 operands_string.push_str(", ");
44 }
45 }
46 let virtual_address = instruction.address();
47 let bytes = instruction.bytes().to_vec();
48 Instruction {
49 mnemonic: mnemonic.to_string(),
50 operands: operands_string,
51 virtual_address,
52 bytes,
53 }
54 }
55
56 pub fn mnemonic(&self) -> &str {
57 &self.mnemonic
58 }
59
60 pub fn operands(&self) -> &str {
61 &self.operands
62 }
63
64 pub fn ip(&self) -> u64 {
65 self.virtual_address
66 }
67
68 pub fn len(&self) -> usize {
69 self.bytes.len()
70 }
71
72 pub fn is_empty(&self) -> bool {
73 self.bytes.is_empty()
74 }
75}
76
77impl Display for Instruction {
78 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
79 write!(f, "{} {}", self.mnemonic, self.operands)
80 }
81}