tokens mutations
This commit is contained in:
parent
c849b435b7
commit
e7f27a96fd
@ -2,6 +2,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,
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
@ -914,7 +912,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,
|
||||||
|
@ -1,11 +1,61 @@
|
|||||||
|
|
||||||
|
use crate::{
|
||||||
|
inputs::{HasBytesVec, Input},
|
||||||
|
mutators::*,
|
||||||
|
utils::Rand,
|
||||||
|
serde_anymap::SerdeAny,
|
||||||
|
AflError,
|
||||||
|
};
|
||||||
|
|
||||||
struct Tokens {
|
use alloc::{vec::Vec};
|
||||||
vec: Vec<Vec<u8>>,
|
use serde::{Serialize, Deserialize};
|
||||||
|
use core::any::Any;
|
||||||
|
|
||||||
|
/// Mem move in the own vec
|
||||||
|
#[inline]
|
||||||
|
fn self_mem_move(data: &mut [u8], from: usize, to: usize, len: usize) {
|
||||||
|
debug_assert!(data.len() > 0);
|
||||||
|
debug_assert!(from + len < data.len());
|
||||||
|
debug_assert!(to + len < data.len());
|
||||||
|
if len != 0 && from != to {
|
||||||
|
let ptr = data.as_mut_ptr();
|
||||||
|
unsafe { core::ptr::copy(ptr.offset(from as isize), ptr.offset(to as isize), len) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsAny for Tokens {
|
/// 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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct TokensMetadata {
|
||||||
|
tokens: Vec<Vec<u8>>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SerdeAny for TokensMetadata {
|
||||||
|
fn as_any(&self) -> &Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_any_mut(&mut self) -> &mut Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Insert a dictionary token
|
/// Insert a dictionary token
|
||||||
@ -21,25 +71,28 @@ 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,13 +109,18 @@ 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)
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user