added some comments
This commit is contained in:
parent
fd45ef7c27
commit
526ae75262
@ -14,6 +14,7 @@ use crate::inputs::Input;
|
|||||||
use crate::utils::Rand;
|
use crate::utils::Rand;
|
||||||
use crate::AflError;
|
use crate::AflError;
|
||||||
|
|
||||||
|
/// A way to obtain the containing testcase entries
|
||||||
pub trait HasTestcaseVec<I>
|
pub trait HasTestcaseVec<I>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
@ -111,6 +112,7 @@ where
|
|||||||
fn current_testcase(&self) -> (&RefCell<Testcase<I>>, usize);
|
fn current_testcase(&self) -> (&RefCell<Testcase<I>>, usize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A corpus handling all important fuzzing in memory.
|
||||||
pub struct InMemoryCorpus<I, R>
|
pub struct InMemoryCorpus<I, R>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
@ -171,6 +173,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A corpus able to store testcases to dis, and load them from disk, when they are being used.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub struct OnDiskCorpus<I, R>
|
pub struct OnDiskCorpus<I, R>
|
||||||
where
|
where
|
||||||
|
@ -21,13 +21,17 @@ pub trait StateMetadata: Debug {
|
|||||||
fn name(&self) -> &'static str;
|
fn name(&self) -> &'static str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The state a fuzz run.
|
||||||
pub struct State<I, R>
|
pub struct State<I, R>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
|
/// How many times the executor ran the harness/target
|
||||||
executions: usize,
|
executions: usize,
|
||||||
|
/// At what time the fuzzing started
|
||||||
start_time: u64,
|
start_time: u64,
|
||||||
|
/// Metadata stored for this state by one of the components
|
||||||
metadatas: HashMap<&'static str, Box<dyn StateMetadata>>,
|
metadatas: HashMap<&'static str, Box<dyn StateMetadata>>,
|
||||||
// additional_corpuses: HashMap<&'static str, Box<dyn Corpus>>,
|
// additional_corpuses: HashMap<&'static str, Box<dyn Corpus>>,
|
||||||
feedbacks: Vec<Box<dyn Feedback<I>>>,
|
feedbacks: Vec<Box<dyn Feedback<I>>>,
|
||||||
|
@ -23,7 +23,7 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct ipc_perm {
|
struct ipc_perm {
|
||||||
pub __key: c_int,
|
pub __key: c_int,
|
||||||
pub uid: c_uint,
|
pub uid: c_uint,
|
||||||
pub gid: c_uint,
|
pub gid: c_uint,
|
||||||
@ -39,7 +39,7 @@ pub struct ipc_perm {
|
|||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct shmid_ds {
|
struct shmid_ds {
|
||||||
pub shm_perm: ipc_perm,
|
pub shm_perm: ipc_perm,
|
||||||
pub shm_segsz: c_ulong,
|
pub shm_segsz: c_ulong,
|
||||||
pub shm_atime: c_long,
|
pub shm_atime: c_long,
|
||||||
@ -135,7 +135,7 @@ impl AflShmem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Deinitialize this shmem instance
|
/// Deinitialize this shmem instance
|
||||||
pub unsafe fn afl_shmem_deinit(shm: *mut AflShmem) {
|
unsafe fn afl_shmem_deinit(shm: *mut AflShmem) {
|
||||||
if shm.is_null() || (*shm).map.is_null() {
|
if shm.is_null() || (*shm).map.is_null() {
|
||||||
/* Serialized map id */
|
/* Serialized map id */
|
||||||
// Not set or not initialized;
|
// Not set or not initialized;
|
||||||
@ -148,7 +148,7 @@ pub unsafe fn afl_shmem_deinit(shm: *mut AflShmem) {
|
|||||||
|
|
||||||
/// Functions to create Shared memory region, for observation channels and
|
/// Functions to create Shared memory region, for observation channels and
|
||||||
/// opening inputs and stuff.
|
/// opening inputs and stuff.
|
||||||
pub unsafe fn afl_shmem_init(shm: *mut AflShmem, map_size: usize) -> *mut c_uchar {
|
unsafe fn afl_shmem_init(shm: *mut AflShmem, map_size: usize) -> *mut c_uchar {
|
||||||
(*shm).map_size = map_size;
|
(*shm).map_size = map_size;
|
||||||
(*shm).map = 0 as *mut c_uchar;
|
(*shm).map = 0 as *mut c_uchar;
|
||||||
(*shm).shm_id = shmget(
|
(*shm).shm_id = shmget(
|
||||||
@ -180,7 +180,7 @@ pub unsafe fn afl_shmem_init(shm: *mut AflShmem, map_size: usize) -> *mut c_ucha
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Uses a shmap id string to open a shared map
|
/// Uses a shmap id string to open a shared map
|
||||||
pub unsafe fn afl_shmem_by_str(
|
unsafe fn afl_shmem_by_str(
|
||||||
shm: *mut AflShmem,
|
shm: *mut AflShmem,
|
||||||
shm_str: &CStr,
|
shm_str: &CStr,
|
||||||
map_size: usize,
|
map_size: usize,
|
||||||
@ -211,7 +211,7 @@ pub unsafe fn afl_shmem_by_str(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Write sharedmap as env var and the size as name#_SIZE
|
/// Write sharedmap as env var and the size as name#_SIZE
|
||||||
pub unsafe fn afl_shmem_to_env_var(shmem: &AflShmem, env_name: &CStr) -> c_uint {
|
unsafe fn afl_shmem_to_env_var(shmem: &AflShmem, env_name: &CStr) -> c_uint {
|
||||||
let env_len = env_name.to_bytes().len();
|
let env_len = env_name.to_bytes().len();
|
||||||
if env_len == 0 || env_len > 200 || (*shmem).shm_str[0 as c_int as usize] == 0 {
|
if env_len == 0 || env_len > 200 || (*shmem).shm_str[0 as c_int as usize] == 0 {
|
||||||
return AFL_RET_NULL_PTR;
|
return AFL_RET_NULL_PTR;
|
||||||
|
@ -6,8 +6,14 @@ use crate::inputs::Input;
|
|||||||
use crate::observers::observer_serde::NamedSerdeAnyMap;
|
use crate::observers::observer_serde::NamedSerdeAnyMap;
|
||||||
use crate::AflError;
|
use crate::AflError;
|
||||||
|
|
||||||
|
/// The (unsafe) pointer to the current inmem executor, for the current run.
|
||||||
|
/// This is neede for certain non-rust side effects, as well as unix signal handling.
|
||||||
|
static mut CURRENT_INMEMORY_EXECUTOR_PTR: *const c_void = ptr::null();
|
||||||
|
|
||||||
|
/// The inmem executor harness
|
||||||
type HarnessFunction<I> = fn(&dyn Executor<I>, &[u8]) -> ExitKind;
|
type HarnessFunction<I> = fn(&dyn Executor<I>, &[u8]) -> ExitKind;
|
||||||
|
|
||||||
|
/// The inmem executor simply calls a target function, then returns afterwards.
|
||||||
pub struct InMemoryExecutor<I>
|
pub struct InMemoryExecutor<I>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
@ -16,8 +22,6 @@ where
|
|||||||
observers: NamedSerdeAnyMap,
|
observers: NamedSerdeAnyMap,
|
||||||
}
|
}
|
||||||
|
|
||||||
static mut CURRENT_INMEMORY_EXECUTOR_PTR: *const c_void = ptr::null();
|
|
||||||
|
|
||||||
impl<I> Executor<I> for InMemoryExecutor<I>
|
impl<I> Executor<I> for InMemoryExecutor<I>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
|
@ -7,6 +7,7 @@ use crate::observers::observer_serde::NamedSerdeAnyMap;
|
|||||||
use crate::observers::Observer;
|
use crate::observers::Observer;
|
||||||
use crate::AflError;
|
use crate::AflError;
|
||||||
|
|
||||||
|
/// How an execution finished.
|
||||||
pub enum ExitKind {
|
pub enum ExitKind {
|
||||||
Ok,
|
Ok,
|
||||||
Crash,
|
Crash,
|
||||||
@ -14,6 +15,7 @@ pub enum ExitKind {
|
|||||||
Timeout,
|
Timeout,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An executor takes the given inputs, and runs the harness/target.
|
||||||
pub trait Executor<I>
|
pub trait Executor<I>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
|
@ -8,6 +8,15 @@ use crate::observers::observer_serde::NamedSerdeAnyMap;
|
|||||||
use crate::observers::MapObserver;
|
use crate::observers::MapObserver;
|
||||||
use crate::AflError;
|
use crate::AflError;
|
||||||
|
|
||||||
|
pub type MaxMapFeedback<T, O> = MapFeedback<T, MaxReducer<T>, O>;
|
||||||
|
pub type MinMapFeedback<T, O> = MapFeedback<T, MinReducer<T>, O>;
|
||||||
|
|
||||||
|
//pub type MaxMapTrackerFeedback<T, O> = MapFeedback<T, MaxReducer<T>, O>;
|
||||||
|
//pub type MinMapTrackerFeedback<T, O> = MapFeedback<T, MinReducer<T>, O>;
|
||||||
|
|
||||||
|
/// Feedbacks evaluate the observers.
|
||||||
|
/// Basically, they reduce the information provided by an observer to a value,
|
||||||
|
/// indicating the "interestingness" of the last run.
|
||||||
pub trait Feedback<I>
|
pub trait Feedback<I>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
@ -25,6 +34,7 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The name of this feedback
|
||||||
fn name(&self) -> &'static str;
|
fn name(&self) -> &'static str;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,8 +301,3 @@ where
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pub type MaxMapFeedback<T, O> = MapFeedback<T, MaxReducer<T>, O>;
|
|
||||||
pub type MinMapFeedback<T, O> = MapFeedback<T, MinReducer<T>, O>;
|
|
||||||
|
|
||||||
//pub type MaxMapTrackerFeedback<T, O> = MapFeedback<T, MaxReducer<T>, O>;
|
|
||||||
//pub type MinMapTrackerFeedback<T, O> = MapFeedback<T, MinReducer<T>, O>;
|
|
||||||
|
@ -7,6 +7,10 @@ use crate::inputs::Input;
|
|||||||
use crate::utils::Rand;
|
use crate::utils::Rand;
|
||||||
use crate::AflError;
|
use crate::AflError;
|
||||||
|
|
||||||
|
/// The maximum size of dummy bytes generated by _dummy generator methods
|
||||||
|
const DUMMY_BYTES_MAX: usize = 64;
|
||||||
|
|
||||||
|
/// Generators can generate ranges of bytes.
|
||||||
pub trait Generator<I, R>
|
pub trait Generator<I, R>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
@ -19,8 +23,7 @@ where
|
|||||||
fn generate_dummy(&self) -> I;
|
fn generate_dummy(&self) -> I;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DUMMY_BYTES_SIZE: usize = 64;
|
/// Generates random bytes
|
||||||
|
|
||||||
pub struct RandBytesGenerator<R>
|
pub struct RandBytesGenerator<R>
|
||||||
where
|
where
|
||||||
R: Rand,
|
R: Rand,
|
||||||
@ -42,8 +45,9 @@ where
|
|||||||
Ok(BytesInput::new(random_bytes))
|
Ok(BytesInput::new(random_bytes))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generates up to DUMMY_BYTES_MAX non-random dummy bytes (0)
|
||||||
fn generate_dummy(&self) -> BytesInput {
|
fn generate_dummy(&self) -> BytesInput {
|
||||||
let size = min(self.max_size, DUMMY_BYTES_SIZE);
|
let size = min(self.max_size, DUMMY_BYTES_MAX);
|
||||||
BytesInput::new(vec![0; size])
|
BytesInput::new(vec![0; size])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,6 +64,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generates random printable characters
|
||||||
pub struct RandPrintablesGenerator<R> {
|
pub struct RandPrintablesGenerator<R> {
|
||||||
max_size: usize,
|
max_size: usize,
|
||||||
phantom: PhantomData<R>,
|
phantom: PhantomData<R>,
|
||||||
@ -81,8 +86,9 @@ where
|
|||||||
Ok(BytesInput::new(random_bytes))
|
Ok(BytesInput::new(random_bytes))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generates up to DUMMY_BYTES_MAX non-random dummy bytes (0)
|
||||||
fn generate_dummy(&self) -> BytesInput {
|
fn generate_dummy(&self) -> BytesInput {
|
||||||
let size = min(self.max_size, DUMMY_BYTES_SIZE);
|
let size = min(self.max_size, DUMMY_BYTES_MAX);
|
||||||
BytesInput::new(vec!['0' as u8; size])
|
BytesInput::new(vec!['0' as u8; size])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
/*!
|
||||||
|
Welcome to libAFL
|
||||||
|
*/
|
||||||
|
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
@ -8,6 +8,8 @@ use crate::inputs::Input;
|
|||||||
use crate::utils::Rand;
|
use crate::utils::Rand;
|
||||||
use crate::AflError;
|
use crate::AflError;
|
||||||
|
|
||||||
|
/// A mutator takes input, and mutates it.
|
||||||
|
/// Simple as that.
|
||||||
pub trait Mutator<C, I, R>
|
pub trait Mutator<C, I, R>
|
||||||
where
|
where
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
@ -34,9 +36,13 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The maximum size of a testcase
|
||||||
pub const DEFAULT_MAX_SIZE: usize = 1048576;
|
pub const DEFAULT_MAX_SIZE: usize = 1048576;
|
||||||
|
|
||||||
|
/// Interact with the maximum size
|
||||||
pub trait HasMaxSize {
|
pub trait HasMaxSize {
|
||||||
|
/// The maximum size of the contents returned
|
||||||
fn max_size(&self) -> usize;
|
fn max_size(&self) -> usize;
|
||||||
|
/// Sets the maximum size of the contents returned
|
||||||
fn set_max_size(&mut self, max_size: usize);
|
fn set_max_size(&mut self, max_size: usize);
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,9 @@ use crate::mutators::*;
|
|||||||
use crate::utils::Rand;
|
use crate::utils::Rand;
|
||||||
use crate::AflError;
|
use crate::AflError;
|
||||||
|
|
||||||
|
/// The result of a mutation.
|
||||||
|
/// If the mutation got skipped, the target
|
||||||
|
/// will not be executed with the returned input.
|
||||||
pub enum MutationResult {
|
pub enum MutationResult {
|
||||||
Mutated,
|
Mutated,
|
||||||
Skipped,
|
Skipped,
|
||||||
|
@ -60,6 +60,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct StdMapObserver<T>
|
pub struct StdMapObserver<T>
|
||||||
where
|
where
|
||||||
|
@ -9,6 +9,8 @@ use crate::inputs::Input;
|
|||||||
use crate::utils::Rand;
|
use crate::utils::Rand;
|
||||||
use crate::AflError;
|
use crate::AflError;
|
||||||
|
|
||||||
|
/// A stage is one step in the fuzzing process.
|
||||||
|
/// Multiple stages will be scheduled one by one for each input.
|
||||||
pub trait Stage<EM, E, C, I, R>
|
pub trait Stage<EM, E, C, I, R>
|
||||||
where
|
where
|
||||||
EM: EventManager<C, E, I, R>,
|
EM: EventManager<C, E, I, R>,
|
||||||
|
@ -14,6 +14,9 @@ use crate::serde_anymap::{Ptr, PtrMut};
|
|||||||
|
|
||||||
// TODO multi mutators stage
|
// TODO multi mutators stage
|
||||||
|
|
||||||
|
/// A Mutational stage is the stage in a fuzzing run that mutates inputs.
|
||||||
|
/// Mutational stages will usually have a range of mutations that are
|
||||||
|
/// being applied to the input one by one.
|
||||||
pub trait MutationalStage<M, EM, E, C, I, R>: Stage<EM, E, C, I, R>
|
pub trait MutationalStage<M, EM, E, C, I, R>: Stage<EM, E, C, I, R>
|
||||||
where
|
where
|
||||||
M: Mutator<C, I, R>,
|
M: Mutator<C, I, R>,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user