added corpus access to perform
This commit is contained in:
parent
a24d1edd80
commit
fe892a94f0
@ -1,5 +1,7 @@
|
|||||||
|
//! The engine is the core piece of every good fuzzer
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
use crate::corpus::testcase::Testcase;
|
|
||||||
|
use crate::corpus::Corpus;
|
||||||
use crate::feedbacks::Feedback;
|
use crate::feedbacks::Feedback;
|
||||||
use crate::inputs::Input;
|
use crate::inputs::Input;
|
||||||
use crate::stages::Stage;
|
use crate::stages::Stage;
|
||||||
@ -8,8 +10,9 @@ use crate::AflError;
|
|||||||
use alloc::rc::Rc;
|
use alloc::rc::Rc;
|
||||||
use core::cell::RefCell;
|
use core::cell::RefCell;
|
||||||
|
|
||||||
pub trait Engine<I>
|
pub trait Engine<C, I>
|
||||||
where
|
where
|
||||||
|
C: Corpus<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
{
|
{
|
||||||
fn feedbacks(&self) -> &Vec<Box<dyn Feedback<I>>>;
|
fn feedbacks(&self) -> &Vec<Box<dyn Feedback<I>>>;
|
||||||
@ -20,32 +23,34 @@ where
|
|||||||
self.feedbacks_mut().push(feedback);
|
self.feedbacks_mut().push(feedback);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stages(&self) -> &Vec<Box<dyn Stage<I>>>;
|
fn stages(&self) -> &Vec<Box<dyn Stage<C, I>>>;
|
||||||
|
|
||||||
fn stages_mut(&mut self) -> &mut Vec<Box<dyn Stage<I>>>;
|
fn stages_mut(&mut self) -> &mut Vec<Box<dyn Stage<C, I>>>;
|
||||||
|
|
||||||
fn add_stage(&mut self, stage: Box<dyn Stage<I>>) {
|
fn add_stage(&mut self, stage: Box<dyn Stage<C, I>>) {
|
||||||
self.stages_mut().push(stage);
|
self.stages_mut().push(stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fuzz_one(&mut self, testcase: &Rc<RefCell<Testcase<I>>>) -> Result<(), AflError> {
|
fn fuzz_one(&mut self, corpus: &mut C) -> Result<(), AflError> {
|
||||||
for stage in self.stages_mut() {
|
for stage in self.stages_mut() {
|
||||||
stage.perform(&testcase)?;
|
stage.perform(corpus)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DefaultEngine<I>
|
pub struct DefaultEngine<C, I>
|
||||||
where
|
where
|
||||||
|
C: Corpus<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
{
|
{
|
||||||
feedbacks: Vec<Box<dyn Feedback<I>>>,
|
feedbacks: Vec<Box<dyn Feedback<I>>>,
|
||||||
stages: Vec<Box<dyn Stage<I>>>,
|
stages: Vec<Box<dyn Stage<C, I>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I> Engine<I> for DefaultEngine<I>
|
impl<C, I> Engine<C, I> for DefaultEngine<C, I>
|
||||||
where
|
where
|
||||||
|
C: Corpus<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
{
|
{
|
||||||
fn feedbacks(&self) -> &Vec<Box<dyn Feedback<I>>> {
|
fn feedbacks(&self) -> &Vec<Box<dyn Feedback<I>>> {
|
||||||
@ -56,17 +61,18 @@ where
|
|||||||
&mut self.feedbacks
|
&mut self.feedbacks
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stages(&self) -> &Vec<Box<dyn Stage<I>>> {
|
fn stages(&self) -> &Vec<Box<dyn Stage<C, I>>> {
|
||||||
&self.stages
|
&self.stages
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stages_mut(&mut self) -> &mut Vec<Box<dyn Stage<I>>> {
|
fn stages_mut(&mut self) -> &mut Vec<Box<dyn Stage<C, I>>> {
|
||||||
&mut self.stages
|
&mut self.stages
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I> DefaultEngine<I>
|
impl<C, I> DefaultEngine<C, I>
|
||||||
where
|
where
|
||||||
|
C: Corpus<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
{
|
{
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
@ -92,6 +98,8 @@ mod tests {
|
|||||||
mutation_bitflip, ComposedByMutations, DefaultScheduledMutator,
|
mutation_bitflip, ComposedByMutations, DefaultScheduledMutator,
|
||||||
};
|
};
|
||||||
use crate::stages::mutational::DefaultMutationalStage;
|
use crate::stages::mutational::DefaultMutationalStage;
|
||||||
|
use alloc::rc::Rc;
|
||||||
|
use core::cell::RefCell;
|
||||||
|
|
||||||
use crate::utils::Xoshiro256StarRand;
|
use crate::utils::Xoshiro256StarRand;
|
||||||
|
|
||||||
@ -106,12 +114,16 @@ mod tests {
|
|||||||
let mut corpus = InMemoryCorpus::<BytesInput, _>::new(&rand);
|
let mut corpus = InMemoryCorpus::<BytesInput, _>::new(&rand);
|
||||||
let testcase = Testcase::new_rr(BytesInput::new(vec![0; 4]));
|
let testcase = Testcase::new_rr(BytesInput::new(vec![0; 4]));
|
||||||
corpus.add(testcase);
|
corpus.add(testcase);
|
||||||
let executor = InMemoryExecutor::new_rr(harness);
|
let executor: Rc<RefCell<InMemoryExecutor<BytesInput>>> = InMemoryExecutor::new_rr(harness);
|
||||||
let mut engine = DefaultEngine::new();
|
let mut engine = DefaultEngine::new();
|
||||||
let mut mutator = DefaultScheduledMutator::new(&rand);
|
let mut mutator = DefaultScheduledMutator::new(&rand);
|
||||||
mutator.add_mutation(mutation_bitflip);
|
mutator.add_mutation(mutation_bitflip);
|
||||||
let stage = DefaultMutationalStage::new(&rand, &executor, mutator);
|
let stage = DefaultMutationalStage::new(&rand, &executor, mutator);
|
||||||
engine.add_stage(Box::new(stage));
|
engine.add_stage(Box::new(stage));
|
||||||
engine.fuzz_one(&corpus.next().unwrap()).unwrap();
|
for i in 0..1000 {
|
||||||
|
engine
|
||||||
|
.fuzz_one(&mut corpus)
|
||||||
|
.expect(&format!("Error in iter {}", i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,16 @@
|
|||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
pub mod mutational;
|
pub mod mutational;
|
||||||
|
use crate::corpus::Corpus;
|
||||||
pub use mutational::DefaultMutationalStage;
|
pub use mutational::DefaultMutationalStage;
|
||||||
|
|
||||||
use crate::corpus::Testcase;
|
|
||||||
use crate::inputs::Input;
|
use crate::inputs::Input;
|
||||||
use crate::AflError;
|
use crate::AflError;
|
||||||
|
|
||||||
use alloc::rc::Rc;
|
pub trait Stage<C, I>
|
||||||
use core::cell::RefCell;
|
|
||||||
|
|
||||||
pub trait Stage<I>
|
|
||||||
where
|
where
|
||||||
|
C: Corpus<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
{
|
{
|
||||||
/// Run the stage
|
/// Run the stage
|
||||||
fn perform(&mut self, entry: &Rc<RefCell<Testcase<I>>>) -> Result<(), AflError>;
|
fn perform(&mut self, corpus: &mut C) -> Result<(), AflError>;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ use crate::corpus::testcase::Testcase;
|
|||||||
use crate::executors::Executor;
|
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::Stage;
|
use crate::stages::Stage;
|
||||||
use crate::utils::{HasRand, Rand};
|
use crate::utils::{HasRand, Rand};
|
||||||
use crate::AflError;
|
use crate::AflError;
|
||||||
@ -13,8 +14,9 @@ use core::marker::PhantomData;
|
|||||||
|
|
||||||
// TODO create HasMutatorsVec trait
|
// TODO create HasMutatorsVec trait
|
||||||
|
|
||||||
pub trait MutationalStage<I, M, E>: Stage<I> + HasRand
|
pub trait MutationalStage<C, I, M, E>: Stage<C, I> + HasRand
|
||||||
where
|
where
|
||||||
|
C: Corpus<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
M: Mutator<I, R = Self::R>,
|
M: Mutator<I, R = Self::R>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
@ -34,9 +36,9 @@ where
|
|||||||
1 + self.rand_below(128) as usize
|
1 + self.rand_below(128) as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: We need a way to get testcases for splicing
|
|
||||||
/// Runs this (mutational) stage for the given testcase
|
/// Runs this (mutational) stage for the given testcase
|
||||||
fn perform_mutational(&mut self, testcase: &Rc<RefCell<Testcase<I>>>) -> Result<(), AflError> {
|
fn perform_mutational(&mut self, corpus: &mut C) -> Result<(), AflError> {
|
||||||
|
let testcase = corpus.next()?;
|
||||||
let num = self.iterations();
|
let num = self.iterations();
|
||||||
let input = testcase.borrow_mut().load_input()?.clone();
|
let input = testcase.borrow_mut().load_input()?.clone();
|
||||||
|
|
||||||
@ -47,6 +49,10 @@ where
|
|||||||
let interesting = self.executor().borrow_mut().evaluate_input(&input_tmp)?;
|
let interesting = self.executor().borrow_mut().evaluate_input(&input_tmp)?;
|
||||||
|
|
||||||
self.mutator_mut().post_exec(interesting, i as i32)?;
|
self.mutator_mut().post_exec(interesting, i as i32)?;
|
||||||
|
|
||||||
|
if interesting {
|
||||||
|
corpus.add(Testcase::new_rr(input_tmp));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -80,8 +86,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, R, M, E> MutationalStage<I, M, E> for DefaultMutationalStage<I, R, M, E>
|
impl<C, I, R, M, E> MutationalStage<C, I, M, E> for DefaultMutationalStage<I, R, M, E>
|
||||||
where
|
where
|
||||||
|
C: Corpus<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
M: Mutator<I, R = R>,
|
M: Mutator<I, R = R>,
|
||||||
@ -102,15 +109,16 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, R, M, E> Stage<I> for DefaultMutationalStage<I, R, M, E>
|
impl<C, I, R, M, E> Stage<C, I> for DefaultMutationalStage<I, R, M, E>
|
||||||
where
|
where
|
||||||
|
C: Corpus<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
M: Mutator<I, R = R>,
|
M: Mutator<I, R = R>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
{
|
{
|
||||||
fn perform(&mut self, testcase: &Rc<RefCell<Testcase<I>>>) -> Result<(), AflError> {
|
fn perform(&mut self, corpus: &mut C) -> Result<(), AflError> {
|
||||||
self.perform_mutational(testcase)
|
self.perform_mutational(corpus)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user