almost finished MinimizerCorpusScheduler

This commit is contained in:
Andrea Fioraldi 2021-02-26 16:23:09 +01:00
parent 58c642427e
commit 913968a68d
7 changed files with 125 additions and 51 deletions

View File

@ -10,7 +10,7 @@ use criterion::{black_box, criterion_group, criterion_main, Criterion};
use libafl::utils::{Rand, StdRand}; use libafl::utils::{Rand, StdRand};
fn criterion_benchmark(c: &mut Criterion) { fn criterion_benchmark(c: &mut Criterion) {
let mut rand = StdRand::new(0); let mut rand = StdRand::with_seed(0);
let mut bench_vec: Vec<u8> = vec![]; let mut bench_vec: Vec<u8> = vec![];
for _ in 0..2 << 16 { for _ in 0..2 << 16 {
bench_vec.push(rand.below(256) as u8); bench_vec.push(rand.below(256) as u8);

View File

@ -6,11 +6,11 @@ use libafl::utils::{
}; };
fn criterion_benchmark(c: &mut Criterion) { fn criterion_benchmark(c: &mut Criterion) {
let mut xorshift = XorShift64Rand::new(1); let mut xorshift = XorShift64Rand::with_seed(1);
let mut xoshiro = Xoshiro256StarRand::new(1); let mut xoshiro = Xoshiro256StarRand::with_seed(1);
let mut romu = RomuDuoJrRand::new(1); let mut romu = RomuDuoJrRand::with_seed(1);
let mut lehmer = Lehmer64Rand::new(1); let mut lehmer = Lehmer64Rand::with_seed(1);
let mut romu_trio = RomuTrioRand::new(1); let mut romu_trio = RomuTrioRand::with_seed(1);
c.bench_function("xorshift", |b| b.iter(|| black_box(xorshift.next()))); c.bench_function("xorshift", |b| b.iter(|| black_box(xorshift.next())));
c.bench_function("xoshiro", |b| b.iter(|| black_box(xoshiro.next()))); c.bench_function("xoshiro", |b| b.iter(|| black_box(xoshiro.next())));

View File

@ -505,11 +505,11 @@ pub use serdeany_registry::*;
macro_rules! impl_serdeany { macro_rules! impl_serdeany {
($struct_name:ident) => { ($struct_name:ident) => {
impl crate::bolts::serdeany::SerdeAny for $struct_name { impl crate::bolts::serdeany::SerdeAny for $struct_name {
fn as_any(&self) -> &dyn Any { fn as_any(&self) -> &dyn core::any::Any {
self self
} }
fn as_any_mut(&mut self) -> &mut dyn Any { fn as_any_mut(&mut self) -> &mut dyn core::any::Any {
self self
} }
} }

View File

@ -1,12 +1,38 @@
use core::marker::PhantomData;
use crate::{ use crate::{
bolts::serdeany::SerdeAny,
corpus::{Corpus, CorpusScheduler, Testcase}, corpus::{Corpus, CorpusScheduler, Testcase},
inputs::{HasLen, Input}, inputs::{HasLen, Input},
state::HasCorpus, state::{HasCorpus, HasMetadata},
Error, Error,
}; };
use core::{iter::IntoIterator, marker::PhantomData};
use hashbrown::{HashMap, HashSet};
use serde::{Deserialize, Serialize};
/// A testcase metadata saying if a testcase is favored
#[derive(Serialize, Deserialize)]
pub struct IsFavoredMetadata {}
crate::impl_serdeany!(IsFavoredMetadata);
/// A state metadata holding a map of favoreds testcases for each map entry
#[derive(Serialize, Deserialize)]
pub struct TopRatedsMetadata {
/// map index -> corpus index
pub map: HashMap<usize, usize>,
}
crate::impl_serdeany!(TopRatedsMetadata);
impl TopRatedsMetadata {
pub fn new() -> Self {
Self {
map: HashMap::default(),
}
}
}
pub trait FavFactor<I> pub trait FavFactor<I>
where where
I: Input, I: Input,
@ -30,24 +56,28 @@ where
} }
} }
pub struct MinimizerCorpusScheduler<C, CS, F, I, S> pub struct MinimizerCorpusScheduler<C, CS, F, I, IT, S>
where where
CS: CorpusScheduler<I, S>, CS: CorpusScheduler<I, S>,
F: FavFactor<I>, F: FavFactor<I>,
I: Input, I: Input,
S: HasCorpus<C, I>, IT: IntoIterator<Item = usize> + SerdeAny,
for<'a> &'a IT: IntoIterator<Item = usize>,
S: HasCorpus<C, I> + HasMetadata,
C: Corpus<I>, C: Corpus<I>,
{ {
base: CS, base: CS,
phantom: PhantomData<(C, F, I, S)>, phantom: PhantomData<(C, F, I, IT, S)>,
} }
impl<C, CS, F, I, S> CorpusScheduler<I, S> for MinimizerCorpusScheduler<C, CS, F, I, S> impl<C, CS, F, I, IT, S> CorpusScheduler<I, S> for MinimizerCorpusScheduler<C, CS, F, I, IT, S>
where where
CS: CorpusScheduler<I, S>, CS: CorpusScheduler<I, S>,
F: FavFactor<I>, F: FavFactor<I>,
I: Input, I: Input,
S: HasCorpus<C, I>, IT: IntoIterator<Item = usize> + SerdeAny,
for<'a> &'a IT: IntoIterator<Item = usize>,
S: HasCorpus<C, I> + HasMetadata,
C: Corpus<I>, C: Corpus<I>,
{ {
/// Add an entry to the corpus and return its index /// Add an entry to the corpus and return its index
@ -77,27 +107,68 @@ where
} }
} }
impl<C, CS, F, I, S> MinimizerCorpusScheduler<C, CS, F, I, S> impl<C, CS, F, I, IT, S> MinimizerCorpusScheduler<C, CS, F, I, IT, S>
where where
CS: CorpusScheduler<I, S>, CS: CorpusScheduler<I, S>,
F: FavFactor<I>, F: FavFactor<I>,
I: Input, I: Input,
S: HasCorpus<C, I>, IT: IntoIterator<Item = usize> + SerdeAny,
for<'a> &'a IT: IntoIterator<Item = usize>,
S: HasCorpus<C, I> + HasMetadata,
C: Corpus<I>, C: Corpus<I>,
{ {
/*pub fn update_score(&self, state: &mut S, idx: usize) -> Result<(), Error> { pub fn update_score(&self, state: &mut S, idx: usize) -> Result<(), Error> {
let entry = state.corpus().get(idx)?.borrow_mut(); let mut new_favoreds = vec![];
{
let mut entry = state.corpus().get(idx)?.borrow_mut();
let factor = F::compute(&mut *entry)?; let factor = F::compute(&mut *entry)?;
for elem in entry.get::<IT>() { for elem in entry.metadatas().get::<IT>().unwrap() {
if let val = self.top_rated.get_mut(elem) { // TODO proper check for TopRatedsMetadata and create a new one if not present
if factor > F::compute(self.entries()[val].borrow())? { if let Some(old_idx) = state
continue .metadata()
.get::<TopRatedsMetadata>()
.unwrap()
.map
.get(&elem)
{
if factor > F::compute(&mut *state.corpus().get(*old_idx)?.borrow_mut())? {
continue;
} }
} }
let _ = self.top_rated.insert(elem, idx); new_favoreds.push((elem, idx));
}
}
for pair in new_favoreds {
state
.metadata_mut()
.get_mut::<TopRatedsMetadata>()
.unwrap()
.map
.insert(pair.0, pair.1);
}
Ok(())
}
pub fn cull(&self, state: &mut S) -> Result<(), Error> {
let mut acc = HashSet::new();
let top_rated = state.metadata().get::<TopRatedsMetadata>().unwrap();
for key in top_rated.map.keys() {
if !acc.contains(key) {
let idx = top_rated.map.get(key).unwrap();
let mut entry = state.corpus().get(*idx)?.borrow_mut();
for elem in entry.metadatas().get::<IT>().unwrap() {
acc.insert(elem);
}
entry.add_metadata(IsFavoredMetadata {});
}
}
Ok(())
} }
}*/
pub fn new(base: CS) -> Self { pub fn new(base: CS) -> Self {
Self { Self {
@ -106,22 +177,3 @@ where
} }
} }
} }
/*
pub fn cull(&mut self) {
let mut acc = HashSet::new();
self.minset.clear();
for key in self.top_rated.keys() {
if !acc.contains(key) {
let idx = self.top_rated.get(key).unwrap();
let entry = self.entries()[idx].borrow();
for elem in entry.get::<IT>() {
acc.insert(elem);
}
self.minset.insert(idx);
}
}
}
*/

View File

@ -120,9 +120,15 @@ where
self.fitness = fitness; self.fitness = fitness;
} }
/// Get all the metadatas into an HashMap
#[inline]
pub fn metadatas(&self) -> &SerdeAnyMap {
&self.metadatas
}
/// Get all the metadatas into an HashMap (mutable) /// Get all the metadatas into an HashMap (mutable)
#[inline] #[inline]
pub fn metadatas(&mut self) -> &mut SerdeAnyMap { pub fn metadatas_mut(&mut self) -> &mut SerdeAnyMap {
&mut self.metadatas &mut self.metadatas
} }

View File

@ -2,7 +2,7 @@ use alloc::{
string::{String, ToString}, string::{String, ToString},
vec::Vec, vec::Vec,
}; };
use core::marker::PhantomData; use core::{iter::IntoIterator, marker::PhantomData};
use num::Integer; use num::Integer;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -73,6 +73,23 @@ where
} }
} }
/// A testcase metadata holding a list of indexes of a map
#[derive(Serialize, Deserialize)]
pub struct IndexesMetadata {
pub list: Vec<usize>,
}
crate::impl_serdeany!(IndexesMetadata);
impl IntoIterator for IndexesMetadata {
type Item = usize;
type IntoIter = alloc::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.list.into_iter()
}
}
/// The most common AFL-like feedback type /// The most common AFL-like feedback type
#[derive(Serialize, Deserialize, Clone, Debug)] #[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(bound = "T: serde::de::DeserializeOwned")] #[serde(bound = "T: serde::de::DeserializeOwned")]

View File

@ -10,7 +10,6 @@ use crate::{
}; };
use alloc::vec::Vec; use alloc::vec::Vec;
use core::any::Any;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use mutations::buffer_copy; use mutations::buffer_copy;