works again

This commit is contained in:
Andrea Fioraldi 2020-12-09 12:23:44 +01:00
parent 016f2f30a5
commit 6c917cc385
4 changed files with 49 additions and 54 deletions

View File

@ -102,23 +102,21 @@ where
// TODO move some of these, like evaluate_input, to FuzzingEngine // 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<C, E, EM>( pub fn evaluate_input<E>(
&mut self, &mut self,
input: &I, input: &I,
engine: &mut Engine<EM, E, C, I, R>, executor: &mut E,
) -> Result<u32, AflError> ) -> Result<u32, AflError>
where where
C: Corpus<I, R>,
E: Executor<I>, E: Executor<I>,
EM: EventManager<C, E, I, R>,
{ {
engine.executor_mut().reset_observers()?; executor.reset_observers()?;
engine.executor_mut().run_target(&input)?; executor.run_target(&input)?;
self.set_executions(self.executions() + 1); self.set_executions(self.executions() + 1);
engine.executor_mut().post_exec_observers()?; executor.post_exec_observers()?;
let mut fitness = 0; let mut fitness = 0;
let observers = engine.executor().observers(); let observers = 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)?;
} }
@ -183,7 +181,8 @@ where
rand: &mut R, rand: &mut R,
corpus: &mut C, corpus: &mut C,
generator: &mut G, generator: &mut G,
engine: &mut Engine<EM, E, C, I, R>, engine: &mut Engine<E, I>,
manager: &mut EM,
num: usize, num: usize,
) -> Result<(), AflError> ) -> Result<(), AflError>
where where
@ -194,9 +193,9 @@ where
{ {
for _ in 0..num { for _ in 0..num {
let input = generator.generate(rand)?; let input = generator.generate(rand)?;
let fitness = self.evaluate_input(&input, engine)?; let fitness = self.evaluate_input(&input, engine.executor_mut())?;
self.add_if_interesting(corpus, input, fitness)?; self.add_if_interesting(corpus, input, fitness)?;
engine.events_manager_mut().fire( manager.fire(
Event::LoadInitial { Event::LoadInitial {
sender_id: 0, sender_id: 0,
phantom: PhantomData, phantom: PhantomData,
@ -205,7 +204,7 @@ where
corpus, corpus,
)?; )?;
} }
engine.events_manager_mut().process(self, corpus)?; manager.process(self, corpus)?;
Ok(()) Ok(())
} }
@ -220,35 +219,20 @@ where
} }
} }
pub struct Engine<EM, E, C, I, R> pub struct Engine<E, I>
where where
EM: EventManager<C, E, I, R>,
E: Executor<I>, E: Executor<I>,
C: Corpus<I, R>,
I: Input, I: Input,
R: Rand,
{ {
manager: EM,
executor: E, executor: E,
phantom: PhantomData<(C, I, R)>, phantom: PhantomData<I>,
} }
impl<EM, E, C, I, R> Engine<EM, E, C, I, R> impl<E, I> Engine<E, I>
where where
EM: EventManager<C, E, I, R>,
E: Executor<I>, E: Executor<I>,
C: Corpus<I, R>,
I: Input, 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 /// Return the executor
pub fn executor(&self) -> &E { pub fn executor(&self) -> &E {
&self.executor &self.executor
@ -261,10 +245,9 @@ where
// TODO additional executors, Vec<Box<dyn Executor<I>>> // TODO additional executors, Vec<Box<dyn Executor<I>>>
pub fn new(executor: E, events_manager: EM) -> Self { pub fn new(executor: E) -> Self {
Self { Self {
executor: executor, executor: executor,
manager: events_manager,
phantom: PhantomData, phantom: PhantomData,
} }
} }
@ -291,15 +274,16 @@ where
rand: &mut R, rand: &mut R,
state: &mut State<I, R>, state: &mut State<I, R>,
corpus: &mut C, corpus: &mut C,
engine: &mut Engine<EM, E, C, I, R>, engine: &mut Engine<E, I>,
manager: &mut EM,
) -> Result<usize, AflError> { ) -> Result<usize, AflError> {
let (_, idx) = corpus.next(rand)?; let (_, idx) = corpus.next(rand)?;
for stage in self.stages_mut() { for stage in self.stages_mut() {
stage.perform(rand, state, corpus, engine, idx)?; stage.perform(rand, state, corpus, engine, manager, idx)?;
} }
engine.events_manager_mut().process(state, corpus)?; manager.process(state, corpus)?;
Ok(idx) Ok(idx)
} }
@ -308,15 +292,16 @@ where
rand: &mut R, rand: &mut R,
state: &mut State<I, R>, state: &mut State<I, R>,
corpus: &mut C, corpus: &mut C,
engine: &mut Engine<EM, E, C, I, R>, engine: &mut Engine<E, I>,
manager: &mut EM,
) -> Result<(), AflError> { ) -> Result<(), AflError> {
let mut last = current_milliseconds(); let mut last = current_milliseconds();
loop { loop {
self.fuzz_one(rand, state, corpus, engine)?; self.fuzz_one(rand, state, corpus, engine, manager)?;
let cur = current_milliseconds(); let cur = current_milliseconds();
if cur - last > 60 * 100 { if cur - last > 60 * 100 {
last = cur; last = cur;
engine.events_manager_mut().fire( manager.fire(
Event::UpdateStats { Event::UpdateStats {
sender_id: 0, sender_id: 0,
new_execs: 1, new_execs: 1,
@ -407,9 +392,8 @@ mod tests {
let executor = InMemoryExecutor::<BytesInput>::new(harness); let executor = InMemoryExecutor::<BytesInput>::new(harness);
let mut state = State::new(); let mut state = State::new();
let events_manager = LoggerEventManager::new(stderr()); let mut events_manager = LoggerEventManager::new(stderr());
let mut engine = Engine::new(executor);
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);
@ -420,7 +404,7 @@ mod tests {
for i in 0..1000 { for i in 0..1000 {
fuzzer fuzzer
.fuzz_one(&mut rand, &mut state, &mut corpus, &mut engine) .fuzz_one(&mut rand, &mut state, &mut corpus, &mut engine, &mut events_manager)
.expect(&format!("Error in iter {}", i)); .expect(&format!("Error in iter {}", i));
} }
} }

View File

@ -324,7 +324,7 @@ where
corpus: &mut C, corpus: &mut C,
) -> Result<(), AflError> { ) -> Result<(), AflError> {
match event.handle_in_broker(state, corpus)? { match event.handle_in_broker(state, corpus)? {
BrokerEventResult::Forward => event.handle_in_client(state, corpus)?, BrokerEventResult::Forward => (), //event.handle_in_client(state, corpus)?,
// Ignore broker-only events // Ignore broker-only events
BrokerEventResult::Handled => (), BrokerEventResult::Handled => (),
} }

View File

@ -23,7 +23,8 @@ where
rand: &mut R, rand: &mut R,
state: &mut State<I, R>, state: &mut State<I, R>,
corpus: &mut C, corpus: &mut C,
engine: &mut Engine<EM, E, C, I, R>, engine: &mut Engine<E, I>,
manager: &mut EM,
corpus_idx: usize, corpus_idx: usize,
) -> Result<(), AflError>; ) -> Result<(), AflError>;
} }

View File

@ -10,6 +10,8 @@ use crate::utils::Rand;
use crate::AflError; use crate::AflError;
use crate::{engines::State, events::Event}; use crate::{engines::State, events::Event};
use crate::serde_anymap::{Ptr, PtrMut};
// TODO multi mutators stage // TODO multi mutators stage
pub trait MutationalStage<M, EM, E, C, I, R>: Stage<EM, E, C, I, R> pub trait MutationalStage<M, EM, E, C, I, R>: Stage<EM, E, C, I, R>
@ -39,7 +41,8 @@ where
rand: &mut R, rand: &mut R,
state: &mut State<I, R>, state: &mut State<I, R>,
corpus: &mut C, corpus: &mut C,
engine: &mut Engine<EM, E, C, I, R>, engine: &mut Engine<E, I>,
manager: &mut EM,
corpus_idx: usize, corpus_idx: usize,
) -> Result<(), AflError> { ) -> Result<(), AflError> {
let num = self.iterations(rand); let num = self.iterations(rand);
@ -48,23 +51,29 @@ 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, engine)?; let fitness = state.evaluate_input(&input_mut, engine.executor_mut())?;
self.mutator_mut() self.mutator_mut()
.post_exec(fitness, &input_mut, i as i32)?; .post_exec(fitness, &input_mut, i as i32)?;
// put all this shit in some overridable function in engine maybe? or in corpus.
// consider a corpus that strores new testcases in a temporary queue, for later processing
// in a late stage, NewTestcase should be triggere donly after the processing in the later stage
// So by default we shoudl trigger it in corpus.add, so that the user can override it and remove
// if needed by particular cases
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(mut testcase) = testcase_maybe {
//corpus.entries()[idx] // TODO decouple events manager and engine
engine.events_manager_mut().fire( manager.fire(
Event::NewTestcase { Event::NewTestcase2 {
sender_id: 0, sender_id: 0,
testcase: testcase, input: Ptr::Ref(testcase.load_input()?),
phantom: PhantomData, observers: PtrMut::Ref(engine.executor_mut().observers_mut()),
}, },
state, state,
corpus, corpus,
)?; )?;
let _ = corpus.add(testcase);
} }
} }
Ok(()) Ok(())
@ -119,10 +128,11 @@ where
rand: &mut R, rand: &mut R,
state: &mut State<I, R>, state: &mut State<I, R>,
corpus: &mut C, corpus: &mut C,
engine: &mut Engine<EM, E, C, I, R>, engine: &mut Engine<E, I>,
manager: &mut EM,
corpus_idx: usize, corpus_idx: usize,
) -> Result<(), AflError> { ) -> Result<(), AflError> {
self.perform_mutational(rand, state, corpus, engine, corpus_idx) self.perform_mutational(rand, state, corpus, engine, manager, corpus_idx)
} }
} }