Cmplog routines mutator (#204)
* save * routines in meta * execute passes * fix cmplog rtn pass * clippy
This commit is contained in:
parent
84a9e36acf
commit
5b76c22ea7
@ -443,9 +443,25 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CmpValues::Bytes(_v) => {
|
CmpValues::Bytes(v) => {
|
||||||
// TODO
|
'outer: for i in off..len {
|
||||||
// buffer_copy(input.bytes_mut(), token, 0, 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,6 +188,9 @@ impl CompilerWrapper for ClangWrapper {
|
|||||||
args.push(self.wrapped_cc.clone());
|
args.push(self.wrapped_cc.clone());
|
||||||
}
|
}
|
||||||
args.extend_from_slice(self.base_args.as_slice());
|
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 {
|
for pass in &self.passes {
|
||||||
args.push("-Xclang".into());
|
args.push("-Xclang".into());
|
||||||
args.push("-load".into());
|
args.push("-load".into());
|
||||||
|
@ -247,7 +247,7 @@ bool CmpLogRoutines::hookRtns(Module &M) {
|
|||||||
/* iterate over all functions, bbs and instruction and add suitable calls */
|
/* iterate over all functions, bbs and instruction and add suitable calls */
|
||||||
for (auto &F : M) {
|
for (auto &F : M) {
|
||||||
|
|
||||||
if (!isIgnoreFunction(&F)) continue;
|
if (isIgnoreFunction(&F)) continue;
|
||||||
|
|
||||||
for (auto &BB : F) {
|
for (auto &BB : F) {
|
||||||
|
|
||||||
|
@ -205,3 +205,4 @@ void __cmplog_rtn_llvm_stdstring_stdstring(uint8_t *stdstring1, uint8_t *stdstri
|
|||||||
get_llvm_stdstring(stdstring2));
|
get_llvm_stdstring(stdstring2));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
#define CMPLOG_RTN_LEN 32
|
#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_INS 0
|
||||||
#define CMPLOG_KIND_RTN 1
|
#define CMPLOG_KIND_RTN 1
|
||||||
@ -23,10 +23,10 @@ typedef struct CmpLogHeader {
|
|||||||
uint8_t kind;
|
uint8_t kind;
|
||||||
} CmpLogHeader;
|
} CmpLogHeader;
|
||||||
|
|
||||||
typedef struct CmpLogOperands {
|
typedef struct CmpLogInstruction {
|
||||||
uint64_t v0;
|
uint64_t v0;
|
||||||
uint64_t v1;
|
uint64_t v1;
|
||||||
} CmpLogOperands;
|
} CmpLogInstruction;
|
||||||
|
|
||||||
typedef struct CmpLogRoutine {
|
typedef struct CmpLogRoutine {
|
||||||
uint8_t v0[CMPLOG_RTN_LEN];
|
uint8_t v0[CMPLOG_RTN_LEN];
|
||||||
@ -36,7 +36,7 @@ typedef struct CmpLogRoutine {
|
|||||||
typedef struct CmpLogMap {
|
typedef struct CmpLogMap {
|
||||||
CmpLogHeader headers[CMPLOG_MAP_W];
|
CmpLogHeader headers[CMPLOG_MAP_W];
|
||||||
union {
|
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];
|
CmpLogRoutine routines[CMPLOG_MAP_W][CMPLOG_MAP_RTN_H];
|
||||||
} vals;
|
} vals;
|
||||||
} CmpLogMap;
|
} CmpLogMap;
|
||||||
|
@ -13,6 +13,12 @@ use crate::{CMPLOG_MAP_H, CMPLOG_MAP_W};
|
|||||||
/// The `CmpLog` map size
|
/// The `CmpLog` map size
|
||||||
pub const CMPLOG_MAP_SIZE: usize = CMPLOG_MAP_W * CMPLOG_MAP_H;
|
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
|
/// `CmpLog` instruction kind
|
||||||
pub const CMPLOG_KIND_INS: u8 = 0;
|
pub const CMPLOG_KIND_INS: u8 = 0;
|
||||||
/// `CmpLog` return kind
|
/// `CmpLog` return kind
|
||||||
@ -30,26 +36,31 @@ pub struct CmpLogHeader {
|
|||||||
/// The operands logged during `CmpLog`.
|
/// The operands logged during `CmpLog`.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Default, Debug, Clone, Copy)]
|
#[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.
|
/// A struct containing the `CmpLog` metadata for a `LibAFL` run.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct CmpLogMap {
|
pub struct CmpLogMap {
|
||||||
headers: [CmpLogHeader; CMPLOG_MAP_W],
|
headers: [CmpLogHeader; CMPLOG_MAP_W],
|
||||||
operands: [[CmpLogOperands; CMPLOG_MAP_H]; CMPLOG_MAP_W],
|
vals: CmpLogVals,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for CmpLogMap {
|
impl Default for CmpLogMap {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
unsafe { core::mem::zeroed() }
|
||||||
headers: [CmpLogHeader {
|
|
||||||
hits: 0,
|
|
||||||
shape: 0,
|
|
||||||
kind: 0,
|
|
||||||
}; CMPLOG_MAP_W],
|
|
||||||
operands: [[CmpLogOperands(0, 0); CMPLOG_MAP_H]; CMPLOG_MAP_W],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,50 +74,56 @@ impl CmpMap for CmpLogMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn usable_executions_for(&self, idx: usize) -> usize {
|
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)
|
self.executions_for(idx)
|
||||||
} else {
|
} else {
|
||||||
CMPLOG_MAP_H
|
CMPLOG_MAP_RTN_H
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn values_of(&self, idx: usize, execution: usize) -> CmpValues {
|
fn values_of(&self, idx: usize, execution: usize) -> CmpValues {
|
||||||
if self.headers[idx].kind == CMPLOG_KIND_INS {
|
if self.headers[idx].kind == CMPLOG_KIND_INS {
|
||||||
match self.headers[idx].shape {
|
unsafe {
|
||||||
1 => {
|
match self.headers[idx].shape {
|
||||||
return CmpValues::U8((
|
1 => CmpValues::U8((
|
||||||
self.operands[idx][execution].0 as u8,
|
self.vals.operands[idx][execution].0 as u8,
|
||||||
self.operands[idx][execution].1 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((
|
} else {
|
||||||
self.operands[idx][execution].0 as u16,
|
unsafe {
|
||||||
self.operands[idx][execution].1 as u16,
|
CmpValues::Bytes((
|
||||||
))
|
self.vals.routines[idx][execution].0.to_vec(),
|
||||||
}
|
self.vals.routines[idx][execution].1.to_vec(),
|
||||||
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,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
// TODO bytes
|
|
||||||
CmpValues::Bytes((vec![], vec![]))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset(&mut self) -> Result<(), Error> {
|
fn reset(&mut self) -> Result<(), Error> {
|
||||||
|
// For performance, we reset just the headers
|
||||||
self.headers = unsafe { core::mem::zeroed() };
|
self.headers = unsafe { core::mem::zeroed() };
|
||||||
// self.operands = unsafe { core::mem::zeroed() };
|
// self.vals.operands = unsafe { core::mem::zeroed() };
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -119,7 +136,9 @@ pub static mut libafl_cmplog_map: CmpLogMap = CmpLogMap {
|
|||||||
shape: 0,
|
shape: 0,
|
||||||
kind: 0,
|
kind: 0,
|
||||||
}; CMPLOG_MAP_W],
|
}; 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;
|
pub use libafl_cmplog_map as CMPLOG_MAP;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user