splitted events rand and state, works again
This commit is contained in:
parent
1ec34dbaa8
commit
a3501cfb43
@ -200,9 +200,9 @@ where
|
||||
R: Rand,
|
||||
{
|
||||
corpus: C,
|
||||
phantom: PhantomData<(I, R)>,
|
||||
pos: usize,
|
||||
cycles: u64,
|
||||
phantom: PhantomData<(I, R)>,
|
||||
}
|
||||
|
||||
impl<C, I, R> HasTestcaseVec<I> for QueueCorpus<C, I, R>
|
||||
|
@ -5,6 +5,7 @@ use alloc::rc::Rc;
|
||||
use alloc::vec::Vec;
|
||||
use core::cell::RefCell;
|
||||
use core::fmt::Debug;
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use hashbrown::HashMap;
|
||||
|
||||
@ -15,6 +16,7 @@ use crate::feedbacks::Feedback;
|
||||
use crate::inputs::Input;
|
||||
use crate::observers::Observer;
|
||||
use crate::stages::Stage;
|
||||
use crate::utils::Rand;
|
||||
use crate::AflError;
|
||||
|
||||
// TODO FeedbackMetadata to store histroy_map
|
||||
@ -29,6 +31,7 @@ where
|
||||
C: Corpus<I, R>,
|
||||
E: Executor<I>,
|
||||
I: Input,
|
||||
R: Rand,
|
||||
{
|
||||
/// Get executions
|
||||
fn executions(&self) -> usize;
|
||||
@ -120,9 +123,10 @@ where
|
||||
|
||||
pub struct StdState<C, E, I, R>
|
||||
where
|
||||
C: Corpus<I>,
|
||||
C: Corpus<I, R>,
|
||||
E: Executor<I>,
|
||||
I: Input,
|
||||
R: Rand,
|
||||
{
|
||||
executions: usize,
|
||||
metadatas: HashMap<&'static str, Box<dyn StateMetadata>>,
|
||||
@ -131,9 +135,10 @@ where
|
||||
feedbacks: Vec<Box<dyn Feedback<I>>>,
|
||||
corpus: C,
|
||||
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
|
||||
C: Corpus<I, R>,
|
||||
E: Executor<I>,
|
||||
@ -152,9 +157,10 @@ where
|
||||
|
||||
impl<C, E, I, R> State<C, E, I, R> for StdState<C, E, I, R>
|
||||
where
|
||||
C: Corpus<I>,
|
||||
C: Corpus<I, R>,
|
||||
E: Executor<I>,
|
||||
I: Input,
|
||||
R: Rand,
|
||||
{
|
||||
fn executions(&self) -> usize {
|
||||
self.executions
|
||||
@ -199,9 +205,10 @@ where
|
||||
|
||||
impl<C, E, I, R> StdState<C, E, I, R>
|
||||
where
|
||||
C: Corpus<I>,
|
||||
C: Corpus<I, R>,
|
||||
E: Executor<I>,
|
||||
I: Input,
|
||||
R: Rand,
|
||||
{
|
||||
pub fn new(corpus: C, executor: E) -> Self {
|
||||
StdState {
|
||||
@ -211,22 +218,25 @@ where
|
||||
feedbacks: vec![],
|
||||
corpus: corpus,
|
||||
executor: executor,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Engine<S, C, E, I>
|
||||
pub trait Engine<S, EM, E, C, I, R>
|
||||
where
|
||||
S: State<C, E, I, R>,
|
||||
C: Corpus<I, R>,
|
||||
EM: EventManager,
|
||||
E: Executor<I>,
|
||||
C: Corpus<I, R>,
|
||||
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);
|
||||
}
|
||||
|
||||
@ -234,52 +244,62 @@ where
|
||||
&mut self,
|
||||
rand: &mut R,
|
||||
state: &mut S,
|
||||
events_manager: &mut EM,
|
||||
events: &mut EM,
|
||||
) -> Result<usize, AflError> {
|
||||
let (testcase, idx) = state.corpus_mut().next(rand)?;
|
||||
println!("Cur entry: {}\tExecutions: {}", idx, state.executions());
|
||||
for stage in self.stages_mut() {
|
||||
stage.perform(testcase.clone(), state)?;
|
||||
stage.perform(rand, state, events, testcase.clone())?;
|
||||
}
|
||||
Ok(idx)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct StdEngine<S, C, E, I>
|
||||
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>
|
||||
pub struct StdEngine<S, EM, E, C, I, R>
|
||||
where
|
||||
S: State<C, E, I, R>,
|
||||
C: Corpus<I, R>,
|
||||
EM: EventManager,
|
||||
E: Executor<I>,
|
||||
C: Corpus<I, R>,
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
S: State<C, E, I, R>,
|
||||
C: Corpus<I, R>,
|
||||
EM: EventManager,
|
||||
E: Executor<I>,
|
||||
C: Corpus<I, R>,
|
||||
I: Input,
|
||||
R: Rand,
|
||||
{
|
||||
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::engines::{Engine, StdEngine, StdState};
|
||||
use crate::events::LoggerEventManager;
|
||||
use crate::executors::inmemory::InMemoryExecutor;
|
||||
use crate::executors::{Executor, ExitKind};
|
||||
use crate::inputs::bytes::BytesInput;
|
||||
@ -303,26 +324,28 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
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();
|
||||
corpus.add(testcase);
|
||||
|
||||
let executor = InMemoryExecutor::<BytesInput>::new(harness);
|
||||
let mut state = StdState::new(corpus, executor);
|
||||
|
||||
let mut events_manager = LoggerEventManager::new();
|
||||
|
||||
let mut engine = StdEngine::new();
|
||||
let mut mutator = StdScheduledMutator::new(&rand);
|
||||
let mut mutator = StdScheduledMutator::new();
|
||||
mutator.add_mutation(mutation_bitflip);
|
||||
let stage = StdMutationalStage::new(&rand, mutator);
|
||||
let stage = StdMutationalStage::new(mutator);
|
||||
engine.add_stage(Box::new(stage));
|
||||
|
||||
//
|
||||
|
||||
for i in 0..1000 {
|
||||
engine
|
||||
.fuzz_one(&mut state)
|
||||
.fuzz_one(&mut rand, &mut state, &mut events_manager)
|
||||
.expect(&format!("Error in iter {}", i));
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +1,28 @@
|
||||
pub mod scheduled;
|
||||
pub use scheduled::ComposedByMutations;
|
||||
pub use scheduled::StdScheduledMutator;
|
||||
pub use scheduled::HavocBytesMutator;
|
||||
pub use scheduled::ScheduledMutator;
|
||||
pub use scheduled::StdScheduledMutator;
|
||||
|
||||
use crate::corpus::{Corpus, HasCorpus};
|
||||
//use crate::engines::State;
|
||||
use crate::corpus::Corpus;
|
||||
use crate::inputs::Input;
|
||||
use crate::utils::{HasRand, Rand};
|
||||
use crate::utils::Rand;
|
||||
use crate::AflError;
|
||||
|
||||
pub trait Mutator<S, C, I, R>
|
||||
pub trait Mutator<C, I, R>
|
||||
where
|
||||
S: HasRand<R> + HasCorpus<C, I, R>,
|
||||
C: Corpus<I, R>,
|
||||
I: Input,
|
||||
R: Rand,
|
||||
{
|
||||
/// 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
|
||||
fn post_exec(&mut self, _is_interesting: bool, _stage_idx: i32) -> Result<(), AflError> {
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::inputs::{HasBytesVec, Input};
|
||||
use crate::mutators::Corpus;
|
||||
use crate::mutators::Mutator;
|
||||
use crate::mutators::{Corpus, HasCorpus};
|
||||
use crate::utils::{HasRand, Rand};
|
||||
use crate::utils::Rand;
|
||||
use crate::AflError;
|
||||
|
||||
use alloc::vec::Vec;
|
||||
@ -14,29 +14,27 @@ pub enum MutationResult {
|
||||
|
||||
// TODO maybe the mutator arg is not needed
|
||||
/// 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
|
||||
S: HasRand<R> + HasCorpus<C, I, R>,
|
||||
C: Corpus<I, R>,
|
||||
I: Input,
|
||||
R: Rand,
|
||||
{
|
||||
/// 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
|
||||
fn mutations_count(&self) -> usize;
|
||||
|
||||
/// 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>:
|
||||
Mutator<S, C, I, R> + ComposedByMutations<S, C, I, R>
|
||||
pub trait ScheduledMutator<C, I, R>: Mutator<C, I, R> + ComposedByMutations<C, I, R>
|
||||
where
|
||||
S: HasRand<R> + HasCorpus<C, I, R>,
|
||||
C: Corpus<I, R>,
|
||||
I: Input,
|
||||
R: Rand,
|
||||
@ -51,7 +49,7 @@ where
|
||||
&mut self,
|
||||
rand: &mut R,
|
||||
_input: &I,
|
||||
) -> Result<MutationFunction<Self, S, I>, AflError> {
|
||||
) -> Result<MutationFunction<Self, C, I, R>, AflError> {
|
||||
let count = self.mutations_count() as u64;
|
||||
if count == 0 {
|
||||
return Err(AflError::Empty("no mutations".into()));
|
||||
@ -67,47 +65,52 @@ where
|
||||
/// Implementations must forward mutate() to this method
|
||||
fn scheduled_mutate(
|
||||
&mut self,
|
||||
state: &mut S,
|
||||
rand: &mut R,
|
||||
corpus: &mut C,
|
||||
input: &mut I,
|
||||
_stage_idx: i32,
|
||||
) -> Result<(), AflError> {
|
||||
let num = self.iterations(state.rand_mut(), input);
|
||||
let num = self.iterations(rand, input);
|
||||
for _ in 0..num {
|
||||
self.schedule(state.rand_mut(), input)?(self, state, input)?;
|
||||
self.schedule(rand, input)?(self, rand, corpus, input)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct StdScheduledMutator<S, C, I, R>
|
||||
pub struct StdScheduledMutator<C, I, R>
|
||||
where
|
||||
C: Corpus<I, R>,
|
||||
I: Input,
|
||||
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
|
||||
S: HasRand<R> + HasCorpus<C, I, R>,
|
||||
C: Corpus<I, R>,
|
||||
I: Input,
|
||||
R: Rand,
|
||||
{
|
||||
fn mutate(&mut self, state: &mut S, input: &mut I, _stage_idx: i32) -> Result<(), AflError> {
|
||||
self.scheduled_mutate(state, input, _stage_idx)
|
||||
fn mutate(
|
||||
&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
|
||||
S: HasRand<R> + HasCorpus<C, I, R>,
|
||||
C: Corpus<I, R>,
|
||||
I: Input,
|
||||
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() {
|
||||
return Err(AflError::Unknown("oob".into()));
|
||||
}
|
||||
@ -118,14 +121,13 @@ where
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
S: HasRand<R> + HasCorpus<C, I, R>,
|
||||
C: Corpus<I, R>,
|
||||
I: Input,
|
||||
R: Rand,
|
||||
@ -133,9 +135,8 @@ where
|
||||
// Just use the default methods
|
||||
}
|
||||
|
||||
impl<S, C, I, R> DefaultScheduledMutator<S, C, I, R>
|
||||
impl<C, I, R> StdScheduledMutator<C, I, R>
|
||||
where
|
||||
S: HasRand<R> + HasCorpus<C, I, R>,
|
||||
C: Corpus<I, R>,
|
||||
I: Input,
|
||||
R: Rand,
|
||||
@ -145,8 +146,8 @@ where
|
||||
StdScheduledMutator { mutations: vec![] }
|
||||
}
|
||||
|
||||
/// Create a new StdScheduledMutator instance specifying mutations and corpus too
|
||||
pub fn new_all(mutations: Vec<MutationFunction<Self, S, I>>) -> Self {
|
||||
/// Create a new StdScheduledMutator instance specifying mutations
|
||||
pub fn with_mutations(mutations: Vec<MutationFunction<Self, C, I, R>>) -> Self {
|
||||
StdScheduledMutator {
|
||||
mutations: mutations,
|
||||
}
|
||||
@ -154,19 +155,19 @@ where
|
||||
}
|
||||
|
||||
/// 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,
|
||||
state: &mut S,
|
||||
rand: &mut R,
|
||||
_corpus: &mut C,
|
||||
input: &mut I,
|
||||
) -> Result<MutationResult, AflError>
|
||||
where
|
||||
M: Mutator<S, C, I, R>,
|
||||
S: HasRand<R> + HasCorpus<C, I, R>,
|
||||
M: Mutator<C, I, R>,
|
||||
C: Corpus<I, R>,
|
||||
I: Input + HasBytesVec,
|
||||
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;
|
||||
Ok(MutationResult::Mutated)
|
||||
}
|
||||
@ -188,14 +189,14 @@ fn locate_diffs(this: &[u8], other: &[u8]) -> (i64, i64) {
|
||||
}
|
||||
|
||||
/// Splicing mutator
|
||||
pub fn mutation_splice<M, S, C, R, I>(
|
||||
pub fn mutation_splice<M, C, I, R>(
|
||||
mutator: &mut M,
|
||||
state: &mut S,
|
||||
rand: &mut R,
|
||||
corpus: &mut C,
|
||||
input: &mut I,
|
||||
) -> Result<MutationResult, AflError>
|
||||
where
|
||||
M: Mutator<S, C, I, R>,
|
||||
S: HasRand<R> + HasCorpus<C, I, R>,
|
||||
M: Mutator<C, I, R>,
|
||||
C: Corpus<I, R>,
|
||||
I: Input + HasBytesVec,
|
||||
R: Rand,
|
||||
@ -204,7 +205,7 @@ where
|
||||
// We don't want to use the testcase we're already using for splicing
|
||||
let other_rr = loop {
|
||||
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() {
|
||||
Ok(_) => found = true,
|
||||
Err(_) => {
|
||||
@ -251,42 +252,41 @@ where
|
||||
}
|
||||
|
||||
/// 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
|
||||
SM: ScheduledMutator<C, I, R>,
|
||||
C: Corpus<I, R>,
|
||||
I: Input + HasBytesVec,
|
||||
SM: ScheduledMutator<C, I, R>,
|
||||
R: Rand,
|
||||
{
|
||||
scheduled: SM,
|
||||
phantom: PhantomData<(I, R)>,
|
||||
_phantom_corpus: PhantomData<C>,
|
||||
phantom: PhantomData<(I, R, 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
|
||||
SM: ScheduledMutator<C, I, R>,
|
||||
C: Corpus<I, R>,
|
||||
I: Input + HasBytesVec,
|
||||
SM: ScheduledMutator<C, I, R>,
|
||||
R: Rand,
|
||||
{
|
||||
/// Mutate bytes
|
||||
fn mutate(
|
||||
&mut self,
|
||||
corpus: &mut C,
|
||||
rand: &mut R,
|
||||
corpus: &mut C,
|
||||
input: &mut I,
|
||||
stage_idx: i32,
|
||||
) -> 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
|
||||
SM: ScheduledMutator<C, I, R>,
|
||||
C: Corpus<I, R>,
|
||||
I: Input + HasBytesVec,
|
||||
SM: ScheduledMutator<C, I, R>,
|
||||
R: Rand,
|
||||
{
|
||||
/// Create a new HavocBytesMutator instance given a ScheduledMutator to wrap
|
||||
@ -296,12 +296,11 @@ where
|
||||
HavocBytesMutator {
|
||||
scheduled: scheduled,
|
||||
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
|
||||
C: Corpus<I, R>,
|
||||
I: Input + HasBytesVec,
|
||||
@ -315,7 +314,6 @@ where
|
||||
HavocBytesMutator {
|
||||
scheduled: scheduled,
|
||||
phantom: PhantomData,
|
||||
_phantom_corpus: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -334,7 +332,7 @@ mod tests {
|
||||
fn test_mut_splice() {
|
||||
// With the current impl, seed of 1 will result in a split at pos 2.
|
||||
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!['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();
|
||||
|
||||
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")]
|
||||
println!("{:?}", input.bytes());
|
||||
|
@ -4,6 +4,7 @@ pub use mutational::StdMutationalStage;
|
||||
use crate::corpus::testcase::Testcase;
|
||||
use crate::corpus::Corpus;
|
||||
use crate::engines::State;
|
||||
use crate::events::EventManager;
|
||||
use crate::executors::Executor;
|
||||
use crate::inputs::Input;
|
||||
use crate::utils::Rand;
|
||||
@ -11,11 +12,12 @@ use crate::AflError;
|
||||
use alloc::rc::Rc;
|
||||
use core::cell::RefCell;
|
||||
|
||||
pub trait Stage<S, C, E, I, R>
|
||||
pub trait Stage<S, EM, E, C, I, R>
|
||||
where
|
||||
S: State<C, E, I, R>,
|
||||
C: Corpus<I, R>,
|
||||
EM: EventManager,
|
||||
E: Executor<I>,
|
||||
C: Corpus<I, R>,
|
||||
I: Input,
|
||||
R: Rand,
|
||||
{
|
||||
@ -24,6 +26,7 @@ where
|
||||
&mut self,
|
||||
rand: &mut R,
|
||||
state: &mut S,
|
||||
events: &mut EM,
|
||||
testcase: Rc<RefCell<Testcase<I>>>,
|
||||
) -> Result<(), AflError>;
|
||||
}
|
||||
|
@ -15,12 +15,13 @@ use crate::AflError;
|
||||
|
||||
// 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
|
||||
M: Mutator<C, I, R>,
|
||||
S: State<C, E, I, R>,
|
||||
C: Corpus<I, R>,
|
||||
EM: EventManager,
|
||||
E: Executor<I>,
|
||||
C: Corpus<I, R>,
|
||||
I: Input,
|
||||
R: Rand,
|
||||
{
|
||||
@ -41,6 +42,7 @@ where
|
||||
&mut self,
|
||||
rand: &mut R,
|
||||
state: &mut S,
|
||||
events: &mut EM,
|
||||
testcase: Rc<RefCell<Testcase<I>>>,
|
||||
) -> Result<(), AflError> {
|
||||
let num = self.iterations(rand);
|
||||
@ -49,7 +51,7 @@ where
|
||||
for i in 0..num {
|
||||
let mut input_tmp = input.clone();
|
||||
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)?;
|
||||
|
||||
@ -64,28 +66,28 @@ where
|
||||
}
|
||||
|
||||
/// 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
|
||||
M: Mutator<C, I, R>,
|
||||
S: State<C, E, EM, I, R>,
|
||||
C: Corpus<I, R>,
|
||||
E: Executor<I>,
|
||||
S: State<C, E, I, R>,
|
||||
EM: EventManager,
|
||||
E: Executor<I>,
|
||||
C: Corpus<I, R>,
|
||||
I: Input,
|
||||
R: Rand,
|
||||
{
|
||||
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>
|
||||
for StdMutationalStage<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, EM, E, C, I, R>
|
||||
where
|
||||
M: Mutator<C, I, R>,
|
||||
S: State<C, E, EM, I, R>,
|
||||
C: Corpus<I, R>,
|
||||
E: Executor<I>,
|
||||
S: State<C, E, I, R>,
|
||||
EM: EventManager,
|
||||
E: Executor<I>,
|
||||
C: Corpus<I, R>,
|
||||
I: Input,
|
||||
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
|
||||
M: Mutator<C, I, R>,
|
||||
S: State<C, E, EM, I, R>,
|
||||
C: Corpus<I, R>,
|
||||
E: Executor<I>,
|
||||
S: State<C, E, I, R>,
|
||||
EM: EventManager,
|
||||
E: Executor<I>,
|
||||
C: Corpus<I, R>,
|
||||
I: Input,
|
||||
R: Rand,
|
||||
{
|
||||
fn perform(
|
||||
&mut self,
|
||||
testcase: Rc<RefCell<Testcase<I>>>,
|
||||
rand: &mut R,
|
||||
state: &mut S,
|
||||
events: &mut EM,
|
||||
testcase: Rc<RefCell<Testcase<I>>>,
|
||||
) -> 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
|
||||
M: Mutator<C, I, R>,
|
||||
S: State<C, E, EM, I, R>,
|
||||
C: Corpus<I, R>,
|
||||
E: Executor<I>,
|
||||
S: State<C, E, I, R>,
|
||||
EM: EventManager,
|
||||
E: Executor<I>,
|
||||
C: Corpus<I, R>,
|
||||
I: Input,
|
||||
R: Rand,
|
||||
{
|
||||
|
@ -8,7 +8,8 @@ use alloc::rc::Rc;
|
||||
use core::cell::RefCell;
|
||||
|
||||
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::{Executor, ExitKind};
|
||||
use afl::feedbacks::{create_history_map, MaxMapFeedback};
|
||||
@ -39,9 +40,9 @@ fn harness<I>(_executor: &dyn Executor<I>, buf: &[u8]) -> ExitKind {
|
||||
|
||||
#[no_mangle]
|
||||
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();
|
||||
corpus.add(testcase);
|
||||
|
||||
@ -58,16 +59,17 @@ pub extern "C" fn afl_libfuzzer_main() {
|
||||
state.add_feedback(Box::new(edges_feedback));
|
||||
|
||||
let mut engine = StdEngine::new();
|
||||
let mutator = HavocBytesMutator::new_default(&rand);
|
||||
let stage = StdMutationalStage::new(&rand, mutator);
|
||||
let mutator = HavocBytesMutator::new_default();
|
||||
let stage = StdMutationalStage::new(mutator);
|
||||
engine.add_stage(Box::new(stage));
|
||||
|
||||
let mut events = LoggerEventManager::new();
|
||||
|
||||
for i in 0..1000 {
|
||||
engine
|
||||
.fuzz_one(&mut state)
|
||||
.fuzz_one(&mut rand, &mut state, &mut events)
|
||||
.expect(&format!("Error in iter {}", i));
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
println!("OK");
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user