variable sized map observer
This commit is contained in:
parent
a625904399
commit
1e315baa56
@ -189,7 +189,7 @@ where
|
||||
let mut interesting = 0;
|
||||
// TODO optimize
|
||||
let observer = observers.match_name_type::<O>(&self.name).unwrap();
|
||||
let size = observer.map().len();
|
||||
let size = observer.usable_count();
|
||||
for i in 0..size {
|
||||
let history = self.history_map[i];
|
||||
let item = observer.map()[i];
|
||||
|
@ -2,7 +2,7 @@ extern crate num;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::serde_anymap::ArrayMut;
|
||||
use crate::serde_anymap::{Cptr, ArrayMut};
|
||||
use crate::tuples::{MatchNameAndType, MatchType, Named, TupleList};
|
||||
use crate::AflError;
|
||||
|
||||
@ -92,6 +92,11 @@ where
|
||||
/// 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;
|
||||
|
||||
@ -106,7 +111,8 @@ where
|
||||
fn reset_map(&mut self) -> Result<(), AflError> {
|
||||
// Normal memset, see https://rust.godbolt.org/z/Trs5hv
|
||||
let initial = self.initial();
|
||||
for i in self.map_mut().iter_mut() {
|
||||
let cnt = self.usable_count();
|
||||
for i in self.map_mut()[0..cnt].iter_mut() {
|
||||
*i = initial;
|
||||
}
|
||||
Ok(())
|
||||
@ -204,6 +210,102 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[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 reset(&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,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg(test)]
|
||||
|
@ -629,7 +629,84 @@ impl<'a, T: Sized> SliceMut<'a, T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Array<T: Sized + serde::Serialize> {
|
||||
pub enum Cptr<T: Sized> {
|
||||
Cptr(*const T),
|
||||
Owned(Box<T>),
|
||||
}
|
||||
|
||||
impl<T: Sized + serde::Serialize> serde::Serialize for Cptr<T> {
|
||||
fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
self.as_ref().serialize(se)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, T: Sized + serde::de::DeserializeOwned> Deserialize<'de> for Cptr<T>
|
||||
where
|
||||
Vec<T>: Deserialize<'de>,
|
||||
{
|
||||
fn deserialize<D>(de: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
Deserialize::deserialize(de).map(Cptr::Owned)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Sized> Cptr<T> {
|
||||
pub fn as_ref(&self) -> &T {
|
||||
match self {
|
||||
Cptr::Cptr(p) => unsafe { p.as_ref().unwrap() },
|
||||
Cptr::Owned(v) => v.as_ref(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum CptrMut<T: Sized> {
|
||||
Cptr(*mut T),
|
||||
Owned(Box<T>),
|
||||
}
|
||||
|
||||
impl<T: Sized + serde::Serialize> serde::Serialize for CptrMut<T> {
|
||||
fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
self.as_ref().serialize(se)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, T: Sized + serde::de::DeserializeOwned> Deserialize<'de> for CptrMut<T>
|
||||
where
|
||||
Vec<T>: Deserialize<'de>,
|
||||
{
|
||||
fn deserialize<D>(de: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
Deserialize::deserialize(de).map(CptrMut::Owned)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Sized> CptrMut<T> {
|
||||
pub fn as_ref(&self) -> &T {
|
||||
match self {
|
||||
CptrMut::Cptr(p) => unsafe { p.as_ref().unwrap() },
|
||||
CptrMut::Owned(b) => b.as_ref(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_mut(&mut self) -> &mut T {
|
||||
match self {
|
||||
CptrMut::Cptr(p) => unsafe { p.as_mut().unwrap() },
|
||||
CptrMut::Owned(b) => b.as_mut(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Array<T: Sized> {
|
||||
Cptr((*const T, usize)),
|
||||
Owned(Vec<T>),
|
||||
}
|
||||
@ -655,7 +732,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Sized + serde::Serialize> Array<T> {
|
||||
impl<T: Sized> Array<T> {
|
||||
pub fn as_slice(&self) -> &[T] {
|
||||
match self {
|
||||
Array::Cptr(p) => unsafe { core::slice::from_raw_parts(p.0, p.1) },
|
||||
@ -664,7 +741,7 @@ impl<T: Sized + serde::Serialize> Array<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub enum ArrayMut<T: Sized + serde::Serialize> {
|
||||
pub enum ArrayMut<T: Sized> {
|
||||
Cptr((*mut T, usize)),
|
||||
Owned(Vec<T>),
|
||||
}
|
||||
@ -690,7 +767,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Sized + serde::Serialize> ArrayMut<T> {
|
||||
impl<T: Sized> ArrayMut<T> {
|
||||
pub fn as_slice(&self) -> &[T] {
|
||||
match self {
|
||||
ArrayMut::Cptr(p) => unsafe { core::slice::from_raw_parts(p.0, p.1) },
|
||||
|
@ -14,7 +14,7 @@ use afl::feedbacks::MaxMapFeedback;
|
||||
use afl::generators::RandPrintablesGenerator;
|
||||
use afl::mutators::scheduled::HavocBytesMutator;
|
||||
use afl::mutators::HasMaxSize;
|
||||
use afl::observers::StdMapObserver;
|
||||
use afl::observers::VariableMapObserver;
|
||||
use afl::stages::mutational::StdMutationalStage;
|
||||
use afl::tuples::tuple_list;
|
||||
use afl::utils::StdRand;
|
||||
@ -66,7 +66,7 @@ pub extern "C" fn fuzz_main_loop() {
|
||||
}
|
||||
println!("We're a client, let's fuzz :)");
|
||||
|
||||
let edges_observer = StdMapObserver::new_from_ptr(&NAME_COV_MAP, unsafe { fuzz_hitcounts_map.as_mut_ptr() }, unsafe { fuzz_edges_id });
|
||||
let edges_observer = VariableMapObserver::new(&NAME_COV_MAP, unsafe { &mut fuzz_hitcounts_map }, unsafe { &fuzz_edges_id });
|
||||
let edges_feedback = MaxMapFeedback::new_with_observer(&NAME_COV_MAP, &edges_observer);
|
||||
|
||||
let executor = InMemoryExecutor::new("QEMUFuzzer", harness, tuple_list!(edges_observer));
|
||||
|
Loading…
x
Reference in New Issue
Block a user