diff --git a/libafl_concolic/symcc_runtime/symcc b/libafl_concolic/symcc_runtime/symcc index a42e95e754..5cccc33456 160000 --- a/libafl_concolic/symcc_runtime/symcc +++ b/libafl_concolic/symcc_runtime/symcc @@ -1 +1 @@ -Subproject commit a42e95e754f7d8645957ab399d3eb346d2303b5a +Subproject commit 5cccc33456c48ad83008eb618e7da5d005c72d89 diff --git a/libafl_qemu/src/arm.rs b/libafl_qemu/src/arm.rs index c9aaaf77ae..5cf02ebad7 100644 --- a/libafl_qemu/src/arm.rs +++ b/libafl_qemu/src/arm.rs @@ -1,3 +1,4 @@ +use capstone::arch::BuildsCapstone; use num_enum::{IntoPrimitive, TryFromPrimitive}; #[cfg(feature = "python")] use pyo3::prelude::*; @@ -50,5 +51,14 @@ impl IntoPy for Regs { /// Return an ARM ArchCapstoneBuilder pub fn capstone() -> capstone::arch::arm::ArchCapstoneBuilder { - capstone::Capstone::new().arm() + capstone::Capstone::new() + .arm() + .mode(capstone::arch::arm::ArchMode::Arm) +} + +/// Return an ARM Thumb ArchCapstoneBuilder +pub fn capstone_thumb() -> capstone::arch::arm::ArchCapstoneBuilder { + capstone::Capstone::new() + .arm() + .mode(capstone::arch::arm::ArchMode::Thumb) } diff --git a/libafl_qemu/src/blocks.rs b/libafl_qemu/src/blocks.rs index 823d996a49..1aa1876d86 100644 --- a/libafl_qemu/src/blocks.rs +++ b/libafl_qemu/src/blocks.rs @@ -21,7 +21,11 @@ pub struct Instruction { * - operand string * - instruction length */ -pub fn pc2basicblock(pc: GuestAddr, emu: &Emulator) -> Result, String> { +pub fn pc2basicblock( + pc: GuestAddr, + emu: &Emulator, + mode: Option, +) -> Result, String> { #[allow(unused_mut)] let mut code = { #[cfg(emulation_mode = "usermode")] @@ -43,7 +47,10 @@ pub fn pc2basicblock(pc: GuestAddr, emu: &Emulator) -> Result, let mut iaddr = pc; let mut block = Vec::::new(); - let cs = crate::capstone().detail(true).build().unwrap(); + let mut cs = crate::capstone().detail(true).build().unwrap(); + if let Some(m) = mode { + cs.set_mode(m).unwrap(); + } 'disasm: while let Ok(insns) = cs.disasm_count(code, iaddr.into(), 1) { if insns.is_empty() { diff --git a/libafl_qemu/src/calls.rs b/libafl_qemu/src/calls.rs index 54d7ed8f6c..f75158f2a1 100644 --- a/libafl_qemu/src/calls.rs +++ b/libafl_qemu/src/calls.rs @@ -301,12 +301,23 @@ where S: UsesInput, QT: QemuHelperTuple, { - let emu = hooks.emulator(); - if let Some(h) = hooks.helpers().match_first_type::() { + if let Some(h) = hooks.helpers_mut().match_first_type_mut::() { if !h.must_instrument(pc) { return None; } + #[cfg(cpu_target = "arm")] + h.cs.set_mode(if pc & 1 == 1 { + arch::arm::ArchMode::Thumb.into() + } else { + arch::arm::ArchMode::Arm.into() + }) + .unwrap(); + } + + let emu = hooks.emulator(); + + if let Some(h) = hooks.helpers().match_first_type::() { #[allow(unused_mut)] let mut code = { #[cfg(emulation_mode = "usermode")] diff --git a/libafl_qemu/src/drcov.rs b/libafl_qemu/src/drcov.rs index 2bf72df58f..ceff8404fb 100644 --- a/libafl_qemu/src/drcov.rs +++ b/libafl_qemu/src/drcov.rs @@ -114,7 +114,16 @@ where continue 'pcs_full; } if *idm == *id { - match pc2basicblock(*pc, emulator) { + #[cfg(cpu_target = "arm")] + let mode = if pc & 1 == 1 { + Some(capstone::arch::arm::ArchMode::Thumb.into()) + } else { + Some(capstone::arch::arm::ArchMode::Arm.into()) + }; + #[cfg(not(cpu_target = "arm"))] + let mode = None; + + match pc2basicblock(*pc, emulator, mode) { Ok(block) => { let mut block_len = 0; for instr in &block { @@ -153,7 +162,17 @@ where if !module_found { continue 'pcs; } - match pc2basicblock(*pc, emulator) { + + #[cfg(cpu_target = "arm")] + let mode = if pc & 1 == 1 { + Some(capstone::arch::arm::ArchMode::Thumb.into()) + } else { + Some(capstone::arch::arm::ArchMode::Arm.into()) + }; + #[cfg(not(cpu_target = "arm"))] + let mode = None; + + match pc2basicblock(*pc, emulator, mode) { Ok(block) => { let mut block_len = 0; for instr in &block {