diff --git a/libafl_frida/src/cmplog_rt.rs b/libafl_frida/src/cmplog_rt.rs index e6989e4b64..966adab6ce 100644 --- a/libafl_frida/src/cmplog_rt.rs +++ b/libafl_frida/src/cmplog_rt.rs @@ -77,22 +77,27 @@ impl CmpLogRuntime { );}; } + // ldp/stp is more efficient than str/ldr so we use them instead. macro_rules! tbz_masking { ($ops:ident) => {dynasm!($ops ; .arch aarch64 + ; stp x5, x5, [sp, #-0x10]! ; mov x5, #1 ; lsl x5, x5, x1 ; eor x5, x5, #255 ; orr x1, x0, x5 + ; ldp x5, x5, [sp], #0x10 );}; } macro_rules! tbnz_masking { ($ops:ident) => {dynasm!($ops ; .arch aarch64 + ; stp x5, x5, [sp, #-0x10]! ; mov x5, #1 ; lsl x5, x5, x1 ; orr x1, x0, x5 + ; ldp x5, x5, [sp], #0x10 );}; } diff --git a/libafl_frida/src/helper.rs b/libafl_frida/src/helper.rs index 55fd990456..45ea33ed74 100644 --- a/libafl_frida/src/helper.rs +++ b/libafl_frida/src/helper.rs @@ -62,13 +62,12 @@ enum CmplogOperandType { Mem(capstone::RegId, capstone::RegId, i32, u32), } -#[cfg(all(feature = "cmplog", target_arch = "aarch64"))] enum SpecialCmpLogCase { Tbz, Tbnz, } -#[cfg(target_vendor = "apple")] +#[cfg(any(target_vendor = "apple"))] const ANONYMOUS_FLAG: MapFlags = MapFlags::MAP_ANON; #[cfg(not(any(target_vendor = "apple", target_os = "windows")))] const ANONYMOUS_FLAG: MapFlags = MapFlags::MAP_ANONYMOUS; @@ -1400,11 +1399,11 @@ impl<'a> FridaInstrumentationHelper<'a> { > { // We only care for compare instrunctions - aka instructions which set the flags match instr.mnemonic().unwrap() { - "cmp" | "ands" | "subs" | "adds" | "negs" | "ngcs" | "sbcs" | "bics" | "cls" - | "cbz" | "tbz" | "tbnz" => (), + "cmp" | "ands" | "subs" | "adds" | "negs" | "ngcs" | "sbcs" | "bics" | "cbz" + | "cbnz" | "tbz" | "tbnz" | "adcs" => (), _ => return Err(()), } - let operands = self + let mut operands = self .capstone .insn_detail(instr) .unwrap() @@ -1412,12 +1411,25 @@ impl<'a> FridaInstrumentationHelper<'a> { .operands(); // cbz - 1 operand, tbz - 3 operands - let special_case = ["cbz", "tbz", "tbnz"].contains(&instr.mnemonic().unwrap()); - if operands.len() != 2 || !special_case { + let special_case = [ + "cbz", "cbnz", "tbz", "tbnz", "subs", "adds", "ands", "sbcs", "bics", "adcs", + ] + .contains(&instr.mnemonic().unwrap()); + if operands.len() != 2 && !special_case { return Err(()); } + + // handle special opcodes case which have 3 operands, but the 1st(dest) is not important to us + if ["subs", "adds", "ands", "sbcs", "bics", "adcs"].contains(&instr.mnemonic().unwrap()) { + //remove the dest operand from the list + operands.remove(0); + } + // cbz marked as special since there is only 1 operand - let special_case = instr.mnemonic().unwrap() == "cbz"; + let special_case = match instr.mnemonic().unwrap() { + "cbz" | "cbnz" => true, + _ => false, + }; let operand1 = if let Arm64Operand(arm64operand) = operands.first().unwrap() { match arm64operand.op_type {