This commit is contained in:
Dominik Maier 2021-02-09 10:19:21 +01:00
commit f5b27046bf
4 changed files with 73 additions and 25 deletions

View File

@ -4,6 +4,8 @@ pub mod scheduled;
pub use scheduled::*; pub use scheduled::*;
pub mod mutations; pub mod mutations;
pub use mutations::*; pub use mutations::*;
pub mod token_mutations;
pub use token_mutations::*;
use crate::{ use crate::{
corpus::Corpus, corpus::Corpus,

View File

@ -1,9 +1,7 @@
use crate::{ use crate::{
corpus::InMemoryCorpus, inputs::{HasBytesVec, Input},
inputs::{BytesInput, HasBytesVec, Input},
mutators::Corpus, mutators::Corpus,
mutators::*, mutators::*,
state::State,
utils::Rand, utils::Rand,
AflError, AflError,
}; };
@ -854,7 +852,6 @@ mod tests {
use super::*; use super::*;
use crate::{ use crate::{
corpus::{Corpus, InMemoryCorpus}, corpus::{Corpus, InMemoryCorpus},
executors::InProcessExecutor,
inputs::BytesInput, inputs::BytesInput,
state::State, state::State,
utils::StdRand, utils::StdRand,

View File

@ -1,13 +1,51 @@
//! Tokens are what afl calls extras or dictionaries. //! Tokens are what afl calls extras or dictionaries.
//! They may be inserted as part of mutations during fuzzing. //! They may be inserted as part of mutations during fuzzing.
/// The tokens type, to be stored as metadata use crate::{
struct Tokens { inputs::{HasBytesVec, Input},
vec: Vec<Vec<u8>>, mutators::*,
serde_anymap::SerdeAny,
utils::Rand,
AflError,
};
use alloc::vec::Vec;
use core::any::Any;
use serde::{Deserialize, Serialize};
/// Mem move between vecs
#[inline]
fn mem_move(dst: &mut [u8], src: &[u8], from: usize, to: usize, len: usize) {
debug_assert!(dst.len() > 0);
debug_assert!(src.len() > 0);
debug_assert!(from + len < src.len());
debug_assert!(to + len < dst.len());
let dst_ptr = dst.as_mut_ptr();
let src_ptr = src.as_ptr();
if len != 0 {
unsafe {
core::ptr::copy(
src_ptr.offset(from as isize),
dst_ptr.offset(to as isize),
len,
)
}
}
} }
impl AsAny for Tokens { #[derive(Serialize, Deserialize)]
pub struct TokensMetadata {
tokens: Vec<Vec<u8>>,
}
impl SerdeAny for TokensMetadata {
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
} }
/// Insert a dictionary token /// Insert a dictionary token
@ -23,25 +61,32 @@ where
R: Rand, R: Rand,
S: HasMetadata, S: HasMetadata,
{ {
let tokens: &Tokens = &state.metadata().get::<Tokens>().unwrap(); let meta;
let tokens = tokens.token_vec; match state.metadata().get::<TokensMetadata>() {
if mutator.tokens.size() == 0 { Some(t) => {
meta = t;
}
None => {
return Ok(MutationResult::Skipped);
}
};
if meta.tokens.len() == 0 {
return Ok(MutationResult::Skipped); return Ok(MutationResult::Skipped);
} }
let token = &mutator.tokens[rand.below(token.size())]; let token = &meta.tokens[rand.below(meta.tokens.len() as u64) as usize];
let token_len = token.size(); let token_len = token.len();
let size = input.bytes().len(); let size = input.bytes().len();
let off = if size == 0 { let off = if size == 0 {
0 0
} else { } else {
rand.below(core::cmp::min( rand.below(core::cmp::min(
size, size as u64,
(mutator.max_size() - token_len) as u64, (mutator.max_size() - token_len) as u64,
)) as usize )) as usize
} as usize; } as usize;
input.bytes_mut().resize(size + token_len, 0); input.bytes_mut().resize(size + token_len, 0);
mem_move(input.bytes_mut(), token, 0, off, len); mem_move(input.bytes_mut(), token, 0, off, size);
Ok(MutationResult::Mutated) Ok(MutationResult::Mutated)
} }
@ -58,13 +103,22 @@ where
R: Rand, R: Rand,
S: HasMetadata, S: HasMetadata,
{ {
if mutator.tokens.size() > len || !len { let meta;
match state.metadata().get::<TokensMetadata>() {
Some(t) => {
meta = t;
}
None => {
return Ok(MutationResult::Skipped);
}
};
if meta.tokens.len() == 0 {
return Ok(MutationResult::Skipped); return Ok(MutationResult::Skipped);
} }
let token = &mutator.tokens[rand.below(token.size())]; let token = &meta.tokens[rand.below(meta.tokens.len() as u64) as usize];
let token_len = token.size(); let token_len = token.len();
let size = input.bytes().len(); let size = input.bytes().len();
let off = rand.below((mutator.max_size() - token_len) as u64) as usize; let off = rand.below((mutator.max_size() - token_len) as u64) as usize;
mem_move(input.bytes_mut(), token, 0, off, len); mem_move(input.bytes_mut(), token, 0, off, size);
Ok(MutationResult::Mutated) Ok(MutationResult::Mutated)
} }

View File

@ -24,11 +24,6 @@ use crate::{
#[cfg(feature = "std")] #[cfg(feature = "std")]
use crate::inputs::bytes::BytesInput; use crate::inputs::bytes::BytesInput;
pub trait StateMetadata: Debug {
/// The name of this metadata - used to find it in the list of avaliable metadata
fn name(&self) -> &'static str;
}
/// Trait for elements offering a corpus /// Trait for elements offering a corpus
pub trait HasCorpus<C> { pub trait HasCorpus<C> {
/// The testcase corpus /// The testcase corpus