working refactoring with observers

This commit is contained in:
Andrea Fioraldi 2020-12-08 15:12:40 +01:00
parent de4fb23f31
commit 9111fdcf22
5 changed files with 159 additions and 134 deletions

View File

@ -24,10 +24,8 @@ pub trait StateMetadata: Debug {
fn name(&self) -> &'static str; fn name(&self) -> &'static str;
} }
pub struct State<C, E, I, R> pub struct State<I, R>
where where
C: Corpus<I, R>,
E: Executor<I>,
I: Input, I: Input,
R: Rand, R: Rand,
{ {
@ -35,16 +33,12 @@ where
start_time: u64, start_time: u64,
metadatas: HashMap<&'static str, Box<dyn StateMetadata>>, metadatas: HashMap<&'static str, Box<dyn StateMetadata>>,
// additional_corpuses: HashMap<&'static str, Box<dyn Corpus>>, // additional_corpuses: HashMap<&'static str, Box<dyn Corpus>>,
observers: Vec<Rc<RefCell<dyn Observer>>>,
feedbacks: Vec<Box<dyn Feedback<I>>>, feedbacks: Vec<Box<dyn Feedback<I>>>,
executor: E, phantom: PhantomData<R>,
phantom: PhantomData<(C, R)>,
} }
impl<C, E, I, R> State<C, E, I, R> impl<I, R> State<I, R>
where where
C: Corpus<I, R>,
E: Executor<I>,
I: Input, I: Input,
R: Rand, R: Rand,
{ {
@ -108,10 +102,13 @@ where
self.feedbacks_mut().push(feedback); self.feedbacks_mut().push(feedback);
} }
// TODO move some of these, like evaluate_input, to FuzzingEngine
/// Runs the input and triggers observers and feedback /// Runs the input and triggers observers and feedback
pub fn evaluate_input<FE, EM>(&mut self, input: &I, engine: &FE) -> Result<u32, AflError> pub fn evaluate_input<C, E, EM>(&mut self, input: &I, engine: &mut Engine<EM, E, C, I, R>) -> Result<u32, AflError>
where where
FE: FuzzingEngine<EM, E, C, I, R>, C: Corpus<I, R>,
E: Executor<I>,
EM: EventManager<C, E, I, R>, EM: EventManager<C, E, I, R>,
{ {
engine.executor_mut().reset_observers()?; engine.executor_mut().reset_observers()?;
@ -120,7 +117,7 @@ where
engine.executor_mut().post_exec_observers()?; engine.executor_mut().post_exec_observers()?;
let mut fitness = 0; let mut fitness = 0;
let observers = self.executor().observers(); let observers = engine.executor().observers();
for feedback in self.feedbacks_mut() { for feedback in self.feedbacks_mut() {
fitness += feedback.is_interesting(&input, observers)?; fitness += feedback.is_interesting(&input, observers)?;
} }
@ -162,12 +159,15 @@ where
} }
/// Adds this input to the corpus, if it's intersting /// Adds this input to the corpus, if it's intersting
pub fn add_if_interesting( pub fn add_if_interesting<C>(
&mut self, &mut self,
corpus: &mut C, corpus: &mut C,
input: I, input: I,
fitness: u32, fitness: u32,
) -> Result<Option<usize>, AflError> { ) -> Result<Option<usize>, AflError>
where
C: Corpus<I, R>
{
if fitness > 0 { if fitness > 0 {
let testcase = self.input_to_testcase(input, fitness)?; let testcase = self.input_to_testcase(input, fitness)?;
Ok(Some(corpus.add(testcase))) Ok(Some(corpus.add(testcase)))
@ -177,45 +177,95 @@ where
} }
} }
pub fn generate_initial_inputs<G, EM>( pub fn generate_initial_inputs<G, C, E, FE, EM>(
&mut self, &mut self,
rand: &mut R, rand: &mut R,
corpus: &mut C, corpus: &mut C,
generator: &mut G, generator: &mut G,
events: &mut EM, engine: &mut Engine<EM, E, C, I, R>,
num: usize, num: usize,
) -> Result<(), AflError> ) -> Result<(), AflError>
where where
G: Generator<I, R>, G: Generator<I, R>,
C: Corpus<I, R>,
E: Executor<I>,
EM: EventManager<C, E, I, R>, EM: EventManager<C, E, I, R>,
{ {
for _ in 0..num { for _ in 0..num {
let input = generator.generate(rand)?; let input = generator.generate(rand)?;
let fitness = self.evaluate_input(&input)?; let fitness = self.evaluate_input(&input, engine)?;
self.add_if_interesting(corpus, input, fitness)?; self.add_if_interesting(corpus, input, fitness)?;
events.fire(Event::LoadInitial { engine.events_manager_mut().fire(Event::LoadInitial {
sender_id: 0, sender_id: 0,
phantom: PhantomData, phantom: PhantomData,
})?; })?;
} }
events.process(self, corpus)?; engine.events_manager_mut().process(self, corpus)?;
Ok(()) Ok(())
} }
pub fn new(executor: E) -> Self { pub fn new() -> Self {
Self { Self {
executions: 0, executions: 0,
start_time: current_milliseconds(), start_time: current_milliseconds(),
metadatas: HashMap::default(), metadatas: HashMap::default(),
observers: vec![],
feedbacks: vec![], feedbacks: vec![],
executor: executor,
phantom: PhantomData, phantom: PhantomData,
} }
} }
} }
pub trait FuzzingEngine<EM, E, C, I, R> pub struct Engine<EM, E, C, I, R>
where
EM: EventManager<C, E, I, R>,
E: Executor<I>,
C: Corpus<I, R>,
I: Input,
R: Rand,
{
manager: EM,
executor: E,
phantom: PhantomData<(C, I, R)>
}
impl<EM, E, C, I, R> Engine<EM, E, C, I, R>
where
EM: EventManager<C, E, I, R>,
E: Executor<I>,
C: Corpus<I, R>,
I: Input,
R: Rand,
{
pub fn events_manager(&self) -> &EM {
&self.manager
}
pub fn events_manager_mut(&mut self) -> &mut EM {
&mut self.manager
}
/// Return the executor
pub fn executor(&self) -> &E {
&self.executor
}
/// Return the executor (mutable)
pub fn executor_mut(&mut self) -> &mut E {
&mut self.executor
}
// TODO additional executors, Vec<Box<dyn Executor<I>>>
pub fn new(executor: E, events_manager: EM) -> Self {
Self {
executor: executor,
manager: events_manager,
phantom: PhantomData
}
}
}
pub trait Fuzzer<EM, E, C, I, R>
where where
EM: EventManager<C, E, I, R>, EM: EventManager<C, E, I, R>,
E: Executor<I>, E: Executor<I>,
@ -231,24 +281,12 @@ where
self.stages_mut().push(stage); self.stages_mut().push(stage);
} }
fn events_manager(&self) -> &EM;
fn events_manager_mut(&mut self) -> &mut EM;
/// Return the executor
fn executor(&self) -> &E;
/// Return the executor (mutable)
fn executor_mut(&mut self) -> &mut E;
// TODO additional executors, Vec<Box<dyn Executor<I>>>
fn fuzz_one( fn fuzz_one(
&mut self, &mut self,
rand: &mut R, rand: &mut R,
state: &mut State<C, E, I, R>, state: &mut State<I, R>,
corpus: &mut C, corpus: &mut C,
events: &mut EM, engine: &mut Engine<EM, E, C, I, R>,
) -> Result<usize, AflError> { ) -> Result<usize, AflError> {
let (testcase, idx) = corpus.next(rand)?; let (testcase, idx) = corpus.next(rand)?;
match testcase.input() { match testcase.input() {
@ -262,27 +300,27 @@ where
let input = corpus.get(idx).input().as_ref().unwrap(); let input = corpus.get(idx).input().as_ref().unwrap();
for stage in self.stages_mut() { for stage in self.stages_mut() {
stage.perform(rand, state, corpus, events, &input)?; stage.perform(rand, state, corpus, engine, &input)?;
} }
events.process(state, corpus)?; engine.events_manager_mut().process(state, corpus)?;
Ok(idx) Ok(idx)
} }
fn fuzz_loop( fn fuzz_loop(
&mut self, &mut self,
rand: &mut R, rand: &mut R,
state: &mut State<C, E, I, R>, state: &mut State<I, R>,
corpus: &mut C, corpus: &mut C,
events: &mut EM, engine: &mut Engine<EM, E, C, I, R>,
) -> Result<(), AflError> { ) -> Result<(), AflError> {
let mut last = current_milliseconds(); let mut last = current_milliseconds();
loop { loop {
self.fuzz_one(rand, state, corpus, events)?; self.fuzz_one(rand, state, corpus, engine)?;
let cur = current_milliseconds(); let cur = current_milliseconds();
if cur - last > 60 * 100 { if cur - last > 60 * 100 {
last = cur; last = cur;
events.fire(Event::UpdateStats { engine.events_manager_mut().fire(Event::UpdateStats {
sender_id: 0, sender_id: 0,
new_execs: 1, new_execs: 1,
phantom: PhantomData, phantom: PhantomData,
@ -290,9 +328,10 @@ where
} }
} }
} }
} }
pub struct StdFuzzingEngine<EM, E, C, I, R> pub struct StdFuzzer<EM, E, C, I, R>
where where
EM: EventManager<C, E, I, R>, EM: EventManager<C, E, I, R>,
E: Executor<I>, E: Executor<I>,
@ -301,10 +340,9 @@ where
R: Rand, R: Rand,
{ {
stages: Vec<Box<dyn Stage<EM, E, C, I, R>>>, stages: Vec<Box<dyn Stage<EM, E, C, I, R>>>,
phantom: PhantomData<EM>,
} }
impl<EM, E, C, I, R> FuzzingEngine<EM, E, C, I, R> for StdFuzzingEngine<EM, E, C, I, R> impl<EM, E, C, I, R> Fuzzer<EM, E, C, I, R> for StdFuzzer<EM, E, C, I, R>
where where
EM: EventManager<C, E, I, R>, EM: EventManager<C, E, I, R>,
E: Executor<I>, E: Executor<I>,
@ -321,7 +359,7 @@ where
} }
} }
impl<EM, E, C, I, R> StdFuzzingEngine<EM, E, C, I, R> impl<EM, E, C, I, R> StdFuzzer<EM, E, C, I, R>
where where
EM: EventManager<C, E, I, R>, EM: EventManager<C, E, I, R>,
E: Executor<I>, E: Executor<I>,
@ -331,12 +369,12 @@ where
{ {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
stages: vec![], stages: vec![]
phantom: PhantomData,
} }
} }
} }
// TODO: no_std test // TODO: no_std test
#[cfg(feature = "std")] #[cfg(feature = "std")]
#[cfg(test)] #[cfg(test)]
@ -348,7 +386,7 @@ mod tests {
use std::io::stderr; use std::io::stderr;
use crate::corpus::{Corpus, InMemoryCorpus, Testcase}; use crate::corpus::{Corpus, InMemoryCorpus, Testcase};
use crate::engines::{Engine, StdEngine, StdState}; use crate::engines::{Engine, Fuzzer, StdFuzzer, State};
#[cfg(feature = "std")] #[cfg(feature = "std")]
use crate::events::LoggerEventManager; use crate::events::LoggerEventManager;
use crate::executors::inmemory::InMemoryExecutor; use crate::executors::inmemory::InMemoryExecutor;
@ -371,21 +409,22 @@ mod tests {
corpus.add(testcase); corpus.add(testcase);
let executor = InMemoryExecutor::<BytesInput>::new(harness); let executor = InMemoryExecutor::<BytesInput>::new(harness);
let mut state = StdState::new(executor); let mut state = State::new();
let mut events_manager = LoggerEventManager::new(stderr()); let mut events_manager = LoggerEventManager::new(stderr());
let mut engine = StdEngine::new(); let mut engine = Engine::new(executor, events_manager);
let mut mutator = StdScheduledMutator::new(); let mut mutator = StdScheduledMutator::new();
mutator.add_mutation(mutation_bitflip); mutator.add_mutation(mutation_bitflip);
let stage = StdMutationalStage::new(mutator); let stage = StdMutationalStage::new(mutator);
engine.add_stage(Box::new(stage)); let mut fuzzer = StdFuzzer::new();
fuzzer.add_stage(Box::new(stage));
// //
for i in 0..1000 { for i in 0..1000 {
engine fuzzer
.fuzz_one(&mut rand, &mut state, &mut corpus, &mut events_manager) .fuzz_one(&mut rand, &mut state, &mut corpus, &mut engine)
.expect(&format!("Error in iter {}", i)); .expect(&format!("Error in iter {}", i));
} }
} }

View File

@ -60,35 +60,33 @@ pub unsafe fn llmp_tcp_server_clientloop(client: *mut LlmpClient, _data: *mut c_
/// Eventmanager for multi-processed application /// Eventmanager for multi-processed application
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub struct LLMPEventManager<S, C, E, I, R> pub struct LLMPEventManager<C, E, I, R>
where where
S: State<C, E, I, R>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input, I: Input,
E: Executor<I>, E: Executor<I>,
R: Rand, R: Rand,
//CE: CustomEvent<S, C, E, I, R>, //CE: CustomEvent<C, E, I, R>,
{ {
// TODO... // TODO...
phantom: PhantomData<(S, C, E, I, R)>, phantom: PhantomData<(C, E, I, R)>,
is_broker: bool, is_broker: bool,
} }
#[cfg(feature = "std")] #[cfg(feature = "std")]
impl<S, C, E, I, R> EventManager<S, C, E, I, R> for LLMPEventManager<S, C, E, I, R> impl<C, E, I, R> EventManager<C, E, I, R> for LLMPEventManager<C, E, I, R>
where where
S: State<C, E, I, R>,
C: Corpus<I, R>, C: Corpus<I, R>,
E: Executor<I>, E: Executor<I>,
I: Input, I: Input,
R: Rand, R: Rand,
//CE: CustomEvent<S, C, E, I, R>, //CE: CustomEvent<C, E, I, R>,
{ {
fn enabled(&self) -> bool { fn enabled(&self) -> bool {
true true
} }
fn fire(&mut self, _event: Event<S, C, E, I, R>) -> Result<(), AflError> { fn fire(&mut self, _event: Event<C, E, I, R>) -> Result<(), AflError> {
//self.events.push(event); //self.events.push(event);
// TODO: Serde serialize, llmp send // TODO: Serde serialize, llmp send
@ -96,7 +94,7 @@ where
Ok(()) Ok(())
} }
fn process(&mut self, _state: &mut S, _corpus: &mut C) -> Result<usize, AflError> { fn process(&mut self, _state: &mut State<I, R>, _corpus: &mut C) -> Result<usize, AflError> {
// TODO: iterators // TODO: iterators
/* /*
let mut handled = vec![]; let mut handled = vec![];
@ -127,9 +125,8 @@ where
} }
#[cfg(feature = "std")] #[cfg(feature = "std")]
impl<S, C, E, I, R> LLMPEventManager<S, C, E, I, R> impl<C, E, I, R> LLMPEventManager<C, E, I, R>
where where
S: State<C, E, I, R>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input, I: Input,
E: Executor<I>, E: Executor<I>,

View File

@ -34,9 +34,9 @@ enum BrokerEventResult {
/* /*
/// A custom event, in case a user wants to extend the features (at compile time) /// A custom event, in case a user wants to extend the features (at compile time)
pub trait CustomEvent<S, C, E, I, R> pub trait CustomEvent<C, E, I, R>
where where
S: State<C, E, I, R>, S: State<I, R>,
C: Corpus<I, R>, C: Corpus<I, R>,
E: Executor<I>, E: Executor<I>,
I: Input, I: Input,
@ -45,81 +45,79 @@ where
/// Returns the name of this event /// Returns the name of this event
fn name(&self) -> &str; fn name(&self) -> &str;
/// This method will be called in the broker /// This method will be called in the broker
fn handle_in_broker(&self, broker: &dyn EventManager<S, C, E, I, R, Self>, state: &mut S, corpus: &mut C) -> Result<BrokerEventResult, AflError>; fn handle_in_broker(&self, broker: &dyn EventManager<C, E, I, R, Self>, state: &mut State<I, R>, corpus: &mut C) -> Result<BrokerEventResult, AflError>;
/// This method will be called in the clients after handle_in_broker (unless BrokerEventResult::Handled) was returned in handle_in_broker /// This method will be called in the clients after handle_in_broker (unless BrokerEventResult::Handled) was returned in handle_in_broker
fn handle_in_client(&self, client: &dyn EventManager<S, C, E, I, R, Self>, state: &mut S, corpus: &mut C) -> Result<(), AflError>; fn handle_in_client(&self, client: &dyn EventManager<C, E, I, R, Self>, state: &mut State<I, R>, corpus: &mut C) -> Result<(), AflError>;
} }
struct UnusedCustomEvent {} struct UnusedCustomEvent {}
impl<S, C, E, I, R> CustomEvent<S, C, E, I, R> for UnusedCustomEvent<S, C, E, I, R> impl<C, E, I, R> CustomEvent<C, E, I, R> for UnusedCustomEvent<C, E, I, R>
where where
S: State<C, E, I, R>, S: State<I, R>,
C: Corpus<I, R>, C: Corpus<I, R>,
E: Executor<I>, E: Executor<I>,
I: Input, I: Input,
R: Rand, R: Rand,
{ {
fn name(&self) -> &str {"No custom events"} fn name(&self) -> &str {"No custom events"}
fn handle_in_broker(&self, broker: &dyn EventManager<S, C, E, I, R, Self>, state: &mut S, corpus: &mut C) {Ok(BrokerEventResult::Handled)} fn handle_in_broker(&self, broker: &dyn EventManager<C, E, I, R, Self>, state: &mut State<I, R>, corpus: &mut C) {Ok(BrokerEventResult::Handled)}
fn handle_in_client(&self, client: &dyn EventManager<S, C, E, I, R, Self>, state: &mut S, corpus: &mut C) {Ok(())} fn handle_in_client(&self, client: &dyn EventManager<C, E, I, R, Self>, state: &mut State<I, R>, corpus: &mut C) {Ok(())}
} }
*/ */
/// Events sent around in the library /// Events sent around in the library
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub enum Event<S, C, E, I, R> pub enum Event<C, E, I, R>
where where
S: State<C, E, I, R>,
C: Corpus<I, R>, C: Corpus<I, R>,
E: Executor<I>, E: Executor<I>,
I: Input, I: Input,
R: Rand, R: Rand,
// CE: CustomEvent<S, C, E, I, R>, // CE: CustomEvent<C, E, I, R>,
{ {
LoadInitial { LoadInitial {
sender_id: u64, sender_id: u64,
phantom: PhantomData<(S, C, E, I, R)>, phantom: PhantomData<(C, E, I, R)>,
}, },
NewTestcase { NewTestcase {
sender_id: u64, sender_id: u64,
testcase: Testcase<I>, testcase: Testcase<I>,
phantom: PhantomData<(S, C, E, I, R)>, phantom: PhantomData<(C, E, I, R)>,
}, },
UpdateStats { UpdateStats {
sender_id: u64, sender_id: u64,
new_execs: usize, new_execs: usize,
phantom: PhantomData<(S, C, E, I, R)>, phantom: PhantomData<(C, E, I, R)>,
}, },
Crash { Crash {
sender_id: u64, sender_id: u64,
input: I, input: I,
phantom: PhantomData<(S, C, E, I, R)>, phantom: PhantomData<(C, E, I, R)>,
}, },
Timeout { Timeout {
sender_id: u64, sender_id: u64,
input: I, input: I,
phantom: PhantomData<(S, C, E, I, R)>, phantom: PhantomData<(C, E, I, R)>,
}, },
Log { Log {
sender_id: u64, sender_id: u64,
severity_level: u8, severity_level: u8,
message: String, message: String,
phantom: PhantomData<(S, C, E, I, R)>, phantom: PhantomData<(C, E, I, R)>,
}, },
None { None {
phantom: PhantomData<(S, C, E, I, R)>, phantom: PhantomData<(C, E, I, R)>,
}, },
//Custom {sender_id: u64, custom_event: CE}, //Custom {sender_id: u64, custom_event: CE},
} }
impl<S, C, E, I, R> Event<S, C, E, I, R> impl<C, E, I, R> Event<C, E, I, R>
where where
S: State<C, E, I, R>,
C: Corpus<I, R>, C: Corpus<I, R>,
E: Executor<I>, E: Executor<I>,
I: Input, I: Input,
R: Rand, R: Rand,
//CE: CustomEvent<S, C, E, I, R>, //CE: CustomEvent<C, E, I, R>,
{ {
pub fn name(&self) -> &str { pub fn name(&self) -> &str {
match self { match self {
@ -160,7 +158,7 @@ where
fn handle_in_broker( fn handle_in_broker(
&self, &self,
/*broker: &dyn EventManager<S, C, E, I, R>,*/ _state: &mut S, /*broker: &dyn EventManager<C, E, I, R>,*/ _state: &mut State<I, R>,
_corpus: &mut C, _corpus: &mut C,
) -> Result<BrokerEventResult, AflError> { ) -> Result<BrokerEventResult, AflError> {
match self { match self {
@ -215,7 +213,7 @@ where
fn handle_in_client( fn handle_in_client(
self, self,
/*client: &dyn EventManager<S, C, E, I, R>,*/ _state: &mut S, /*client: &dyn EventManager<C, E, I, R>,*/ _state: &mut State<I, R>,
corpus: &mut C, corpus: &mut C,
) -> Result<(), AflError> { ) -> Result<(), AflError> {
match self { match self {
@ -236,9 +234,8 @@ where
// TODO serialize and deserialize, defaults to serde // TODO serialize and deserialize, defaults to serde
} }
pub trait EventManager<S, C, E, I, R> pub trait EventManager<C, E, I, R>
where where
S: State<C, E, I, R>,
C: Corpus<I, R>, C: Corpus<I, R>,
E: Executor<I>, E: Executor<I>,
I: Input, I: Input,
@ -249,13 +246,13 @@ where
fn enabled(&self) -> bool; fn enabled(&self) -> bool;
/// Fire an Event /// Fire an Event
fn fire(&mut self, event: Event<S, C, E, I, R>) -> Result<(), AflError>; fn fire(&mut self, event: Event<C, E, I, R>) -> Result<(), AflError>;
/// Lookup for incoming events and process them. /// Lookup for incoming events and process them.
/// Return the number of processes events or an error /// Return the number of processes events or an error
fn process(&mut self, state: &mut S, corpus: &mut C) -> Result<usize, AflError>; fn process(&mut self, state: &mut State<I, R>, corpus: &mut C) -> Result<usize, AflError>;
fn on_recv(&self, _state: &mut S, _corpus: &mut C) -> Result<(), AflError> { fn on_recv(&self, _state: &mut State<I, R>, _corpus: &mut C) -> Result<(), AflError> {
// TODO: Better way to move out of testcase, or get ref // TODO: Better way to move out of testcase, or get ref
//Ok(corpus.add(self.testcase.take().unwrap())) //Ok(corpus.add(self.testcase.take().unwrap()))
Ok(()) Ok(())
@ -263,7 +260,7 @@ where
} }
/*TODO /*TODO
fn on_recv(&self, state: &mut S, _corpus: &mut C) -> Result<(), AflError> { fn on_recv(&self, state: &mut State<I, R>, _corpus: &mut C) -> Result<(), AflError> {
println!( println!(
"#{}\t exec/s: {}", "#{}\t exec/s: {}",
state.executions(), state.executions(),
@ -275,41 +272,39 @@ where
*/ */
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub struct LoggerEventManager<S, C, E, I, R, W> pub struct LoggerEventManager<C, E, I, R, W>
where where
S: State<C, E, I, R>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input, I: Input,
E: Executor<I>, E: Executor<I>,
R: Rand, R: Rand,
W: Write, W: Write,
//CE: CustomEvent<S, C, E, I, R>, //CE: CustomEvent<C, E, I, R>,
{ {
events: Vec<Event<S, C, E, I, R>>, events: Vec<Event<C, E, I, R>>,
writer: W, writer: W,
} }
#[cfg(feature = "std")] #[cfg(feature = "std")]
impl<S, C, E, I, R, W> EventManager<S, C, E, I, R> for LoggerEventManager<S, C, E, I, R, W> impl<C, E, I, R, W> EventManager<C, E, I, R> for LoggerEventManager<C, E, I, R, W>
where where
S: State<C, E, I, R>,
C: Corpus<I, R>, C: Corpus<I, R>,
E: Executor<I>, E: Executor<I>,
I: Input, I: Input,
R: Rand, R: Rand,
W: Write, W: Write,
//CE: CustomEvent<S, C, E, I, R>, //CE: CustomEvent<C, E, I, R>,
{ {
fn enabled(&self) -> bool { fn enabled(&self) -> bool {
true true
} }
fn fire(&mut self, event: Event<S, C, E, I, R>) -> Result<(), AflError> { fn fire(&mut self, event: Event<C, E, I, R>) -> Result<(), AflError> {
self.events.push(event); self.events.push(event);
Ok(()) Ok(())
} }
fn process(&mut self, state: &mut S, corpus: &mut C) -> Result<usize, AflError> { fn process(&mut self, state: &mut State<I, R>, corpus: &mut C) -> Result<usize, AflError> {
// TODO: iterators // TODO: iterators
let mut handled = vec![]; let mut handled = vec![];
for x in self.events.iter() { for x in self.events.iter() {
@ -330,9 +325,8 @@ where
} }
#[cfg(feature = "std")] #[cfg(feature = "std")]
impl<S, C, E, I, R, W> LoggerEventManager<S, C, E, I, R, W> impl<C, E, I, R, W> LoggerEventManager<C, E, I, R, W>
where where
S: State<C, E, I, R>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input, I: Input,
E: Executor<I>, E: Executor<I>,

View File

@ -2,7 +2,7 @@ pub mod mutational;
pub use mutational::StdMutationalStage; pub use mutational::StdMutationalStage;
use crate::corpus::Corpus; use crate::corpus::Corpus;
use crate::engines::State; use crate::engines::{Engine, State};
use crate::events::EventManager; use crate::events::EventManager;
use crate::executors::Executor; use crate::executors::Executor;
use crate::inputs::Input; use crate::inputs::Input;
@ -21,9 +21,9 @@ where
fn perform( fn perform(
&mut self, &mut self,
rand: &mut R, rand: &mut R,
state: &mut State<C, E, I, R>, state: &mut State<I, R>,
corpus: &C, corpus: &C,
events: &mut EM, engine: &mut Engine<EM, E, C, I, R>,
input: &I, input: &I,
) -> Result<(), AflError>; ) -> Result<(), AflError>;
} }

View File

@ -5,18 +5,17 @@ use crate::executors::Executor;
use crate::inputs::Input; use crate::inputs::Input;
use crate::mutators::Mutator; use crate::mutators::Mutator;
use crate::stages::Corpus; use crate::stages::Corpus;
use crate::stages::Stage; use crate::stages::{Engine, Stage};
use crate::utils::Rand; use crate::utils::Rand;
use crate::AflError; use crate::AflError;
use crate::{engines::State, events::Event}; use crate::{engines::State, events::Event};
// TODO multi mutators stage // TODO multi mutators stage
pub trait MutationalStage<M, S, EM, E, C, I, R>: Stage<S, EM, E, C, I, R> pub trait MutationalStage<M, EM, E, C, I, R>: Stage<EM, E, C, I, R>
where where
M: Mutator<C, I, R>, M: Mutator<C, I, R>,
S: State<C, E, I, R>, EM: EventManager<C, E, I, R>,
EM: EventManager<S, C, E, I, R>,
E: Executor<I>, E: Executor<I>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input, I: Input,
@ -38,9 +37,9 @@ where
fn perform_mutational( fn perform_mutational(
&mut self, &mut self,
rand: &mut R, rand: &mut R,
state: &mut S, state: &mut State<I, R>,
corpus: &C, corpus: &C,
events: &mut EM, engine: &mut Engine<EM, E, C, I, R>,
input: &I, input: &I,
) -> Result<(), AflError> { ) -> Result<(), AflError> {
let num = self.iterations(rand); let num = self.iterations(rand);
@ -49,7 +48,7 @@ where
self.mutator_mut() self.mutator_mut()
.mutate(rand, corpus, &mut input_mut, i as i32)?; .mutate(rand, corpus, &mut input_mut, i as i32)?;
let fitness = state.evaluate_input(&input_mut)?; let fitness = state.evaluate_input(&input_mut, engine)?;
self.mutator_mut() self.mutator_mut()
.post_exec(fitness, &input_mut, i as i32)?; .post_exec(fitness, &input_mut, i as i32)?;
@ -57,7 +56,7 @@ where
let testcase_maybe = state.testcase_if_interesting(input_mut, fitness)?; let testcase_maybe = state.testcase_if_interesting(input_mut, fitness)?;
if let Some(testcase) = testcase_maybe { if let Some(testcase) = testcase_maybe {
//corpus.entries()[idx] //corpus.entries()[idx]
events.fire(Event::NewTestcase { engine.events_manager_mut().fire(Event::NewTestcase {
sender_id: 0, sender_id: 0,
testcase: testcase, testcase: testcase,
phantom: PhantomData, phantom: PhantomData,
@ -69,26 +68,24 @@ where
} }
/// The default mutational stage /// The default mutational stage
pub struct StdMutationalStage<M, S, EM, E, C, I, R> pub struct StdMutationalStage<M, EM, E, C, I, R>
where where
M: Mutator<C, I, R>, M: Mutator<C, I, R>,
S: State<C, E, I, R>, EM: EventManager<C, E, I, R>,
EM: EventManager<S, C, E, I, R>,
E: Executor<I>, E: Executor<I>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input, I: Input,
R: Rand, R: Rand,
{ {
mutator: M, mutator: M,
phantom: PhantomData<(S, EM, E, C, I, R)>, phantom: PhantomData<(EM, E, C, I, R)>,
} }
impl<M, S, EM, E, C, I, R> MutationalStage<M, S, EM, E, C, I, R> impl<M, EM, E, C, I, R> MutationalStage<M, EM, E, C, I, R>
for StdMutationalStage<M, S, EM, E, C, I, R> for StdMutationalStage<M, EM, E, C, I, R>
where where
M: Mutator<C, I, R>, M: Mutator<C, I, R>,
S: State<C, E, I, R>, EM: EventManager<C, E, I, R>,
EM: EventManager<S, C, E, I, R>,
E: Executor<I>, E: Executor<I>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input, I: Input,
@ -105,11 +102,10 @@ where
} }
} }
impl<M, S, EM, E, C, I, R> Stage<S, EM, E, C, I, R> for StdMutationalStage<M, S, EM, E, C, I, R> impl<M, EM, E, C, I, R> Stage<EM, E, C, I, R> for StdMutationalStage<M, EM, E, C, I, R>
where where
M: Mutator<C, I, R>, M: Mutator<C, I, R>,
S: State<C, E, I, R>, EM: EventManager<C, E, I, R>,
EM: EventManager<S, C, E, I, R>,
E: Executor<I>, E: Executor<I>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input, I: Input,
@ -118,20 +114,19 @@ where
fn perform( fn perform(
&mut self, &mut self,
rand: &mut R, rand: &mut R,
state: &mut S, state: &mut State<I, R>,
corpus: &C, corpus: &C,
events: &mut EM, engine: &mut Engine<EM, E, C, I, R>,
input: &I, input: &I,
) -> Result<(), AflError> { ) -> Result<(), AflError> {
self.perform_mutational(rand, state, corpus, events, input) self.perform_mutational(rand, state, corpus, engine, input)
} }
} }
impl<M, S, EM, E, C, I, R> StdMutationalStage<M, S, EM, E, C, I, R> impl<M, EM, E, C, I, R> StdMutationalStage<M, EM, E, C, I, R>
where where
M: Mutator<C, I, R>, M: Mutator<C, I, R>,
S: State<C, E, I, R>, EM: EventManager<C, E, I, R>,
EM: EventManager<S, C, E, I, R>,
E: Executor<I>, E: Executor<I>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input, I: Input,