additional executors

This commit is contained in:
Andrea Fioraldi 2020-12-11 21:57:29 +01:00
parent 6d844e1fa3
commit 299634ccce
8 changed files with 156 additions and 73 deletions

View File

@ -7,12 +7,13 @@ use hashbrown::HashMap;
use crate::corpus::{Corpus, Testcase}; use crate::corpus::{Corpus, Testcase};
use crate::events::{Event, EventManager}; use crate::events::{Event, EventManager};
use crate::executors::{Executor, HasObservers}; use crate::executors::{Executor, ExecutorsTuple, HasObservers};
use crate::feedbacks::FeedbacksTuple; use crate::feedbacks::FeedbacksTuple;
use crate::generators::Generator; use crate::generators::Generator;
use crate::inputs::Input; use crate::inputs::Input;
use crate::observers::ObserversTuple; use crate::observers::ObserversTuple;
use crate::stages::StagesTuple; use crate::stages::StagesTuple;
use crate::tuples::{tuple_list, tuple_list_type};
use crate::utils::{current_milliseconds, Rand}; use crate::utils::{current_milliseconds, Rand};
use crate::AflError; use crate::AflError;
@ -179,12 +180,12 @@ where
} }
} }
pub fn generate_initial_inputs<G, C, E, OT, EM>( pub fn generate_initial_inputs<G, C, E, OT, ET, EM>(
&mut self, &mut self,
rand: &mut R, rand: &mut R,
corpus: &mut C, corpus: &mut C,
generator: &mut G, generator: &mut G,
engine: &mut Engine<E, OT, I>, engine: &mut Engine<E, OT, ET, I>,
manager: &mut EM, manager: &mut EM,
num: usize, num: usize,
) -> Result<(), AflError> ) -> Result<(), AflError>
@ -193,6 +194,7 @@ where
C: Corpus<I, R>, C: Corpus<I, R>,
E: Executor<I> + HasObservers<OT>, E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple, OT: ObserversTuple,
ET: ExecutorsTuple<I>,
EM: EventManager<C, E, OT, FT, I, R>, EM: EventManager<C, E, OT, FT, I, R>,
{ {
let mut added = 0; let mut added = 0;
@ -226,49 +228,71 @@ where
} }
} }
pub struct Engine<E, OT, I> pub struct Engine<E, OT, ET, I>
where where
E: Executor<I> + HasObservers<OT>, E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple, OT: ObserversTuple,
ET: ExecutorsTuple<I>,
I: Input, I: Input,
{ {
executor: E, main_executor: E,
additional_executors: ET,
phantom: PhantomData<(OT, I)>, phantom: PhantomData<(OT, I)>,
} }
impl<E, OT, I> Engine<E, OT, I> impl<E, OT, ET, I> Engine<E, OT, ET, I>
where where
E: Executor<I> + HasObservers<OT>, E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple, OT: ObserversTuple,
ET: ExecutorsTuple<I>,
I: Input, I: Input,
{ {
/// Return the executor /// Return the executor
pub fn executor(&self) -> &E { pub fn executor(&self) -> &E {
&self.executor &self.main_executor
} }
/// Return the executor (mutable) /// Return the executor (mutable)
pub fn executor_mut(&mut self) -> &mut E { pub fn executor_mut(&mut self) -> &mut E {
&mut self.executor &mut self.main_executor
} }
// TODO additional executors, Vec<Box<dyn Executor<I>>> pub fn additional_executors(&self) -> &ET {
&self.additional_executors
}
pub fn new(executor: E) -> Self { pub fn additional_executors_mut(&mut self) -> &mut ET {
&mut self.additional_executors
}
pub fn with_executors(main_executor: E, additional_executors: ET) -> Self {
Self { Self {
executor: executor, main_executor: main_executor,
additional_executors: additional_executors,
phantom: PhantomData, phantom: PhantomData,
} }
} }
} }
pub trait Fuzzer<ST, EM, E, OT, FT, C, I, R> impl<E, OT, I> Engine<E, OT, tuple_list_type!(), I>
where where
ST: StagesTuple<EM, E, OT, FT, C, I, R>, E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple,
I: Input,
{
pub fn new(main_executor: E) -> Self {
Self::with_executors(main_executor, tuple_list!())
}
}
pub trait Fuzzer<ST, EM, E, OT, FT, ET, C, I, R>
where
ST: StagesTuple<EM, E, OT, FT, ET, C, I, R>,
EM: EventManager<C, E, OT, FT, I, R>, EM: EventManager<C, E, OT, FT, I, R>,
E: Executor<I> + HasObservers<OT>, E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple, OT: ObserversTuple,
FT: FeedbacksTuple<I>, FT: FeedbacksTuple<I>,
ET: ExecutorsTuple<I>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input, I: Input,
R: Rand, R: Rand,
@ -282,7 +306,7 @@ where
rand: &mut R, rand: &mut R,
state: &mut State<I, R, FT>, state: &mut State<I, R, FT>,
corpus: &mut C, corpus: &mut C,
engine: &mut Engine<E, OT, I>, engine: &mut Engine<E, OT, ET, I>,
manager: &mut EM, manager: &mut EM,
) -> Result<usize, AflError> { ) -> Result<usize, AflError> {
let (_, idx) = corpus.next(rand)?; let (_, idx) = corpus.next(rand)?;
@ -299,7 +323,7 @@ where
rand: &mut R, rand: &mut R,
state: &mut State<I, R, FT>, state: &mut State<I, R, FT>,
corpus: &mut C, corpus: &mut C,
engine: &mut Engine<E, OT, I>, engine: &mut Engine<E, OT, ET, I>,
manager: &mut EM, manager: &mut EM,
) -> Result<(), AflError> { ) -> Result<(), AflError> {
let mut last = current_milliseconds(); let mut last = current_milliseconds();
@ -317,29 +341,31 @@ where
} }
} }
pub struct StdFuzzer<ST, EM, E, OT, FT, C, I, R> pub struct StdFuzzer<ST, EM, E, OT, FT, ET, C, I, R>
where where
ST: StagesTuple<EM, E, OT, FT, C, I, R>, ST: StagesTuple<EM, E, OT, FT, ET, C, I, R>,
EM: EventManager<C, E, OT, FT, I, R>, EM: EventManager<C, E, OT, FT, I, R>,
E: Executor<I> + HasObservers<OT>, E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple, OT: ObserversTuple,
FT: FeedbacksTuple<I>, FT: FeedbacksTuple<I>,
ET: ExecutorsTuple<I>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input, I: Input,
R: Rand, R: Rand,
{ {
stages: ST, stages: ST,
phantom: PhantomData<(EM, E, OT, FT, C, I, R)>, phantom: PhantomData<(EM, E, OT, FT, ET, C, I, R)>,
} }
impl<ST, EM, E, OT, FT, C, I, R> Fuzzer<ST, EM, E, OT, FT, C, I, R> impl<ST, EM, E, OT, FT, ET, C, I, R> Fuzzer<ST, EM, E, OT, FT, ET, C, I, R>
for StdFuzzer<ST, EM, E, OT, FT, C, I, R> for StdFuzzer<ST, EM, E, OT, FT, ET, C, I, R>
where where
ST: StagesTuple<EM, E, OT, FT, C, I, R>, ST: StagesTuple<EM, E, OT, FT, ET, C, I, R>,
EM: EventManager<C, E, OT, FT, I, R>, EM: EventManager<C, E, OT, FT, I, R>,
E: Executor<I> + HasObservers<OT>, E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple, OT: ObserversTuple,
FT: FeedbacksTuple<I>, FT: FeedbacksTuple<I>,
ET: ExecutorsTuple<I>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input, I: Input,
R: Rand, R: Rand,
@ -353,13 +379,14 @@ where
} }
} }
impl<ST, EM, E, OT, FT, C, I, R> StdFuzzer<ST, EM, E, OT, FT, C, I, R> impl<ST, EM, E, OT, FT, ET, C, I, R> StdFuzzer<ST, EM, E, OT, FT, ET, C, I, R>
where where
ST: StagesTuple<EM, E, OT, FT, C, I, R>, ST: StagesTuple<EM, E, OT, FT, ET, C, I, R>,
EM: EventManager<C, E, OT, FT, I, R>, EM: EventManager<C, E, OT, FT, I, R>,
E: Executor<I> + HasObservers<OT>, E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple, OT: ObserversTuple,
FT: FeedbacksTuple<I>, FT: FeedbacksTuple<I>,
ET: ExecutorsTuple<I>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input, I: Input,
R: Rand, R: Rand,
@ -404,7 +431,7 @@ mod tests {
let testcase = Testcase::new(vec![0; 4]).into(); let testcase = Testcase::new(vec![0; 4]).into();
corpus.add(testcase); corpus.add(testcase);
let executor = InMemoryExecutor::<BytesInput, _>::new(harness, tuple_list!()); let executor = InMemoryExecutor::<BytesInput, _>::new("main", harness, tuple_list!());
let mut state = State::new(tuple_list!()); let mut state = State::new(tuple_list!());
let mut events_manager = LoggerEventManager::new(stderr()); let mut events_manager = LoggerEventManager::new(stderr());

View File

@ -603,7 +603,7 @@ mod tests {
use crate::events::Event; use crate::events::Event;
use crate::inputs::bytes::BytesInput; use crate::inputs::bytes::BytesInput;
use crate::observers::{Observer, ObserversTuple, StdMapObserver}; use crate::observers::StdMapObserver;
use crate::serde_anymap::{Ptr, PtrMut}; use crate::serde_anymap::{Ptr, PtrMut};
use crate::tuples::{tuple_list, tuple_list_type, MatchNameAndType, Named}; use crate::tuples::{tuple_list, tuple_list_type, MatchNameAndType, Named};

View File

@ -4,6 +4,7 @@ use core::ptr;
use crate::executors::{Executor, ExitKind, HasObservers}; use crate::executors::{Executor, ExitKind, HasObservers};
use crate::inputs::{HasTargetBytes, Input}; use crate::inputs::{HasTargetBytes, Input};
use crate::observers::ObserversTuple; use crate::observers::ObserversTuple;
use crate::tuples::Named;
use crate::AflError; use crate::AflError;
/// The (unsafe) pointer to the current inmem executor, for the current run. /// The (unsafe) pointer to the current inmem executor, for the current run.
@ -21,6 +22,7 @@ where
{ {
harness: HarnessFunction<I>, harness: HarnessFunction<I>,
observers: OT, observers: OT,
name: &'static str,
} }
impl<I, OT> Executor<I> for InMemoryExecutor<I, OT> impl<I, OT> Executor<I> for InMemoryExecutor<I, OT>
@ -42,6 +44,16 @@ where
} }
} }
impl<I, OT> Named for InMemoryExecutor<I, OT>
where
I: Input + HasTargetBytes,
OT: ObserversTuple,
{
fn name(&self) -> &str {
self.name
}
}
impl<I, OT> HasObservers<OT> for InMemoryExecutor<I, OT> impl<I, OT> HasObservers<OT> for InMemoryExecutor<I, OT>
where where
I: Input + HasTargetBytes, I: Input + HasTargetBytes,
@ -63,7 +75,7 @@ where
I: Input + HasTargetBytes, I: Input + HasTargetBytes,
OT: ObserversTuple, OT: ObserversTuple,
{ {
pub fn new(harness_fn: HarnessFunction<I>, observers: OT) -> Self { pub fn new(name: &'static str, harness_fn: HarnessFunction<I>, observers: OT) -> Self {
#[cfg(feature = "std")] #[cfg(feature = "std")]
unsafe { unsafe {
os_signals::setup_crash_handlers::<I>(); os_signals::setup_crash_handlers::<I>();
@ -71,6 +83,7 @@ where
Self { Self {
harness: harness_fn, harness: harness_fn,
observers: observers, observers: observers,
name: name,
} }
} }
} }
@ -178,7 +191,7 @@ mod tests {
use crate::executors::inmemory::InMemoryExecutor; use crate::executors::inmemory::InMemoryExecutor;
use crate::executors::{Executor, ExitKind}; use crate::executors::{Executor, ExitKind};
use crate::inputs::{HasTargetBytes, Input, TargetBytes}; use crate::inputs::{HasTargetBytes, Input, TargetBytes};
use crate::tuples::{tuple_list, tuple_list_type}; use crate::tuples::tuple_list;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -204,7 +217,7 @@ mod tests {
#[test] #[test]
fn test_inmem_exec() { fn test_inmem_exec() {
let mut in_mem_executor = InMemoryExecutor::new(test_harness_fn_nop, tuple_list!()); let mut in_mem_executor = InMemoryExecutor::new("main", test_harness_fn_nop, tuple_list!());
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());
} }

View File

@ -2,6 +2,7 @@ pub mod inmemory;
use crate::inputs::Input; use crate::inputs::Input;
use crate::observers::ObserversTuple; use crate::observers::ObserversTuple;
use crate::tuples::{MatchNameAndType, MatchType, Named, TupleList};
use crate::AflError; use crate::AflError;
/// How an execution finished. /// How an execution finished.
@ -36,10 +37,43 @@ where
} }
/// An executor takes the given inputs, and runs the harness/target. /// An executor takes the given inputs, and runs the harness/target.
pub trait Executor<I> pub trait Executor<I>: Named
where where
I: Input, I: Input,
{ {
/// Instruct the target about the input and run /// Instruct the target about the input and run
fn run_target(&mut self, input: &I) -> Result<ExitKind, AflError>; fn run_target(&mut self, input: &I) -> Result<ExitKind, AflError>;
} }
pub trait ExecutorsTuple<I>: MatchType + MatchNameAndType
where
I: Input,
{
fn for_each(&self, f: fn(&dyn Executor<I>));
fn for_each_mut(&mut self, f: fn(&mut dyn Executor<I>));
}
impl<I> ExecutorsTuple<I> for ()
where
I: Input,
{
fn for_each(&self, _f: fn(&dyn Executor<I>)) {}
fn for_each_mut(&mut self, _f: fn(&mut dyn Executor<I>)) {}
}
impl<Head, Tail, I> ExecutorsTuple<I> for (Head, Tail)
where
Head: Executor<I> + 'static,
Tail: ExecutorsTuple<I> + TupleList,
I: Input,
{
fn for_each(&self, f: fn(&dyn Executor<I>)) {
f(&self.0);
self.1.for_each(f)
}
fn for_each_mut(&mut self, f: fn(&mut dyn Executor<I>)) {
f(&mut self.0);
self.1.for_each_mut(f)
}
}

View File

@ -1,5 +1,3 @@
use alloc::string::String;
use alloc::string::ToString;
use alloc::vec::Vec; use alloc::vec::Vec;
use core::marker::PhantomData; use core::marker::PhantomData;
use num::Integer; use num::Integer;
@ -64,15 +62,15 @@ where
{ {
fn is_interesting_all<OT: ObserversTuple>( fn is_interesting_all<OT: ObserversTuple>(
&mut self, &mut self,
input: &I, _input: &I,
observers: &OT, _observers: &OT,
) -> Result<u32, AflError> { ) -> Result<u32, AflError> {
Ok(0) Ok(0)
} }
fn append_metadata_all(&mut self, testcase: &mut Testcase<I>) -> Result<(), AflError> { fn append_metadata_all(&mut self, _testcase: &mut Testcase<I>) -> Result<(), AflError> {
Ok(()) Ok(())
} }
fn discard_metadata_all(&mut self, input: &I) -> Result<(), AflError> { fn discard_metadata_all(&mut self, _input: &I) -> Result<(), AflError> {
Ok(()) Ok(())
} }
//fn for_each(&self, f: fn(&dyn Feedback<I>)) {} //fn for_each(&self, f: fn(&dyn Feedback<I>)) {}

View File

@ -4,22 +4,23 @@ pub use mutational::StdMutationalStage;
use crate::corpus::Corpus; use crate::corpus::Corpus;
use crate::engines::{Engine, State}; use crate::engines::{Engine, State};
use crate::events::EventManager; use crate::events::EventManager;
use crate::executors::{Executor, HasObservers}; use crate::executors::{Executor, ExecutorsTuple, HasObservers};
use crate::feedbacks::FeedbacksTuple; use crate::feedbacks::FeedbacksTuple;
use crate::inputs::Input; use crate::inputs::Input;
use crate::observers::ObserversTuple; use crate::observers::ObserversTuple;
use crate::tuples::{MatchType, TupleList}; use crate::tuples::TupleList;
use crate::utils::Rand; use crate::utils::Rand;
use crate::AflError; use crate::AflError;
/// A stage is one step in the fuzzing process. /// A stage is one step in the fuzzing process.
/// Multiple stages will be scheduled one by one for each input. /// Multiple stages will be scheduled one by one for each input.
pub trait Stage<EM, E, OT, FT, C, I, R> pub trait Stage<EM, E, OT, FT, ET, C, I, R>
where where
EM: EventManager<C, E, OT, FT, I, R>, EM: EventManager<C, E, OT, FT, I, R>,
E: Executor<I> + HasObservers<OT>, E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple, OT: ObserversTuple,
FT: FeedbacksTuple<I>, FT: FeedbacksTuple<I>,
ET: ExecutorsTuple<I>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input, I: Input,
R: Rand, R: Rand,
@ -30,18 +31,19 @@ where
rand: &mut R, rand: &mut R,
state: &mut State<I, R, FT>, state: &mut State<I, R, FT>,
corpus: &mut C, corpus: &mut C,
engine: &mut Engine<E, OT, I>, engine: &mut Engine<E, OT, ET, I>,
manager: &mut EM, manager: &mut EM,
corpus_idx: usize, corpus_idx: usize,
) -> Result<(), AflError>; ) -> Result<(), AflError>;
} }
pub trait StagesTuple<EM, E, OT, FT, C, I, R> pub trait StagesTuple<EM, E, OT, FT, ET, C, I, R>
where where
EM: EventManager<C, E, OT, FT, I, R>, EM: EventManager<C, E, OT, FT, I, R>,
E: Executor<I> + HasObservers<OT>, E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple, OT: ObserversTuple,
FT: FeedbacksTuple<I>, FT: FeedbacksTuple<I>,
ET: ExecutorsTuple<I>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input, I: Input,
R: Rand, R: Rand,
@ -51,47 +53,50 @@ where
rand: &mut R, rand: &mut R,
state: &mut State<I, R, FT>, state: &mut State<I, R, FT>,
corpus: &mut C, corpus: &mut C,
engine: &mut Engine<E, OT, I>, engine: &mut Engine<E, OT, ET, I>,
manager: &mut EM, manager: &mut EM,
corpus_idx: usize, corpus_idx: usize,
) -> Result<(), AflError>; ) -> Result<(), AflError>;
fn for_each(&self, f: fn(&dyn Stage<EM, E, OT, FT, C, I, R>)); fn for_each(&self, f: fn(&dyn Stage<EM, E, OT, FT, ET, C, I, R>));
fn for_each_mut(&mut self, f: fn(&mut dyn Stage<EM, E, OT, FT, C, I, R>)); fn for_each_mut(&mut self, f: fn(&mut dyn Stage<EM, E, OT, FT, ET, C, I, R>));
} }
impl<EM, E, OT, FT, C, I, R> StagesTuple<EM, E, OT, FT, C, I, R> for () impl<EM, E, OT, FT, ET, C, I, R> StagesTuple<EM, E, OT, FT, ET, C, I, R> for ()
where where
EM: EventManager<C, E, OT, FT, I, R>, EM: EventManager<C, E, OT, FT, I, R>,
E: Executor<I> + HasObservers<OT>, E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple, OT: ObserversTuple,
FT: FeedbacksTuple<I>, FT: FeedbacksTuple<I>,
ET: ExecutorsTuple<I>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input, I: Input,
R: Rand, R: Rand,
{ {
fn perform_all( fn perform_all(
&mut self, &mut self,
rand: &mut R, _rand: &mut R,
state: &mut State<I, R, FT>, _state: &mut State<I, R, FT>,
corpus: &mut C, _corpus: &mut C,
engine: &mut Engine<E, OT, I>, _engine: &mut Engine<E, OT, ET, I>,
manager: &mut EM, _manager: &mut EM,
corpus_idx: usize, _corpus_idx: usize,
) -> Result<(), AflError> { ) -> Result<(), AflError> {
Ok(()) Ok(())
} }
fn for_each(&self, f: fn(&dyn Stage<EM, E, OT, FT, C, I, R>)) {} fn for_each(&self, _f: fn(&dyn Stage<EM, E, OT, FT, ET, C, I, R>)) {}
fn for_each_mut(&mut self, f: fn(&mut dyn Stage<EM, E, OT, FT, C, I, R>)) {} fn for_each_mut(&mut self, _f: fn(&mut dyn Stage<EM, E, OT, FT, ET, C, I, R>)) {}
} }
impl<Head, Tail, EM, E, OT, FT, C, I, R> StagesTuple<EM, E, OT, FT, C, I, R> for (Head, Tail) impl<Head, Tail, EM, E, OT, FT, ET, C, I, R> StagesTuple<EM, E, OT, FT, ET, C, I, R>
for (Head, Tail)
where where
Head: Stage<EM, E, OT, FT, C, I, R>, Head: Stage<EM, E, OT, FT, ET, C, I, R>,
Tail: StagesTuple<EM, E, OT, FT, C, I, R> + TupleList, Tail: StagesTuple<EM, E, OT, FT, ET, C, I, R> + TupleList,
EM: EventManager<C, E, OT, FT, I, R>, EM: EventManager<C, E, OT, FT, I, R>,
E: Executor<I> + HasObservers<OT>, E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple, OT: ObserversTuple,
FT: FeedbacksTuple<I>, FT: FeedbacksTuple<I>,
ET: ExecutorsTuple<I>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input, I: Input,
R: Rand, R: Rand,
@ -101,7 +106,7 @@ where
rand: &mut R, rand: &mut R,
state: &mut State<I, R, FT>, state: &mut State<I, R, FT>,
corpus: &mut C, corpus: &mut C,
engine: &mut Engine<E, OT, I>, engine: &mut Engine<E, OT, ET, I>,
manager: &mut EM, manager: &mut EM,
corpus_idx: usize, corpus_idx: usize,
) -> Result<(), AflError> { ) -> Result<(), AflError> {
@ -111,12 +116,12 @@ where
.perform_all(rand, state, corpus, engine, manager, corpus_idx) .perform_all(rand, state, corpus, engine, manager, corpus_idx)
} }
fn for_each(&self, f: fn(&dyn Stage<EM, E, OT, FT, C, I, R>)) { fn for_each(&self, f: fn(&dyn Stage<EM, E, OT, FT, ET, C, I, R>)) {
f(&self.0); f(&self.0);
self.1.for_each(f) self.1.for_each(f)
} }
fn for_each_mut(&mut self, f: fn(&mut dyn Stage<EM, E, OT, FT, C, I, R>)) { fn for_each_mut(&mut self, f: fn(&mut dyn Stage<EM, E, OT, FT, ET, C, I, R>)) {
f(&mut self.0); f(&mut self.0);
self.1.for_each_mut(f) self.1.for_each_mut(f)
} }

View File

@ -1,7 +1,7 @@
use core::marker::PhantomData; use core::marker::PhantomData;
use crate::events::EventManager; use crate::events::EventManager;
use crate::executors::{Executor, HasObservers}; use crate::executors::{Executor, ExecutorsTuple, HasObservers};
use crate::feedbacks::FeedbacksTuple; use crate::feedbacks::FeedbacksTuple;
use crate::inputs::Input; use crate::inputs::Input;
use crate::mutators::Mutator; use crate::mutators::Mutator;
@ -19,13 +19,15 @@ use crate::serde_anymap::{Ptr, PtrMut};
/// A Mutational stage is the stage in a fuzzing run that mutates inputs. /// A Mutational stage is the stage in a fuzzing run that mutates inputs.
/// Mutational stages will usually have a range of mutations that are /// Mutational stages will usually have a range of mutations that are
/// being applied to the input one by one, between executions. /// being applied to the input one by one, between executions.
pub trait MutationalStage<M, EM, E, OT, FT, C, I, R>: Stage<EM, E, OT, FT, C, I, R> pub trait MutationalStage<M, EM, E, OT, FT, ET, C, I, R>:
Stage<EM, E, OT, FT, ET, C, I, R>
where where
M: Mutator<C, I, R>, M: Mutator<C, I, R>,
EM: EventManager<C, E, OT, FT, I, R>, EM: EventManager<C, E, OT, FT, I, R>,
E: Executor<I> + HasObservers<OT>, E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple, OT: ObserversTuple,
FT: FeedbacksTuple<I>, FT: FeedbacksTuple<I>,
ET: ExecutorsTuple<I>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input, I: Input,
R: Rand, R: Rand,
@ -49,7 +51,7 @@ where
rand: &mut R, rand: &mut R,
state: &mut State<I, R, FT>, state: &mut State<I, R, FT>,
corpus: &mut C, corpus: &mut C,
engine: &mut Engine<E, OT, I>, engine: &mut Engine<E, OT, ET, I>,
manager: &mut EM, manager: &mut EM,
corpus_idx: usize, corpus_idx: usize,
) -> Result<(), AflError> { ) -> Result<(), AflError> {
@ -86,29 +88,31 @@ where
} }
/// The default mutational stage /// The default mutational stage
pub struct StdMutationalStage<M, EM, E, OT, FT, C, I, R> pub struct StdMutationalStage<M, EM, E, OT, FT, ET, C, I, R>
where where
M: Mutator<C, I, R>, M: Mutator<C, I, R>,
EM: EventManager<C, E, OT, FT, I, R>, EM: EventManager<C, E, OT, FT, I, R>,
E: Executor<I> + HasObservers<OT>, E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple, OT: ObserversTuple,
FT: FeedbacksTuple<I>, FT: FeedbacksTuple<I>,
ET: ExecutorsTuple<I>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input, I: Input,
R: Rand, R: Rand,
{ {
mutator: M, mutator: M,
phantom: PhantomData<(EM, E, OT, FT, C, I, R)>, phantom: PhantomData<(EM, E, OT, FT, ET, C, I, R)>,
} }
impl<M, EM, E, OT, FT, C, I, R> MutationalStage<M, EM, E, OT, FT, C, I, R> impl<M, EM, E, OT, FT, ET, C, I, R> MutationalStage<M, EM, E, OT, FT, ET, C, I, R>
for StdMutationalStage<M, EM, E, OT, FT, C, I, R> for StdMutationalStage<M, EM, E, OT, FT, ET, C, I, R>
where where
M: Mutator<C, I, R>, M: Mutator<C, I, R>,
EM: EventManager<C, E, OT, FT, I, R>, EM: EventManager<C, E, OT, FT, I, R>,
E: Executor<I> + HasObservers<OT>, E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple, OT: ObserversTuple,
FT: FeedbacksTuple<I>, FT: FeedbacksTuple<I>,
ET: ExecutorsTuple<I>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input, I: Input,
R: Rand, R: Rand,
@ -126,14 +130,15 @@ where
} }
} }
impl<M, EM, E, OT, FT, C, I, R> Stage<EM, E, OT, FT, C, I, R> impl<M, EM, E, OT, FT, ET, C, I, R> Stage<EM, E, OT, FT, ET, C, I, R>
for StdMutationalStage<M, EM, E, OT, FT, C, I, R> for StdMutationalStage<M, EM, E, OT, FT, ET, C, I, R>
where where
M: Mutator<C, I, R>, M: Mutator<C, I, R>,
EM: EventManager<C, E, OT, FT, I, R>, EM: EventManager<C, E, OT, FT, I, R>,
E: Executor<I> + HasObservers<OT>, E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple, OT: ObserversTuple,
FT: FeedbacksTuple<I>, FT: FeedbacksTuple<I>,
ET: ExecutorsTuple<I>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input, I: Input,
R: Rand, R: Rand,
@ -144,7 +149,7 @@ where
rand: &mut R, rand: &mut R,
state: &mut State<I, R, FT>, state: &mut State<I, R, FT>,
corpus: &mut C, corpus: &mut C,
engine: &mut Engine<E, OT, I>, engine: &mut Engine<E, OT, ET, I>,
manager: &mut EM, manager: &mut EM,
corpus_idx: usize, corpus_idx: usize,
) -> Result<(), AflError> { ) -> Result<(), AflError> {
@ -152,13 +157,14 @@ where
} }
} }
impl<M, EM, E, OT, FT, C, I, R> StdMutationalStage<M, EM, E, OT, FT, C, I, R> impl<M, EM, E, OT, FT, ET, C, I, R> StdMutationalStage<M, EM, E, OT, FT, ET, C, I, R>
where where
M: Mutator<C, I, R>, M: Mutator<C, I, R>,
EM: EventManager<C, E, OT, FT, I, R>, EM: EventManager<C, E, OT, FT, I, R>,
E: Executor<I> + HasObservers<OT>, E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple, OT: ObserversTuple,
FT: FeedbacksTuple<I>, FT: FeedbacksTuple<I>,
ET: ExecutorsTuple<I>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input, I: Input,
R: Rand, R: Rand,

View File

@ -65,10 +65,10 @@ pub trait MatchType {
} }
impl MatchType for () { impl MatchType for () {
fn match_type<T: 'static>(&self, f: fn(t: &T)) { fn match_type<T: 'static>(&self, _f: fn(t: &T)) {
() ()
} }
fn match_type_mut<T: 'static>(&mut self, f: fn(t: &mut T)) { fn match_type_mut<T: 'static>(&mut self, _f: fn(t: &mut T)) {
() ()
} }
} }
@ -103,10 +103,10 @@ pub trait MatchNameAndType {
} }
impl MatchNameAndType for () { impl MatchNameAndType for () {
fn match_name_type<T: 'static>(&self, name: &'static str) -> Option<&T> { fn match_name_type<T: 'static>(&self, _name: &'static str) -> Option<&T> {
None None
} }
fn match_name_type_mut<T: 'static>(&mut self, name: &'static str) -> Option<&mut T> { fn match_name_type_mut<T: 'static>(&mut self, _name: &'static str) -> Option<&mut T> {
None None
} }
} }