a bit refactoring

This commit is contained in:
Dominik Maier 2021-01-06 00:51:57 +01:00
parent ccce1c2595
commit 4e4586d3b2
21 changed files with 207 additions and 161 deletions

View File

@ -1,19 +1,14 @@
pub mod testcase;
pub use testcase::Testcase;
use alloc::borrow::ToOwned;
use alloc::vec::Vec;
use core::cell::RefCell;
use core::marker::PhantomData;
use core::ptr;
use alloc::{borrow::ToOwned, vec::Vec};
use core::{cell::RefCell, marker::PhantomData, ptr};
use serde::{Deserialize, Serialize};
#[cfg(feature = "std")]
use std::path::PathBuf;
use crate::inputs::Input;
use crate::utils::Rand;
use crate::AflError;
use crate::{inputs::Input, utils::Rand, AflError};
/// A way to obtain the containing testcase entries
pub trait HasTestcaseVec<I>

View File

@ -1,12 +1,12 @@
use alloc::string::String;
use core::convert::Into;
use core::default::Default;
use core::option::Option;
use core::{convert::Into, default::Default, option::Option};
use serde::{Deserialize, Serialize};
use crate::inputs::Input;
use crate::serde_anymap::{SerdeAny, SerdeAnyMap};
use crate::AflError;
use crate::{
inputs::Input,
serde_anymap::{SerdeAny, SerdeAnyMap},
AflError,
};
/// An entry in the Testcase Corpus
#[derive(Default, Serialize, Deserialize, Clone, Debug)]

View File

@ -9,21 +9,23 @@ use std::{
path::{Path, PathBuf},
};
use crate::corpus::{Corpus, Testcase};
use crate::events::EventManager;
use crate::executors::{Executor, ExecutorsTuple, HasObservers};
use crate::feedbacks::FeedbacksTuple;
use crate::generators::Generator;
use crate::{
corpus::{Corpus, Testcase},
events::EventManager,
executors::{Executor, ExecutorsTuple, HasObservers},
feedbacks::FeedbacksTuple,
generators::Generator,
inputs::Input,
observers::ObserversTuple,
serde_anymap::{SerdeAny, SerdeAnyMap},
stages::StagesTuple,
tuples::{tuple_list, tuple_list_type},
utils::{current_milliseconds, Rand},
AflError,
};
#[cfg(feature = "std")]
use crate::inputs::bytes::BytesInput;
use crate::inputs::Input;
use crate::observers::ObserversTuple;
use crate::serde_anymap::{SerdeAny, SerdeAnyMap};
use crate::stages::StagesTuple;
use crate::tuples::{tuple_list, tuple_list_type};
use crate::utils::{current_milliseconds, Rand};
use crate::AflError;
pub trait StateMetadata: Debug {
/// The name of this metadata - used to find it in the list of avaliable metadatas

View File

@ -1,25 +1,30 @@
pub mod llmp;
pub mod shmem;
use alloc::string::{String, ToString};
use alloc::vec::Vec;
use core::time::Duration;
use core::{marker::PhantomData, time};
use alloc::{
string::{String, ToString},
vec::Vec,
};
use core::{
time::Duration,
{marker::PhantomData, time},
};
use serde::{Deserialize, Serialize};
use self::{
llmp::{LlmpClient, Tag},
shmem::ShMem,
};
use crate::corpus::Corpus;
use crate::executors::Executor;
use crate::feedbacks::FeedbacksTuple;
use crate::inputs::Input;
use crate::observers::ObserversTuple;
use crate::serde_anymap::Ptr;
use crate::utils::Rand;
use crate::AflError;
use crate::{engines::State, utils};
use crate::{
corpus::Corpus,
feedbacks::FeedbacksTuple,
inputs::Input,
observers::ObserversTuple,
serde_anymap::Ptr,
utils::Rand,
AflError,
{engines::State, utils},
};
#[cfg(feature = "std")]
use shmem::AflShmem;
@ -235,16 +240,23 @@ where
&mut self,
state: &mut State<I, R, FT>,
corpus: &mut C,
) -> Result<usize, AflError> where
) -> Result<usize, AflError>
where
C: Corpus<I, R>,
FT: FeedbacksTuple<I>,
R: Rand;
fn serialize_observers<OT>(&mut self, observers: &OT) -> Result<Vec<u8>, AflError> where OT: ObserversTuple {
fn serialize_observers<OT>(&mut self, observers: &OT) -> Result<Vec<u8>, AflError>
where
OT: ObserversTuple,
{
Ok(postcard::to_allocvec(observers)?)
}
fn deserialize_observers<OT>(&mut self, observers_buf: &[u8]) -> Result<OT, AflError> where OT: ObserversTuple {
fn deserialize_observers<OT>(&mut self, observers_buf: &[u8]) -> Result<OT, AflError>
where
OT: ObserversTuple,
{
Ok(postcard::from_bytes(observers_buf)?)
}
@ -254,7 +266,10 @@ where
_observers: &OT,
_corpus_size: usize,
_config: String,
) -> Result<(), AflError> where OT: ObserversTuple {
) -> Result<(), AflError>
where
OT: ObserversTuple,
{
Ok(())
}
@ -410,8 +425,7 @@ where
events: Vec<LoggerEvent<I>>,
}
impl<I, ST> EventManager<I>
for LoggerEventManager<I, ST>
impl<I, ST> EventManager<I> for LoggerEventManager<I, ST>
where
I: Input,
ST: Stats,
@ -421,10 +435,12 @@ where
&mut self,
state: &mut State<I, R, FT>,
corpus: &mut C,
) -> Result<usize, AflError> where
) -> Result<usize, AflError>
where
C: Corpus<I, R>,
FT: FeedbacksTuple<I>,
R: Rand {
R: Rand,
{
let count = self.events.len();
self.events
.drain(..)
@ -438,7 +454,10 @@ where
_observers: &OT,
corpus_size: usize,
_config: String,
) -> Result<(), AflError> where OT: ObserversTuple {
) -> Result<(), AflError>
where
OT: ObserversTuple,
{
let event = LoggerEvent::NewTestcase {
corpus_size: corpus_size,
phantom: PhantomData,
@ -823,8 +842,7 @@ where
}
}
impl<I, ST, SH> EventManager<I>
for LlmpEventManager<I, SH, ST>
impl<I, ST, SH> EventManager<I> for LlmpEventManager<I, SH, ST>
where
I: Input,
SH: ShMem,
@ -835,10 +853,12 @@ where
&mut self,
state: &mut State<I, R, FT>,
corpus: &mut C,
) -> Result<usize, AflError> where
) -> Result<usize, AflError>
where
C: Corpus<I, R>,
FT: FeedbacksTuple<I>,
R: Rand {
R: Rand,
{
// TODO: Get around local event copy by moving handle_in_client
Ok(match &mut self.llmp {
llmp::LlmpConnection::IsClient { client } => {
@ -875,7 +895,10 @@ where
observers: &OT,
corpus_size: usize,
config: String,
) -> Result<(), AflError> where OT: ObserversTuple {
) -> Result<(), AflError>
where
OT: ObserversTuple,
{
let kind = LLMPEventKind::NewTestcase {
input: Ptr::Ref(input),
observers_buf: postcard::to_allocvec(observers)?,

View File

@ -1,4 +1,4 @@
use alloc::{boxed::Box, string::ToString, vec::Vec};
use alloc::{boxed::Box, vec::Vec};
use core::{ffi::c_void, ptr};
use crate::{
@ -134,8 +134,7 @@ where
_state: &State<I, R, FT>,
_corpus: &C,
_event_mgr: &EM,
) -> Self
{
) -> Self {
/*#[cfg(feature = "std")]
unsafe {
CORPUS_PTR = _corpus as *const _ as *const c_void;
@ -155,7 +154,10 @@ where
/// Serialize the current state and corpus during an executiont to bytes.
/// This method is needed when the fuzzer run crashes and has to restart.
pub fn serialize_state_corpus<C, FT, I, R>(state: &State<I, R, FT>, corpus: &C) -> Result<Vec<u8>, AflError>
pub fn serialize_state_corpus<C, FT, I, R>(
state: &State<I, R, FT>,
corpus: &C,
) -> Result<Vec<u8>, AflError>
where
C: Corpus<I, R>,
FT: FeedbacksTuple<I>,
@ -205,12 +207,12 @@ pub mod unix_signals {
use crate::{
corpus::Corpus,
events::EventManager,
executors::{
inmemory::{OnCrashFunction, ExitKind, CURRENT_INPUT_PTR, CURRENT_ON_CRASH_FN, CORPUS_PTR, STATE_PTR, EVENT_MANAGER_PTR},
Executor,
},
engines::State,
events::EventManager,
executors::inmemory::{
ExitKind, OnCrashFunction, CORPUS_PTR, CURRENT_INPUT_PTR, CURRENT_ON_CRASH_FN,
EVENT_MANAGER_PTR, STATE_PTR,
},
feedbacks::FeedbacksTuple,
inputs::Input,
observers::ObserversTuple,
@ -243,7 +245,9 @@ pub mod unix_signals {
let input = (CURRENT_INPUT_PTR as *const I).as_ref().unwrap();
let corpus = (CORPUS_PTR as *const C).as_ref().unwrap();
let state = (EVENT_MANAGER_PTR as *const State<I, R, FT>).as_ref().unwrap();
let state = (EVENT_MANAGER_PTR as *const State<I, R, FT>)
.as_ref()
.unwrap();
let manager = (EVENT_MANAGER_PTR as *mut EM).as_mut().unwrap();
if !CURRENT_ON_CRASH_FN.is_null() {
@ -279,7 +283,9 @@ pub mod unix_signals {
let input = (CURRENT_INPUT_PTR as *const I).as_ref().unwrap();
let corpus = (CORPUS_PTR as *const C).as_ref().unwrap();
let state = (EVENT_MANAGER_PTR as *const State<I, R, FT>).as_ref().unwrap();
let state = (EVENT_MANAGER_PTR as *const State<I, R, FT>)
.as_ref()
.unwrap();
let manager = (EVENT_MANAGER_PTR as *mut EM).as_mut().unwrap();
if !CURRENT_ON_CRASH_FN.is_null() {
@ -288,7 +294,7 @@ pub mod unix_signals {
input,
state,
corpus,
manager
manager,
);
}
@ -299,8 +305,11 @@ pub mod unix_signals {
}
// TODO clearly state that manager should be static (maybe put the 'static lifetime?)
pub unsafe fn setup_crash_handlers<EM, C, E, OT, FT, I, R>(state: &State<I, R, FT>, corpus: &C, manager: &mut EM)
where
pub unsafe fn setup_crash_handlers<EM, C, E, OT, FT, I, R>(
state: &State<I, R, FT>,
corpus: &C,
manager: &mut EM,
) where
EM: EventManager<I>,
C: Corpus<I, R>,
OT: ObserversTuple,
@ -311,7 +320,7 @@ pub mod unix_signals {
CORPUS_PTR = corpus as *const _ as *const c_void;
STATE_PTR = state as *const _ as *const c_void;
EVENT_MANAGER_PTR = manager as *mut _ as *mut c_void;
let mut sa: sigaction = mem::zeroed();
libc::sigemptyset(&mut sa.sa_mask as *mut libc::sigset_t);
sa.sa_flags = SA_NODEFER | SA_SIGINFO;

View File

@ -4,10 +4,12 @@ pub mod runtime;
use core::marker::PhantomData;
use crate::inputs::{HasTargetBytes, Input};
use crate::observers::ObserversTuple;
use crate::tuples::{MatchNameAndType, MatchType, Named, TupleList};
use crate::AflError;
use crate::{
inputs::{HasTargetBytes, Input},
observers::ObserversTuple,
tuples::{MatchNameAndType, MatchType, Named, TupleList},
AflError,
};
/// How an execution finished.
pub enum ExitKind {

View File

@ -1,14 +1,18 @@
use alloc::string::{String, ToString};
use alloc::vec::Vec;
use alloc::{
string::{String, ToString},
vec::Vec,
};
use core::marker::PhantomData;
use num::Integer;
use serde::{Deserialize, Serialize};
use crate::corpus::Testcase;
use crate::inputs::Input;
use crate::observers::{MapObserver, Observer, ObserversTuple};
use crate::tuples::{Named, TupleList};
use crate::AflError;
use crate::{
corpus::Testcase,
inputs::Input,
observers::{MapObserver, Observer, ObserversTuple},
tuples::{Named, TupleList},
AflError,
};
pub type MaxMapFeedback<T, O> = MapFeedback<T, MaxReducer<T>, O>;
pub type MinMapFeedback<T, O> = MapFeedback<T, MinReducer<T>, O>;

View File

@ -1,11 +1,11 @@
use alloc::vec::Vec;
use core::cmp::min;
use core::marker::PhantomData;
use core::{cmp::min, marker::PhantomData};
use crate::inputs::bytes::BytesInput;
use crate::inputs::Input;
use crate::utils::Rand;
use crate::AflError;
use crate::{
inputs::{bytes::BytesInput, Input},
utils::Rand,
AflError,
};
/// The maximum size of dummy bytes generated by _dummy generator methods
const DUMMY_BYTES_MAX: usize = 64;

View File

@ -1,8 +1,5 @@
use alloc::borrow::ToOwned;
use alloc::rc::Rc;
use alloc::vec::Vec;
use core::cell::RefCell;
use core::convert::From;
use alloc::{borrow::ToOwned, rc::Rc, vec::Vec};
use core::{cell::RefCell, convert::From};
use serde::{Deserialize, Serialize};
use crate::inputs::{HasBytesVec, HasTargetBytes, Input, TargetBytes};

View File

@ -2,15 +2,14 @@ pub mod bytes;
pub use bytes::BytesInput;
use alloc::vec::Vec;
use core::clone::Clone;
use core::fmt::Debug;
use core::{clone::Clone, fmt::Debug};
#[cfg(feature = "std")]
use std::fs::File;
#[cfg(feature = "std")]
use std::io::{Read, Write};
#[cfg(feature = "std")]
use std::path::Path;
use std::{
fs::File,
io::{Read, Write},
path::Path,
};
use crate::AflError;

View File

@ -1,9 +1,12 @@
use alloc::boxed::Box;
use alloc::vec::Vec;
use core::any::{Any, TypeId};
use core::slice::{Iter, IterMut};
use hashbrown::hash_map::{Keys, Values, ValuesMut};
use hashbrown::HashMap;
use alloc::{boxed::Box, vec::Vec};
use core::{
any::{Any, TypeId},
slice::{Iter, IterMut},
};
use hashbrown::{
hash_map::{Keys, Values, ValuesMut},
HashMap,
};
/// A map, storing any trait object by TypeId
#[derive(Default)]

View File

@ -3,10 +3,7 @@ pub use scheduled::*;
pub mod mutations;
pub use mutations::*;
use crate::corpus::Corpus;
use crate::inputs::Input;
use crate::utils::Rand;
use crate::AflError;
use crate::{corpus::Corpus, inputs::Input, utils::Rand, AflError};
// TODO mutator stats method that produces something that can be sent with the NewTestcase event
// We can use it to report which mutations generated the testcase in the broker logs

View File

@ -1,8 +1,10 @@
use crate::inputs::{HasBytesVec, Input};
use crate::mutators::Corpus;
use crate::mutators::*;
use crate::utils::Rand;
use crate::AflError;
use crate::{
inputs::{HasBytesVec, Input},
mutators::Corpus,
mutators::*,
utils::Rand,
AflError,
};
/// The result of a mutation.
/// If the mutation got skipped, the target

View File

@ -1,11 +1,12 @@
use alloc::vec::Vec;
use core::marker::PhantomData;
use crate::inputs::{HasBytesVec, Input};
use crate::mutators::Corpus;
use crate::mutators::*;
use crate::utils::Rand;
use crate::AflError;
use crate::{
inputs::{HasBytesVec, Input},
mutators::{Corpus, *},
utils::Rand,
AflError,
};
pub trait ScheduledMutator<C, I, R>: Mutator<C, I, R> + ComposedByMutations<C, I, R>
where

View File

@ -1,12 +1,16 @@
extern crate num;
use alloc::string::{String, ToString};
use alloc::vec::Vec;
use alloc::{
string::{String, ToString},
vec::Vec,
};
use serde::{Deserialize, Serialize};
use crate::serde_anymap::{ArrayMut, Cptr};
use crate::tuples::{MatchNameAndType, MatchType, Named, TupleList};
use crate::AflError;
use crate::{
serde_anymap::{ArrayMut, Cptr},
tuples::{MatchNameAndType, MatchType, Named, TupleList},
AflError,
};
/// Observers observe different information about the target.
/// They can then be used by various sorts of feedback.

View File

@ -1,16 +1,18 @@
pub mod mutational;
pub use mutational::StdMutationalStage;
use crate::corpus::Corpus;
use crate::engines::{Engine, State};
use crate::events::EventManager;
use crate::executors::{Executor, ExecutorsTuple, HasObservers};
use crate::feedbacks::FeedbacksTuple;
use crate::inputs::Input;
use crate::observers::ObserversTuple;
use crate::tuples::TupleList;
use crate::utils::Rand;
use crate::AflError;
use crate::{
corpus::Corpus,
engines::{Engine, State},
events::EventManager,
executors::{Executor, ExecutorsTuple, HasObservers},
feedbacks::FeedbacksTuple,
inputs::Input,
observers::ObserversTuple,
tuples::TupleList,
utils::Rand,
AflError,
};
/// A stage is one step in the fuzzing process.
/// Multiple stages will be scheduled one by one for each input.

View File

@ -1,16 +1,18 @@
use core::marker::PhantomData;
use crate::engines::State;
use crate::events::EventManager;
use crate::executors::{Executor, ExecutorsTuple, HasObservers};
use crate::feedbacks::FeedbacksTuple;
use crate::inputs::Input;
use crate::mutators::Mutator;
use crate::observers::ObserversTuple;
use crate::stages::Corpus;
use crate::stages::{Engine, Stage};
use crate::utils::Rand;
use crate::AflError;
use crate::{
engines::State,
events::EventManager,
executors::{Executor, ExecutorsTuple, HasObservers},
feedbacks::FeedbacksTuple,
inputs::Input,
mutators::Mutator,
observers::ObserversTuple,
stages::Corpus,
stages::{Engine, Stage},
utils::Rand,
AflError,
};
// TODO multi mutators stage

View File

@ -1,6 +1,4 @@
pub use tuple_list::tuple_list;
pub use tuple_list::tuple_list_type;
pub use tuple_list::TupleList;
pub use tuple_list::{tuple_list, tuple_list_type, TupleList};
use core::any::TypeId;

View File

@ -1,9 +1,7 @@
//! Utility functions for AFL
use alloc::rc::Rc;
use core::debug_assert;
use core::fmt::Debug;
use core::{cell::RefCell, time};
use core::{cell::RefCell, debug_assert, fmt::Debug, time};
use xxhash_rust::xxh3::xxh3_64_with_seed;
#[cfg(feature = "std")]

View File

@ -4,7 +4,8 @@ use std::env;
use std::path::Path;
use std::process::Command;
const LIBPNG_URL: &str = "https://deac-fra.dl.sourceforge.net/project/libpng/libpng16/1.6.37/libpng-1.6.37.tar.xz";
const LIBPNG_URL: &str =
"https://deac-fra.dl.sourceforge.net/project/libpng/libpng16/1.6.37/libpng-1.6.37.tar.xz";
fn main() {
let out_dir = env::var_os("OUT_DIR").unwrap();
@ -18,7 +19,7 @@ fn main() {
let libpng = format!("{}/libpng-1.6.37", &out_dir);
let libpng_path = Path::new(&libpng);
let libpng_tar = format!("{}/libpng-1.6.37.tar.xz", &cwd);
if !libpng_path.is_dir() {
if !Path::new(&libpng_tar).is_file() {
println!("cargo:warning=Libpng not found, downloading...");
@ -82,7 +83,7 @@ fn main() {
.status()
.unwrap();
}
cc::Build::new()
.include(&libpng_path)
.file("../libfuzzer_runtime/rt.c")

View File

@ -2,7 +2,6 @@
extern crate clap;
use clap::{App, Arg};
use postcard;
use std::{env, path::PathBuf, process::Command};
use afl::{
@ -15,17 +14,17 @@ use afl::{
EventManager, LlmpEventManager, SimpleStats,
},
executors::{
inmemory::{serialize_state_corpus, deserialize_state_corpus, InMemoryExecutor},
inmemory::{deserialize_state_corpus, serialize_state_corpus, InMemoryExecutor},
Executor, ExitKind,
},
feedbacks::MaxMapFeedback,
generators::RandPrintablesGenerator,
inputs::BytesInput,
mutators::{scheduled::HavocBytesMutator, HasMaxSize},
observers::StdMapObserver,
stages::mutational::StdMutationalStage,
tuples::tuple_list,
utils::StdRand,
inputs::BytesInput,
AflError,
};
@ -104,7 +103,10 @@ fn fuzz(input: Option<Vec<PathBuf>>, broker_port: u16) -> Result<(), AflError> {
// We are the fuzzing instance, first, connect to all channels.
// Mgr to send and receive msgs from/to all other fuzzer instances
mgr = LlmpEventManager::<BytesInput, _, _>::existing_client_from_env_std(ENV_FUZZER_BROKER_CLIENT, stats)?;
mgr = LlmpEventManager::<BytesInput, _, _>::existing_client_from_env_std(
ENV_FUZZER_BROKER_CLIENT,
stats,
)?;
// A sender and a receiver for single communication
let mut receiver = LlmpReceiver::<AflShmem>::on_existing_from_env(ENV_FUZZER_RECEIVER)?;
let mut sender = LlmpSender::<AflShmem>::on_existing_from_env(ENV_FUZZER_SENDER)?;
@ -143,9 +145,14 @@ fn fuzz(input: Option<Vec<PathBuf>>, broker_port: u16) -> Result<(), AflError> {
tuple_list!(edges_observer),
Box::new(move |exit_kind, input, state, corpus, mgr| {
match exit_kind {
ExitKind::Timeout => mgr.timeout(input).expect(&format!("Error sending Timeout event for input {:?}", input)),
ExitKind::Crash => mgr.crash(input).expect(&format!("Error sending crash event for input {:?}", input)),
_ => ()
ExitKind::Timeout => mgr.timeout(input).expect(&format!(
"Error sending Timeout event for input {:?}",
input
)),
ExitKind::Crash => mgr
.crash(input)
.expect(&format!("Error sending crash event for input {:?}", input)),
_ => (),
}
let state_corpus_serialized = serialize_state_corpus(state, corpus).unwrap();
sender.send_buf(0x1, &state_corpus_serialized).unwrap();
@ -250,6 +257,6 @@ pub fn main() {
println!("Workdir: {:?}", workdir);
fuzz(Some(vec![PathBuf::from("./corpus/")]), broker_port).expect("An error occurred while fuzzing");
fuzz(Some(vec![PathBuf::from("./in1")]), broker_port).expect("An error occurred while fuzzing");
//fuzz(input, broker_port).expect("An error occurred while fuzzing");
}