Closed pr0me closed 2 years ago
Found a (super dirty) solution:
unsafe {
let op = ops.nth(1).unwrap();
let mem_op: capstone_sys::arm_op_mem =
*((&(*((core::ptr::addr_of!(op.op_type) as u32 + std::mem::size_of::<usize>())
as *const ArmOperandType)) as *const _)
as *const capstone_sys::arm_op_mem);
}
Feel free to let me know whether there is a better way.
The .op_type
field gives you an instance of the ArmOperandType
enum. Just like any enum, you can use a match
or if let
statement to destructure the value. The Mem
variant contains a ArmOpMem
which you want.
The underlying cs_op_mem
is not directly accessible, but you don't need the ArmOpMem
has accessor methods.
use capstone::arch::arm::ArmOperandType;
use capstone::prelude::*;
use capstone::InsnDetail;
const ARM_CODE: &[u8] = b"\x04\xe0\x2d\xe5";
fn main() {
let cs: Capstone = Capstone::new()
.arm()
.mode(arch::arm::ArchMode::Arm)
.detail(true)
.build()
.unwrap();
let insns = cs.disasm_all(ARM_CODE, 0x1000).unwrap();
let insn = insns.iter().next().unwrap();
println!("{}", insn);
let detail: InsnDetail = cs.insn_detail(&insn).unwrap();
let arch_detail: ArchDetail = detail.arch_detail();
let arm_detail = arch_detail.arm().unwrap();
let op = arm_detail.operands().nth(1).unwrap();
println!("op = {:?}", op);
match op.op_type {
ArmOperandType::Mem(arm_op_mem) => {
println!("disp = {}", arm_op_mem.disp());
}
_ => (), // ignored for now
}
}
Found a (super dirty) solution: ... Feel free to let me know whether there is a better way.
I think my above solution is preferred since this invokes undefined behavior (could not work on different host platform or different compiler version). 😉
ah right! Yea, definitely more idiomatic and less UB :P
Thank you
Hey, I can't seem to figure out how to access the inner
arm_op_mem
in aMem(ArmOpMem)
. The following code gives meMem(ArmOpMem(arm_op_mem { base: 11, index: 0, scale: 1, disp: 8, lshift: 0 }))
from which I want to access, e.g.,disp
:Sorry if it's obvious but I can't seem to see through the ffi.