From a78a4b73fa798c1ed7a3d053369cca435e57aa07 Mon Sep 17 00:00:00 2001 From: s1341 Date: Mon, 3 May 2021 10:34:15 +0300 Subject: [PATCH] frida-asan: Un-inline report funclet to reduce code bloat (#81) * frida-asan: Outline report funclet to reduce code bloat * fmt --- fuzzers/frida_libpng/Cargo.toml | 9 +- fuzzers/frida_libpng/harness.cc | 3 +- libafl_frida/Cargo.toml | 6 +- libafl_frida/src/asan_rt.rs | 430 +++++++++++--------------------- libafl_frida/src/helper.rs | 34 ++- 5 files changed, 194 insertions(+), 288 deletions(-) diff --git a/fuzzers/frida_libpng/Cargo.toml b/fuzzers/frida_libpng/Cargo.toml index c59b89c88c..23d7c9146b 100644 --- a/fuzzers/frida_libpng/Cargo.toml +++ b/fuzzers/frida_libpng/Cargo.toml @@ -6,9 +6,8 @@ edition = "2018" build = "build.rs" [features] -default = ["std", "frida"] +default = ["std"] std = [] -frida = ["frida-gum", "frida-gum-sys"] [profile.release] lto = true @@ -22,10 +21,10 @@ num_cpus = "1.0" which = "4.1" [target.'cfg(unix)'.dependencies] -libafl = { path = "../../libafl/", features = [ "std" ] } #, "llmp_small_maps", "llmp_debug"]} +libafl = { path = "../../libafl/", features = [ "std", "llmp_compression" ] } #, "llmp_small_maps", "llmp_debug"]} capstone = "0.8.0" -frida-gum = { version = "0.4", optional = true, features = [ "auto-download", "event-sink", "invocation-listener"] } -frida-gum-sys = { version = "0.2.4", optional = true, features = [ "auto-download", "event-sink", "invocation-listener"] } +frida-gum = { version = "0.4", git = "https://github.com/s1341/frida-rust", features = [ "auto-download", "event-sink", "invocation-listener"] } +#frida-gum = { version = "0.4", path = "../../../frida-rust/frida-gum", features = [ "auto-download", "event-sink", "invocation-listener"] } libafl_frida = { path = "../../libafl_frida", version = "0.1.0" } lazy_static = "1.4.0" libc = "0.2" diff --git a/fuzzers/frida_libpng/harness.cc b/fuzzers/frida_libpng/harness.cc index b5e3e6eda8..625ab3b18f 100644 --- a/fuzzers/frida_libpng/harness.cc +++ b/fuzzers/frida_libpng/harness.cc @@ -89,7 +89,8 @@ __attribute__((noinline)) void func3( char * alloc) { printf("func3\n"); if (random() == 0) { - alloc[0xff] = 0xde; + alloc[0x1ff] = 0xde; + printf("alloc[0x200]: %d\n", alloc[0x200]); } } __attribute__((noinline)) diff --git a/libafl_frida/Cargo.toml b/libafl_frida/Cargo.toml index d5326ef631..15ec573dea 100644 --- a/libafl_frida/Cargo.toml +++ b/libafl_frida/Cargo.toml @@ -20,8 +20,10 @@ libc = "0.2.92" hashbrown = "0.11" libloading = "0.7.0" rangemap = "0.1.10" -frida-gum = { version = "0.4.0", features = [ "auto-download", "backtrace", "event-sink", "invocation-listener"] } -frida-gum-sys = { version = "0.2.4", features = [ "auto-download", "event-sink", "invocation-listener"] } +frida-gum = { version = "0.4.0", git = "https://github.com/s1341/frida-rust", features = [ "auto-download", "backtrace", "event-sink", "invocation-listener"] } +frida-gum-sys = { version = "0.2.4", git = "https://github.com/s1341/frida-rust", features = [ "auto-download", "event-sink", "invocation-listener"] } +#frida-gum = { version = "0.4.0", path = "../../frida-rust/frida-gum", features = [ "auto-download", "backtrace", "event-sink", "invocation-listener"] } +#frida-gum-sys = { version = "0.2.4", path = "../../frida-rust/frida-gum-sys", features = [ "auto-download", "event-sink", "invocation-listener"] } regex = "1.4" dynasmrt = "1.0.1" capstone = "0.8.0" diff --git a/libafl_frida/src/asan_rt.rs b/libafl_frida/src/asan_rt.rs index f1ad2ceda0..5c325a00f1 100644 --- a/libafl_frida/src/asan_rt.rs +++ b/libafl_frida/src/asan_rt.rs @@ -595,6 +595,7 @@ extern "C" { pub struct AsanRuntime { regs: [usize; 32], + blob_report: Option>, blob_check_mem_byte: Option>, blob_check_mem_halfword: Option>, blob_check_mem_dword: Option>, @@ -679,6 +680,7 @@ impl AsanRuntime { pub fn new(options: FridaOptions) -> Rc> { let res = Rc::new(RefCell::new(Self { regs: [0; 32], + blob_report: None, blob_check_mem_byte: None, blob_check_mem_halfword: None, blob_check_mem_dword: None, @@ -1421,113 +1423,12 @@ impl AsanRuntime { } } - /// Generate the instrumentation blobs for the current arch. - #[allow(clippy::similar_names)] // We allow things like dword and qword - fn generate_instrumentation_blobs(&mut self) { + fn generate_shadow_check_blob(&mut self, bit: u32) -> Box<[u8]> { let shadow_bit = Allocator::get().shadow_bit as u32; macro_rules! shadow_check { ($ops:ident, $bit:expr) => {dynasm!($ops ; .arch aarch64 - //; brk #5 - ; b >skip_report - ; report: - ; stp x29, x30, [sp, #-0x10]! - ; mov x29, sp - - ; ldr x0, >self_regs_addr - ; stp x2, x3, [x0, #0x10] - ; stp x4, x5, [x0, #0x20] - ; stp x6, x7, [x0, #0x30] - ; stp x8, x9, [x0, #0x40] - ; stp x10, x11, [x0, #0x50] - ; stp x12, x13, [x0, #0x60] - ; stp x14, x15, [x0, #0x70] - ; stp x16, x17, [x0, #0x80] - ; stp x18, x19, [x0, #0x90] - ; stp x20, x21, [x0, #0xa0] - ; stp x22, x23, [x0, #0xb0] - ; stp x24, x25, [x0, #0xc0] - ; stp x26, x27, [x0, #0xd0] - ; stp x28, x29, [x0, #0xe0] - ; stp x30, xzr, [x0, #0xf0] - ; mov x28, x0 - ; .dword (0xd53b4218u32 as i32) // mrs x24, nzcv - //; ldp x0, x1, [sp], #144 - ; ldp x0, x1, [sp, 0x10] - ; stp x0, x1, [x28] - - ; adr x25, >done - ; str x25, [x28, 0xf8] - - ; adr x25, eh_frame_fde - ; adr x27, >fde_address - ; ldr w26, [x27] - ; cmp w26, #0x0 - ; b.ne >skip_register - ; sub x25, x25, x27 - ; str w25, [x27] - ; ldr x1, >register_frame_func - //; brk #11 - ; blr x1 - ; skip_register: - ; ldr x0, >self_addr - ; ldr x1, >trap_func - ; blr x1 - - ; .dword (0xd51b4218u32 as i32) // msr nzcv, x24 - ; ldr x0, >self_regs_addr - ; ldp x2, x3, [x0, #0x10] - ; ldp x4, x5, [x0, #0x20] - ; ldp x6, x7, [x0, #0x30] - ; ldp x8, x9, [x0, #0x40] - ; ldp x10, x11, [x0, #0x50] - ; ldp x12, x13, [x0, #0x60] - ; ldp x14, x15, [x0, #0x70] - ; ldp x16, x17, [x0, #0x80] - ; ldp x18, x19, [x0, #0x90] - ; ldp x20, x21, [x0, #0xa0] - ; ldp x22, x23, [x0, #0xb0] - ; ldp x24, x25, [x0, #0xc0] - ; ldp x26, x27, [x0, #0xd0] - ; ldp x28, x29, [x0, #0xe0] - ; ldp x30, xzr, [x0, #0xf0] - - ; ldp x29, x30, [sp], #0x10 - ; b >done - ; self_addr: - ; .qword self as *mut _ as *mut c_void as i64 - ; self_regs_addr: - ; .qword &mut self.regs as *mut _ as *mut c_void as i64 - ; trap_func: - ; .qword AsanRuntime::handle_trap as *mut c_void as i64 - ; register_frame_func: - ; .qword __register_frame as *mut c_void as i64 - ; eh_frame_cie: - ; .dword 0x14 - ; .dword 0x00 - ; .dword 0x00527a01 - ; .dword 0x011e7c01 - ; .dword 0x001f0c1b - ; eh_frame_fde: - ; .dword 0x14 - ; .dword 0x18 - ; fde_address: - ; .dword 0x0 // <-- address offset goes here - ; .dword 0x104 - //advance_loc 12 - //def_cfa r29 (x29) at offset 16 - //offset r30 (x30) at cfa-8 - //offset r29 (x29) at cfa-16 - ; .dword 0x1d0c4c00 - ; .dword (0x9d029e10 as u32 as i32) - ; .dword 0x04 - // empty next FDE: - ; .dword 0x0 - ; .dword 0x0 - - ; skip_report: ; mov x1, #1 ; add x1, xzr, x1, lsl #shadow_bit ; add x1, x1, x0, lsr #3 @@ -1539,115 +1440,25 @@ impl AsanRuntime { ; lsr x1, x1, #16 ; lsr x1, x1, x0 ; tbnz x1, #$bit, >done - ; b done + ; nop // will be replaced by b to report ; done: );}; } + let mut ops = dynasmrt::VecAssembler::::new(0); + shadow_check!(ops, bit); + let ops_vec = ops.finalize().unwrap(); + ops_vec[..ops_vec.len() - 4].to_vec().into_boxed_slice() + } + + fn generate_shadow_check_exact_blob(&mut self, val: u32) -> Box<[u8]> { + let shadow_bit = Allocator::get().shadow_bit as u32; macro_rules! shadow_check_exact { ($ops:ident, $val:expr) => {dynasm!($ops ; .arch aarch64 - ; b >skip_report - ; report: - ; stp x29, x30, [sp, #-0x10]! - ; mov x29, sp - - ; ldr x0, >self_regs_addr - ; stp x2, x3, [x0, #0x10] - ; stp x4, x5, [x0, #0x20] - ; stp x6, x7, [x0, #0x30] - ; stp x8, x9, [x0, #0x40] - ; stp x10, x11, [x0, #0x50] - ; stp x12, x13, [x0, #0x60] - ; stp x14, x15, [x0, #0x70] - ; stp x16, x17, [x0, #0x80] - ; stp x18, x19, [x0, #0x90] - ; stp x20, x21, [x0, #0xa0] - ; stp x22, x23, [x0, #0xb0] - ; stp x24, x25, [x0, #0xc0] - ; stp x26, x27, [x0, #0xd0] - ; stp x28, x29, [x0, #0xe0] - ; stp x30, xzr, [x0, #0xf0] - ; mov x28, x0 - ; .dword (0xd53b4218u32 as i32) // mrs x24, nzcv - ; ldp x0, x1, [sp, 0x10] - ; stp x0, x1, [x28] - - ; adr x25, >done - ; add x25, x25, 4 - ; str x25, [x28, 0xf8] - - ; adr x25, eh_frame_fde - ; adr x27, >fde_address - ; ldr w26, [x27] - ; cmp w26, #0x0 - ; b.ne >skip_register - ; sub x25, x25, x27 - ; str w25, [x27] - ; ldr x1, >register_frame_func - //; brk #11 - ; blr x1 - ; skip_register: - ; ldr x0, >self_addr - ; ldr x1, >trap_func - ; blr x1 - - ; .dword (0xd51b4218u32 as i32) // msr nzcv, x24 - ; ldr x0, >self_regs_addr - ; ldp x2, x3, [x0, #0x10] - ; ldp x4, x5, [x0, #0x20] - ; ldp x6, x7, [x0, #0x30] - ; ldp x8, x9, [x0, #0x40] - ; ldp x10, x11, [x0, #0x50] - ; ldp x12, x13, [x0, #0x60] - ; ldp x14, x15, [x0, #0x70] - ; ldp x16, x17, [x0, #0x80] - ; ldp x18, x19, [x0, #0x90] - ; ldp x20, x21, [x0, #0xa0] - ; ldp x22, x23, [x0, #0xb0] - ; ldp x24, x25, [x0, #0xc0] - ; ldp x26, x27, [x0, #0xd0] - ; ldp x28, x29, [x0, #0xe0] - ; ldp x30, xzr, [x0, #0xf0] - - ; ldp x29, x30, [sp], #0x10 - ; b >done - ; self_addr: - ; .qword self as *mut _ as *mut c_void as i64 - ; self_regs_addr: - ; .qword &mut self.regs as *mut _ as *mut c_void as i64 - ; trap_func: - ; .qword AsanRuntime::handle_trap as *mut c_void as i64 - ; register_frame_func: - ; .qword __register_frame as *mut c_void as i64 - ; eh_frame_cie: - ; .dword 0x14 - ; .dword 0x00 - ; .dword 0x00527a01 - ; .dword 0x011e7c01 - ; .dword 0x001f0c1b - ; eh_frame_fde: - ; .dword 0x14 - ; .dword 0x18 - ; fde_address: - ; .dword 0x0 // <-- address offset goes here - ; .dword 0x104 - //advance_loc 12 - //def_cfa r29 (x29) at offset 16 - //offset r30 (x30) at cfa-8 - //offset r29 (x29) at cfa-16 - ; .dword 0x1d0c4c00 - ; .dword (0x9d029e10 as u32 as i32) - ; .dword 0x04 - // empty next FDE: - ; .dword 0x0 - ; .dword 0x0 - - - ; skip_report: ; mov x1, #1 ; add x1, xzr, x1, lsl #shadow_bit ; add x1, x1, x0, lsr #3 @@ -1659,92 +1470,153 @@ impl AsanRuntime { ; lsr x1, x1, #16 ; lsr x1, x1, x0 ; .dword -717536768 // 0xd53b4200 //mrs x0, NZCV - ; and x1, x1, #$val + ; and x1, x1, #$val as u64 ; cmp x1, #$val ; b.eq >done - ; b done + ; nop // will be replaced by b to report ; done: - ; .dword -719633920 //0xd51b4200 // msr nvcz, x0 );}; } - let mut ops_check_mem_byte = - dynasmrt::VecAssembler::::new(0); - shadow_check!(ops_check_mem_byte, 0); - self.blob_check_mem_byte = Some(ops_check_mem_byte.finalize().unwrap().into_boxed_slice()); - - let mut ops_check_mem_halfword = - dynasmrt::VecAssembler::::new(0); - shadow_check!(ops_check_mem_halfword, 1); - self.blob_check_mem_halfword = Some( - ops_check_mem_halfword - .finalize() - .unwrap() - .into_boxed_slice(), - ); - - let mut ops_check_mem_dword = - dynasmrt::VecAssembler::::new(0); - shadow_check!(ops_check_mem_dword, 2); - self.blob_check_mem_dword = - Some(ops_check_mem_dword.finalize().unwrap().into_boxed_slice()); - - let mut ops_check_mem_qword = - dynasmrt::VecAssembler::::new(0); - shadow_check!(ops_check_mem_qword, 3); - self.blob_check_mem_qword = - Some(ops_check_mem_qword.finalize().unwrap().into_boxed_slice()); - - let mut ops_check_mem_16bytes = - dynasmrt::VecAssembler::::new(0); - shadow_check!(ops_check_mem_16bytes, 4); - self.blob_check_mem_16bytes = - Some(ops_check_mem_16bytes.finalize().unwrap().into_boxed_slice()); - - let mut ops_check_mem_3bytes = - dynasmrt::VecAssembler::::new(0); - shadow_check_exact!(ops_check_mem_3bytes, 3); - self.blob_check_mem_3bytes = - Some(ops_check_mem_3bytes.finalize().unwrap().into_boxed_slice()); - - let mut ops_check_mem_6bytes = - dynasmrt::VecAssembler::::new(0); - shadow_check_exact!(ops_check_mem_6bytes, 6); - self.blob_check_mem_6bytes = - Some(ops_check_mem_6bytes.finalize().unwrap().into_boxed_slice()); - - let mut ops_check_mem_12bytes = - dynasmrt::VecAssembler::::new(0); - shadow_check_exact!(ops_check_mem_12bytes, 12); - self.blob_check_mem_12bytes = - Some(ops_check_mem_12bytes.finalize().unwrap().into_boxed_slice()); - - let mut ops_check_mem_24bytes = - dynasmrt::VecAssembler::::new(0); - shadow_check_exact!(ops_check_mem_24bytes, 24); - self.blob_check_mem_24bytes = - Some(ops_check_mem_24bytes.finalize().unwrap().into_boxed_slice()); - - let mut ops_check_mem_32bytes = - dynasmrt::VecAssembler::::new(0); - shadow_check_exact!(ops_check_mem_32bytes, 32); - self.blob_check_mem_32bytes = - Some(ops_check_mem_32bytes.finalize().unwrap().into_boxed_slice()); - - let mut ops_check_mem_48bytes = - dynasmrt::VecAssembler::::new(0); - shadow_check_exact!(ops_check_mem_48bytes, 48); - self.blob_check_mem_48bytes = - Some(ops_check_mem_48bytes.finalize().unwrap().into_boxed_slice()); - - let mut ops_check_mem_64bytes = - dynasmrt::VecAssembler::::new(0); - shadow_check_exact!(ops_check_mem_64bytes, 64); - self.blob_check_mem_64bytes = - Some(ops_check_mem_64bytes.finalize().unwrap().into_boxed_slice()); + let mut ops = dynasmrt::VecAssembler::::new(0); + shadow_check_exact!(ops, val); + let ops_vec = ops.finalize().unwrap(); + ops_vec[..ops_vec.len() - 4].to_vec().into_boxed_slice() } + /// + /// Generate the instrumentation blobs for the current arch. + #[allow(clippy::similar_names)] // We allow things like dword and qword + fn generate_instrumentation_blobs(&mut self) { + let mut ops_report = dynasmrt::VecAssembler::::new(0); + dynasm!(ops_report + ; .arch aarch64 + + ; report: + ; stp x29, x30, [sp, #-0x10]! + ; mov x29, sp + // save the nvcz and the 'return-address'/address of instrumented instruction + ; stp x0, x1, [sp, #-0x10]! + + ; ldr x0, >self_regs_addr + ; stp x2, x3, [x0, #0x10] + ; stp x4, x5, [x0, #0x20] + ; stp x6, x7, [x0, #0x30] + ; stp x8, x9, [x0, #0x40] + ; stp x10, x11, [x0, #0x50] + ; stp x12, x13, [x0, #0x60] + ; stp x14, x15, [x0, #0x70] + ; stp x16, x17, [x0, #0x80] + ; stp x18, x19, [x0, #0x90] + ; stp x20, x21, [x0, #0xa0] + ; stp x22, x23, [x0, #0xb0] + ; stp x24, x25, [x0, #0xc0] + ; stp x26, x27, [x0, #0xd0] + ; stp x28, x29, [x0, #0xe0] + ; stp x30, xzr, [x0, #0xf0] + ; mov x28, x0 + + ; mov x25, x1 // address of instrumented instruction. + ; str x25, [x28, 0xf8] + + ; .dword 0xd53b4218u32 as i32 // mrs x24, nzcv + ; ldp x0, x1, [sp, 0x20] + ; stp x0, x1, [x28] + + ; adr x25, eh_frame_fde + ; adr x27, >fde_address + ; ldr w26, [x27] + ; cmp w26, #0x0 + ; b.ne >skip_register + ; sub x25, x25, x27 + ; str w25, [x27] + ; ldr x1, >register_frame_func + //; brk #11 + ; blr x1 + ; skip_register: + ; ldr x0, >self_addr + ; ldr x1, >trap_func + ; blr x1 + + ; .dword 0xd51b4218u32 as i32 // msr nzcv, x24 + ; ldr x0, >self_regs_addr + ; ldp x2, x3, [x0, #0x10] + ; ldp x4, x5, [x0, #0x20] + ; ldp x6, x7, [x0, #0x30] + ; ldp x8, x9, [x0, #0x40] + ; ldp x10, x11, [x0, #0x50] + ; ldp x12, x13, [x0, #0x60] + ; ldp x14, x15, [x0, #0x70] + ; ldp x16, x17, [x0, #0x80] + ; ldp x18, x19, [x0, #0x90] + ; ldp x20, x21, [x0, #0xa0] + ; ldp x22, x23, [x0, #0xb0] + ; ldp x24, x25, [x0, #0xc0] + ; ldp x26, x27, [x0, #0xd0] + ; ldp x28, x29, [x0, #0xe0] + ; ldp x30, xzr, [x0, #0xf0] + + // restore nzcv. and 'return address' + ; ldp x0, x1, [sp], #0x10 + ; ldp x29, x30, [sp], #0x10 + ; br x1 // go back to the 'return address' + + ; self_addr: + ; .qword self as *mut _ as *mut c_void as i64 + ; self_regs_addr: + ; .qword &mut self.regs as *mut _ as *mut c_void as i64 + ; trap_func: + ; .qword AsanRuntime::handle_trap as *mut c_void as i64 + ; register_frame_func: + ; .qword __register_frame as *mut c_void as i64 + ; eh_frame_cie: + ; .dword 0x14 + ; .dword 0x00 + ; .dword 0x00527a01 + ; .dword 0x011e7c01 + ; .dword 0x001f0c1b + ; eh_frame_fde: + ; .dword 0x14 + ; .dword 0x18 + ; fde_address: + ; .dword 0x0 // <-- address offset goes here + ; .dword 0x104 + //advance_loc 12 + //def_cfa r29 (x29) at offset 16 + //offset r30 (x30) at cfa-8 + //offset r29 (x29) at cfa-16 + ; .dword 0x1d0c4c00 + ; .dword 0x9d029e10 as u32 as i32 + ; .dword 0x04 + // empty next FDE: + ; .dword 0x0 + ; .dword 0x0 + ); + self.blob_report = Some(ops_report.finalize().unwrap().into_boxed_slice()); + + self.blob_check_mem_byte = Some(self.generate_shadow_check_blob(0)); + self.blob_check_mem_halfword = Some(self.generate_shadow_check_blob(1)); + self.blob_check_mem_dword = Some(self.generate_shadow_check_blob(2)); + self.blob_check_mem_qword = Some(self.generate_shadow_check_blob(3)); + self.blob_check_mem_16bytes = Some(self.generate_shadow_check_blob(4)); + + self.blob_check_mem_3bytes = Some(self.generate_shadow_check_exact_blob(3)); + self.blob_check_mem_6bytes = Some(self.generate_shadow_check_exact_blob(6)); + self.blob_check_mem_12bytes = Some(self.generate_shadow_check_exact_blob(12)); + self.blob_check_mem_24bytes = Some(self.generate_shadow_check_exact_blob(24)); + self.blob_check_mem_32bytes = Some(self.generate_shadow_check_exact_blob(32)); + self.blob_check_mem_48bytes = Some(self.generate_shadow_check_exact_blob(48)); + self.blob_check_mem_64bytes = Some(self.generate_shadow_check_exact_blob(64)); + } + + /// Get the blob which implements the report funclet + #[inline] + pub fn blob_report(&self) -> &[u8] { + self.blob_report.as_ref().unwrap() + } /// Get the blob which checks a byte access #[inline] pub fn blob_check_mem_byte(&self) -> &[u8] { diff --git a/libafl_frida/src/helper.rs b/libafl_frida/src/helper.rs index a307a0d3ed..fd9a76830e 100644 --- a/libafl_frida/src/helper.rs +++ b/libafl_frida/src/helper.rs @@ -58,6 +58,7 @@ pub struct FridaInstrumentationHelper<'a> { map: [u8; MAP_SIZE], previous_pc: [u64; 1], current_log_impl: u64, + current_report_impl: u64, /// Transformer that has to be passed to FridaInProcessExecutor transformer: Option>, capstone: Capstone, @@ -205,6 +206,7 @@ impl<'a> FridaInstrumentationHelper<'a> { map: [0u8; MAP_SIZE], previous_pc: [0u64; 1], current_log_impl: 0, + current_report_impl: 0, transformer: None, capstone: Capstone::new() .arm64() @@ -315,7 +317,7 @@ impl<'a> FridaInstrumentationHelper<'a> { #[cfg(target_arch = "aarch64")] #[inline] fn emit_shadow_check( - &self, + &mut self, _address: u64, output: &StalkerOutput, basereg: capstone::RegId, @@ -334,6 +336,22 @@ impl<'a> FridaInstrumentationHelper<'a> { None }; + if self.current_report_impl == 0 + || !writer.can_branch_directly_to(self.current_report_impl) + || !writer.can_branch_directly_between(writer.pc() + 128, self.current_report_impl) + { + let after_report_impl = writer.code_offset() + 2; + + #[cfg(target_arch = "x86_64")] + writer.put_jmp_near_label(after_report_impl); + #[cfg(target_arch = "aarch64")] + writer.put_b_label(after_report_impl); + + self.current_report_impl = writer.pc(); + writer.put_bytes(self.asan_runtime.borrow().blob_report()); + + writer.put_label(after_report_impl); + } //writer.put_brk_imm(1); // Preserve x0, x1: @@ -477,9 +495,23 @@ impl<'a> FridaInstrumentationHelper<'a> { 16 => writer.put_bytes(&self.asan_runtime.borrow().blob_check_mem_16bytes()), 24 => writer.put_bytes(&self.asan_runtime.borrow().blob_check_mem_24bytes()), 32 => writer.put_bytes(&self.asan_runtime.borrow().blob_check_mem_32bytes()), + 48 => writer.put_bytes(&self.asan_runtime.borrow().blob_check_mem_48bytes()), + 64 => writer.put_bytes(&self.asan_runtime.borrow().blob_check_mem_64bytes()), _ => false, }; + // Add the branch to report + //writer.put_brk_imm(0x12); + writer.put_branch_address(self.current_report_impl); + + match width { + 3 | 6 | 12 | 24 | 32 | 48 | 64 => { + let msr_nvcz_x0: u32 = 0xd51b4200; + writer.put_bytes(&msr_nvcz_x0.to_le_bytes()); + } + _ => (), + } + // Restore x0, x1 assert!(writer.put_ldp_reg_reg_reg_offset( Aarch64Register::X0,