added corpus to mutators
This commit is contained in:
parent
fe892a94f0
commit
74beae3636
@ -1,5 +1,6 @@
|
|||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
pub mod scheduled;
|
pub mod scheduled;
|
||||||
|
use crate::corpus::Corpus;
|
||||||
pub use scheduled::ComposedByMutations;
|
pub use scheduled::ComposedByMutations;
|
||||||
pub use scheduled::DefaultScheduledMutator;
|
pub use scheduled::DefaultScheduledMutator;
|
||||||
pub use scheduled::HavocBytesMutator;
|
pub use scheduled::HavocBytesMutator;
|
||||||
@ -9,12 +10,13 @@ use crate::inputs::Input;
|
|||||||
use crate::utils::HasRand;
|
use crate::utils::HasRand;
|
||||||
use crate::AflError;
|
use crate::AflError;
|
||||||
|
|
||||||
pub trait Mutator<I>: HasRand
|
pub trait Mutator<C, I>: HasRand
|
||||||
where
|
where
|
||||||
|
C: Corpus<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
{
|
{
|
||||||
/// Mutate a given input
|
/// Mutate a given input
|
||||||
fn mutate(&mut self, input: &mut I, stage_idx: i32) -> Result<(), AflError>;
|
fn mutate(&mut self, 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> {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
use crate::mutators::Corpus;
|
||||||
use crate::inputs::{HasBytesVec, Input};
|
use crate::inputs::{HasBytesVec, Input};
|
||||||
use crate::mutators::Mutator;
|
use crate::mutators::Mutator;
|
||||||
use crate::utils::{HasRand, Rand};
|
use crate::utils::{HasRand, Rand};
|
||||||
@ -9,24 +10,26 @@ use core::cell::RefCell;
|
|||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
/// The generic function type that identifies mutations
|
/// The generic function type that identifies mutations
|
||||||
type MutationFunction<M, I> = fn(&mut M, &mut I) -> Result<(), AflError>;
|
type MutationFunction<C, M, I> = fn(&mut M, &mut C, &mut I) -> Result<(), AflError>;
|
||||||
|
|
||||||
pub trait ComposedByMutations<I>
|
pub trait ComposedByMutations<C, I>
|
||||||
where
|
where
|
||||||
|
C: Corpus<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
{
|
{
|
||||||
/// Get a mutation by index
|
/// Get a mutation by index
|
||||||
fn mutation_by_idx(&self, index: usize) -> Result<MutationFunction<Self, I>, AflError>;
|
fn mutation_by_idx(&self, index: usize) -> Result<MutationFunction<C, Self, I>, 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, I>);
|
fn add_mutation(&mut self, mutation: MutationFunction<C, Self, I>);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ScheduledMutator<I>: Mutator<I> + ComposedByMutations<I>
|
pub trait ScheduledMutator<C, I>: Mutator<C, I> + ComposedByMutations<C, I>
|
||||||
where
|
where
|
||||||
|
C: Corpus<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
{
|
{
|
||||||
/// Compute the number of iterations used to apply stacked mutations
|
/// Compute the number of iterations used to apply stacked mutations
|
||||||
@ -35,7 +38,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the next mutation to apply
|
/// Get the next mutation to apply
|
||||||
fn schedule(&mut self, _input: &I) -> Result<MutationFunction<Self, I>, AflError> {
|
fn schedule(&mut self, _input: &I) -> Result<MutationFunction<C, Self, I>, 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".to_string()));
|
return Err(AflError::Empty("no mutations".to_string()));
|
||||||
@ -49,26 +52,28 @@ where
|
|||||||
|
|
||||||
/// New default implementation for mutate
|
/// New default implementation for mutate
|
||||||
/// Implementations must forward mutate() to this method
|
/// Implementations must forward mutate() to this method
|
||||||
fn scheduled_mutate(&mut self, input: &mut I, _stage_idx: i32) -> Result<(), AflError> {
|
fn scheduled_mutate(&mut self, corpus: &mut C, input: &mut I, _stage_idx: i32) -> Result<(), AflError> {
|
||||||
let num = self.iterations(input);
|
let num = self.iterations(input);
|
||||||
for _ in 0..num {
|
for _ in 0..num {
|
||||||
self.schedule(input)?(self, input)?;
|
self.schedule(input)?(self, corpus, input)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DefaultScheduledMutator<'a, I, R>
|
pub struct DefaultScheduledMutator<'a, C, I, R>
|
||||||
where
|
where
|
||||||
|
C: Corpus<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
rand: Rc<RefCell<R>>,
|
rand: Rc<RefCell<R>>,
|
||||||
mutations: Vec<MutationFunction<Self, I>>,
|
mutations: Vec<MutationFunction<C, Self, I>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I, R> HasRand for DefaultScheduledMutator<'_, I, R>
|
impl<'a, C, I, R> HasRand for DefaultScheduledMutator<'_, C, I, R>
|
||||||
where
|
where
|
||||||
|
C: Corpus<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
@ -79,22 +84,24 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I, R> Mutator<I> for DefaultScheduledMutator<'_, I, R>
|
impl<'a, C, I, R> Mutator<C, I> for DefaultScheduledMutator<'_, C, I, R>
|
||||||
where
|
where
|
||||||
|
C: Corpus<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
fn mutate(&mut self, input: &mut I, _stage_idx: i32) -> Result<(), AflError> {
|
fn mutate(&mut self, corpus: &mut C, input: &mut I, _stage_idx: i32) -> Result<(), AflError> {
|
||||||
self.scheduled_mutate(input, _stage_idx)
|
self.scheduled_mutate(corpus, input, _stage_idx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I, R> ComposedByMutations<I> for DefaultScheduledMutator<'_, I, R>
|
impl<'a, C, I, R> ComposedByMutations<C, I> for DefaultScheduledMutator<'_, C, I, R>
|
||||||
where
|
where
|
||||||
|
C: Corpus<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
fn mutation_by_idx(&self, index: usize) -> Result<MutationFunction<Self, I>, AflError> {
|
fn mutation_by_idx(&self, index: usize) -> Result<MutationFunction<C, Self, I>, AflError> {
|
||||||
if index >= self.mutations.len() {
|
if index >= self.mutations.len() {
|
||||||
return Err(AflError::Unknown("oob".to_string()));
|
return Err(AflError::Unknown("oob".to_string()));
|
||||||
}
|
}
|
||||||
@ -105,21 +112,23 @@ where
|
|||||||
self.mutations.len()
|
self.mutations.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_mutation(&mut self, mutation: MutationFunction<Self, I>) {
|
fn add_mutation(&mut self, mutation: MutationFunction<C, Self, I>) {
|
||||||
self.mutations.push(mutation)
|
self.mutations.push(mutation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I, R> ScheduledMutator<I> for DefaultScheduledMutator<'_, I, R>
|
impl<'a, C, I, R> ScheduledMutator<C, I> for DefaultScheduledMutator<'_, C, I, R>
|
||||||
where
|
where
|
||||||
|
C: Corpus<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
// Just use the default methods
|
// Just use the default methods
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I, R> DefaultScheduledMutator<'a, I, R>
|
impl<'a, C, I, R> DefaultScheduledMutator<'a, C, I, R>
|
||||||
where
|
where
|
||||||
|
C: Corpus<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
@ -132,7 +141,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new DefaultScheduledMutator instance specifying mutations and corpus too
|
/// Create a new DefaultScheduledMutator instance specifying mutations and corpus too
|
||||||
pub fn new_all(rand: &Rc<RefCell<R>>, mutations: Vec<MutationFunction<Self, I>>) -> Self {
|
pub fn new_all(rand: &Rc<RefCell<R>>, mutations: Vec<MutationFunction<C, Self, I>>) -> Self {
|
||||||
DefaultScheduledMutator {
|
DefaultScheduledMutator {
|
||||||
rand: Rc::clone(rand),
|
rand: Rc::clone(rand),
|
||||||
mutations: mutations,
|
mutations: mutations,
|
||||||
@ -141,9 +150,10 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Bitflip mutation for inputs with a bytes vector
|
/// Bitflip mutation for inputs with a bytes vector
|
||||||
pub fn mutation_bitflip<M, I>(mutator: &mut M, input: &mut I) -> Result<(), AflError>
|
pub fn mutation_bitflip<C, M, I>(mutator: &mut M, _corpus: &mut C, input: &mut I) -> Result<(), AflError>
|
||||||
where
|
where
|
||||||
M: Mutator<I>,
|
C: Corpus<I>,
|
||||||
|
M: Mutator<C, I>,
|
||||||
I: Input + HasBytesVec,
|
I: Input + HasBytesVec,
|
||||||
{
|
{
|
||||||
let bit = mutator.rand_below(input.bytes().len() as u64) as usize;
|
let bit = mutator.rand_below(input.bytes().len() as u64) as usize;
|
||||||
@ -152,19 +162,22 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Schedule some selected byte level mutations given a ScheduledMutator type
|
/// Schedule some selected byte level mutations given a ScheduledMutator type
|
||||||
pub struct HavocBytesMutator<I, S>
|
pub struct HavocBytesMutator<C, I, S>
|
||||||
where
|
where
|
||||||
|
C: Corpus<I>,
|
||||||
I: Input + HasBytesVec,
|
I: Input + HasBytesVec,
|
||||||
S: ScheduledMutator<I>,
|
S: ScheduledMutator<C, I>,
|
||||||
{
|
{
|
||||||
scheduled: S,
|
scheduled: S,
|
||||||
phantom: PhantomData<I>,
|
phantom: PhantomData<I>,
|
||||||
|
_phantom_corpus: PhantomData<C>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, S> HasRand for HavocBytesMutator<I, S>
|
impl<C, I, S> HasRand for HavocBytesMutator<C, I, S>
|
||||||
where
|
where
|
||||||
|
C: Corpus<I>,
|
||||||
I: Input + HasBytesVec,
|
I: Input + HasBytesVec,
|
||||||
S: ScheduledMutator<I>,
|
S: ScheduledMutator<C, I>,
|
||||||
{
|
{
|
||||||
type R = S::R;
|
type R = S::R;
|
||||||
|
|
||||||
@ -173,20 +186,22 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, S> Mutator<I> for HavocBytesMutator<I, S>
|
impl<C, I, S> Mutator<C, I> for HavocBytesMutator<C, I, S>
|
||||||
where
|
where
|
||||||
|
C: Corpus<I>,
|
||||||
I: Input + HasBytesVec,
|
I: Input + HasBytesVec,
|
||||||
S: ScheduledMutator<I>,
|
S: ScheduledMutator<C, I>,
|
||||||
{
|
{
|
||||||
fn mutate(&mut self, input: &mut I, stage_idx: i32) -> Result<(), AflError> {
|
fn mutate(&mut self, corpus: &mut C, input: &mut I, stage_idx: i32) -> Result<(), AflError> {
|
||||||
self.scheduled.mutate(input, stage_idx)
|
self.scheduled.mutate(corpus, input, stage_idx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, S> HavocBytesMutator<I, S>
|
impl<C, I, S> HavocBytesMutator<C, I, S>
|
||||||
where
|
where
|
||||||
|
C: Corpus<I>,
|
||||||
I: Input + HasBytesVec,
|
I: Input + HasBytesVec,
|
||||||
S: ScheduledMutator<I>,
|
S: ScheduledMutator<C, I>,
|
||||||
{
|
{
|
||||||
/// Create a new HavocBytesMutator instance given a ScheduledMutator to wrap
|
/// Create a new HavocBytesMutator instance given a ScheduledMutator to wrap
|
||||||
pub fn new(mut scheduled: S) -> Self {
|
pub fn new(mut scheduled: S) -> Self {
|
||||||
@ -194,22 +209,25 @@ where
|
|||||||
HavocBytesMutator {
|
HavocBytesMutator {
|
||||||
scheduled: scheduled,
|
scheduled: scheduled,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_phantom_corpus: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I, R> HavocBytesMutator<I, DefaultScheduledMutator<'a, I, R>>
|
impl<'a, C, I, R> HavocBytesMutator<C, I, DefaultScheduledMutator<'a, C, I, R>>
|
||||||
where
|
where
|
||||||
|
C: Corpus<I>,
|
||||||
I: Input + HasBytesVec,
|
I: Input + HasBytesVec,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
/// Create a new HavocBytesMutator instance wrapping DefaultScheduledMutator
|
/// Create a new HavocBytesMutator instance wrapping DefaultScheduledMutator
|
||||||
pub fn new_default(rand: &Rc<RefCell<R>>) -> Self {
|
pub fn new_default(rand: &Rc<RefCell<R>>) -> Self {
|
||||||
let mut scheduled = DefaultScheduledMutator::<'a, I, R>::new(rand);
|
let mut scheduled = DefaultScheduledMutator::<'a, C, I, R>::new(rand);
|
||||||
scheduled.add_mutation(mutation_bitflip);
|
scheduled.add_mutation(mutation_bitflip);
|
||||||
HavocBytesMutator {
|
HavocBytesMutator {
|
||||||
scheduled: scheduled,
|
scheduled: scheduled,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_phantom_corpus: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ pub trait MutationalStage<C, I, M, E>: Stage<C, I> + HasRand
|
|||||||
where
|
where
|
||||||
C: Corpus<I>,
|
C: Corpus<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
M: Mutator<I, R = Self::R>,
|
M: Mutator<C, I, R = Self::R>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
{
|
{
|
||||||
/// The mutator registered for this stage
|
/// The mutator registered for this stage
|
||||||
@ -44,7 +44,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().mutate(&mut input_tmp, i as i32)?;
|
self.mutator_mut().mutate(corpus, &mut input_tmp, i as i32)?;
|
||||||
|
|
||||||
let interesting = self.executor().borrow_mut().evaluate_input(&input_tmp)?;
|
let interesting = self.executor().borrow_mut().evaluate_input(&input_tmp)?;
|
||||||
|
|
||||||
@ -59,24 +59,27 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The default mutational stage
|
/// The default mutational stage
|
||||||
pub struct DefaultMutationalStage<I, R, M, E>
|
pub struct DefaultMutationalStage<C, I, R, M, E>
|
||||||
where
|
where
|
||||||
|
C: Corpus<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
M: Mutator<I, R = R>,
|
M: Mutator<C, I, R = R>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
{
|
{
|
||||||
rand: Rc<RefCell<R>>,
|
rand: Rc<RefCell<R>>,
|
||||||
executor: Rc<RefCell<E>>,
|
executor: Rc<RefCell<E>>,
|
||||||
mutator: M,
|
mutator: M,
|
||||||
|
_phantom_corpus: PhantomData<C>,
|
||||||
_phantom_input: PhantomData<I>,
|
_phantom_input: PhantomData<I>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, R, M, E> HasRand for DefaultMutationalStage<I, R, M, E>
|
impl<C, I, R, M, E> HasRand for DefaultMutationalStage<C, I, R, M, E>
|
||||||
where
|
where
|
||||||
|
C: Corpus<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
M: Mutator<I, R = R>,
|
M: Mutator<C, I, R = R>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
{
|
{
|
||||||
type R = R;
|
type R = R;
|
||||||
@ -86,12 +89,12 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, I, R, M, E> MutationalStage<C, I, M, E> for DefaultMutationalStage<I, R, M, E>
|
impl<C, I, R, M, E> MutationalStage<C, I, M, E> for DefaultMutationalStage<C, I, R, M, E>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
C: Corpus<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
M: Mutator<I, R = R>,
|
M: Mutator<C, I, R = R>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
{
|
{
|
||||||
/// The mutator, added to this stage
|
/// The mutator, added to this stage
|
||||||
@ -109,12 +112,12 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, I, R, M, E> Stage<C, I> for DefaultMutationalStage<I, R, M, E>
|
impl<C, I, R, M, E> Stage<C, I> for DefaultMutationalStage<C, I, R, M, E>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
C: Corpus<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
M: Mutator<I, R = R>,
|
M: Mutator<C, I, R = R>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
{
|
{
|
||||||
fn perform(&mut self, corpus: &mut C) -> Result<(), AflError> {
|
fn perform(&mut self, corpus: &mut C) -> Result<(), AflError> {
|
||||||
@ -122,11 +125,12 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, R, M, E> DefaultMutationalStage<I, R, M, E>
|
impl<C, I, R, M, E> DefaultMutationalStage<C, I, R, M, E>
|
||||||
where
|
where
|
||||||
|
C: Corpus<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
M: Mutator<I, R = R>,
|
M: Mutator<C, I, R = R>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
{
|
{
|
||||||
/// Creates a new default mutational stage
|
/// Creates a new default mutational stage
|
||||||
@ -135,6 +139,7 @@ where
|
|||||||
rand: Rc::clone(rand),
|
rand: Rc::clone(rand),
|
||||||
executor: Rc::clone(executor),
|
executor: Rc::clone(executor),
|
||||||
mutator: mutator,
|
mutator: mutator,
|
||||||
|
_phantom_corpus: PhantomData,
|
||||||
_phantom_input: PhantomData,
|
_phantom_input: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user