libafl_qemu: 32-bit arm thumb state breakpoint handling
When emulating a 32-bit arm binary the return address written to the lr register might indicate thumb state through the least significant bit (0 = arm state, 1 = thumb state). Trying to set a breakpoint on a thumb state address won't work (i.e. the breakpoint will never trigger).
Afaict, none of the qemu examples here handle this edge case, e.g.: https://github.com/AFLplusplus/LibAFL/blob/c857b8dd77341c6cd9a2c132939a782a1205f034/fuzzers/qemu/qemu_launcher/src/client.rs#L162-L166
I've worked around this in my own fuzzer with the following:
let ret_addr: GuestAddr = emu.read_return_address().unwrap();
let mut breakpoint = ret_addr;
#[cfg(feature = "qemu_arm")]
if breakpoint & 1 == 1 {
breakpoint -= 1;
}
emu.set_breakpoint(breakpoint);
This workaround seems to the trick but it might more appropriate for libafl to handle this internally?
Thank you for the report! Good catch; it is something we should indeed handle internally. I will fix it whenever I have some free time.
This should be fixed then, right?