tidying up
This commit is contained in:
parent
b4e9890b78
commit
95fff9d740
@ -509,7 +509,7 @@ mod tests {
|
|||||||
use crate::inputs::bytes::BytesInput;
|
use crate::inputs::bytes::BytesInput;
|
||||||
use crate::mutators::{mutation_bitflip, ComposedByMutations, StdScheduledMutator};
|
use crate::mutators::{mutation_bitflip, ComposedByMutations, StdScheduledMutator};
|
||||||
use crate::stages::mutational::StdMutationalStage;
|
use crate::stages::mutational::StdMutationalStage;
|
||||||
use crate::tuples::{tuple_list, tuple_list_type};
|
use crate::tuples::tuple_list;
|
||||||
use crate::utils::StdRand;
|
use crate::utils::StdRand;
|
||||||
|
|
||||||
fn harness<I>(_executor: &dyn Executor<I>, _buf: &[u8]) -> ExitKind {
|
fn harness<I>(_executor: &dyn Executor<I>, _buf: &[u8]) -> ExitKind {
|
||||||
@ -534,7 +534,7 @@ mod tests {
|
|||||||
"main",
|
"main",
|
||||||
harness,
|
harness,
|
||||||
tuple_list!(),
|
tuple_list!(),
|
||||||
Box::new(|_, _| ()),
|
Box::new(|_, _, _, _, _| ()),
|
||||||
&state,
|
&state,
|
||||||
&corpus,
|
&corpus,
|
||||||
&mut event_manager,
|
&mut event_manager,
|
||||||
@ -559,7 +559,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let state_serialized = postcard::to_allocvec(&state).unwrap();
|
let state_serialized = postcard::to_allocvec(&state).unwrap();
|
||||||
let state_deserialized: State<BytesInput, StdRand, tuple_list_type!(), tuple_list_type!()> =
|
let state_deserialized: State<BytesInput, StdRand, ()> =
|
||||||
postcard::from_bytes(state_serialized.as_slice()).unwrap();
|
postcard::from_bytes(state_serialized.as_slice()).unwrap();
|
||||||
assert_eq!(state.executions, state_deserialized.executions);
|
assert_eq!(state.executions, state_deserialized.executions);
|
||||||
|
|
||||||
|
@ -292,6 +292,30 @@ where
|
|||||||
// TODO Custom event fire (dyn CustomEvent or similar)
|
// TODO Custom event fire (dyn CustomEvent or similar)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An eventmgr for tests, and as placeholder if you really don't need an event manager.
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
pub struct NopEventManager<I> {
|
||||||
|
phantom: PhantomData<I>,
|
||||||
|
}
|
||||||
|
impl<I> EventManager<I> for NopEventManager<I>
|
||||||
|
where
|
||||||
|
I: Input,
|
||||||
|
{
|
||||||
|
fn process<C, FT, R>(
|
||||||
|
&mut self,
|
||||||
|
_state: &mut State<I, R, FT>,
|
||||||
|
_corpus: &mut C,
|
||||||
|
) -> Result<usize, AflError>
|
||||||
|
where
|
||||||
|
C: Corpus<I, R>,
|
||||||
|
FT: FeedbacksTuple<I>,
|
||||||
|
R: Rand,
|
||||||
|
{
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Events that may happen
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum LoggerEvent<I>
|
pub enum LoggerEvent<I>
|
||||||
where
|
where
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use alloc::{boxed::Box, vec::Vec};
|
use alloc::boxed::Box;
|
||||||
use core::{ffi::c_void, ptr};
|
use core::{ffi::c_void, ptr};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -15,17 +15,17 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use self::unix_signals::setup_crash_handlers;
|
#[cfg(unix)]
|
||||||
|
use unix_signals as os_signals;
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
use self::os_signals::setup_crash_handlers;
|
||||||
|
|
||||||
/// The (unsafe) pointer to the current inmem input, for the current run.
|
/// The (unsafe) pointer to the current inmem input, for the current run.
|
||||||
/// This is neede for certain non-rust side effects, as well as unix signal handling.
|
/// This is neede for certain non-rust side effects, as well as unix signal handling.
|
||||||
static mut CURRENT_INPUT_PTR: *const c_void = ptr::null();
|
static mut CURRENT_INPUT_PTR: *const c_void = ptr::null();
|
||||||
static mut CURRENT_ON_CRASH_FN: *mut c_void = ptr::null_mut();
|
static mut CURRENT_ON_CRASH_FN: *mut c_void = ptr::null_mut();
|
||||||
|
|
||||||
static mut CORPUS_PTR: *const c_void = ptr::null_mut();
|
|
||||||
static mut STATE_PTR: *const c_void = ptr::null_mut();
|
|
||||||
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> = dyn FnMut(ExitKind, &I, &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);
|
||||||
@ -149,40 +149,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Serialize the current state and corpus during an executiont to bytes.
|
|
||||||
/// This method is needed when the fuzzer run crashes and has to restart.
|
|
||||||
pub fn serialize_state_corpus<C, FT, I, R>(
|
|
||||||
state: &State<I, R, FT>,
|
|
||||||
corpus: &C,
|
|
||||||
) -> Result<Vec<u8>, AflError>
|
|
||||||
where
|
|
||||||
C: Corpus<I, R>,
|
|
||||||
FT: FeedbacksTuple<I>,
|
|
||||||
I: Input,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
let state_bytes = postcard::to_allocvec(&state)?;
|
|
||||||
let corpus_bytes = postcard::to_allocvec(&corpus)?;
|
|
||||||
Ok(postcard::to_allocvec(&(state_bytes, corpus_bytes))?)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Deserialize the state and corpus tuple, previously serialized with `serialize_state_corpus(...)`
|
|
||||||
pub fn deserialize_state_corpus<C, FT, I, R>(
|
|
||||||
state_corpus_serialized: &[u8],
|
|
||||||
) -> Result<(State<I, R, FT>, C), AflError>
|
|
||||||
where
|
|
||||||
C: Corpus<I, R>,
|
|
||||||
FT: FeedbacksTuple<I>,
|
|
||||||
I: Input,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
let tuple: (Vec<u8>, Vec<u8>) = postcard::from_bytes(&state_corpus_serialized)?;
|
|
||||||
Ok((
|
|
||||||
postcard::from_bytes(&tuple.0)?,
|
|
||||||
postcard::from_bytes(&tuple.1)?,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
pub mod unix_signals {
|
pub mod unix_signals {
|
||||||
@ -206,16 +172,19 @@ pub mod unix_signals {
|
|||||||
corpus::Corpus,
|
corpus::Corpus,
|
||||||
engines::State,
|
engines::State,
|
||||||
events::EventManager,
|
events::EventManager,
|
||||||
executors::inmemory::{
|
executors::inmemory::{ExitKind, OnCrashFunction, CURRENT_INPUT_PTR, CURRENT_ON_CRASH_FN},
|
||||||
ExitKind, OnCrashFunction, CORPUS_PTR, CURRENT_INPUT_PTR, CURRENT_ON_CRASH_FN,
|
|
||||||
EVENT_MANAGER_PTR, STATE_PTR,
|
|
||||||
},
|
|
||||||
feedbacks::FeedbacksTuple,
|
feedbacks::FeedbacksTuple,
|
||||||
inputs::Input,
|
inputs::Input,
|
||||||
observers::ObserversTuple,
|
observers::ObserversTuple,
|
||||||
utils::Rand,
|
utils::Rand,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Pointers to values only needed on crash. As the program will not continue after a crash,
|
||||||
|
/// we should (tm) be okay with raw pointers here,
|
||||||
|
static mut CORPUS_PTR: *const c_void = ptr::null_mut();
|
||||||
|
static mut STATE_PTR: *const c_void = ptr::null_mut();
|
||||||
|
static mut EVENT_MANAGER_PTR: *mut c_void = ptr::null_mut();
|
||||||
|
|
||||||
pub unsafe extern "C" fn libaflrs_executor_inmem_handle_crash<EM, C, OT, FT, I, R>(
|
pub unsafe extern "C" fn libaflrs_executor_inmem_handle_crash<EM, C, OT, FT, I, R>(
|
||||||
_sig: c_int,
|
_sig: c_int,
|
||||||
info: siginfo_t,
|
info: siginfo_t,
|
||||||
@ -230,9 +199,10 @@ pub mod unix_signals {
|
|||||||
{
|
{
|
||||||
if CURRENT_INPUT_PTR == ptr::null() {
|
if CURRENT_INPUT_PTR == ptr::null() {
|
||||||
println!(
|
println!(
|
||||||
"We died accessing addr {}, but are not in client...",
|
"We died accessing addr {}, but are not in client... Exiting.",
|
||||||
info.si_addr() as usize
|
info.si_addr() as usize
|
||||||
);
|
);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
@ -274,7 +244,7 @@ pub mod unix_signals {
|
|||||||
{
|
{
|
||||||
dbg!("TIMEOUT/SIGUSR2 received");
|
dbg!("TIMEOUT/SIGUSR2 received");
|
||||||
if CURRENT_INPUT_PTR.is_null() {
|
if CURRENT_INPUT_PTR.is_null() {
|
||||||
dbg!("TIMEOUT or SIGUSR2 happened, but currently not fuzzing.");
|
dbg!("TIMEOUT or SIGUSR2 happened, but currently not fuzzing. Exiting");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -342,33 +312,16 @@ pub mod unix_signals {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//#[cfg(feature = "std")]
|
|
||||||
//#[cfg(unix)]
|
|
||||||
//use unix_signals as os_signals;
|
|
||||||
//#[cfg(feature = "std")]
|
|
||||||
//#[cfg(not(unix))]
|
|
||||||
//compile_error!("InMemoryExecutor not yet supported on this OS");
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
|
|
||||||
use crate::executors::inmemory::InMemoryExecutor;
|
use crate::{
|
||||||
use crate::executors::{Executor, ExitKind};
|
executors::{inmemory::InMemoryExecutor, Executor, ExitKind},
|
||||||
use crate::inputs::{HasTargetBytes, Input, TargetBytes};
|
inputs::NopInput,
|
||||||
use crate::tuples::tuple_list;
|
tuples::tuple_list,
|
||||||
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
#[derive(Clone, Serialize, Deserialize, Debug)]
|
|
||||||
struct NopInput {}
|
|
||||||
impl Input for NopInput {}
|
|
||||||
impl HasTargetBytes for NopInput {
|
|
||||||
fn target_bytes(&self) -> TargetBytes {
|
|
||||||
TargetBytes::Owned(vec![0])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
fn test_harness_fn_nop(_executor: &dyn Executor<NopInput>, buf: &[u8]) -> ExitKind {
|
fn test_harness_fn_nop(_executor: &dyn Executor<NopInput>, buf: &[u8]) -> ExitKind {
|
||||||
@ -383,12 +336,22 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_inmem_exec() {
|
fn test_inmem_exec() {
|
||||||
let mut in_mem_executor = InMemoryExecutor {
|
use crate::{
|
||||||
|
corpus::InMemoryCorpus, events::NopEventManager, inputs::NopInput, utils::StdRand,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut in_mem_executor = InMemoryExecutor::<
|
||||||
|
NopInput,
|
||||||
|
(),
|
||||||
|
InMemoryCorpus<_, _>,
|
||||||
|
NopEventManager<_>,
|
||||||
|
(),
|
||||||
|
StdRand,
|
||||||
|
> {
|
||||||
harness_fn: 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());
|
||||||
|
@ -3,7 +3,6 @@ pub use bytes::BytesInput;
|
|||||||
|
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::{clone::Clone, fmt::Debug};
|
use core::{clone::Clone, fmt::Debug};
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::{
|
use std::{
|
||||||
fs::File,
|
fs::File,
|
||||||
@ -11,6 +10,8 @@ use std::{
|
|||||||
path::Path,
|
path::Path,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::AflError;
|
use crate::AflError;
|
||||||
|
|
||||||
/// An input for the target
|
/// An input for the target
|
||||||
@ -54,6 +55,16 @@ where {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An input for tests, mainly. There is no real use much else.
|
||||||
|
#[derive(Copy, Clone, Serialize, Deserialize, Debug)]
|
||||||
|
pub struct NopInput {}
|
||||||
|
impl Input for NopInput {}
|
||||||
|
impl HasTargetBytes for NopInput {
|
||||||
|
fn target_bytes(&self) -> TargetBytes {
|
||||||
|
TargetBytes::Owned(vec![0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub enum TargetBytes<'a> {
|
pub enum TargetBytes<'a> {
|
||||||
Ref(&'a [u8]),
|
Ref(&'a [u8]),
|
||||||
Owned(Vec<u8>),
|
Owned(Vec<u8>),
|
||||||
|
@ -1,14 +1,51 @@
|
|||||||
//! Utility functions for AFL
|
//! Utility functions for AFL
|
||||||
|
|
||||||
use alloc::rc::Rc;
|
use alloc::vec::Vec;
|
||||||
use core::{cell::RefCell, debug_assert, fmt::Debug, time};
|
use core::{cell::RefCell, debug_assert, fmt::Debug, time};
|
||||||
|
use postcard;
|
||||||
use xxhash_rust::xxh3::xxh3_64_with_seed;
|
use xxhash_rust::xxh3::xxh3_64_with_seed;
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
|
use crate::{corpus::Corpus, engines::State, feedbacks::FeedbacksTuple, inputs::Input, AflError};
|
||||||
|
|
||||||
pub type StdRand = RomuTrioRand;
|
pub type StdRand = RomuTrioRand;
|
||||||
|
|
||||||
|
/// Serialize the current state and corpus during an executiont to bytes.
|
||||||
|
/// This method is needed when the fuzzer run crashes and has to restart.
|
||||||
|
pub fn serialize_state_corpus<C, FT, I, R>(
|
||||||
|
state: &State<I, R, FT>,
|
||||||
|
corpus: &C,
|
||||||
|
) -> Result<Vec<u8>, AflError>
|
||||||
|
where
|
||||||
|
C: Corpus<I, R>,
|
||||||
|
FT: FeedbacksTuple<I>,
|
||||||
|
I: Input,
|
||||||
|
R: Rand,
|
||||||
|
{
|
||||||
|
let state_bytes = postcard::to_allocvec(&state)?;
|
||||||
|
let corpus_bytes = postcard::to_allocvec(&corpus)?;
|
||||||
|
Ok(postcard::to_allocvec(&(state_bytes, corpus_bytes))?)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deserialize the state and corpus tuple, previously serialized with `serialize_state_corpus(...)`
|
||||||
|
pub fn deserialize_state_corpus<C, FT, I, R>(
|
||||||
|
state_corpus_serialized: &[u8],
|
||||||
|
) -> Result<(State<I, R, FT>, C), AflError>
|
||||||
|
where
|
||||||
|
C: Corpus<I, R>,
|
||||||
|
FT: FeedbacksTuple<I>,
|
||||||
|
I: Input,
|
||||||
|
R: Rand,
|
||||||
|
{
|
||||||
|
let tuple: (Vec<u8>, Vec<u8>) = postcard::from_bytes(&state_corpus_serialized)?;
|
||||||
|
Ok((
|
||||||
|
postcard::from_bytes(&tuple.0)?,
|
||||||
|
postcard::from_bytes(&tuple.1)?,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
/// Ways to get random around here
|
/// Ways to get random around here
|
||||||
pub trait Rand: Debug {
|
pub trait Rand: Debug {
|
||||||
// Sets the seed of this Rand
|
// Sets the seed of this Rand
|
||||||
@ -137,12 +174,6 @@ impl Rand for Xoshiro256StarRand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<Rc<RefCell<Self>>> for Xoshiro256StarRand {
|
|
||||||
fn into(self) -> Rc<RefCell<Self>> {
|
|
||||||
Rc::new(RefCell::new(self))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Xoshiro256StarRand {
|
impl Xoshiro256StarRand {
|
||||||
/// Creates a new Xoshiro rand with the given seed
|
/// Creates a new Xoshiro rand with the given seed
|
||||||
pub fn new(seed: u64) -> Self {
|
pub fn new(seed: u64) -> Self {
|
||||||
@ -184,12 +215,6 @@ impl Rand for XorShift64Rand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<Rc<RefCell<Self>>> for XorShift64Rand {
|
|
||||||
fn into(self) -> Rc<RefCell<Self>> {
|
|
||||||
Rc::new(RefCell::new(self))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl XorShift64Rand {
|
impl XorShift64Rand {
|
||||||
/// Creates a new Xoshiro rand with the given seed
|
/// Creates a new Xoshiro rand with the given seed
|
||||||
pub fn new(seed: u64) -> Self {
|
pub fn new(seed: u64) -> Self {
|
||||||
@ -227,12 +252,6 @@ impl Rand for Lehmer64Rand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<Rc<RefCell<Self>>> for Lehmer64Rand {
|
|
||||||
fn into(self) -> Rc<RefCell<Self>> {
|
|
||||||
Rc::new(RefCell::new(self))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Lehmer64Rand {
|
impl Lehmer64Rand {
|
||||||
/// Creates a new Lehmer rand with the given seed
|
/// Creates a new Lehmer rand with the given seed
|
||||||
pub fn new(seed: u64) -> Self {
|
pub fn new(seed: u64) -> Self {
|
||||||
@ -360,13 +379,6 @@ impl Rand for XKCDRand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
impl Into<Rc<RefCell<Self>>> for XKCDRand {
|
|
||||||
fn into(self) -> Rc<RefCell<Self>> {
|
|
||||||
Rc::new(RefCell::new(self))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
impl XKCDRand {
|
impl XKCDRand {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
|
@ -13,10 +13,7 @@ use afl::{
|
|||||||
shmem::{AflShmem, ShMem},
|
shmem::{AflShmem, ShMem},
|
||||||
EventManager, LlmpEventManager, SimpleStats,
|
EventManager, LlmpEventManager, SimpleStats,
|
||||||
},
|
},
|
||||||
executors::{
|
executors::{inmemory::InMemoryExecutor, Executor, ExitKind},
|
||||||
inmemory::{deserialize_state_corpus, serialize_state_corpus, InMemoryExecutor},
|
|
||||||
Executor, ExitKind,
|
|
||||||
},
|
|
||||||
feedbacks::MaxMapFeedback,
|
feedbacks::MaxMapFeedback,
|
||||||
generators::RandPrintablesGenerator,
|
generators::RandPrintablesGenerator,
|
||||||
inputs::BytesInput,
|
inputs::BytesInput,
|
||||||
@ -24,7 +21,7 @@ use afl::{
|
|||||||
observers::StdMapObserver,
|
observers::StdMapObserver,
|
||||||
stages::mutational::StdMutationalStage,
|
stages::mutational::StdMutationalStage,
|
||||||
tuples::tuple_list,
|
tuples::tuple_list,
|
||||||
utils::StdRand,
|
utils::{deserialize_state_corpus, serialize_state_corpus, StdRand},
|
||||||
AflError,
|
AflError,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user