diff --git a/afl/src/mutators/mod.rs b/afl/src/mutators/mod.rs index c575d3f9cc..ddc52ebb22 100644 --- a/afl/src/mutators/mod.rs +++ b/afl/src/mutators/mod.rs @@ -4,6 +4,8 @@ pub mod scheduled; pub use scheduled::*; pub mod mutations; pub use mutations::*; +pub mod token_mutations; +pub use token_mutations::*; use crate::{ corpus::Corpus, diff --git a/afl/src/mutators/mutations.rs b/afl/src/mutators/mutations.rs index fda3a304c7..4005ce3334 100644 --- a/afl/src/mutators/mutations.rs +++ b/afl/src/mutators/mutations.rs @@ -1,9 +1,7 @@ use crate::{ - corpus::InMemoryCorpus, - inputs::{BytesInput, HasBytesVec, Input}, + inputs::{HasBytesVec, Input}, mutators::Corpus, mutators::*, - state::State, utils::Rand, AflError, }; @@ -854,7 +852,6 @@ mod tests { use super::*; use crate::{ corpus::{Corpus, InMemoryCorpus}, - executors::InProcessExecutor, inputs::BytesInput, state::State, utils::StdRand, diff --git a/afl/src/mutators/token_mutations.rs b/afl/src/mutators/token_mutations.rs index 3e16b9749c..eb230ab450 100644 --- a/afl/src/mutators/token_mutations.rs +++ b/afl/src/mutators/token_mutations.rs @@ -1,13 +1,51 @@ //! Tokens are what afl calls extras or dictionaries. //! They may be inserted as part of mutations during fuzzing. -/// The tokens type, to be stored as metadata -struct Tokens { - vec: Vec>, +use crate::{ + inputs::{HasBytesVec, Input}, + 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>, +} + +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 @@ -23,25 +61,32 @@ where R: Rand, S: HasMetadata, { - let tokens: &Tokens = &state.metadata().get::().unwrap(); - let tokens = tokens.token_vec; - if mutator.tokens.size() == 0 { + let meta; + match state.metadata().get::() { + Some(t) => { + meta = t; + } + None => { + return Ok(MutationResult::Skipped); + } + }; + if meta.tokens.len() == 0 { return Ok(MutationResult::Skipped); } - let token = &mutator.tokens[rand.below(token.size())]; - let token_len = token.size(); + let token = &meta.tokens[rand.below(meta.tokens.len() as u64) as usize]; + let token_len = token.len(); let size = input.bytes().len(); let off = if size == 0 { 0 } else { rand.below(core::cmp::min( - size, + size as u64, (mutator.max_size() - token_len) as u64, )) as usize } as usize; 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) } @@ -58,13 +103,22 @@ where R: Rand, S: HasMetadata, { - if mutator.tokens.size() > len || !len { + let meta; + match state.metadata().get::() { + Some(t) => { + meta = t; + } + None => { + return Ok(MutationResult::Skipped); + } + }; + if meta.tokens.len() == 0 { return Ok(MutationResult::Skipped); } - let token = &mutator.tokens[rand.below(token.size())]; - let token_len = token.size(); + let token = &meta.tokens[rand.below(meta.tokens.len() as u64) as usize]; + let token_len = token.len(); let size = input.bytes().len(); 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) } diff --git a/afl/src/state/mod.rs b/afl/src/state/mod.rs index 3a194a48c1..88b6522349 100644 --- a/afl/src/state/mod.rs +++ b/afl/src/state/mod.rs @@ -24,11 +24,6 @@ use crate::{ #[cfg(feature = "std")] 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 pub trait HasCorpus { /// The testcase corpus