wat
This commit is contained in:
parent
cf7c9cd571
commit
1581993a3f
@ -28,7 +28,7 @@ static mut EVENT_MANAGER_PTR: *mut c_void = ptr::null_mut();
|
|||||||
|
|
||||||
/// The inmem executor harness
|
/// The inmem executor harness
|
||||||
type HarnessFunction<I> = fn(&dyn Executor<I>, &[u8]) -> ExitKind;
|
type HarnessFunction<I> = fn(&dyn Executor<I>, &[u8]) -> ExitKind;
|
||||||
type OnCrashFunction<I, C, EM, FT, R> = fn(ExitKind, &State<I, R, FT>, &C, &mut EM);
|
type OnCrashFunction<I, C, EM, FT, R> = dyn FnMut(ExitKind, &I, &State<I, R, FT>, &C, &mut EM);
|
||||||
|
|
||||||
/// The inmem executor simply calls a target function, then returns afterwards.
|
/// The inmem executor simply calls a target function, then returns afterwards.
|
||||||
pub struct InMemoryExecutor<I, OT, C, E, EM, FT, R>
|
pub struct InMemoryExecutor<I, OT, C, E, EM, FT, R>
|
||||||
@ -44,11 +44,11 @@ where
|
|||||||
/// The name of this executor instance, to address it from other components
|
/// The name of this executor instance, to address it from other components
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
/// The harness function, being executed for each fuzzing loop execution
|
/// The harness function, being executed for each fuzzing loop execution
|
||||||
harness: HarnessFunction<I>,
|
harness_fn: HarnessFunction<I>,
|
||||||
/// The observers, observing each run
|
/// The observers, observing each run
|
||||||
observers: OT,
|
observers: OT,
|
||||||
/// A special function being called right before the process crashes. It may save state to restore fuzzing after respawn.
|
/// A special function being called right before the process crashes. It may save state to restore fuzzing after respawn.
|
||||||
on_crash_fn: OnCrashFunction<I, C, EM, FT, R>,
|
on_crash_fn: Box<OnCrashFunction<I, C, EM, FT, R>>,
|
||||||
|
|
||||||
phantom: PhantomData<E>
|
phantom: PhantomData<E>
|
||||||
}
|
}
|
||||||
@ -70,7 +70,7 @@ where
|
|||||||
CURRENT_ON_CRASH_FN = &mut self.on_crash_fn as *mut _ as *mut c_void;
|
CURRENT_ON_CRASH_FN = &mut self.on_crash_fn as *mut _ as *mut c_void;
|
||||||
CURRENT_INPUT_PTR = input as *const _ as *const c_void;
|
CURRENT_INPUT_PTR = input as *const _ as *const c_void;
|
||||||
}
|
}
|
||||||
let ret = (self.harness)(self, bytes.as_slice());
|
let ret = (self.harness_fn)(self, bytes.as_slice());
|
||||||
unsafe {
|
unsafe {
|
||||||
CURRENT_ON_CRASH_FN = ptr::null_mut();
|
CURRENT_ON_CRASH_FN = ptr::null_mut();
|
||||||
CURRENT_INPUT_PTR = ptr::null();
|
CURRENT_INPUT_PTR = ptr::null();
|
||||||
@ -137,7 +137,8 @@ where
|
|||||||
name: &'static str,
|
name: &'static str,
|
||||||
harness_fn: HarnessFunction<I>,
|
harness_fn: HarnessFunction<I>,
|
||||||
observers: OT,
|
observers: OT,
|
||||||
on_crash_fn: OnCrashFunction<I, C, EM, FT, R>,
|
on_crash_fn: Box<OnCrashFunction<I, C, EM, FT, R>>,
|
||||||
|
_event_mgr: &EM,
|
||||||
) -> Self
|
) -> Self
|
||||||
{
|
{
|
||||||
/*#[cfg(feature = "std")]
|
/*#[cfg(feature = "std")]
|
||||||
@ -149,7 +150,7 @@ where
|
|||||||
}*/
|
}*/
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
harness: harness_fn,
|
harness_fn,
|
||||||
on_crash_fn,
|
on_crash_fn,
|
||||||
observers,
|
observers,
|
||||||
name,
|
name,
|
||||||
@ -160,36 +161,26 @@ where
|
|||||||
|
|
||||||
/// Serialize the current state and corpus during an executiont to bytes.
|
/// Serialize the current state and corpus during an executiont to bytes.
|
||||||
/// This method is needed when the fuzzer run crashes and has to restart.
|
/// This method is needed when the fuzzer run crashes and has to restart.
|
||||||
pub unsafe fn serialize_state_corpus<C, FT, I, OT, R>() -> Result<Vec<u8>, AflError>
|
pub fn serialize_state_corpus<C, FT, I, OT, R>(state: &State<I, R, FT>, corpus: &C) -> Result<Vec<u8>, AflError>
|
||||||
where
|
where
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
OT: ObserversTuple,
|
|
||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
if STATE_PTR.is_null() || CORPUS_PTR.is_null() {
|
|
||||||
return Err(AflError::IllegalState(
|
|
||||||
"State or corpus is not currently set and cannot be serialized in in-mem-executor"
|
|
||||||
.to_string(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
let state: &State<I, R, FT> = (STATE_PTR as *const State<I, R, FT>).as_ref().unwrap();
|
|
||||||
let corpus = (CORPUS_PTR as *mut C).as_ref().unwrap();
|
|
||||||
let state_bytes = postcard::to_allocvec(&state)?;
|
let state_bytes = postcard::to_allocvec(&state)?;
|
||||||
let corpus_bytes = postcard::to_allocvec(&corpus)?;
|
let corpus_bytes = postcard::to_allocvec(&corpus)?;
|
||||||
Ok(postcard::to_allocvec(&(state_bytes, corpus_bytes))?)
|
Ok(postcard::to_allocvec(&(state_bytes, corpus_bytes))?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deserialize the state and corpus tuple, previously serialized with `serialize_state_corpus(...)`
|
/// Deserialize the state and corpus tuple, previously serialized with `serialize_state_corpus(...)`
|
||||||
pub fn deserialize_state_corpus<C, FT, I, OT, R>(
|
pub fn deserialize_state_corpus<C, FT, I, R>(
|
||||||
state_corpus_serialized: &[u8],
|
state_corpus_serialized: &[u8],
|
||||||
) -> Result<(State<I, R, FT>, C), AflError>
|
) -> Result<(State<I, R, FT>, C), AflError>
|
||||||
where
|
where
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
OT: ObserversTuple,
|
|
||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
let tuple: (Vec<u8>, Vec<u8>) = postcard::from_bytes(&state_corpus_serialized)?;
|
let tuple: (Vec<u8>, Vec<u8>) = postcard::from_bytes(&state_corpus_serialized)?;
|
||||||
@ -262,14 +253,13 @@ pub mod unix_signals {
|
|||||||
let state = (EVENT_MANAGER_PTR as *const State<I, R, FT>).as_ref().unwrap();
|
let state = (EVENT_MANAGER_PTR as *const State<I, R, FT>).as_ref().unwrap();
|
||||||
let manager = (EVENT_MANAGER_PTR as *mut EM).as_mut().unwrap();
|
let manager = (EVENT_MANAGER_PTR as *mut EM).as_mut().unwrap();
|
||||||
|
|
||||||
manager.crash(input).expect("Error in sending Crash event");
|
|
||||||
|
|
||||||
if !CURRENT_ON_CRASH_FN.is_null() {
|
if !CURRENT_ON_CRASH_FN.is_null() {
|
||||||
(*(CURRENT_ON_CRASH_FN as *mut OnCrashFunction<I, C, EM, FT, R>))(
|
(*(CURRENT_ON_CRASH_FN as *mut Box<OnCrashFunction<I, C, EM, FT, R>>))(
|
||||||
ExitKind::Crash,
|
ExitKind::Crash,
|
||||||
|
input,
|
||||||
state,
|
state,
|
||||||
corpus,
|
corpus,
|
||||||
manager
|
manager,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,13 +290,10 @@ pub mod unix_signals {
|
|||||||
let state = (EVENT_MANAGER_PTR as *const State<I, R, FT>).as_ref().unwrap();
|
let state = (EVENT_MANAGER_PTR as *const State<I, R, FT>).as_ref().unwrap();
|
||||||
let manager = (EVENT_MANAGER_PTR as *mut EM).as_mut().unwrap();
|
let manager = (EVENT_MANAGER_PTR as *mut EM).as_mut().unwrap();
|
||||||
|
|
||||||
manager
|
|
||||||
.timeout(input)
|
|
||||||
.expect("Error in sending Timeout event");
|
|
||||||
|
|
||||||
if !CURRENT_ON_CRASH_FN.is_null() {
|
if !CURRENT_ON_CRASH_FN.is_null() {
|
||||||
(*(CURRENT_ON_CRASH_FN as *mut OnCrashFunction<I, C, EM, FT, R>))(
|
(*(CURRENT_ON_CRASH_FN as *mut Box<OnCrashFunction<I, C, EM, FT, R>>))(
|
||||||
ExitKind::Timeout,
|
ExitKind::Timeout,
|
||||||
|
input,
|
||||||
state,
|
state,
|
||||||
corpus,
|
corpus,
|
||||||
manager
|
manager
|
||||||
@ -400,10 +387,11 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_inmem_exec() {
|
fn test_inmem_exec() {
|
||||||
let mut in_mem_executor = InMemoryExecutor {
|
let mut in_mem_executor = InMemoryExecutor {
|
||||||
harness: test_harness_fn_nop,
|
harness_fn: test_harness_fn_nop,
|
||||||
on_crash_fn: Box::new(|_, _| ()),
|
on_crash_fn: Box::new(|_, _| ()),
|
||||||
observers: tuple_list!(),
|
observers: tuple_list!(),
|
||||||
name: "main",
|
name: "main",
|
||||||
|
phantom: PhantomData,
|
||||||
};
|
};
|
||||||
let mut input = NopInput {};
|
let mut input = NopInput {};
|
||||||
assert!(in_mem_executor.run_target(&mut input).is_ok());
|
assert!(in_mem_executor.run_target(&mut input).is_ok());
|
||||||
|
@ -15,7 +15,7 @@ use afl::{
|
|||||||
LlmpEventManager, SimpleStats,
|
LlmpEventManager, SimpleStats,
|
||||||
},
|
},
|
||||||
executors::{
|
executors::{
|
||||||
inmemory::{deserialize_state_corpus, InMemoryExecutor},
|
inmemory::{serialize_state_corpus, deserialize_state_corpus, InMemoryExecutor},
|
||||||
Executor, ExitKind,
|
Executor, ExitKind,
|
||||||
},
|
},
|
||||||
feedbacks::MaxMapFeedback,
|
feedbacks::MaxMapFeedback,
|
||||||
@ -140,12 +140,15 @@ fn fuzz(input: Option<Vec<PathBuf>>, broker_port: u16) -> Result<(), AflError> {
|
|||||||
"Libfuzzer",
|
"Libfuzzer",
|
||||||
harness,
|
harness,
|
||||||
tuple_list!(edges_observer),
|
tuple_list!(edges_observer),
|
||||||
Box::new(move |exit_kind, state_corpus_serialized| {
|
Box::new(move |exit_kind, input, state, corpus, mgr| {
|
||||||
|
match exit_kind {
|
||||||
|
ExitKind::Timeout => mgr.timeout(input).expect("Error sending Timeout event for input {:?}", input),
|
||||||
|
ExitKind::Crash => mgr.crash(input).expect("Error sending crash event for input {:?}", input),
|
||||||
|
}
|
||||||
|
let state_corpus_serialized = serialize_state_corpus(state, corpus).unwrap();
|
||||||
sender.send_buf(0x1, &state_corpus_serialized).unwrap();
|
sender.send_buf(0x1, &state_corpus_serialized).unwrap();
|
||||||
}),
|
}),
|
||||||
&state,
|
&mgr,
|
||||||
&corpus,
|
|
||||||
&mut mgr,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut engine = Engine::new(executor);
|
let mut engine = Engine::new(executor);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user