map observers file

This commit is contained in:
Andrea Fioraldi 2021-02-13 00:16:32 +01:00
parent ffab1e021e
commit a8dd59f588
7 changed files with 373 additions and 364 deletions

View File

@ -18,7 +18,7 @@ pub fn unpack_type_id(id: TypeId) -> u64 {
unsafe { *(&id as *const _ as *const u64) }
}
/// An any object
/// A (de)serializable Any trait
pub trait SerdeAny: Any + erased_serde::Serialize {
/// returns this as Any trait
fn as_any(&self) -> &dyn Any;
@ -142,8 +142,12 @@ macro_rules! create_serde_registry_for_trait {
finalized: false,
};
/// This shugar must be used to register all the structs which
/// have trait objects that can be serialized and deserialized in the program
pub struct RegistryBuilder {}
impl RegistryBuilder {
/// Register a given struct type for trait object (de)serialization
pub fn register<T>()
where
T: $trait_name + Serialize + serde::de::DeserializeOwned,
@ -153,6 +157,7 @@ macro_rules! create_serde_registry_for_trait {
}
}
/// Finalize the registry, no more registrations are allowed after this call
pub fn finalize() {
unsafe {
REGISTRY.finalize();
@ -161,6 +166,8 @@ macro_rules! create_serde_registry_for_trait {
}
#[derive(Serialize, Deserialize)]
/// A (de)serializable anymap containing (de)serializable trait objects registered
/// in the registry
pub struct SerdeAnyMap {
map: HashMap<u64, Box<dyn $trait_name>>,
}

View File

@ -488,7 +488,7 @@ where
R: Rand,
{
let size = input.bytes().len();
let off = rand.below((size +1) as u64) as usize;
let off = rand.below((size + 1) as u64) as usize;
let mut len = 1 + rand.below(16) as usize;
if size + len > mutator.max_size() {
@ -517,7 +517,7 @@ where
R: Rand,
{
let size = input.bytes().len();
let off = rand.below((size +1) as u64) as usize;
let off = rand.below((size + 1) as u64) as usize;
let mut len = 1 + rand.below(16) as usize;
if size + len > mutator.max_size() {
@ -549,7 +549,7 @@ where
R: Rand,
{
let size = input.bytes().len();
let off = rand.below((size +1) as u64) as usize;
let off = rand.below((size + 1) as u64) as usize;
let mut len = 1 + rand.below(16) as usize;
if size + len > mutator.max_size() {
@ -700,7 +700,7 @@ where
let from = rand.below(other_size as u64) as usize;
let to = rand.below(size as u64) as usize;
let mut len = rand.below((other_size - from) as u64) as usize;
if size + len > mutator.max_size() {
if mutator.max_size() > size {
len = mutator.max_size() - size;

View File

@ -304,8 +304,7 @@ where
scheduled.add_mutation(mutation_bytesswap);
scheduled.add_mutation(mutation_tokeninsert);
/*scheduled.add_mutation(mutation_tokenreplace);
*/
scheduled.add_mutation(mutation_tokenreplace);
scheduled.add_mutation(mutation_crossover_insert);
scheduled.add_mutation(mutation_crossover_replace);

View File

@ -15,6 +15,7 @@ use serde::{Deserialize, Serialize};
use mutations::buffer_copy;
/// A state metadata holding a list of tokens
#[derive(Serialize, Deserialize)]
pub struct TokensMetadata {
tokens: Vec<Vec<u8>>,
@ -32,9 +33,7 @@ impl SerdeAny for TokensMetadata {
impl TokensMetadata {
pub fn new(tokens: Vec<Vec<u8>>) -> Self {
Self {
tokens: tokens
}
Self { tokens: tokens }
}
}
@ -64,9 +63,9 @@ where
return Ok(MutationResult::Skipped);
}
let token = &meta.tokens[rand.below(meta.tokens.len() as u64) as usize];
let size = input.bytes().len();
let off = rand.below((size +1) as u64) as usize;
let off = rand.below((size + 1) as u64) as usize;
let mut len = token.len();
if size + len > mutator.max_size() {
@ -80,7 +79,7 @@ where
input.bytes_mut().resize(size + len, 0);
buffer_self_copy(input.bytes_mut(), off, off + len, size - off);
buffer_copy(input.bytes_mut(), token, 0, off, len);
Ok(MutationResult::Mutated)
}
@ -88,7 +87,7 @@ where
pub fn mutation_tokenreplace<I, M, R, S>(
_: &mut M,
rand: &mut R,
state: &S,
state: &mut S,
input: &mut I,
) -> Result<MutationResult, AflError>
where
@ -114,9 +113,9 @@ where
return Ok(MutationResult::Skipped);
}
let token = &meta.tokens[rand.below(meta.tokens.len() as u64) as usize];
let off = rand.below(size as u64) as usize;
let mut len = token.len();
if off + len > size {
len = size - off;

340
afl/src/observers/map.rs Normal file
View File

@ -0,0 +1,340 @@
use alloc::string::{String, ToString};
use serde::{Deserialize, Serialize};
use crate::{
bolts::{
ownedref::{ArrayMut, Cptr},
tuples::Named,
},
observers::Observer,
AflError,
};
/// A MapObserver observes the static map, as oftentimes used for afl-like coverage information
pub trait MapObserver<T>: Observer
where
T: Default + Copy,
{
/// Get the map
fn map(&self) -> &[T];
/// Get the map (mutable)
fn map_mut(&mut self) -> &mut [T];
/// Get the number of usable entries in the map (all by default)
fn usable_count(&self) -> usize {
self.map().len()
}
/// Get the initial value for reset()
fn initial(&self) -> T;
/// Get the initial value for reset()
fn initial_mut(&mut self) -> &mut T;
/// Set the initial value for reset()
fn set_initial(&mut self, initial: T);
/// Reset the map
#[inline]
fn reset_map(&mut self) -> Result<(), AflError> {
// Normal memset, see https://rust.godbolt.org/z/Trs5hv
let initial = self.initial();
let cnt = self.usable_count();
for i in self.map_mut()[0..cnt].iter_mut() {
*i = initial;
}
Ok(())
}
}
/// The Map Observer retrieves the state of a map,
/// that will get updated by the target.
/// A well-known example is the AFL-Style coverage map.
#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(bound = "T: serde::de::DeserializeOwned")]
pub struct StdMapObserver<T>
where
T: Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{
map: ArrayMut<T>,
initial: T,
name: String,
}
impl<T> Observer for StdMapObserver<T>
where
T: Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{
#[inline]
fn pre_exec(&mut self) -> Result<(), AflError> {
self.reset_map()
}
}
impl<T> Named for StdMapObserver<T>
where
T: Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{
#[inline]
fn name(&self) -> &str {
self.name.as_str()
}
}
impl<T> MapObserver<T> for StdMapObserver<T>
where
T: Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{
#[inline]
fn map(&self) -> &[T] {
self.map.as_slice()
}
#[inline]
fn map_mut(&mut self) -> &mut [T] {
self.map.as_mut_slice()
}
#[inline]
fn initial(&self) -> T {
self.initial
}
#[inline]
fn initial_mut(&mut self) -> &mut T {
&mut self.initial
}
#[inline]
fn set_initial(&mut self, initial: T) {
self.initial = initial
}
}
impl<T> StdMapObserver<T>
where
T: Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{
/// Creates a new MapObserver
pub fn new(name: &'static str, map: &'static mut [T]) -> Self {
let initial = if map.len() > 0 { map[0] } else { T::default() };
Self {
map: ArrayMut::Cptr((map.as_mut_ptr(), map.len())),
name: name.to_string(),
initial,
}
}
/// Creates a new MapObserver from a raw pointer
pub fn new_from_ptr(name: &'static str, map_ptr: *mut T, len: usize) -> Self {
unsafe {
let initial = if len > 0 { *map_ptr } else { T::default() };
StdMapObserver {
map: ArrayMut::Cptr((map_ptr, len)),
name: name.to_string(),
initial,
}
}
}
}
/// Overlooking a variable bitmap
#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(bound = "T: serde::de::DeserializeOwned")]
pub struct VariableMapObserver<T>
where
T: Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{
map: ArrayMut<T>,
size: Cptr<usize>,
initial: T,
name: String,
}
impl<T> Observer for VariableMapObserver<T>
where
T: Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{
#[inline]
fn pre_exec(&mut self) -> Result<(), AflError> {
self.reset_map()
}
}
impl<T> Named for VariableMapObserver<T>
where
T: Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{
#[inline]
fn name(&self) -> &str {
self.name.as_str()
}
}
impl<T> MapObserver<T> for VariableMapObserver<T>
where
T: Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{
#[inline]
fn map(&self) -> &[T] {
self.map.as_slice()
}
#[inline]
fn map_mut(&mut self) -> &mut [T] {
self.map.as_mut_slice()
}
#[inline]
fn usable_count(&self) -> usize {
*self.size.as_ref()
}
#[inline]
fn initial(&self) -> T {
self.initial
}
#[inline]
fn initial_mut(&mut self) -> &mut T {
&mut self.initial
}
#[inline]
fn set_initial(&mut self, initial: T) {
self.initial = initial
}
}
impl<T> VariableMapObserver<T>
where
T: Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{
/// Creates a new MapObserver
pub fn new(name: &'static str, map: &'static mut [T], size: &usize) -> Self {
let initial = if map.len() > 0 { map[0] } else { T::default() };
Self {
map: ArrayMut::Cptr((map.as_mut_ptr(), map.len())),
size: Cptr::Cptr(size as *const _),
name: name.into(),
initial,
}
}
/// Creates a new MapObserver from a raw pointer
pub fn new_from_ptr(
name: &'static str,
map_ptr: *mut T,
max_len: usize,
size_ptr: *const usize,
) -> Self {
unsafe {
let initial = if max_len > 0 { *map_ptr } else { T::default() };
VariableMapObserver {
map: ArrayMut::Cptr((map_ptr, max_len)),
size: Cptr::Cptr(size_ptr),
name: name.into(),
initial,
}
}
}
}
/// Map observer with hitcounts postprocessing
#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(bound = "M: serde::de::DeserializeOwned")]
pub struct HitcountsMapObserver<M>
where
M: MapObserver<u8>,
{
base: M,
}
static COUNT_CLASS_LOOKUP: [u8; 256] = [
0, 1, 2, 0, 8, 8, 8, 8, 16, 16, 16, 16, 16, 16, 16, 16, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
];
impl<M> Observer for HitcountsMapObserver<M>
where
M: MapObserver<u8>,
{
#[inline]
fn pre_exec(&mut self) -> Result<(), AflError> {
self.reset_map()
}
#[inline]
fn post_exec(&mut self) -> Result<(), AflError> {
for x in self.map_mut().iter_mut() {
*x = COUNT_CLASS_LOOKUP[*x as usize];
}
Ok(())
}
}
impl<M> Named for HitcountsMapObserver<M>
where
M: MapObserver<u8>,
{
#[inline]
fn name(&self) -> &str {
self.base.name()
}
}
impl<M> MapObserver<u8> for HitcountsMapObserver<M>
where
M: MapObserver<u8>,
{
#[inline]
fn map(&self) -> &[u8] {
self.base.map()
}
#[inline]
fn map_mut(&mut self) -> &mut [u8] {
self.base.map_mut()
}
#[inline]
fn usable_count(&self) -> usize {
self.base.usable_count()
}
#[inline]
fn initial(&self) -> u8 {
self.base.initial()
}
#[inline]
fn initial_mut(&mut self) -> &mut u8 {
self.base.initial_mut()
}
#[inline]
fn set_initial(&mut self, initial: u8) {
self.base.set_initial(initial);
}
}
impl<M> HitcountsMapObserver<M>
where
M: MapObserver<u8>,
{
/// Creates a new MapObserver
pub fn new(base: M) -> Self {
Self { base: base }
}
}

View File

@ -1,17 +1,12 @@
extern crate num;
pub mod map;
pub use map::*;
use alloc::{
string::{String, ToString},
vec::Vec,
};
use alloc::string::{String, ToString};
use core::time::Duration;
use serde::{Deserialize, Serialize};
use crate::{
bolts::{
ownedref::{ArrayMut, Cptr},
tuples::{MatchNameAndType, MatchType, Named, TupleList},
},
bolts::tuples::{MatchNameAndType, MatchType, Named, TupleList},
utils::current_time,
AflError,
};
@ -152,335 +147,6 @@ impl Named for TimeObserver {
}
}
/// A MapObserver observes the static map, as oftentimes used for afl-like coverage information
pub trait MapObserver<T>: Observer
where
T: Default + Copy,
{
/// Get the map
fn map(&self) -> &[T];
/// Get the map (mutable)
fn map_mut(&mut self) -> &mut [T];
/// Get the number of usable entries in the map (all by default)
fn usable_count(&self) -> usize {
self.map().len()
}
/// Get the initial value for reset()
fn initial(&self) -> T;
/// Get the initial value for reset()
fn initial_mut(&mut self) -> &mut T;
/// Set the initial value for reset()
fn set_initial(&mut self, initial: T);
/// Reset the map
#[inline]
fn reset_map(&mut self) -> Result<(), AflError> {
// Normal memset, see https://rust.godbolt.org/z/Trs5hv
let initial = self.initial();
let cnt = self.usable_count();
for i in self.map_mut()[0..cnt].iter_mut() {
*i = initial;
}
Ok(())
}
}
/// The Map Observer retrieves the state of a map,
/// that will get updated by the target.
/// A well-known example is the AFL-Style coverage map.
#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(bound = "T: serde::de::DeserializeOwned")]
pub struct StdMapObserver<T>
where
T: Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{
map: ArrayMut<T>,
initial: T,
name: String,
}
impl<T> Observer for StdMapObserver<T>
where
T: Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{
#[inline]
fn pre_exec(&mut self) -> Result<(), AflError> {
self.reset_map()
}
}
impl<T> Named for StdMapObserver<T>
where
T: Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{
#[inline]
fn name(&self) -> &str {
self.name.as_str()
}
}
impl<T> MapObserver<T> for StdMapObserver<T>
where
T: Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{
#[inline]
fn map(&self) -> &[T] {
self.map.as_slice()
}
#[inline]
fn map_mut(&mut self) -> &mut [T] {
self.map.as_mut_slice()
}
#[inline]
fn initial(&self) -> T {
self.initial
}
#[inline]
fn initial_mut(&mut self) -> &mut T {
&mut self.initial
}
#[inline]
fn set_initial(&mut self, initial: T) {
self.initial = initial
}
}
impl<T> StdMapObserver<T>
where
T: Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{
/// Creates a new MapObserver
pub fn new(name: &'static str, map: &'static mut [T]) -> Self {
let initial = if map.len() > 0 { map[0] } else { T::default() };
Self {
map: ArrayMut::Cptr((map.as_mut_ptr(), map.len())),
name: name.to_string(),
initial,
}
}
/// Creates a new MapObserver from a raw pointer
pub fn new_from_ptr(name: &'static str, map_ptr: *mut T, len: usize) -> Self {
unsafe {
let initial = if len > 0 { *map_ptr } else { T::default() };
StdMapObserver {
map: ArrayMut::Cptr((map_ptr, len)),
name: name.to_string(),
initial,
}
}
}
}
/// Overlooking a variable bitmap
#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(bound = "T: serde::de::DeserializeOwned")]
pub struct VariableMapObserver<T>
where
T: Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{
map: ArrayMut<T>,
size: Cptr<usize>,
initial: T,
name: String,
}
impl<T> Observer for VariableMapObserver<T>
where
T: Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{
#[inline]
fn pre_exec(&mut self) -> Result<(), AflError> {
self.reset_map()
}
}
impl<T> Named for VariableMapObserver<T>
where
T: Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{
#[inline]
fn name(&self) -> &str {
self.name.as_str()
}
}
impl<T> MapObserver<T> for VariableMapObserver<T>
where
T: Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{
#[inline]
fn map(&self) -> &[T] {
self.map.as_slice()
}
#[inline]
fn map_mut(&mut self) -> &mut [T] {
self.map.as_mut_slice()
}
#[inline]
fn usable_count(&self) -> usize {
*self.size.as_ref()
}
#[inline]
fn initial(&self) -> T {
self.initial
}
#[inline]
fn initial_mut(&mut self) -> &mut T {
&mut self.initial
}
#[inline]
fn set_initial(&mut self, initial: T) {
self.initial = initial
}
}
impl<T> VariableMapObserver<T>
where
T: Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{
/// Creates a new MapObserver
pub fn new(name: &'static str, map: &'static mut [T], size: &usize) -> Self {
let initial = if map.len() > 0 { map[0] } else { T::default() };
Self {
map: ArrayMut::Cptr((map.as_mut_ptr(), map.len())),
size: Cptr::Cptr(size as *const _),
name: name.into(),
initial,
}
}
/// Creates a new MapObserver from a raw pointer
pub fn new_from_ptr(
name: &'static str,
map_ptr: *mut T,
max_len: usize,
size_ptr: *const usize,
) -> Self {
unsafe {
let initial = if max_len > 0 { *map_ptr } else { T::default() };
VariableMapObserver {
map: ArrayMut::Cptr((map_ptr, max_len)),
size: Cptr::Cptr(size_ptr),
name: name.into(),
initial,
}
}
}
}
/// Map observer with hitcounts postprocessing
#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(bound = "M: serde::de::DeserializeOwned")]
pub struct HitcountsMapObserver<M>
where
M: MapObserver<u8>,
{
base: M,
}
static COUNT_CLASS_LOOKUP: [u8; 256] = [
0, 1, 2, 0, 8, 8, 8, 8, 16, 16, 16, 16, 16, 16, 16, 16, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
];
impl<M> Observer for HitcountsMapObserver<M>
where
M: MapObserver<u8>,
{
#[inline]
fn pre_exec(&mut self) -> Result<(), AflError> {
self.reset_map()
}
#[inline]
fn post_exec(&mut self) -> Result<(), AflError> {
for x in self.map_mut().iter_mut() {
*x = COUNT_CLASS_LOOKUP[*x as usize];
}
Ok(())
}
}
impl<M> Named for HitcountsMapObserver<M>
where
M: MapObserver<u8>,
{
#[inline]
fn name(&self) -> &str {
self.base.name()
}
}
impl<M> MapObserver<u8> for HitcountsMapObserver<M>
where
M: MapObserver<u8>,
{
#[inline]
fn map(&self) -> &[u8] {
self.base.map()
}
#[inline]
fn map_mut(&mut self) -> &mut [u8] {
self.base.map_mut()
}
#[inline]
fn usable_count(&self) -> usize {
self.base.usable_count()
}
#[inline]
fn initial(&self) -> u8 {
self.base.initial()
}
#[inline]
fn initial_mut(&mut self) -> &mut u8 {
self.base.initial_mut()
}
#[inline]
fn set_initial(&mut self, initial: u8) {
self.base.set_initial(initial);
}
}
impl<M> HitcountsMapObserver<M>
where
M: MapObserver<u8>,
{
/// Creates a new MapObserver
pub fn new(base: M) -> Self {
Self { base: base }
}
}
#[cfg(feature = "std")]
#[cfg(test)]
mod tests {

View File

@ -4,7 +4,7 @@
use std::{env, path::PathBuf};
use afl::{
bolts::{shmem::AflShmem, tuples::tuple_list, serdeany::RegistryBuilder},
bolts::{serdeany::RegistryBuilder, shmem::AflShmem, tuples::tuple_list},
corpus::{Corpus, InMemoryCorpus},
events::setup_restarting_mgr,
events::SimpleStats,
@ -92,15 +92,13 @@ fn fuzz(corpus_dirs: Vec<PathBuf>, broker_port: u16) -> Result<(), AflError> {
// Create a PNG dictionary of not existing
if state.metadata().get::<TokensMetadata>().is_none() {
state.add_metadata(TokensMetadata::new(
vec![
vec![137, 80, 78, 71, 13, 10, 26, 10], // PNG header
"IHDR".as_bytes().to_vec(),
"IDAT".as_bytes().to_vec(),
"PLTE".as_bytes().to_vec(),
"IEND".as_bytes().to_vec(),
]
));
state.add_metadata(TokensMetadata::new(vec![
vec![137, 80, 78, 71, 13, 10, 26, 10], // PNG header
"IHDR".as_bytes().to_vec(),
"IDAT".as_bytes().to_vec(),
"PLTE".as_bytes().to_vec(),
"IEND".as_bytes().to_vec(),
]));
}
// Setup a basic mutator with a mutational stage