diff --git a/fuzzers/frida_libpng/src/fuzzer.rs b/fuzzers/frida_libpng/src/fuzzer.rs index c6b90170a4..3fb03f922a 100644 --- a/fuzzers/frida_libpng/src/fuzzer.rs +++ b/fuzzers/frida_libpng/src/fuzzer.rs @@ -57,6 +57,7 @@ use libafl_frida::{ helper::{FridaHelper, FridaInstrumentationHelper, MAP_SIZE}, FridaOptions, }; +use libafl_targets::cmplog::{CmpLogObserver, CMPLOG_MAP}; struct FridaInProcessExecutor<'a, 'b, 'c, FH, H, I, OT, S> where @@ -317,6 +318,9 @@ unsafe fn fuzz( &modules_to_instrument, ); + // Create an observation channel using cmplog map + let cmplog_observer = CmpLogObserver::new("cmplog", &mut CMPLOG_MAP, true); + // Create an observation channel using the coverage map let edges_observer = HitcountsMapObserver::new(StdMapObserver::new_from_ptr( "edges", @@ -396,6 +400,7 @@ unsafe fn fuzz( tuple_list!( edges_observer, time_observer, + cmplog_observer, AsanErrorsObserver::new(&ASAN_ERRORS) ), &mut fuzzer, diff --git a/libafl_frida/src/cmplog_rt.rs b/libafl_frida/src/cmplog_rt.rs index 8bd66fac73..48d38bb340 100644 --- a/libafl_frida/src/cmplog_rt.rs +++ b/libafl_frida/src/cmplog_rt.rs @@ -1,80 +1,67 @@ use dynasmrt::{dynasm, DynasmApi, DynasmLabelApi}; +use libafl_targets::cmplog::{ + libafl_cmplog_map, CmpLogHeader, CmpLogMap, CmpLogOperands, CMPLOG_MAP_W, +}; use nix::{ libc::{memmove, memset}, sys::mman::{mmap, MapFlags, ProtFlags}, }; use std::ffi::c_void; -// TODO compile time flag -//pub const CMPLOG_MAP_W: usize = 65536; -pub const CMPLOG_MAP_W: usize = 8000; -pub const CMPLOG_MAP_H: usize = 32; -pub const CMPLOG_MAP_SIZE: usize = CMPLOG_MAP_W * CMPLOG_MAP_H; - -pub const CMPLOG_KIND_INS: u8 = 0; -pub const CMPLOG_KIND_RTN: u8 = 1; - extern crate libafl_targets; extern "C" { - pub fn __sanitizer_cov_trace_cmp8(arg1: u64, arg2: u64); + pub fn libafl_targets_cmplog_wrapper(k: u64, shape: u8, arg1: u64, arg2: u64); } -#[repr(C)] -#[derive(Debug, Clone, Copy)] -pub struct CmpLogHeader { - hits: u16, - shape: u8, - kind: u8, -} +// #[repr(C)] +// #[derive(Debug, Clone, Copy)] +// pub struct CmpLogHeader { +// hits: u16, +// shape: u8, +// kind: u8, +// } -#[repr(C)] -#[derive(Debug, Clone, Copy)] -pub struct CmpLogOperands(u64, u64); +// #[repr(C)] +// #[derive(Debug, Clone, Copy)] +// pub struct CmpLogOperands(u64, u64); -#[repr(C)] -#[derive(Debug, Clone, Copy)] -pub struct CmpLogMap { - headers: [CmpLogHeader; CMPLOG_MAP_W], - operands: [CmpLogOperands; CMPLOG_MAP_W], -} +// #[repr(C)] +// #[derive(Debug, Clone, Copy)] +// pub struct CmpLogMap { +// headers: [CmpLogHeader; CMPLOG_MAP_W], +// operands: [CmpLogOperands; CMPLOG_MAP_W], +// } -#[no_mangle] -pub static mut libafl_cmplog_map: CmpLogMap = CmpLogMap { - headers: [CmpLogHeader { - hits: 0, - shape: 0, - kind: 0, - }; CMPLOG_MAP_W], - operands: [CmpLogOperands(0, 0); CMPLOG_MAP_W], -}; - -pub use libafl_cmplog_map as CMPLOG_MAP; - -#[no_mangle] -pub static mut libafl_cmplog_enabled: u8 = 0; - -pub use libafl_cmplog_enabled as CMPLOG_ENABLED; +// #[no_mangle] +// pub static mut libafl_cmplog_map: CmpLogMap = CmpLogMap { +// headers: [CmpLogHeader { +// hits: 0, +// shape: 0, +// kind: 0, +// }; CMPLOG_MAP_W], +// operands: [CmpLogOperands(0, 0); CMPLOG_MAP_W], +// }; pub struct CmpLogRuntime { - regs: [u64; 2], - cmp_idx: usize, - cmplog_map: CmpLogMap, + regs: [u64; 3], + // cmp_idx: usize, + // cmplog_map: CmpLogMap, ops_save_register_and_blr_to_populate: Option>, } impl CmpLogRuntime { pub fn new() -> CmpLogRuntime { Self { - regs: [0; 2], - cmp_idx: 0, - cmplog_map: CmpLogMap { - headers: [CmpLogHeader { - hits: 0, - shape: 0, - kind: 0, - }; CMPLOG_MAP_W], - operands: [CmpLogOperands(0, 0); CMPLOG_MAP_W], - }, + regs: [0; 3], + // cmp_idx: 0, + // cmplog_map: CmpLogMap { + // headers: [CmpLogHeader { + // hits: 0, + // shape: 0, + // kind: 0, + // }; CMPLOG_MAP_W], + // operands: [CmpLogOperands(0, 0); CMPLOG_MAP_W], + // }, ops_save_register_and_blr_to_populate: None, } } @@ -82,18 +69,33 @@ impl CmpLogRuntime { extern "C" fn populate_lists(&mut self) { let op1 = self.regs[0]; let op2 = self.regs[1]; + let retaddr = self.regs[2]; - self.cmplog_map.headers[self.cmp_idx].hits += 1; - self.cmplog_map.headers[self.cmp_idx].shape = 8; - let cmplog_ops: CmpLogOperands = CmpLogOperands(op1, op2); - self.cmplog_map.operands[self.cmp_idx] = cmplog_ops; - self.cmp_idx += 1; + println!( + "entered populate_lists with: {:#02x}, {:#02x}, {:#02x}", + op1, op2, retaddr + ); + let mut k = (retaddr >> 4) ^ (retaddr << 8); + + k = k & ((CMPLOG_MAP_W as u64) - 1); + + unsafe { + libafl_targets_cmplog_wrapper(k, 8, op1, op2); + } + + println!("returned from c code"); + + // self.cmplog_map.headers[self.cmp_idx].hits += 1; + // self.cmplog_map.headers[self.cmp_idx].shape = 8; + // let cmplog_ops: CmpLogOperands = CmpLogOperands(op1, op2); + // self.cmplog_map.operands[self.cmp_idx] = cmplog_ops; + // self.cmp_idx += 1; } /// Generate the instrumentation blobs for the current arch. fn generate_instrumentation_blobs(&mut self) { macro_rules! blr_to_populate { - ($ops:ident, $bit:expr) => {dynasm!($ops + ($ops:ident) => {dynasm!($ops ; .arch aarch64 ; stp x2, x3, [sp, #-0x10]! ; stp x4, x5, [sp, #-0x10]! @@ -102,28 +104,17 @@ impl CmpLogRuntime { ; stp x10, x11, [sp, #-0x10]! ; stp x12, x13, [sp, #-0x10]! ; stp x14, x15, [sp, #-0x10]! - ; stp x16, x17, [sp, #-0x10]! - ; stp x18, x19, [sp, #-0x10]! - ; stp x20, x21, [sp, #-0x10]! - ; stp x22, x23, [sp, #-0x10]! - ; stp x24, x25, [sp, #-0x10]! - ; stp x26, x27, [sp, #-0x10]! - ; stp x28, x29, [sp, #-0x10]! - ; stp x30, xzr, [sp, #-0x10]! + ; stp x29, x30, [sp, #-0x10]! // jump to rust based population of the lists - // ; ldr x2, >self_regs_addr - // ; stp x0, x1, [x2] - // jump to c implementation of cmplog pupolation - ; ldr x2, >populate_lists - ; blr x2 - ; ldp x30, xzr, [sp], #0x10 - ; ldp x28, x29, [sp], #0x10 - ; ldp x26, x27, [sp], #0x10 - ; ldp x24, x25, [sp], #0x10 - ; ldp x22, x23, [sp], #0x10 - ; ldp x20, x21, [sp], #0x10 - ; ldp x18, x19, [sp], #0x10 - ; ldp x16, x17, [sp], #0x10 + ; ldr x5, >self_regs_addr + ; stp x0, x1, [x5] + ; adr x2, >done + ; str x2, [x5, 0x10] + ; ldr x4, >populate_lists + ; ldr x0, >self_addr + ; blr x4 + // restore the reg state before returning to the caller + ; ldp x29, x30, [sp], #0x10 ; ldp x14, x15, [sp], #0x10 ; ldp x12, x13, [sp], #0x10 ; ldp x10, x11, [sp], #0x10 @@ -132,17 +123,20 @@ impl CmpLogRuntime { ; ldp x4, x5, [sp], #0x10 ; ldp x2, x3, [sp], #0x10 ; b >done + ; self_addr: + ; .qword self as *mut _ as *mut c_void as i64 ; self_regs_addr: //for rust based population of the lists.. ; .qword &mut self.regs as *mut _ as *mut c_void as i64 ; populate_lists: - ; .qword __sanitizer_cov_trace_cmp8 as *mut c_void as i64 + //; .qword __sanitizer_cov_trace_cmp8 as *mut c_void as i64 + ; .qword CmpLogRuntime::populate_lists as *mut c_void as i64 ; done: );}; } let mut ops_save_register_and_blr_to_populate = dynasmrt::VecAssembler::::new(0); - blr_to_populate!(ops_save_register_and_blr_to_populate, 0); + blr_to_populate!(ops_save_register_and_blr_to_populate); self.ops_save_register_and_blr_to_populate = Some( ops_save_register_and_blr_to_populate diff --git a/libafl_targets/src/sancov_cmp.c b/libafl_targets/src/sancov_cmp.c index de795b4e45..3720878fcd 100644 --- a/libafl_targets/src/sancov_cmp.c +++ b/libafl_targets/src/sancov_cmp.c @@ -96,6 +96,12 @@ void __sanitizer_cov_trace_cmp8(uint64_t arg1, uint64_t arg2) { } +#ifdef SANCOV_CMPLOG +void libafl_targets_cmplog_wrapper(uintptr_t k, uint8_t shape, uint64_t arg1, uint64_t arg2){ + return __libafl_targets_cmplog(k, shape, arg1, arg2); +} +#endif + void __sanitizer_cov_trace_switch(uint64_t val, uint64_t *cases) { uintptr_t rt = RETADDR;