works again
This commit is contained in:
parent
016f2f30a5
commit
6c917cc385
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 => (),
|
||||||
}
|
}
|
||||||
|
@ -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>;
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user