This commit is contained in:
Andrea Fioraldi 2020-12-11 17:08:50 +01:00
parent 60b0b16a60
commit 55c043ec73
6 changed files with 223 additions and 110 deletions

View File

@ -194,7 +194,7 @@ where
C: Corpus<I, R>,
E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple,
EM: EventManager<C, E, I, R>,
EM: EventManager<C, E, OT, FT, I, R>,
{
let mut added = 0;
for _ in 0..num {
@ -234,7 +234,7 @@ where
I: Input,
{
executor: E,
phantom: PhantomData<I>,
phantom: PhantomData<(OT, I)>,
}
impl<E, OT, I> Engine<E, OT, I>
@ -263,24 +263,25 @@ where
}
}
pub trait Fuzzer<EM, E, OT, C, I, R>
pub trait Fuzzer<EM, E, OT, FT, C, I, R>
where
EM: EventManager<C, E, I, R>,
EM: EventManager<C, E, OT, FT, I, R>,
E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple,
FT: FeedbacksTuple<I>,
C: Corpus<I, R>,
I: Input,
R: Rand,
{
fn stages(&self) -> &[Box<dyn Stage<EM, E, OT, C, I, R>>];
fn stages(&self) -> &[Box<dyn Stage<EM, E, OT, FT, C, I, R>>];
fn stages_mut(&mut self) -> &mut Vec<Box<dyn Stage<EM, E, OT, C, I, R>>>;
fn stages_mut(&mut self) -> &mut Vec<Box<dyn Stage<EM, E, OT, FT, C, I, R>>>;
fn add_stage(&mut self, stage: Box<dyn Stage<EM, E, OT, C, I, R>>) {
fn add_stage(&mut self, stage: Box<dyn Stage<EM, E, OT, FT, C, I, R>>) {
self.stages_mut().push(stage);
}
fn fuzz_one<FT>(
fn fuzz_one(
&mut self,
rand: &mut R,
state: &mut State<I, R, FT>,
@ -288,8 +289,6 @@ where
engine: &mut Engine<E, OT, I>,
manager: &mut EM,
) -> Result<usize, AflError>
where
FT: FeedbacksTuple<I>
{
let (_, idx) = corpus.next(rand)?;
@ -301,15 +300,15 @@ where
Ok(idx)
}
fn fuzz_loop<FT>(
fn fuzz_loop(
&mut self,
rand: &mut R,
state: &mut State<I, R, FT>,
corpus: &mut C,
engine: &mut Engine<E, OT, I>,
manager: &mut EM,
) -> Result<(), AflError> where
FT: FeedbacksTuple<I>{
) -> Result<(), AflError>
{
let mut last = current_milliseconds();
loop {
self.fuzz_one(rand, state, corpus, engine, manager)?;
@ -325,41 +324,44 @@ where
}
}
pub struct StdFuzzer<EM, E, OT, C, I, R>
pub struct StdFuzzer<EM, E, OT, FT, C, I, R>
where
EM: EventManager<C, E, I, R>,
EM: EventManager<C, E, OT, FT, I, R>,
E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple,
FT: FeedbacksTuple<I>,
C: Corpus<I, R>,
I: Input,
R: Rand,
{
stages: Vec<Box<dyn Stage<EM, E, OT, C, I, R>>>,
stages: Vec<Box<dyn Stage<EM, E, OT, FT, C, I, R>>>,
}
impl<EM, E, OT, C, I, R> Fuzzer<EM, E, OT, C, I, R> for StdFuzzer<EM, E, OT, C, I, R>
impl<EM, E, OT, FT, C, I, R> Fuzzer<EM, E, OT, FT, C, I, R> for StdFuzzer<EM, E, OT, FT, C, I, R>
where
EM: EventManager<C, E, I, R>,
EM: EventManager<C, E, OT, FT, I, R>,
E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple,
FT: FeedbacksTuple<I>,
C: Corpus<I, R>,
I: Input,
R: Rand,
{
fn stages(&self) -> &[Box<dyn Stage<EM, E, OT, C, I, R>>] {
fn stages(&self) -> &[Box<dyn Stage<EM, E, OT, FT, C, I, R>>] {
&self.stages
}
fn stages_mut(&mut self) -> &mut Vec<Box<dyn Stage<EM, E, OT, C, I, R>>> {
fn stages_mut(&mut self) -> &mut Vec<Box<dyn Stage<EM, E, OT, FT, C, I, R>>> {
&mut self.stages
}
}
impl<EM, E, OT, C, I, R> StdFuzzer<EM, E, OT, C, I, R>
impl<EM, E, OT, FT, C, I, R> StdFuzzer<EM, E, OT, FT, C, I, R>
where
EM: EventManager<C, E, I, R>,
EM: EventManager<C, E, OT, FT, I, R>,
E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple,
FT: FeedbacksTuple<I>,
C: Corpus<I, R>,
I: Input,
R: Rand,
@ -403,8 +405,8 @@ mod tests {
let testcase = Testcase::new(vec![0; 4]).into();
corpus.add(testcase);
let executor = InMemoryExecutor::<BytesInput, _>::new(harness, tuple_list!());
let mut state = State::new();
let executor = InMemoryExecutor::new(harness, tuple_list!());
let mut state = State::<BytesInput, _, _>::new();
let mut events_manager = LoggerEventManager::new(stderr());
let mut engine = Engine::new(executor);

View File

@ -16,11 +16,13 @@ use std::io::Write;
use crate::engines::State;
use crate::executors::Executor;
use crate::observers::ObserversTuple;
use crate::feedbacks::FeedbacksTuple;
use crate::inputs::Input;
use crate::serde_anymap::{Ptr, PtrMut};
use crate::serde_anymap::{SerdeAny, Ptr, PtrMut};
use crate::utils::Rand;
use crate::AflError;
use crate::{corpus::Corpus, serde_anymap::SerdeAny};
use crate::corpus::Corpus;
/// Indicate if an event worked or not
pub enum BrokerEventResult {
@ -33,7 +35,7 @@ pub enum BrokerEventResult {
pub trait ShowStats {}
/// A custom event, for own messages, with own handler.
pub trait CustomEvent<I>: SerdeAny + Serialize
pub trait CustomEvent<I, OT>: SerdeAny + Serialize
where
I: Input,
{
@ -48,9 +50,10 @@ where
/// Events sent around in the library
#[derive(Serialize, Deserialize)]
#[serde(bound = "I: serde::de::DeserializeOwned")]
pub enum Event<'a, I>
pub enum Event<'a, I, OT>
where
I: Input,
OT: ObserversTuple
{
LoadInitial {
sender_id: u64,
@ -59,7 +62,7 @@ where
NewTestcase {
sender_id: u64,
input: Ptr<'a, I>,
observers: PtrMut<'a, crate::observers::observer_serde::NamedSerdeAnyMap>,
observers: PtrMut<'a, OT>,
corpus_count: usize,
},
UpdateStats {
@ -90,14 +93,15 @@ where
Custom {
sender_id: u64,
// TODO: Allow custom events
// custom_event: Box<dyn CustomEvent<I>>,
// custom_event: Box<dyn CustomEvent<I, OT>>,
},
}
impl<'a, I> Event<'a, I>
impl<'a, I, OT> Event<'a, I, OT>
where
I: Input,
//CE: CustomEvent<I>,
OT: ObserversTuple
//CE: CustomEvent<I, OT>,
{
pub fn name(&self) -> &str {
match self {
@ -159,29 +163,31 @@ where
}
}
pub trait EventManager<C, E, I, R>
pub trait EventManager<C, E, OT, FT, I, R>
where
C: Corpus<I, R>,
E: Executor<I>,
OT: ObserversTuple,
FT: FeedbacksTuple<I>,
I: Input,
R: Rand,
{
/// Fire an Event
fn fire<'a>(&mut self, event: Event<'a, I>) -> Result<(), AflError>;
fn fire<'a>(&mut self, event: Event<'a, I, OT>) -> Result<(), AflError>;
/// Lookup for incoming events and process them.
/// Return the number of processes events or an error
fn process(&mut self, state: &mut State<I, R>, corpus: &mut C) -> Result<usize, AflError>;
fn process(&mut self, state: &mut State<I, R, FT>, corpus: &mut C) -> Result<usize, AflError>;
#[inline]
fn on_recv(&self, _state: &mut State<I, R>, _corpus: &mut C) -> Result<(), AflError> {
fn on_recv(&self, _state: &mut State<I, R, FT>, _corpus: &mut C) -> Result<(), AflError> {
// TODO: Better way to move out of testcase, or get ref
//Ok(corpus.add(self.testcase.take().unwrap()))
Ok(())
}
// TODO the broker has a state? do we need to pass state and corpus?
fn handle_in_broker(&mut self, event: &Event<I>) -> Result<BrokerEventResult, AflError> {
fn handle_in_broker(&mut self, event: &Event<I, OT>) -> Result<BrokerEventResult, AflError> {
match event {
Event::LoadInitial {
sender_id: _,
@ -238,8 +244,8 @@ where
fn handle_in_client(
&mut self,
event: Event<I>,
_state: &mut State<I, R>,
event: Event<I, OT>,
_state: &mut State<I, R, FT>,
_corpus: &mut C,
) -> Result<(), AflError> {
match event {
@ -263,7 +269,7 @@ where
}
/*TODO
fn on_recv(&self, state: &mut State<I, R>, _corpus: &mut C) -> Result<(), AflError> {
fn on_recv(&self, state: &mut State<I, R, FT>, _corpus: &mut C) -> Result<(), AflError> {
println!(
"#{}\t exec/s: {}",
state.executions(),
@ -275,10 +281,16 @@ where
*/
#[cfg(feature = "std")]
pub struct LoggerEventManager<C, E, I, R, W>
pub struct LoggerEventManager<C, E, OT, FT, I, R, W>
where
C: Corpus<I, R>,
E: Executor<I>,
OT: ObserversTuple,
FT: FeedbacksTuple<I>,
I: Input,
R: Rand,
W: Write,
//CE: CustomEvent<I>,
//CE: CustomEvent<I, OT>,
{
writer: W,
count: usize,
@ -288,21 +300,23 @@ where
execs_over_sec: u64,
corpus_count: usize,
phantom: PhantomData<(C, E, I, R)>,
phantom: PhantomData<(C, E, OT, FT, I, R)>,
}
#[cfg(feature = "std")]
impl<C, E, I, R, W> EventManager<C, E, I, R> for LoggerEventManager<C, E, I, R, W>
impl<C, E, OT, FT, I, R, W> EventManager<C, E, OT, FT, I, R> for LoggerEventManager<C, E, OT, FT, I, R, W>
where
C: Corpus<I, R>,
E: Executor<I>,
OT: ObserversTuple,
FT: FeedbacksTuple<I>,
I: Input,
R: Rand,
W: Write,
//CE: CustomEvent<I>,
//CE: CustomEvent<I, OT>,
{
#[inline]
fn fire<'a>(&mut self, event: Event<'a, I>) -> Result<(), AflError> {
fn fire<'a>(&mut self, event: Event<'a, I, OT>) -> Result<(), AflError> {
match self.handle_in_broker(&event)? {
BrokerEventResult::Forward => (), //self.handle_in_client(event, state, corpus)?,
// Ignore broker-only events
@ -311,13 +325,13 @@ where
Ok(())
}
fn process(&mut self, _state: &mut State<I, R>, _corpus: &mut C) -> Result<usize, AflError> {
fn process(&mut self, _state: &mut State<I, R, FT>, _corpus: &mut C) -> Result<usize, AflError> {
let c = self.count;
self.count = 0;
Ok(c)
}
fn handle_in_broker(&mut self, event: &Event<I>) -> Result<BrokerEventResult, AflError> {
fn handle_in_broker(&mut self, event: &Event<I, OT>) -> Result<BrokerEventResult, AflError> {
match event {
Event::NewTestcase {
sender_id: _,
@ -377,11 +391,13 @@ where
}
#[cfg(feature = "std")]
impl<C, E, I, R, W> LoggerEventManager<C, E, I, R, W>
impl<C, E, OT, FT, I, R, W> LoggerEventManager<C, E, OT, FT, I, R, W>
where
C: Corpus<I, R>,
I: Input,
E: Executor<I>,
OT: ObserversTuple,
FT: FeedbacksTuple<I>,
R: Rand,
W: Write,
//TODO CE: CustomEvent,
@ -400,16 +416,18 @@ where
/// Eventmanager for multi-processed application
#[cfg(feature = "std")]
pub struct LlmpBrokerEventManager<C, E, I, R>
pub struct LlmpBrokerEventManager<C, E, OT, FT, I, R>
where
C: Corpus<I, R>,
I: Input,
E: Executor<I>,
OT: ObserversTuple,
FT: FeedbacksTuple<I>,
R: Rand,
//CE: CustomEvent<I>,
//CE: CustomEvent<I, OT>,
{
llmp_broker: llmp::LlmpBroker,
phantom: PhantomData<(C, E, I, R)>,
phantom: PhantomData<(C, E, OT, FT, I, R)>,
}
#[cfg(feature = "std")]
@ -424,35 +442,39 @@ const _LLMP_TAG_EVENT_TO_BOTH: llmp::Tag = 0x2B0741;
/// Eventmanager for multi-processed application
#[cfg(feature = "std")]
pub struct LlmpClientEventManager<C, E, I, R>
pub struct LlmpClientEventManager<C, E, OT, FT, I, R>
where
C: Corpus<I, R>,
I: Input,
E: Executor<I>,
OT: ObserversTuple,
FT: FeedbacksTuple<I>,
R: Rand,
//CE: CustomEvent<I>,
//CE: CustomEvent<I, OT>,
{
_llmp_client: llmp::LlmpClient,
phantom: PhantomData<(C, E, I, R)>,
phantom: PhantomData<(C, E, OT, FT, I, R)>,
}
#[cfg(feature = "std")]
impl<C, E, I, R> EventManager<C, E, I, R> for LlmpBrokerEventManager<C, E, I, R>
impl<C, E, OT, FT, I, R> EventManager<C, E, OT, FT, I, R> for LlmpBrokerEventManager<C, E, OT, FT, I, R>
where
C: Corpus<I, R>,
E: Executor<I>,
OT: ObserversTuple,
FT: FeedbacksTuple<I>,
I: Input,
R: Rand,
{
/// Fire an Event
fn fire<'a>(&mut self, event: Event<'a, I>) -> Result<(), AflError> {
fn fire<'a>(&mut self, event: Event<'a, I, OT>) -> Result<(), AflError> {
let serialized = postcard::to_allocvec(&event)?;
self.llmp_broker
.send_buf(LLMP_TAG_EVENT_TO_CLIENT, &serialized)?;
Ok(())
}
fn process(&mut self, _state: &mut State<I, R>, _corpus: &mut C) -> Result<usize, AflError> {
fn process(&mut self, _state: &mut State<I, R, FT>, _corpus: &mut C) -> Result<usize, AflError> {
// TODO: iterators
/*
let mut handled = vec![];
@ -481,13 +503,13 @@ where
Ok(0)
}
fn on_recv(&self, _state: &mut State<I, R>, _corpus: &mut C) -> Result<(), AflError> {
fn on_recv(&self, _state: &mut State<I, R, FT>, _corpus: &mut C) -> Result<(), AflError> {
// TODO: Better way to move out of testcase, or get ref
//Ok(corpus.add(self.testcase.take().unwrap()))
Ok(())
}
fn handle_in_broker(&mut self, event: &Event<I>) -> Result<BrokerEventResult, AflError> {
fn handle_in_broker(&mut self, event: &Event<I, OT>) -> Result<BrokerEventResult, AflError> {
match event {
Event::LoadInitial {
sender_id: _,
@ -542,8 +564,8 @@ where
fn handle_in_client(
&mut self,
event: Event<I>,
/*client: &dyn EventManager<C, E, I, R>,*/ _state: &mut State<I, R>,
event: Event<I, OT>,
_state: &mut State<I, R, FT>,
_corpus: &mut C,
) -> Result<(), AflError> {
match event {
@ -572,17 +594,17 @@ mod tests {
use crate::events::Event;
use crate::inputs::bytes::BytesInput;
use crate::observers::observer_serde::NamedSerdeAnyMap;
use crate::observers::{Observer, StdMapObserver};
use crate::observers::{Observer, StdMapObserver, ObserversTuple};
use crate::tuples::{MatchNameAndType, Named, tuple_list, tuple_list_type};
use crate::serde_anymap::{Ptr, PtrMut};
static mut MAP: [u32; 4] = [0; 4];
#[test]
fn test_event_serde() {
let mut map = NamedSerdeAnyMap::new();
let obv = StdMapObserver::new("test", unsafe { &mut MAP });
map.insert(Box::new(obv), &"key".to_string());
let mut map = tuple_list!(obv);
let i = BytesInput::new(vec![0]);
let e = Event::NewTestcase {
@ -594,19 +616,16 @@ mod tests {
let j = serde_json::to_string(&e).unwrap();
let d: Event<BytesInput> = serde_json::from_str(&j).unwrap();
let d: Event<BytesInput, tuple_list_type!(StdMapObserver<u32>)> = serde_json::from_str(&j).unwrap();
match d {
Event::NewTestcase {
sender_id: _,
input: _,
observers: obs,
observers,
corpus_count: _,
} => {
let o = obs
.as_ref()
.get::<StdMapObserver<u32>>(&"key".to_string())
.unwrap();
assert_eq!("test".to_string(), *o.name());
let o = observers.as_ref().match_name_type::<StdMapObserver<u32>>("test").unwrap();
assert_eq!("test", o.name());
}
_ => panic!("mistmatch".to_string()),
};

View File

@ -19,7 +19,7 @@ pub type MinMapFeedback<T, O> = MapFeedback<T, MinReducer<T>, O>;
/// Feedbacks evaluate the observers.
/// Basically, they reduce the information provided by an observer to a value,
/// indicating the "interestingness" of the last run.
pub trait Feedback<I>: Named
pub trait Feedback<I>: Named + 'static
where
I: Input,
{
@ -39,7 +39,7 @@ where
}
}
pub trait FeedbacksTuple<I>: TupleList + MatchType + MatchNameAndType
pub trait FeedbacksTuple<I>: MatchType + MatchNameAndType
where
I: Input
{
@ -61,7 +61,7 @@ I: Input{
impl<Head, Tail, I> FeedbacksTuple<I> for (Head, Tail) where
Head: Feedback<I>,
Tail: FeedbacksTuple<I>,
Tail: FeedbacksTuple<I> + TupleList,
I: Input
{
fn is_interesting_all<OT: ObserversTuple>(&mut self, input: &I, observers: &OT) -> Result<u32, AflError> {
@ -90,7 +90,7 @@ impl<Head, Tail, I> FeedbacksTuple<I> for (Head, Tail) where
}
/// A Reducer function is used to aggregate values for the novelty search
pub trait Reducer<T>
pub trait Reducer<T>: 'static
where
T: Integer + Copy + 'static,
{

View File

@ -1,8 +1,5 @@
extern crate num;
use alloc::boxed::Box;
use alloc::string::String;
use core::any::Any;
use serde::{Deserialize, Serialize};
use crate::serde_anymap::ArrayMut;
@ -26,21 +23,23 @@ pub trait Observer: Named + 'static {
}
}
pub trait ObserversTuple: TupleList + MatchNameAndType + MatchType + serde::Serialize + serde::de::DeserializeOwned {
pub trait ObserversTuple: MatchNameAndType + MatchType + serde::Serialize + serde::de::DeserializeOwned {
fn reset_all(&mut self) -> Result<(), AflError>;
fn post_exec_all(&mut self) -> Result<(), AflError>;
fn for_each(&self, f: fn(&dyn Observer));
//fn for_each(&self, f: fn(&dyn Observer));
//fn for_each_mut(&mut self, f: fn(&mut dyn Observer));
}
impl ObserversTuple for () {
fn reset_all(&mut self) -> Result<(), AflError> { Ok(()) }
fn post_exec_all(&mut self) -> Result<(), AflError> { Ok(()) }
fn for_each(&self, f: fn(&dyn Observer)) { }
//fn for_each(&self, f: fn(&dyn Observer)) { }
//fn for_each_mut(&mut self, f: fn(&mut dyn Observer)) { }
}
impl<Head, Tail> ObserversTuple for (Head, Tail) where
Head: Observer,
Tail: ObserversTuple,
Head: Observer + serde::Serialize + serde::de::DeserializeOwned,
Tail: ObserversTuple + TupleList,
{
fn reset_all(&mut self) -> Result<(), AflError> {
self.0.reset()?;
@ -52,10 +51,15 @@ impl<Head, Tail> ObserversTuple for (Head, Tail) where
self.1.post_exec_all()
}
fn for_each(&self, f: fn(&dyn Observer)) {
f(self.0);
/*fn for_each(&self, f: fn(&dyn Observer)) {
f(&self.0);
self.1.for_each(f)
}
fn for_each_mut(&mut self, f: fn(&mut dyn Observer)) {
f(&mut self.0);
self.1.for_each_mut(f)
}*/
}
/// A MapObserver observes the static map, as oftentimes used for afl-like coverage information

View File

@ -7,15 +7,16 @@ use crate::events::EventManager;
use crate::executors::{HasObservers, Executor};
use crate::observers::ObserversTuple;
use crate::feedbacks::FeedbacksTuple;
use crate::tuples::{TupleList, MatchType};
use crate::inputs::Input;
use crate::utils::Rand;
use crate::AflError;
/// A stage is one step in the fuzzing process.
/// Multiple stages will be scheduled one by one for each input.
pub trait Stage<EM, E, OT, C, I, R>
pub trait Stage<EM, E, OT, FT, C, I, R>
where
EM: EventManager<C, E, I, R>,
EM: EventManager<C, E, OT, FT, I, R>,
E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple,
FT: FeedbacksTuple<I>,
@ -34,3 +35,84 @@ where
corpus_idx: usize,
) -> Result<(), AflError>;
}
pub trait StagesTuple<EM, E, OT, FT, C, I, R>
where
EM: EventManager<C, E, OT, FT, I, R>,
E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple,
FT: FeedbacksTuple<I>,
C: Corpus<I, R>,
I: Input,
R: Rand,
{
fn perform_all(
&mut self,
rand: &mut R,
state: &mut State<I, R, FT>,
corpus: &mut C,
engine: &mut Engine<E, OT, I>,
manager: &mut EM,
corpus_idx: usize,
) -> Result<(), AflError>;
fn for_each(&self, f: fn(&dyn Stage<EM, E, OT, FT, C, I, R>));
fn for_each_mut(&mut self, f: fn(&mut dyn Stage<EM, E, OT, FT, C, I, R>));
}
impl<EM, E, OT, FT, C, I, R> StagesTuple<EM, E, OT, FT, C, I, R> for ()
where
EM: EventManager<C, E, OT, FT, I, R>,
E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple,
FT: FeedbacksTuple<I>,
C: Corpus<I, R>,
I: Input,
R: Rand,
{
fn perform_all(
&mut self,
rand: &mut R,
state: &mut State<I, R, FT>,
corpus: &mut C,
engine: &mut Engine<E, OT, I>,
manager: &mut EM,
corpus_idx: usize,
) -> Result<(), AflError> { Ok(()) }
fn for_each(&self, f: fn(&dyn Stage<EM, E, OT, FT, C, I, R>)) { }
fn for_each_mut(&mut self, f: fn(&mut dyn Stage<EM, E, OT, FT, C, I, R>)) { }
}
impl<Head, Tail, EM, E, OT, FT, C, I, R> StagesTuple<EM, E, OT, FT, C, I, R> for (Head, Tail) where
Head: Stage<EM, E, OT, FT, C, I, R>,
Tail: StagesTuple<EM, E, OT, FT, C, I, R> + TupleList,
EM: EventManager<C, E, OT, FT, I, R>,
E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple,
FT: FeedbacksTuple<I>,
C: Corpus<I, R>,
I: Input,
R: Rand,
{
fn perform_all(
&mut self,
rand: &mut R,
state: &mut State<I, R, FT>,
corpus: &mut C,
engine: &mut Engine<E, OT, I>,
manager: &mut EM,
corpus_idx: usize,
) -> Result<(), AflError> {
self.0.perform(rand, state, corpus, engine, manager, corpus_idx)?;
self.1.perform_all(rand, state, corpus, engine, manager, corpus_idx)
}
fn for_each(&self, f: fn(&dyn Stage<EM, E, OT, FT, C, I, R>)) {
f(&self.0);
self.1.for_each(f)
}
fn for_each_mut(&mut self, f: fn(&mut dyn Stage<EM, E, OT, FT, C, I, R>)) {
f(&mut self.0);
self.1.for_each_mut(f)
}
}

View File

@ -1,8 +1,9 @@
use core::marker::PhantomData;
use crate::events::EventManager;
use crate::executors::Executor;
use crate::executors::{HasObservers, Executor};
use crate::observers::ObserversTuple;
use crate::feedbacks::FeedbacksTuple;
use crate::inputs::Input;
use crate::mutators::Mutator;
use crate::stages::Corpus;
@ -18,12 +19,13 @@ use crate::serde_anymap::{Ptr, PtrMut};
/// A Mutational stage is the stage in a fuzzing run that mutates inputs.
/// Mutational stages will usually have a range of mutations that are
/// being applied to the input one by one, between executions.
pub trait MutationalStage<M, EM, E, OT, C, I, R>: Stage<EM, E, OT, C, I, R>
pub trait MutationalStage<M, EM, E, OT, FT, C, I, R>: Stage<EM, E, OT, FT, C, I, R>
where
M: Mutator<C, I, R>,
EM: EventManager<C, E, I, R>,
E: Executor<I, OT>,
EM: EventManager<C, E, OT, FT, I, R>,
E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple,
FT: FeedbacksTuple<I>,
C: Corpus<I, R>,
I: Input,
R: Rand,
@ -45,9 +47,9 @@ where
fn perform_mutational(
&mut self,
rand: &mut R,
state: &mut State<I, R>,
state: &mut State<I, R, FT>,
corpus: &mut C,
engine: &mut Engine<E, I>,
engine: &mut Engine<E, OT, I>,
manager: &mut EM,
corpus_idx: usize,
) -> Result<(), AflError> {
@ -84,26 +86,28 @@ where
}
/// The default mutational stage
pub struct StdMutationalStage<M, EM, E, OT, C, I, R>
pub struct StdMutationalStage<M, EM, E, OT, FT, C, I, R>
where
M: Mutator<C, I, R>,
EM: EventManager<C, E, I, R>,
E: Executor<I, OT>,
EM: EventManager<C, E, OT, FT, I, R>,
E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple,
FT: FeedbacksTuple<I>,
C: Corpus<I, R>,
I: Input,
R: Rand,
{
mutator: M,
phantom: PhantomData<(EM, E, OT, C, I, R)>,
phantom: PhantomData<(EM, E, OT, FT, C, I, R)>,
}
impl<M, EM, E, OT, C, I, R> MutationalStage<M, EM, E, OT, C, I, R> for StdMutationalStage<M, EM, E, OT, C, I, R>
impl<M, EM, E, OT, FT, C, I, R> MutationalStage<M, EM, E, OT, FT, C, I, R> for StdMutationalStage<M, EM, E, OT, FT, C, I, R>
where
M: Mutator<C, I, R>,
EM: EventManager<C, E, I, R>,
E: Executor<I, OT>,
EM: EventManager<C, E, OT, FT, I, R>,
E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple,
FT: FeedbacksTuple<I>,
C: Corpus<I, R>,
I: Input,
R: Rand,
@ -121,12 +125,13 @@ where
}
}
impl<M, EM, E, OT, C, I, R> Stage<EM, E, OT, C, I, R> for StdMutationalStage<M, EM, E, OT, C, I, R>
impl<M, EM, E, OT, FT, C, I, R> Stage<EM, E, OT, FT, C, I, R> for StdMutationalStage<M, EM, E, OT, FT, C, I, R>
where
M: Mutator<C, I, R>,
EM: EventManager<C, E, I, R>,
E: Executor<I, OT>,
EM: EventManager<C, E, OT, FT, I, R>,
E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple,
FT: FeedbacksTuple<I>,
C: Corpus<I, R>,
I: Input,
R: Rand,
@ -135,9 +140,9 @@ where
fn perform(
&mut self,
rand: &mut R,
state: &mut State<I, R>,
state: &mut State<I, R, FT>,
corpus: &mut C,
engine: &mut Engine<E, I>,
engine: &mut Engine<E, OT, I>,
manager: &mut EM,
corpus_idx: usize,
) -> Result<(), AflError> {
@ -145,12 +150,13 @@ where
}
}
impl<M, EM, E, OT, C, I, R> StdMutationalStage<M, EM, E, OT, C, I, R>
impl<M, EM, E, OT, FT, C, I, R> StdMutationalStage<M, EM, E, OT, FT, C, I, R>
where
M: Mutator<C, I, R>,
EM: EventManager<C, E, I, R>,
E: Executor<I, OT>,
EM: EventManager<C, E, OT, FT, I, R>,
E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple,
FT: FeedbacksTuple<I>,
C: Corpus<I, R>,
I: Input,
R: Rand,