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},
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,

View File

@ -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<Box<[u8]>>,
}
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::<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(
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) {
uintptr_t rt = RETADDR;