Frida Cmplog improvements for aarch64 (#363)
* add support for cbz/tbz * remove unecessary print * implemented support for tbz * add support for tbnz * fix an error in the emitted code for both tbz/tbnz * add support for cbnz * fix error in logic * add special handling to "subs" * add restoration for X5 for tbz/tbnz * add "adds" support * add special handling for different opcodes * add support for cbz/tbz * remove unecessary print * implemented support for tbz * add support for tbnz * fix an error in the emitted code for both tbz/tbnz * add support for cbnz * fix error in logic * add special handling to "subs" * add restoration for X5 for tbz/tbnz * add "adds" support * add special handling for different opcodes * add adcs to cmplog commands * get rid of irrelevant allocations
This commit is contained in:
parent
dd0b5fa74f
commit
3ffcfde9a3
@ -77,22 +77,27 @@ impl CmpLogRuntime {
|
|||||||
);};
|
);};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ldp/stp is more efficient than str/ldr so we use them instead.
|
||||||
macro_rules! tbz_masking {
|
macro_rules! tbz_masking {
|
||||||
($ops:ident) => {dynasm!($ops
|
($ops:ident) => {dynasm!($ops
|
||||||
; .arch aarch64
|
; .arch aarch64
|
||||||
|
; stp x5, x5, [sp, #-0x10]!
|
||||||
; mov x5, #1
|
; mov x5, #1
|
||||||
; lsl x5, x5, x1
|
; lsl x5, x5, x1
|
||||||
; eor x5, x5, #255
|
; eor x5, x5, #255
|
||||||
; orr x1, x0, x5
|
; orr x1, x0, x5
|
||||||
|
; ldp x5, x5, [sp], #0x10
|
||||||
);};
|
);};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! tbnz_masking {
|
macro_rules! tbnz_masking {
|
||||||
($ops:ident) => {dynasm!($ops
|
($ops:ident) => {dynasm!($ops
|
||||||
; .arch aarch64
|
; .arch aarch64
|
||||||
|
; stp x5, x5, [sp, #-0x10]!
|
||||||
; mov x5, #1
|
; mov x5, #1
|
||||||
; lsl x5, x5, x1
|
; lsl x5, x5, x1
|
||||||
; orr x1, x0, x5
|
; orr x1, x0, x5
|
||||||
|
; ldp x5, x5, [sp], #0x10
|
||||||
);};
|
);};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -62,13 +62,12 @@ enum CmplogOperandType {
|
|||||||
Mem(capstone::RegId, capstone::RegId, i32, u32),
|
Mem(capstone::RegId, capstone::RegId, i32, u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(feature = "cmplog", target_arch = "aarch64"))]
|
|
||||||
enum SpecialCmpLogCase {
|
enum SpecialCmpLogCase {
|
||||||
Tbz,
|
Tbz,
|
||||||
Tbnz,
|
Tbnz,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_vendor = "apple")]
|
#[cfg(any(target_vendor = "apple"))]
|
||||||
const ANONYMOUS_FLAG: MapFlags = MapFlags::MAP_ANON;
|
const ANONYMOUS_FLAG: MapFlags = MapFlags::MAP_ANON;
|
||||||
#[cfg(not(any(target_vendor = "apple", target_os = "windows")))]
|
#[cfg(not(any(target_vendor = "apple", target_os = "windows")))]
|
||||||
const ANONYMOUS_FLAG: MapFlags = MapFlags::MAP_ANONYMOUS;
|
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
|
// We only care for compare instrunctions - aka instructions which set the flags
|
||||||
match instr.mnemonic().unwrap() {
|
match instr.mnemonic().unwrap() {
|
||||||
"cmp" | "ands" | "subs" | "adds" | "negs" | "ngcs" | "sbcs" | "bics" | "cls"
|
"cmp" | "ands" | "subs" | "adds" | "negs" | "ngcs" | "sbcs" | "bics" | "cbz"
|
||||||
| "cbz" | "tbz" | "tbnz" => (),
|
| "cbnz" | "tbz" | "tbnz" | "adcs" => (),
|
||||||
_ => return Err(()),
|
_ => return Err(()),
|
||||||
}
|
}
|
||||||
let operands = self
|
let mut operands = self
|
||||||
.capstone
|
.capstone
|
||||||
.insn_detail(instr)
|
.insn_detail(instr)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -1412,12 +1411,25 @@ impl<'a> FridaInstrumentationHelper<'a> {
|
|||||||
.operands();
|
.operands();
|
||||||
|
|
||||||
// cbz - 1 operand, tbz - 3 operands
|
// cbz - 1 operand, tbz - 3 operands
|
||||||
let special_case = ["cbz", "tbz", "tbnz"].contains(&instr.mnemonic().unwrap());
|
let special_case = [
|
||||||
if operands.len() != 2 || !special_case {
|
"cbz", "cbnz", "tbz", "tbnz", "subs", "adds", "ands", "sbcs", "bics", "adcs",
|
||||||
|
]
|
||||||
|
.contains(&instr.mnemonic().unwrap());
|
||||||
|
if operands.len() != 2 && !special_case {
|
||||||
return Err(());
|
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
|
// 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() {
|
let operand1 = if let Arm64Operand(arm64operand) = operands.first().unwrap() {
|
||||||
match arm64operand.op_type {
|
match arm64operand.op_type {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user