update cmplog runtime code to work with the cmplog backend implementation

This commit is contained in:
Omree 2021-05-26 18:15:09 +03:00
parent 2a325beeff
commit ac27efb954
3 changed files with 89 additions and 84 deletions

View File

@ -57,6 +57,7 @@ use libafl_frida::{
helper::{FridaHelper, FridaInstrumentationHelper, MAP_SIZE}, helper::{FridaHelper, FridaInstrumentationHelper, MAP_SIZE},
FridaOptions, FridaOptions,
}; };
use libafl_targets::cmplog::{CmpLogObserver, CMPLOG_MAP};
struct FridaInProcessExecutor<'a, 'b, 'c, FH, H, I, OT, S> struct FridaInProcessExecutor<'a, 'b, 'c, FH, H, I, OT, S>
where where
@ -317,6 +318,9 @@ unsafe fn fuzz(
&modules_to_instrument, &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 // Create an observation channel using the coverage map
let edges_observer = HitcountsMapObserver::new(StdMapObserver::new_from_ptr( let edges_observer = HitcountsMapObserver::new(StdMapObserver::new_from_ptr(
"edges", "edges",
@ -396,6 +400,7 @@ unsafe fn fuzz(
tuple_list!( tuple_list!(
edges_observer, edges_observer,
time_observer, time_observer,
cmplog_observer,
AsanErrorsObserver::new(&ASAN_ERRORS) AsanErrorsObserver::new(&ASAN_ERRORS)
), ),
&mut fuzzer, &mut fuzzer,

View File

@ -1,80 +1,67 @@
use dynasmrt::{dynasm, DynasmApi, DynasmLabelApi}; use dynasmrt::{dynasm, DynasmApi, DynasmLabelApi};
use libafl_targets::cmplog::{
libafl_cmplog_map, CmpLogHeader, CmpLogMap, CmpLogOperands, CMPLOG_MAP_W,
};
use nix::{ use nix::{
libc::{memmove, memset}, libc::{memmove, memset},
sys::mman::{mmap, MapFlags, ProtFlags}, sys::mman::{mmap, MapFlags, ProtFlags},
}; };
use std::ffi::c_void; 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 crate libafl_targets;
extern "C" { 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)] // #[repr(C)]
#[derive(Debug, Clone, Copy)] // #[derive(Debug, Clone, Copy)]
pub struct CmpLogHeader { // pub struct CmpLogHeader {
hits: u16, // hits: u16,
shape: u8, // shape: u8,
kind: u8, // kind: u8,
} // }
#[repr(C)] // #[repr(C)]
#[derive(Debug, Clone, Copy)] // #[derive(Debug, Clone, Copy)]
pub struct CmpLogOperands(u64, u64); // pub struct CmpLogOperands(u64, u64);
#[repr(C)] // #[repr(C)]
#[derive(Debug, Clone, Copy)] // #[derive(Debug, Clone, Copy)]
pub struct CmpLogMap { // pub struct CmpLogMap {
headers: [CmpLogHeader; CMPLOG_MAP_W], // headers: [CmpLogHeader; CMPLOG_MAP_W],
operands: [CmpLogOperands; CMPLOG_MAP_W], // operands: [CmpLogOperands; CMPLOG_MAP_W],
} // }
#[no_mangle] // #[no_mangle]
pub static mut libafl_cmplog_map: CmpLogMap = CmpLogMap { // pub static mut libafl_cmplog_map: CmpLogMap = CmpLogMap {
headers: [CmpLogHeader { // headers: [CmpLogHeader {
hits: 0, // hits: 0,
shape: 0, // shape: 0,
kind: 0, // kind: 0,
}; CMPLOG_MAP_W], // }; CMPLOG_MAP_W],
operands: [CmpLogOperands(0, 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;
pub struct CmpLogRuntime { pub struct CmpLogRuntime {
regs: [u64; 2], regs: [u64; 3],
cmp_idx: usize, // cmp_idx: usize,
cmplog_map: CmpLogMap, // cmplog_map: CmpLogMap,
ops_save_register_and_blr_to_populate: Option<Box<[u8]>>, ops_save_register_and_blr_to_populate: Option<Box<[u8]>>,
} }
impl CmpLogRuntime { impl CmpLogRuntime {
pub fn new() -> CmpLogRuntime { pub fn new() -> CmpLogRuntime {
Self { Self {
regs: [0; 2], regs: [0; 3],
cmp_idx: 0, // cmp_idx: 0,
cmplog_map: CmpLogMap { // cmplog_map: CmpLogMap {
headers: [CmpLogHeader { // headers: [CmpLogHeader {
hits: 0, // hits: 0,
shape: 0, // shape: 0,
kind: 0, // kind: 0,
}; CMPLOG_MAP_W], // }; CMPLOG_MAP_W],
operands: [CmpLogOperands(0, 0); CMPLOG_MAP_W], // operands: [CmpLogOperands(0, 0); CMPLOG_MAP_W],
}, // },
ops_save_register_and_blr_to_populate: None, ops_save_register_and_blr_to_populate: None,
} }
} }
@ -82,18 +69,33 @@ impl CmpLogRuntime {
extern "C" fn populate_lists(&mut self) { extern "C" fn populate_lists(&mut self) {
let op1 = self.regs[0]; let op1 = self.regs[0];
let op2 = self.regs[1]; let op2 = self.regs[1];
let retaddr = self.regs[2];
self.cmplog_map.headers[self.cmp_idx].hits += 1; println!(
self.cmplog_map.headers[self.cmp_idx].shape = 8; "entered populate_lists with: {:#02x}, {:#02x}, {:#02x}",
let cmplog_ops: CmpLogOperands = CmpLogOperands(op1, op2); op1, op2, retaddr
self.cmplog_map.operands[self.cmp_idx] = cmplog_ops; );
self.cmp_idx += 1; 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. /// Generate the instrumentation blobs for the current arch.
fn generate_instrumentation_blobs(&mut self) { fn generate_instrumentation_blobs(&mut self) {
macro_rules! blr_to_populate { macro_rules! blr_to_populate {
($ops:ident, $bit:expr) => {dynasm!($ops ($ops:ident) => {dynasm!($ops
; .arch aarch64 ; .arch aarch64
; stp x2, x3, [sp, #-0x10]! ; stp x2, x3, [sp, #-0x10]!
; stp x4, x5, [sp, #-0x10]! ; stp x4, x5, [sp, #-0x10]!
@ -102,28 +104,17 @@ impl CmpLogRuntime {
; stp x10, x11, [sp, #-0x10]! ; stp x10, x11, [sp, #-0x10]!
; stp x12, x13, [sp, #-0x10]! ; stp x12, x13, [sp, #-0x10]!
; stp x14, x15, [sp, #-0x10]! ; stp x14, x15, [sp, #-0x10]!
; stp x16, x17, [sp, #-0x10]! ; stp x29, x30, [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]!
// jump to rust based population of the lists // jump to rust based population of the lists
// ; ldr x2, >self_regs_addr ; ldr x5, >self_regs_addr
// ; stp x0, x1, [x2] ; stp x0, x1, [x5]
// jump to c implementation of cmplog pupolation ; adr x2, >done
; ldr x2, >populate_lists ; str x2, [x5, 0x10]
; blr x2 ; ldr x4, >populate_lists
; ldp x30, xzr, [sp], #0x10 ; ldr x0, >self_addr
; ldp x28, x29, [sp], #0x10 ; blr x4
; ldp x26, x27, [sp], #0x10 // restore the reg state before returning to the caller
; ldp x24, x25, [sp], #0x10 ; ldp x29, x30, [sp], #0x10
; ldp x22, x23, [sp], #0x10
; ldp x20, x21, [sp], #0x10
; ldp x18, x19, [sp], #0x10
; ldp x16, x17, [sp], #0x10
; ldp x14, x15, [sp], #0x10 ; ldp x14, x15, [sp], #0x10
; ldp x12, x13, [sp], #0x10 ; ldp x12, x13, [sp], #0x10
; ldp x10, x11, [sp], #0x10 ; ldp x10, x11, [sp], #0x10
@ -132,17 +123,20 @@ impl CmpLogRuntime {
; ldp x4, x5, [sp], #0x10 ; ldp x4, x5, [sp], #0x10
; ldp x2, x3, [sp], #0x10 ; ldp x2, x3, [sp], #0x10
; b >done ; b >done
; self_addr:
; .qword self as *mut _ as *mut c_void as i64
; self_regs_addr: //for rust based population of the lists.. ; self_regs_addr: //for rust based population of the lists..
; .qword &mut self.regs as *mut _ as *mut c_void as i64 ; .qword &mut self.regs as *mut _ as *mut c_void as i64
; populate_lists: ; 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: ; done:
);}; );};
} }
let mut ops_save_register_and_blr_to_populate = let mut ops_save_register_and_blr_to_populate =
dynasmrt::VecAssembler::<dynasmrt::aarch64::Aarch64Relocation>::new(0); dynasmrt::VecAssembler::<dynasmrt::aarch64::Aarch64Relocation>::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( self.ops_save_register_and_blr_to_populate = Some(
ops_save_register_and_blr_to_populate ops_save_register_and_blr_to_populate

View File

@ -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) { void __sanitizer_cov_trace_switch(uint64_t val, uint64_t *cases) {
uintptr_t rt = RETADDR; uintptr_t rt = RETADDR;