Cmplog routines mutator (#204)

* save

* routines in meta

* execute passes

* fix cmplog rtn pass

* clippy
This commit is contained in:
Andrea Fioraldi 2021-07-05 09:54:44 +02:00 committed by GitHub
parent 84a9e36acf
commit 5b76c22ea7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 90 additions and 51 deletions

View File

@ -443,9 +443,25 @@ where
}
}
}
CmpValues::Bytes(_v) => {
// TODO
// buffer_copy(input.bytes_mut(), token, 0, off, len);
CmpValues::Bytes(v) => {
'outer: for i in off..len {
let mut size = core::cmp::min(v.0.len(), len - i);
while size != 0 {
if v.0[0..size] == input.bytes()[i..i + size] {
buffer_copy(input.bytes_mut(), &v.1, 0, i, size);
break 'outer;
}
size -= 1;
}
size = core::cmp::min(v.1.len(), len - i);
while size != 0 {
if v.1[0..size] == input.bytes()[i..i + size] {
buffer_copy(input.bytes_mut(), &v.0, 0, i, size);
break 'outer;
}
size -= 1;
}
}
}
}

View File

@ -188,6 +188,9 @@ impl CompilerWrapper for ClangWrapper {
args.push(self.wrapped_cc.clone());
}
args.extend_from_slice(self.base_args.as_slice());
if !self.passes.is_empty() {
args.push("-fno-experimental-new-pass-manager".into());
}
for pass in &self.passes {
args.push("-Xclang".into());
args.push("-load".into());

View File

@ -247,7 +247,7 @@ bool CmpLogRoutines::hookRtns(Module &M) {
/* iterate over all functions, bbs and instruction and add suitable calls */
for (auto &F : M) {
if (!isIgnoreFunction(&F)) continue;
if (isIgnoreFunction(&F)) continue;
for (auto &BB : F) {

View File

@ -205,3 +205,4 @@ void __cmplog_rtn_llvm_stdstring_stdstring(uint8_t *stdstring1, uint8_t *stdstri
get_llvm_stdstring(stdstring2));
}

View File

@ -12,7 +12,7 @@
#define CMPLOG_RTN_LEN 32
#define CMPLOG_MAP_RTN_H ((CMPLOG_MAP_H * sizeof(CmpLogOperands)) / sizeof(CmpLogRoutine))
#define CMPLOG_MAP_RTN_H ((CMPLOG_MAP_H * sizeof(CmpLogInstruction)) / sizeof(CmpLogRoutine))
#define CMPLOG_KIND_INS 0
#define CMPLOG_KIND_RTN 1
@ -23,10 +23,10 @@ typedef struct CmpLogHeader {
uint8_t kind;
} CmpLogHeader;
typedef struct CmpLogOperands {
typedef struct CmpLogInstruction {
uint64_t v0;
uint64_t v1;
} CmpLogOperands;
} CmpLogInstruction;
typedef struct CmpLogRoutine {
uint8_t v0[CMPLOG_RTN_LEN];
@ -36,7 +36,7 @@ typedef struct CmpLogRoutine {
typedef struct CmpLogMap {
CmpLogHeader headers[CMPLOG_MAP_W];
union {
CmpLogOperands operands[CMPLOG_MAP_W][CMPLOG_MAP_H];
CmpLogInstruction operands[CMPLOG_MAP_W][CMPLOG_MAP_H];
CmpLogRoutine routines[CMPLOG_MAP_W][CMPLOG_MAP_RTN_H];
} vals;
} CmpLogMap;

View File

@ -13,6 +13,12 @@ use crate::{CMPLOG_MAP_H, CMPLOG_MAP_W};
/// The `CmpLog` map size
pub const CMPLOG_MAP_SIZE: usize = CMPLOG_MAP_W * CMPLOG_MAP_H;
/// The size of a logged routine argument in bytes
pub const CMPLOG_RTN_LEN: usize = 32;
pub const CMPLOG_MAP_RTN_H: usize = (CMPLOG_MAP_H * core::mem::size_of::<CmpLogInstruction>())
/ core::mem::size_of::<CmpLogRoutine>();
/// `CmpLog` instruction kind
pub const CMPLOG_KIND_INS: u8 = 0;
/// `CmpLog` return kind
@ -30,26 +36,31 @@ pub struct CmpLogHeader {
/// The operands logged during `CmpLog`.
#[repr(C)]
#[derive(Default, Debug, Clone, Copy)]
pub struct CmpLogOperands(u64, u64);
pub struct CmpLogInstruction(u64, u64);
/// The routine arguments logged during `CmpLog`.
#[repr(C)]
#[derive(Default, Debug, Clone, Copy)]
pub struct CmpLogRoutine([u8; CMPLOG_RTN_LEN], [u8; CMPLOG_RTN_LEN]);
#[repr(C)]
#[derive(Clone, Copy)]
pub union CmpLogVals {
operands: [[CmpLogInstruction; CMPLOG_MAP_H]; CMPLOG_MAP_W],
routines: [[CmpLogRoutine; CMPLOG_MAP_RTN_H]; CMPLOG_MAP_W],
}
/// A struct containing the `CmpLog` metadata for a `LibAFL` run.
#[repr(C)]
#[derive(Debug, Clone, Copy)]
#[derive(Clone, Copy)]
pub struct CmpLogMap {
headers: [CmpLogHeader; CMPLOG_MAP_W],
operands: [[CmpLogOperands; CMPLOG_MAP_H]; CMPLOG_MAP_W],
vals: CmpLogVals,
}
impl Default for CmpLogMap {
fn default() -> Self {
Self {
headers: [CmpLogHeader {
hits: 0,
shape: 0,
kind: 0,
}; CMPLOG_MAP_W],
operands: [[CmpLogOperands(0, 0); CMPLOG_MAP_H]; CMPLOG_MAP_W],
}
unsafe { core::mem::zeroed() }
}
}
@ -63,50 +74,56 @@ impl CmpMap for CmpLogMap {
}
fn usable_executions_for(&self, idx: usize) -> usize {
if self.executions_for(idx) < CMPLOG_MAP_H {
if self.headers[idx].kind == CMPLOG_KIND_INS {
if self.executions_for(idx) < CMPLOG_MAP_H {
self.executions_for(idx)
} else {
CMPLOG_MAP_H
}
} else if self.executions_for(idx) < CMPLOG_MAP_RTN_H {
self.executions_for(idx)
} else {
CMPLOG_MAP_H
CMPLOG_MAP_RTN_H
}
}
fn values_of(&self, idx: usize, execution: usize) -> CmpValues {
if self.headers[idx].kind == CMPLOG_KIND_INS {
match self.headers[idx].shape {
1 => {
return CmpValues::U8((
self.operands[idx][execution].0 as u8,
self.operands[idx][execution].1 as u8,
))
unsafe {
match self.headers[idx].shape {
1 => CmpValues::U8((
self.vals.operands[idx][execution].0 as u8,
self.vals.operands[idx][execution].1 as u8,
)),
2 => CmpValues::U16((
self.vals.operands[idx][execution].0 as u16,
self.vals.operands[idx][execution].1 as u16,
)),
4 => CmpValues::U32((
self.vals.operands[idx][execution].0 as u32,
self.vals.operands[idx][execution].1 as u32,
)),
8 => CmpValues::U64((
self.vals.operands[idx][execution].0 as u64,
self.vals.operands[idx][execution].1 as u64,
)),
other => panic!("Invalid CmpLog shape {}", other),
}
2 => {
return CmpValues::U16((
self.operands[idx][execution].0 as u16,
self.operands[idx][execution].1 as u16,
))
}
4 => {
return CmpValues::U32((
self.operands[idx][execution].0 as u32,
self.operands[idx][execution].1 as u32,
))
}
8 => {
return CmpValues::U64((
self.operands[idx][execution].0 as u64,
self.operands[idx][execution].1 as u64,
))
}
_ => {}
};
}
} else {
unsafe {
CmpValues::Bytes((
self.vals.routines[idx][execution].0.to_vec(),
self.vals.routines[idx][execution].1.to_vec(),
))
}
}
// TODO bytes
CmpValues::Bytes((vec![], vec![]))
}
fn reset(&mut self) -> Result<(), Error> {
// For performance, we reset just the headers
self.headers = unsafe { core::mem::zeroed() };
// self.operands = unsafe { core::mem::zeroed() };
// self.vals.operands = unsafe { core::mem::zeroed() };
Ok(())
}
}
@ -119,7 +136,9 @@ pub static mut libafl_cmplog_map: CmpLogMap = CmpLogMap {
shape: 0,
kind: 0,
}; CMPLOG_MAP_W],
operands: [[CmpLogOperands(0, 0); CMPLOG_MAP_H]; CMPLOG_MAP_W],
vals: CmpLogVals {
operands: [[CmpLogInstruction(0, 0); CMPLOG_MAP_H]; CMPLOG_MAP_W],
},
};
pub use libafl_cmplog_map as CMPLOG_MAP;