splitted events rand and state, works again

This commit is contained in:
Andrea Fioraldi 2020-11-22 23:35:42 +01:00
parent 1ec34dbaa8
commit a3501cfb43
7 changed files with 163 additions and 129 deletions

View File

@ -200,9 +200,9 @@ where
R: Rand, R: Rand,
{ {
corpus: C, corpus: C,
phantom: PhantomData<(I, R)>,
pos: usize, pos: usize,
cycles: u64, cycles: u64,
phantom: PhantomData<(I, R)>,
} }
impl<C, I, R> HasTestcaseVec<I> for QueueCorpus<C, I, R> impl<C, I, R> HasTestcaseVec<I> for QueueCorpus<C, I, R>

View File

@ -5,6 +5,7 @@ use alloc::rc::Rc;
use alloc::vec::Vec; use alloc::vec::Vec;
use core::cell::RefCell; use core::cell::RefCell;
use core::fmt::Debug; use core::fmt::Debug;
use core::marker::PhantomData;
use hashbrown::HashMap; use hashbrown::HashMap;
@ -15,6 +16,7 @@ use crate::feedbacks::Feedback;
use crate::inputs::Input; use crate::inputs::Input;
use crate::observers::Observer; use crate::observers::Observer;
use crate::stages::Stage; use crate::stages::Stage;
use crate::utils::Rand;
use crate::AflError; use crate::AflError;
// TODO FeedbackMetadata to store histroy_map // TODO FeedbackMetadata to store histroy_map
@ -29,6 +31,7 @@ where
C: Corpus<I, R>, C: Corpus<I, R>,
E: Executor<I>, E: Executor<I>,
I: Input, I: Input,
R: Rand,
{ {
/// Get executions /// Get executions
fn executions(&self) -> usize; fn executions(&self) -> usize;
@ -120,9 +123,10 @@ where
pub struct StdState<C, E, I, R> pub struct StdState<C, E, I, R>
where where
C: Corpus<I>, C: Corpus<I, R>,
E: Executor<I>, E: Executor<I>,
I: Input, I: Input,
R: Rand,
{ {
executions: usize, executions: usize,
metadatas: HashMap<&'static str, Box<dyn StateMetadata>>, metadatas: HashMap<&'static str, Box<dyn StateMetadata>>,
@ -131,9 +135,10 @@ where
feedbacks: Vec<Box<dyn Feedback<I>>>, feedbacks: Vec<Box<dyn Feedback<I>>>,
corpus: C, corpus: C,
executor: E, executor: E,
phantom: PhantomData<R>,
} }
impl<C, E, I, R> HasCorpus<C, I, R> for DefaultState<C, E, I, R> impl<C, E, I, R> HasCorpus<C, I, R> for StdState<C, E, I, R>
where where
C: Corpus<I, R>, C: Corpus<I, R>,
E: Executor<I>, E: Executor<I>,
@ -152,9 +157,10 @@ where
impl<C, E, I, R> State<C, E, I, R> for StdState<C, E, I, R> impl<C, E, I, R> State<C, E, I, R> for StdState<C, E, I, R>
where where
C: Corpus<I>, C: Corpus<I, R>,
E: Executor<I>, E: Executor<I>,
I: Input, I: Input,
R: Rand,
{ {
fn executions(&self) -> usize { fn executions(&self) -> usize {
self.executions self.executions
@ -199,9 +205,10 @@ where
impl<C, E, I, R> StdState<C, E, I, R> impl<C, E, I, R> StdState<C, E, I, R>
where where
C: Corpus<I>, C: Corpus<I, R>,
E: Executor<I>, E: Executor<I>,
I: Input, I: Input,
R: Rand,
{ {
pub fn new(corpus: C, executor: E) -> Self { pub fn new(corpus: C, executor: E) -> Self {
StdState { StdState {
@ -211,22 +218,25 @@ where
feedbacks: vec![], feedbacks: vec![],
corpus: corpus, corpus: corpus,
executor: executor, executor: executor,
phantom: PhantomData,
} }
} }
} }
pub trait Engine<S, C, E, I> pub trait Engine<S, EM, E, C, I, R>
where where
S: State<C, E, I, R>, S: State<C, E, I, R>,
C: Corpus<I, R>, EM: EventManager,
E: Executor<I>, E: Executor<I>,
C: Corpus<I, R>,
I: Input, I: Input,
R: Rand,
{ {
fn stages(&self) -> &[Box<dyn Stage<S, C, E, I, R>>]; fn stages(&self) -> &[Box<dyn Stage<S, EM, E, C, I, R>>];
fn stages_mut(&mut self) -> &mut Vec<Box<dyn Stage<S, C, E, I, R>>>; fn stages_mut(&mut self) -> &mut Vec<Box<dyn Stage<S, EM, E, C, I, R>>>;
fn add_stage(&mut self, stage: Box<dyn Stage<S, C, E, I, R>>) { fn add_stage(&mut self, stage: Box<dyn Stage<S, EM, E, C, I, R>>) {
self.stages_mut().push(stage); self.stages_mut().push(stage);
} }
@ -234,52 +244,62 @@ where
&mut self, &mut self,
rand: &mut R, rand: &mut R,
state: &mut S, state: &mut S,
events_manager: &mut EM, events: &mut EM,
) -> Result<usize, AflError> { ) -> Result<usize, AflError> {
let (testcase, idx) = state.corpus_mut().next(rand)?; let (testcase, idx) = state.corpus_mut().next(rand)?;
println!("Cur entry: {}\tExecutions: {}", idx, state.executions()); println!("Cur entry: {}\tExecutions: {}", idx, state.executions());
for stage in self.stages_mut() { for stage in self.stages_mut() {
stage.perform(testcase.clone(), state)?; stage.perform(rand, state, events, testcase.clone())?;
} }
Ok(idx) Ok(idx)
} }
} }
pub struct StdEngine<S, C, E, I> pub struct StdEngine<S, EM, E, C, I, R>
where
S: State<C, E, I>,
C: Corpus<I>,
E: Executor<I>,
I: Input,
{
stages: Vec<Box<dyn Stage<S, C, E, I, R>>>,
}
impl<S, C, E, I> Engine<S, C, E, I> for StdEngine<S, C, E, I>
where where
S: State<C, E, I, R>, S: State<C, E, I, R>,
C: Corpus<I, R>, EM: EventManager,
E: Executor<I>, E: Executor<I>,
C: Corpus<I, R>,
I: Input, I: Input,
R: Rand,
{ {
fn stages(&self) -> &[Box<dyn Stage<S, C, E, I, R>>] { stages: Vec<Box<dyn Stage<S, EM, E, C, I, R>>>,
phantom: PhantomData<EM>,
}
impl<S, EM, E, C, I, R> Engine<S, EM, E, C, I, R> for StdEngine<S, EM, E, C, I, R>
where
S: State<C, E, I, R>,
EM: EventManager,
E: Executor<I>,
C: Corpus<I, R>,
I: Input,
R: Rand,
{
fn stages(&self) -> &[Box<dyn Stage<S, EM, E, C, I, R>>] {
&self.stages &self.stages
} }
fn stages_mut(&mut self) -> &mut Vec<Box<dyn Stage<S, C, E, I, R>>> { fn stages_mut(&mut self) -> &mut Vec<Box<dyn Stage<S, EM, E, C, I, R>>> {
&mut self.stages &mut self.stages
} }
} }
impl<S, C, E, I> StdEngine<S, C, E, I> impl<S, EM, E, C, I, R> StdEngine<S, EM, E, C, I, R>
where where
S: State<C, E, I, R>, S: State<C, E, I, R>,
C: Corpus<I, R>, EM: EventManager,
E: Executor<I>, E: Executor<I>,
C: Corpus<I, R>,
I: Input, I: Input,
R: Rand,
{ {
pub fn new() -> Self { pub fn new() -> Self {
StdEngine { stages: vec![] } StdEngine {
stages: vec![],
phantom: PhantomData,
}
} }
} }
@ -290,6 +310,7 @@ mod tests {
use crate::corpus::{Corpus, InMemoryCorpus, Testcase}; use crate::corpus::{Corpus, InMemoryCorpus, Testcase};
use crate::engines::{Engine, StdEngine, StdState}; use crate::engines::{Engine, StdEngine, StdState};
use crate::events::LoggerEventManager;
use crate::executors::inmemory::InMemoryExecutor; use crate::executors::inmemory::InMemoryExecutor;
use crate::executors::{Executor, ExitKind}; use crate::executors::{Executor, ExitKind};
use crate::inputs::bytes::BytesInput; use crate::inputs::bytes::BytesInput;
@ -303,26 +324,28 @@ mod tests {
#[test] #[test]
fn test_engine() { fn test_engine() {
let rand = StdRand::new(0).into(); let mut rand = StdRand::new(0);
let mut corpus = InMemoryCorpus::<BytesInput, _>::new(&rand); let mut corpus = InMemoryCorpus::<BytesInput, StdRand>::new();
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); let executor = InMemoryExecutor::<BytesInput>::new(harness);
let mut state = StdState::new(corpus, executor); let mut state = StdState::new(corpus, executor);
let mut events_manager = LoggerEventManager::new();
let mut engine = StdEngine::new(); let mut engine = StdEngine::new();
let mut mutator = StdScheduledMutator::new(&rand); let mut mutator = StdScheduledMutator::new();
mutator.add_mutation(mutation_bitflip); mutator.add_mutation(mutation_bitflip);
let stage = StdMutationalStage::new(&rand, mutator); let stage = StdMutationalStage::new(mutator);
engine.add_stage(Box::new(stage)); engine.add_stage(Box::new(stage));
// //
for i in 0..1000 { for i in 0..1000 {
engine engine
.fuzz_one(&mut state) .fuzz_one(&mut rand, &mut state, &mut events_manager)
.expect(&format!("Error in iter {}", i)); .expect(&format!("Error in iter {}", i));
} }
} }

View File

@ -1,24 +1,28 @@
pub mod scheduled; pub mod scheduled;
pub use scheduled::ComposedByMutations; pub use scheduled::ComposedByMutations;
pub use scheduled::StdScheduledMutator;
pub use scheduled::HavocBytesMutator; pub use scheduled::HavocBytesMutator;
pub use scheduled::ScheduledMutator; pub use scheduled::ScheduledMutator;
pub use scheduled::StdScheduledMutator;
use crate::corpus::{Corpus, HasCorpus}; use crate::corpus::Corpus;
//use crate::engines::State;
use crate::inputs::Input; use crate::inputs::Input;
use crate::utils::{HasRand, Rand}; use crate::utils::Rand;
use crate::AflError; use crate::AflError;
pub trait Mutator<S, C, I, R> pub trait Mutator<C, I, R>
where where
S: HasRand<R> + HasCorpus<C, I, R>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input, I: Input,
R: Rand, R: Rand,
{ {
/// Mutate a given input /// Mutate a given input
fn mutate(&mut self, state: &mut S, input: &mut I, stage_idx: i32) -> Result<(), AflError>; fn mutate(
&mut self,
rand: &mut R,
corpus: &mut C,
input: &mut I,
stage_idx: i32,
) -> Result<(), AflError>;
/// Post-process given the outcome of the execution /// Post-process given the outcome of the execution
fn post_exec(&mut self, _is_interesting: bool, _stage_idx: i32) -> Result<(), AflError> { fn post_exec(&mut self, _is_interesting: bool, _stage_idx: i32) -> Result<(), AflError> {

View File

@ -1,7 +1,7 @@
use crate::inputs::{HasBytesVec, Input}; use crate::inputs::{HasBytesVec, Input};
use crate::mutators::Corpus;
use crate::mutators::Mutator; use crate::mutators::Mutator;
use crate::mutators::{Corpus, HasCorpus}; use crate::utils::Rand;
use crate::utils::{HasRand, Rand};
use crate::AflError; use crate::AflError;
use alloc::vec::Vec; use alloc::vec::Vec;
@ -14,29 +14,27 @@ pub enum MutationResult {
// TODO maybe the mutator arg is not needed // TODO maybe the mutator arg is not needed
/// The generic function type that identifies mutations /// The generic function type that identifies mutations
type MutationFunction<M, S, I> = fn(&mut M, &mut S, &mut I) -> Result<MutationResult, AflError>; type MutationFunction<M, C, I, R> =
fn(&mut M, &mut R, &mut C, &mut I) -> Result<MutationResult, AflError>;
pub trait ComposedByMutations<S, C, I, R> pub trait ComposedByMutations<C, I, R>
where where
S: HasRand<R> + HasCorpus<C, I, R>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input, I: Input,
R: Rand, R: Rand,
{ {
/// Get a mutation by index /// Get a mutation by index
fn mutation_by_idx(&self, index: usize) -> Result<MutationFunction<Self, S, I>, AflError>; fn mutation_by_idx(&self, index: usize) -> Result<MutationFunction<Self, C, I, R>, AflError>;
/// Get the number of mutations /// Get the number of mutations
fn mutations_count(&self) -> usize; fn mutations_count(&self) -> usize;
/// Add a mutation /// Add a mutation
fn add_mutation(&mut self, mutation: MutationFunction<Self, S, I>); fn add_mutation(&mut self, mutation: MutationFunction<Self, C, I, R>);
} }
pub trait ScheduledMutator<S, C, I, R>: pub trait ScheduledMutator<C, I, R>: Mutator<C, I, R> + ComposedByMutations<C, I, R>
Mutator<S, C, I, R> + ComposedByMutations<S, C, I, R>
where where
S: HasRand<R> + HasCorpus<C, I, R>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input, I: Input,
R: Rand, R: Rand,
@ -51,7 +49,7 @@ where
&mut self, &mut self,
rand: &mut R, rand: &mut R,
_input: &I, _input: &I,
) -> Result<MutationFunction<Self, S, I>, AflError> { ) -> Result<MutationFunction<Self, C, I, R>, AflError> {
let count = self.mutations_count() as u64; let count = self.mutations_count() as u64;
if count == 0 { if count == 0 {
return Err(AflError::Empty("no mutations".into())); return Err(AflError::Empty("no mutations".into()));
@ -67,47 +65,52 @@ where
/// Implementations must forward mutate() to this method /// Implementations must forward mutate() to this method
fn scheduled_mutate( fn scheduled_mutate(
&mut self, &mut self,
state: &mut S, rand: &mut R,
corpus: &mut C,
input: &mut I, input: &mut I,
_stage_idx: i32, _stage_idx: i32,
) -> Result<(), AflError> { ) -> Result<(), AflError> {
let num = self.iterations(state.rand_mut(), input); let num = self.iterations(rand, input);
for _ in 0..num { for _ in 0..num {
self.schedule(state.rand_mut(), input)?(self, state, input)?; self.schedule(rand, input)?(self, rand, corpus, input)?;
} }
Ok(()) Ok(())
} }
} }
pub struct StdScheduledMutator<S, C, I, R> pub struct StdScheduledMutator<C, I, R>
where where
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input, I: Input,
R: Rand, R: Rand,
{ {
mutations: Vec<MutationFunction<Self, S, I>>, mutations: Vec<MutationFunction<Self, C, I, R>>,
} }
impl<S, C, I, R> Mutator<S, C, I, R> for StdScheduledMutator<S, C, I, R> impl<C, I, R> Mutator<C, I, R> for StdScheduledMutator<C, I, R>
where where
S: HasRand<R> + HasCorpus<C, I, R>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input, I: Input,
R: Rand, R: Rand,
{ {
fn mutate(&mut self, state: &mut S, input: &mut I, _stage_idx: i32) -> Result<(), AflError> { fn mutate(
self.scheduled_mutate(state, input, _stage_idx) &mut self,
rand: &mut R,
corpus: &mut C,
input: &mut I,
_stage_idx: i32,
) -> Result<(), AflError> {
self.scheduled_mutate(rand, corpus, input, _stage_idx)
} }
} }
impl<S, C, I, R> ComposedByMutations<S, C, I, R> for StdScheduledMutator<S, C, I, R> impl<C, I, R> ComposedByMutations<C, I, R> for StdScheduledMutator<C, I, R>
where where
S: HasRand<R> + HasCorpus<C, I, R>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input, I: Input,
R: Rand, R: Rand,
{ {
fn mutation_by_idx(&self, index: usize) -> Result<MutationFunction<Self, S, I>, AflError> { fn mutation_by_idx(&self, index: usize) -> Result<MutationFunction<Self, C, I, R>, AflError> {
if index >= self.mutations.len() { if index >= self.mutations.len() {
return Err(AflError::Unknown("oob".into())); return Err(AflError::Unknown("oob".into()));
} }
@ -118,14 +121,13 @@ where
self.mutations.len() self.mutations.len()
} }
fn add_mutation(&mut self, mutation: MutationFunction<Self, S, I>) { fn add_mutation(&mut self, mutation: MutationFunction<Self, C, I, R>) {
self.mutations.push(mutation) self.mutations.push(mutation)
} }
} }
impl<S, C, I, R> ScheduledMutator<S, C, I, R> for DefaultScheduledMutator<S, C, I, R> impl<C, I, R> ScheduledMutator<C, I, R> for StdScheduledMutator<C, I, R>
where where
S: HasRand<R> + HasCorpus<C, I, R>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input, I: Input,
R: Rand, R: Rand,
@ -133,9 +135,8 @@ where
// Just use the default methods // Just use the default methods
} }
impl<S, C, I, R> DefaultScheduledMutator<S, C, I, R> impl<C, I, R> StdScheduledMutator<C, I, R>
where where
S: HasRand<R> + HasCorpus<C, I, R>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input, I: Input,
R: Rand, R: Rand,
@ -145,8 +146,8 @@ where
StdScheduledMutator { mutations: vec![] } StdScheduledMutator { mutations: vec![] }
} }
/// Create a new StdScheduledMutator instance specifying mutations and corpus too /// Create a new StdScheduledMutator instance specifying mutations
pub fn new_all(mutations: Vec<MutationFunction<Self, S, I>>) -> Self { pub fn with_mutations(mutations: Vec<MutationFunction<Self, C, I, R>>) -> Self {
StdScheduledMutator { StdScheduledMutator {
mutations: mutations, mutations: mutations,
} }
@ -154,19 +155,19 @@ where
} }
/// Bitflip mutation for inputs with a bytes vector /// Bitflip mutation for inputs with a bytes vector
pub fn mutation_bitflip<M, S, C, R, I>( pub fn mutation_bitflip<M, C, I, R>(
mutator: &mut M, mutator: &mut M,
state: &mut S, rand: &mut R,
_corpus: &mut C,
input: &mut I, input: &mut I,
) -> Result<MutationResult, AflError> ) -> Result<MutationResult, AflError>
where where
M: Mutator<S, C, I, R>, M: Mutator<C, I, R>,
S: HasRand<R> + HasCorpus<C, I, R>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input + HasBytesVec, I: Input + HasBytesVec,
R: Rand, R: Rand,
{ {
let bit = state.rand_mut().below((input.bytes().len() * 8) as u64) as usize; let bit = rand.below((input.bytes().len() * 8) as u64) as usize;
input.bytes_mut()[bit >> 3] ^= (128 >> (bit & 7)) as u8; input.bytes_mut()[bit >> 3] ^= (128 >> (bit & 7)) as u8;
Ok(MutationResult::Mutated) Ok(MutationResult::Mutated)
} }
@ -188,14 +189,14 @@ fn locate_diffs(this: &[u8], other: &[u8]) -> (i64, i64) {
} }
/// Splicing mutator /// Splicing mutator
pub fn mutation_splice<M, S, C, R, I>( pub fn mutation_splice<M, C, I, R>(
mutator: &mut M, mutator: &mut M,
state: &mut S, rand: &mut R,
corpus: &mut C,
input: &mut I, input: &mut I,
) -> Result<MutationResult, AflError> ) -> Result<MutationResult, AflError>
where where
M: Mutator<S, C, I, R>, M: Mutator<C, I, R>,
S: HasRand<R> + HasCorpus<C, I, R>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input + HasBytesVec, I: Input + HasBytesVec,
R: Rand, R: Rand,
@ -204,7 +205,7 @@ where
// We don't want to use the testcase we're already using for splicing // We don't want to use the testcase we're already using for splicing
let other_rr = loop { let other_rr = loop {
let mut found = false; let mut found = false;
let (other_rr, _) = state.corpus_mut().random_entry(state.rand_mut())?.clone(); let (other_rr, _) = corpus.random_entry(rand)?.clone();
match other_rr.try_borrow_mut() { match other_rr.try_borrow_mut() {
Ok(_) => found = true, Ok(_) => found = true,
Err(_) => { Err(_) => {
@ -251,42 +252,41 @@ where
} }
/// Schedule some selected byte level mutations given a ScheduledMutator type /// Schedule some selected byte level mutations given a ScheduledMutator type
pub struct HavocBytesMutator<C, I, SM, R> pub struct HavocBytesMutator<SM, C, I, R>
where where
SM: ScheduledMutator<C, I, R>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input + HasBytesVec, I: Input + HasBytesVec,
SM: ScheduledMutator<C, I, R>,
R: Rand, R: Rand,
{ {
scheduled: SM, scheduled: SM,
phantom: PhantomData<(I, R)>, phantom: PhantomData<(I, R, C)>,
_phantom_corpus: PhantomData<C>,
} }
impl<C, I, SM, R> Mutator<C, I, R> for HavocBytesMutator<C, I, SM, R> impl<SM, C, I, R> Mutator<C, I, R> for HavocBytesMutator<SM, C, I, R>
where where
SM: ScheduledMutator<C, I, R>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input + HasBytesVec, I: Input + HasBytesVec,
SM: ScheduledMutator<C, I, R>,
R: Rand, R: Rand,
{ {
/// Mutate bytes /// Mutate bytes
fn mutate( fn mutate(
&mut self, &mut self,
corpus: &mut C,
rand: &mut R, rand: &mut R,
corpus: &mut C,
input: &mut I, input: &mut I,
stage_idx: i32, stage_idx: i32,
) -> Result<(), AflError> { ) -> Result<(), AflError> {
self.scheduled.mutate(corpus, rand, input, stage_idx) self.scheduled.mutate(rand, corpus, input, stage_idx)
} }
} }
impl<C, I, SM, R> HavocBytesMutator<C, I, SM, R> impl<SM, C, I, R> HavocBytesMutator<SM, C, I, R>
where where
SM: ScheduledMutator<C, I, R>,
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input + HasBytesVec, I: Input + HasBytesVec,
SM: ScheduledMutator<C, I, R>,
R: Rand, R: Rand,
{ {
/// Create a new HavocBytesMutator instance given a ScheduledMutator to wrap /// Create a new HavocBytesMutator instance given a ScheduledMutator to wrap
@ -296,12 +296,11 @@ where
HavocBytesMutator { HavocBytesMutator {
scheduled: scheduled, scheduled: scheduled,
phantom: PhantomData, phantom: PhantomData,
_phantom_corpus: PhantomData,
} }
} }
} }
impl<C, I, R> HavocBytesMutator<C, I, StdScheduledMutator<C, I, R>, R> impl<C, I, R> HavocBytesMutator<StdScheduledMutator<C, I, R>, C, I, R>
where where
C: Corpus<I, R>, C: Corpus<I, R>,
I: Input + HasBytesVec, I: Input + HasBytesVec,
@ -315,7 +314,6 @@ where
HavocBytesMutator { HavocBytesMutator {
scheduled: scheduled, scheduled: scheduled,
phantom: PhantomData, phantom: PhantomData,
_phantom_corpus: PhantomData,
} }
} }
} }
@ -334,7 +332,7 @@ mod tests {
fn test_mut_splice() { fn test_mut_splice() {
// With the current impl, seed of 1 will result in a split at pos 2. // With the current impl, seed of 1 will result in a split at pos 2.
let mut rand = XKCDRand::new(); let mut rand = XKCDRand::new();
let mut corpus: InMemoryCorpus<BytesInput, _> = InMemoryCorpus::new(); let mut corpus: InMemoryCorpus<BytesInput, XKCDRand> = InMemoryCorpus::new();
corpus.add(Testcase::new(vec!['a' as u8, 'b' as u8, 'c' as u8]).into()); corpus.add(Testcase::new(vec!['a' as u8, 'b' as u8, 'c' as u8]).into());
corpus.add(Testcase::new(vec!['d' as u8, 'e' as u8, 'f' as u8]).into()); corpus.add(Testcase::new(vec!['d' as u8, 'e' as u8, 'f' as u8]).into());
@ -345,9 +343,9 @@ mod tests {
let mut input = testcase.load_input().expect("No input in testcase").clone(); let mut input = testcase.load_input().expect("No input in testcase").clone();
rand.set_seed(5); rand.set_seed(5);
let mut mutator = StdScheduledMutator::<InMemoryCorpus<_, _>, BytesInput, XKCDRand>::new(); let mut mutator = StdScheduledMutator::new();
mutation_splice(&mut mutator, &mut corpus, &mut rand, &mut input).unwrap(); mutation_splice(&mut mutator, &mut rand, &mut corpus, &mut input).unwrap();
#[cfg(feature = "std")] #[cfg(feature = "std")]
println!("{:?}", input.bytes()); println!("{:?}", input.bytes());

View File

@ -4,6 +4,7 @@ pub use mutational::StdMutationalStage;
use crate::corpus::testcase::Testcase; use crate::corpus::testcase::Testcase;
use crate::corpus::Corpus; use crate::corpus::Corpus;
use crate::engines::State; use crate::engines::State;
use crate::events::EventManager;
use crate::executors::Executor; use crate::executors::Executor;
use crate::inputs::Input; use crate::inputs::Input;
use crate::utils::Rand; use crate::utils::Rand;
@ -11,11 +12,12 @@ use crate::AflError;
use alloc::rc::Rc; use alloc::rc::Rc;
use core::cell::RefCell; use core::cell::RefCell;
pub trait Stage<S, C, E, I, R> pub trait Stage<S, EM, E, C, I, R>
where where
S: State<C, E, I, R>, S: State<C, E, I, R>,
C: Corpus<I, R>, EM: EventManager,
E: Executor<I>, E: Executor<I>,
C: Corpus<I, R>,
I: Input, I: Input,
R: Rand, R: Rand,
{ {
@ -24,6 +26,7 @@ where
&mut self, &mut self,
rand: &mut R, rand: &mut R,
state: &mut S, state: &mut S,
events: &mut EM,
testcase: Rc<RefCell<Testcase<I>>>, testcase: Rc<RefCell<Testcase<I>>>,
) -> Result<(), AflError>; ) -> Result<(), AflError>;
} }

View File

@ -15,12 +15,13 @@ use crate::AflError;
// TODO multi mutators stage // TODO multi mutators stage
pub trait MutationalStage<M, S, C, E, I, R>: Stage<S, C, E, I, R> pub trait MutationalStage<M, S, EM, E, C, I, R>: Stage<S, EM, E, C, I, R>
where where
M: Mutator<C, I, R>, M: Mutator<C, I, R>,
S: State<C, E, I, R>, S: State<C, E, I, R>,
C: Corpus<I, R>, EM: EventManager,
E: Executor<I>, E: Executor<I>,
C: Corpus<I, R>,
I: Input, I: Input,
R: Rand, R: Rand,
{ {
@ -41,6 +42,7 @@ where
&mut self, &mut self,
rand: &mut R, rand: &mut R,
state: &mut S, state: &mut S,
events: &mut EM,
testcase: Rc<RefCell<Testcase<I>>>, testcase: Rc<RefCell<Testcase<I>>>,
) -> Result<(), AflError> { ) -> Result<(), AflError> {
let num = self.iterations(rand); let num = self.iterations(rand);
@ -49,7 +51,7 @@ where
for i in 0..num { for i in 0..num {
let mut input_tmp = input.clone(); let mut input_tmp = input.clone();
self.mutator_mut() self.mutator_mut()
.mutate(rand, state, &mut input_tmp, i as i32)?; .mutate(rand, state.corpus_mut(), &mut input_tmp, i as i32)?;
let interesting = state.evaluate_input(&input_tmp)?; let interesting = state.evaluate_input(&input_tmp)?;
@ -64,28 +66,28 @@ where
} }
/// The default mutational stage /// The default mutational stage
pub struct StdMutationalStage<M, S, C, E, EM, I, R> pub struct StdMutationalStage<M, S, EM, E, C, I, R>
where where
M: Mutator<C, I, R>, M: Mutator<C, I, R>,
S: State<C, E, EM, I, R>, S: State<C, E, I, R>,
C: Corpus<I, R>,
E: Executor<I>,
EM: EventManager, EM: EventManager,
E: Executor<I>,
C: Corpus<I, R>,
I: Input, I: Input,
R: Rand, R: Rand,
{ {
mutator: M, mutator: M,
phantom: PhantomData<(S, C, E, EM, I, R)>, phantom: PhantomData<(S, EM, E, C, I, R)>,
} }
impl<M, S, C, E, EM, I, R> MutationalStage<M, S, C, E, EM, I, R> impl<M, S, EM, E, C, I, R> MutationalStage<M, S, EM, E, C, I, R>
for StdMutationalStage<M, S, C, E, EM, I, R> for StdMutationalStage<M, S, EM, E, C, I, R>
where where
M: Mutator<C, I, R>, M: Mutator<C, I, R>,
S: State<C, E, EM, I, R>, S: State<C, E, I, R>,
C: Corpus<I, R>,
E: Executor<I>,
EM: EventManager, EM: EventManager,
E: Executor<I>,
C: Corpus<I, R>,
I: Input, I: Input,
R: Rand, R: Rand,
{ {
@ -100,32 +102,34 @@ where
} }
} }
impl<M, S, C, E, EM, I, R> Stage<S, C, E, EM, I, R> for StdMutationalStage<M, S, C, E, EM, I, R> impl<M, S, EM, E, C, I, R> Stage<S, EM, E, C, I, R> for StdMutationalStage<M, S, EM, E, C, I, R>
where where
M: Mutator<C, I, R>, M: Mutator<C, I, R>,
S: State<C, E, EM, I, R>, S: State<C, E, I, R>,
C: Corpus<I, R>,
E: Executor<I>,
EM: EventManager, EM: EventManager,
E: Executor<I>,
C: Corpus<I, R>,
I: Input, I: Input,
R: Rand, R: Rand,
{ {
fn perform( fn perform(
&mut self, &mut self,
testcase: Rc<RefCell<Testcase<I>>>, rand: &mut R,
state: &mut S, state: &mut S,
events: &mut EM,
testcase: Rc<RefCell<Testcase<I>>>,
) -> Result<(), AflError> { ) -> Result<(), AflError> {
self.perform_mutational(testcase, state) self.perform_mutational(rand, state, events, testcase)
} }
} }
impl<M, S, C, E, EM, I, R> StdMutationalStage<M, S, C, E, EM, I, R> impl<M, S, EM, E, C, I, R> StdMutationalStage<M, S, EM, E, C, I, R>
where where
M: Mutator<C, I, R>, M: Mutator<C, I, R>,
S: State<C, E, EM, I, R>, S: State<C, E, I, R>,
C: Corpus<I, R>,
E: Executor<I>,
EM: EventManager, EM: EventManager,
E: Executor<I>,
C: Corpus<I, R>,
I: Input, I: Input,
R: Rand, R: Rand,
{ {

View File

@ -8,7 +8,8 @@ use alloc::rc::Rc;
use core::cell::RefCell; use core::cell::RefCell;
use afl::corpus::{Corpus, InMemoryCorpus, Testcase}; use afl::corpus::{Corpus, InMemoryCorpus, Testcase};
use afl::engines::{StdEngine, StdState, Engine, State}; use afl::engines::{Engine, State, StdEngine, StdState};
use afl::events::LoggerEventManager;
use afl::executors::inmemory::InMemoryExecutor; use afl::executors::inmemory::InMemoryExecutor;
use afl::executors::{Executor, ExitKind}; use afl::executors::{Executor, ExitKind};
use afl::feedbacks::{create_history_map, MaxMapFeedback}; use afl::feedbacks::{create_history_map, MaxMapFeedback};
@ -39,9 +40,9 @@ fn harness<I>(_executor: &dyn Executor<I>, buf: &[u8]) -> ExitKind {
#[no_mangle] #[no_mangle]
pub extern "C" fn afl_libfuzzer_main() { pub extern "C" fn afl_libfuzzer_main() {
let rand = StdRand::new(0).into(); let mut rand = StdRand::new(0);
let mut corpus = InMemoryCorpus::<BytesInput, _>::new(&rand); let mut corpus = InMemoryCorpus::new();
let testcase = Testcase::new(vec![0; 4]).into(); let testcase = Testcase::new(vec![0; 4]).into();
corpus.add(testcase); corpus.add(testcase);
@ -58,16 +59,17 @@ pub extern "C" fn afl_libfuzzer_main() {
state.add_feedback(Box::new(edges_feedback)); state.add_feedback(Box::new(edges_feedback));
let mut engine = StdEngine::new(); let mut engine = StdEngine::new();
let mutator = HavocBytesMutator::new_default(&rand); let mutator = HavocBytesMutator::new_default();
let stage = StdMutationalStage::new(&rand, mutator); let stage = StdMutationalStage::new(mutator);
engine.add_stage(Box::new(stage)); engine.add_stage(Box::new(stage));
let mut events = LoggerEventManager::new();
for i in 0..1000 { for i in 0..1000 {
engine engine
.fuzz_one(&mut state) .fuzz_one(&mut rand, &mut state, &mut events)
.expect(&format!("Error in iter {}", i)); .expect(&format!("Error in iter {}", i));
} }
#[cfg(feature = "std")] #[cfg(feature = "std")]
println!("OK"); println!("OK");
} }