fuck you rust
This commit is contained in:
parent
93947c44cf
commit
1585645972
@ -6,8 +6,8 @@ use std::hash::Hasher;
|
|||||||
use xxhash_rust::const_xxh3;
|
use xxhash_rust::const_xxh3;
|
||||||
use xxhash_rust::xxh3;
|
use xxhash_rust::xxh3;
|
||||||
|
|
||||||
use libafl::utils::{Rand, StdRand};
|
|
||||||
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||||
|
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::new(0);
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
pub mod testcase;
|
pub mod testcase;
|
||||||
pub use testcase::Testcase;
|
pub use testcase::Testcase;
|
||||||
|
|
||||||
use alloc::{vec::Vec};
|
use alloc::vec::Vec;
|
||||||
use core::{cell::RefCell};
|
use core::cell::RefCell;
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
inputs::Input,
|
inputs::Input,
|
||||||
@ -36,36 +36,50 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait CorpusScheduler {
|
pub trait CorpusScheduler {
|
||||||
|
|
||||||
/// Add an entry to the corpus and return its index
|
/// Add an entry to the corpus and return its index
|
||||||
fn on_add<C, I, R, S>(&self, state: &mut S, idx: usize, testcase: &Testcase<I>) -> Result<(), Error>
|
fn on_add<C, I, R, S>(
|
||||||
|
&self,
|
||||||
|
state: &mut S,
|
||||||
|
idx: usize,
|
||||||
|
testcase: &Testcase<I>,
|
||||||
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
S: HasCorpus<C, I> + HasRand<R>,
|
S: HasCorpus<C, I> + HasRand<R>,
|
||||||
C: Corpus<I>,
|
C: Corpus<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand
|
R: Rand,
|
||||||
{
|
{
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Replaces the testcase at the given idx
|
/// Replaces the testcase at the given idx
|
||||||
fn on_replace<C, I, R, S>(&self, state: &mut S, idx: usize, testcase: &Testcase<I>) -> Result<(), Error>
|
fn on_replace<C, I, R, S>(
|
||||||
|
&self,
|
||||||
|
state: &mut S,
|
||||||
|
idx: usize,
|
||||||
|
testcase: &Testcase<I>,
|
||||||
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
S: HasCorpus<C, I> + HasRand<R>,
|
S: HasCorpus<C, I> + HasRand<R>,
|
||||||
C: Corpus<I>,
|
C: Corpus<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand
|
R: Rand,
|
||||||
{
|
{
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes an entry from the corpus, returning it if it was present.
|
/// Removes an entry from the corpus, returning it if it was present.
|
||||||
fn on_remove<C, I, R, S>(&self, state: &mut S, idx: usize, testcase: &Option<Testcase<I>>) -> Result<(), Error>
|
fn on_remove<C, I, R, S>(
|
||||||
|
&self,
|
||||||
|
state: &mut S,
|
||||||
|
idx: usize,
|
||||||
|
testcase: &Option<Testcase<I>>,
|
||||||
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
S: HasCorpus<C, I> + HasRand<R>,
|
S: HasCorpus<C, I> + HasRand<R>,
|
||||||
C: Corpus<I>,
|
C: Corpus<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand
|
R: Rand,
|
||||||
{
|
{
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -78,9 +92,9 @@ pub trait CorpusScheduler {
|
|||||||
C: Corpus<I>,
|
C: Corpus<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand;
|
R: Rand;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
pub struct RandCorpusScheduler {}
|
pub struct RandCorpusScheduler {}
|
||||||
|
|
||||||
impl CorpusScheduler for RandCorpusScheduler {
|
impl CorpusScheduler for RandCorpusScheduler {
|
||||||
@ -90,7 +104,7 @@ impl CorpusScheduler for RandCorpusScheduler {
|
|||||||
S: HasCorpus<C, I> + HasRand<R>,
|
S: HasCorpus<C, I> + HasRand<R>,
|
||||||
C: Corpus<I>,
|
C: Corpus<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand
|
R: Rand,
|
||||||
{
|
{
|
||||||
if state.corpus().count() == 0 {
|
if state.corpus().count() == 0 {
|
||||||
Err(Error::Empty("No entries in corpus".to_owned()))
|
Err(Error::Empty("No entries in corpus".to_owned()))
|
||||||
@ -101,6 +115,7 @@ impl CorpusScheduler for RandCorpusScheduler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
#[derive(Default, Serialize, Deserialize, Clone, Debug)]
|
#[derive(Default, Serialize, Deserialize, Clone, Debug)]
|
||||||
#[serde(bound = "I: serde::de::DeserializeOwned")]
|
#[serde(bound = "I: serde::de::DeserializeOwned")]
|
||||||
@ -115,7 +130,6 @@ impl<I> Corpus<I> for InMemoryCorpus<I>
|
|||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
{
|
{
|
||||||
|
|
||||||
/// Returns the number of elements
|
/// Returns the number of elements
|
||||||
#[inline]
|
#[inline]
|
||||||
fn count(&self) -> usize {
|
fn count(&self) -> usize {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::bolts::llmp::LlmpSender;
|
use crate::bolts::llmp::LlmpSender;
|
||||||
use alloc::{string::ToString, vec::Vec};
|
use alloc::{string::ToString, vec::Vec};
|
||||||
use core::{marker::PhantomData, time::Duration};
|
use core::{marker::PhantomData, time::Duration};
|
||||||
use serde::{Serialize, de::DeserializeOwned};
|
use serde::{de::DeserializeOwned, Serialize};
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use crate::bolts::llmp::LlmpReceiver;
|
use crate::bolts::llmp::LlmpReceiver;
|
||||||
@ -22,7 +22,7 @@ use crate::{
|
|||||||
executors::{Executor, HasObservers},
|
executors::{Executor, HasObservers},
|
||||||
inputs::Input,
|
inputs::Input,
|
||||||
observers::ObserversTuple,
|
observers::ObserversTuple,
|
||||||
state::{IfInteresting},
|
state::IfInteresting,
|
||||||
stats::Stats,
|
stats::Stats,
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
@ -258,7 +258,7 @@ where
|
|||||||
where
|
where
|
||||||
E: Executor<I> + HasObservers<OT>,
|
E: Executor<I> + HasObservers<OT>,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
S: IfInteresting<I>
|
S: IfInteresting<I>,
|
||||||
{
|
{
|
||||||
match event {
|
match event {
|
||||||
Event::NewTestcase {
|
Event::NewTestcase {
|
||||||
@ -293,7 +293,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, SH, ST> EventManager<I> for LlmpEventManager<I, SH, ST>
|
impl<I, SH, ST> EventManager<E, I, S> for LlmpEventManager<I, SH, ST>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
SH: ShMem,
|
SH: ShMem,
|
||||||
@ -311,15 +311,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process<E, OT, S>(
|
fn process<E, OT, S>(&mut self, state: &mut S, executor: &mut E) -> Result<usize, Error>
|
||||||
&mut self,
|
|
||||||
state: &mut S,
|
|
||||||
executor: &mut E,
|
|
||||||
) -> Result<usize, Error>
|
|
||||||
where
|
where
|
||||||
E: Executor<I> + HasObservers<OT>,
|
E: Executor<I> + HasObservers<OT>,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
S: IfInteresting<I>
|
S: IfInteresting<I>,
|
||||||
{
|
{
|
||||||
// TODO: Get around local event copy by moving handle_in_client
|
// TODO: Get around local event copy by moving handle_in_client
|
||||||
let mut events = vec![];
|
let mut events = vec![];
|
||||||
@ -348,11 +344,7 @@ where
|
|||||||
Ok(count)
|
Ok(count)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fire<S>(
|
fn fire<S>(&mut self, _state: &mut S, event: Event<I>) -> Result<(), Error> {
|
||||||
&mut self,
|
|
||||||
_state: &mut S,
|
|
||||||
event: Event<I>,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
let serialized = postcard::to_allocvec(&event)?;
|
let serialized = postcard::to_allocvec(&event)?;
|
||||||
self.llmp.send_buf(LLMP_TAG_EVENT_TO_BOTH, &serialized)?;
|
self.llmp.send_buf(LLMP_TAG_EVENT_TO_BOTH, &serialized)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -407,7 +399,7 @@ where
|
|||||||
sender: LlmpSender<SH>,
|
sender: LlmpSender<SH>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, SH, ST> EventManager<I> for LlmpRestartingEventManager<I, SH, ST>
|
impl<I, SH, ST> EventManager<E, I, S> for LlmpRestartingEventManager<I, SH, ST>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
SH: ShMem,
|
SH: ShMem,
|
||||||
@ -421,10 +413,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Reset the single page (we reuse it over and over from pos 0), then send the current state to the next runner.
|
/// Reset the single page (we reuse it over and over from pos 0), then send the current state to the next runner.
|
||||||
fn on_restart<S>(
|
fn on_restart<S>(&mut self, state: &mut S) -> Result<(), Error>
|
||||||
&mut self,
|
|
||||||
state: &mut S,
|
|
||||||
) -> Result<(), Error>
|
|
||||||
where
|
where
|
||||||
S: Serialize,
|
S: Serialize,
|
||||||
{
|
{
|
||||||
@ -435,24 +424,16 @@ where
|
|||||||
.send_buf(_LLMP_TAG_RESTART, &state_corpus_serialized)
|
.send_buf(_LLMP_TAG_RESTART, &state_corpus_serialized)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process<E, OT, S>(
|
fn process<E, OT, S>(&mut self, state: &mut S, executor: &mut E) -> Result<usize, Error>
|
||||||
&mut self,
|
|
||||||
state: &mut S,
|
|
||||||
executor: &mut E,
|
|
||||||
) -> Result<usize, Error>
|
|
||||||
where
|
where
|
||||||
E: Executor<I> + HasObservers<OT>,
|
E: Executor<I> + HasObservers<OT>,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
S: IfInteresting<I>
|
S: IfInteresting<I>,
|
||||||
{
|
{
|
||||||
self.llmp_mgr.process(state, executor)
|
self.llmp_mgr.process(state, executor)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fire<S>(
|
fn fire<S>(&mut self, state: &mut S, event: Event<I>) -> Result<(), Error> {
|
||||||
&mut self,
|
|
||||||
state: &mut S,
|
|
||||||
event: Event<I>,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
// Check if we are going to crash in the event, in which case we store our current state for the next runner
|
// Check if we are going to crash in the event, in which case we store our current state for the next runner
|
||||||
self.llmp_mgr.fire(state, event)
|
self.llmp_mgr.fire(state, event)
|
||||||
}
|
}
|
||||||
@ -493,13 +474,7 @@ pub fn setup_restarting_mgr<I, S, SH, ST>(
|
|||||||
//mgr: &mut LlmpEventManager<I, SH, ST>,
|
//mgr: &mut LlmpEventManager<I, SH, ST>,
|
||||||
stats: ST,
|
stats: ST,
|
||||||
broker_port: u16,
|
broker_port: u16,
|
||||||
) -> Result<
|
) -> Result<(Option<S>, LlmpRestartingEventManager<I, SH, ST>), Error>
|
||||||
(
|
|
||||||
Option<S>,
|
|
||||||
LlmpRestartingEventManager<I, SH, ST>,
|
|
||||||
),
|
|
||||||
Error,
|
|
||||||
>
|
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
S: DeserializeOwned,
|
S: DeserializeOwned,
|
||||||
@ -562,8 +537,7 @@ where
|
|||||||
// Restoring from a previous run, deserialize state and corpus.
|
// Restoring from a previous run, deserialize state and corpus.
|
||||||
Some((_sender, _tag, msg)) => {
|
Some((_sender, _tag, msg)) => {
|
||||||
println!("Subsequent run. Let's load all data from shmem (received {} bytes from previous instance)", msg.len());
|
println!("Subsequent run. Let's load all data from shmem (received {} bytes from previous instance)", msg.len());
|
||||||
let (state, mgr): (S, LlmpEventManager<I, SH, ST>) =
|
let (state, mgr): (S, LlmpEventManager<I, SH, ST>) = deserialize_state_mgr(&msg)?;
|
||||||
deserialize_state_mgr(&msg)?;
|
|
||||||
|
|
||||||
(Some(state), LlmpRestartingEventManager::new(mgr, sender))
|
(Some(state), LlmpRestartingEventManager::new(mgr, sender))
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
use alloc::{string::ToString, vec::Vec};
|
use alloc::{string::ToString, vec::Vec};
|
||||||
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
use crate::{
|
use crate::{
|
||||||
events::{BrokerEventResult, Event, EventManager},
|
events::{BrokerEventResult, Event, EventManager},
|
||||||
executors::{Executor},
|
|
||||||
inputs::Input,
|
inputs::Input,
|
||||||
stats::Stats,
|
stats::Stats,
|
||||||
Error,
|
Error,
|
||||||
@ -12,7 +12,7 @@ use crate::{
|
|||||||
|
|
||||||
/// A simple, single-threaded event manager that just logs
|
/// A simple, single-threaded event manager that just logs
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct LoggerEventManager<I, ST>
|
pub struct LoggerEventManager<E, I, S, ST>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
ST: Stats, //CE: CustomEvent<I, OT>,
|
ST: Stats, //CE: CustomEvent<I, OT>,
|
||||||
@ -21,21 +21,15 @@ where
|
|||||||
stats: ST,
|
stats: ST,
|
||||||
/// The events that happened since the last handle_in_broker
|
/// The events that happened since the last handle_in_broker
|
||||||
events: Vec<Event<I>>,
|
events: Vec<Event<I>>,
|
||||||
|
phantom: PhantomData<(E, S)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, ST> EventManager<I> for LoggerEventManager<I, ST>
|
impl<E, I, S, ST> EventManager<E, I, S> for LoggerEventManager<E, I, S, ST>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
ST: Stats, //CE: CustomEvent<I, OT>,
|
ST: Stats, //CE: CustomEvent<I, OT>,
|
||||||
{
|
{
|
||||||
fn process<E, S>(
|
fn process(&mut self, state: &mut S, _executor: &mut E) -> Result<usize, Error> {
|
||||||
&mut self,
|
|
||||||
state: &mut S,
|
|
||||||
_executor: &mut E,
|
|
||||||
) -> Result<usize, Error>
|
|
||||||
where
|
|
||||||
E: Executor<I>
|
|
||||||
{
|
|
||||||
let count = self.events.len();
|
let count = self.events.len();
|
||||||
while self.events.len() > 0 {
|
while self.events.len() > 0 {
|
||||||
let event = self.events.pop().unwrap();
|
let event = self.events.pop().unwrap();
|
||||||
@ -44,12 +38,7 @@ where
|
|||||||
Ok(count)
|
Ok(count)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fire<S>(
|
fn fire(&mut self, _state: &mut S, event: Event<I>) -> Result<(), Error> {
|
||||||
&mut self,
|
|
||||||
_state: &mut S,
|
|
||||||
event: Event<I>,
|
|
||||||
) -> Result<(), Error>
|
|
||||||
{
|
|
||||||
match Self::handle_in_broker(&mut self.stats, &event)? {
|
match Self::handle_in_broker(&mut self.stats, &event)? {
|
||||||
BrokerEventResult::Forward => self.events.push(event),
|
BrokerEventResult::Forward => self.events.push(event),
|
||||||
BrokerEventResult::Handled => (),
|
BrokerEventResult::Handled => (),
|
||||||
@ -58,7 +47,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, ST> LoggerEventManager<I, ST>
|
impl<E, I, S, ST> LoggerEventManager<E, I, S, ST>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
ST: Stats, //TODO CE: CustomEvent,
|
ST: Stats, //TODO CE: CustomEvent,
|
||||||
@ -67,6 +56,7 @@ where
|
|||||||
Self {
|
Self {
|
||||||
stats: stats,
|
stats: stats,
|
||||||
events: vec![],
|
events: vec![],
|
||||||
|
phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,11 +105,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle arriving events in the client
|
// Handle arriving events in the client
|
||||||
fn handle_in_client<S>(
|
fn handle_in_client(&mut self, _state: &mut S, event: Event<I>) -> Result<(), Error> {
|
||||||
&mut self,
|
|
||||||
_state: &mut S,
|
|
||||||
event: Event<I>,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
match event {
|
match event {
|
||||||
_ => Err(Error::Unknown(format!(
|
_ => Err(Error::Unknown(format!(
|
||||||
"Received illegal message that message should not have arrived: {:?}.",
|
"Received illegal message that message should not have arrived: {:?}.",
|
||||||
|
@ -9,10 +9,7 @@ use core::{fmt, marker::PhantomData, time::Duration};
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
executors::{Executor},
|
executors::Executor, inputs::Input, observers::ObserversTuple, state::IfInteresting, Error,
|
||||||
inputs::Input,
|
|
||||||
observers::ObserversTuple,
|
|
||||||
Error,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The log event severity
|
/// The log event severity
|
||||||
@ -149,7 +146,7 @@ where
|
|||||||
|
|
||||||
/// EventManager is the main communications hub.
|
/// EventManager is the main communications hub.
|
||||||
/// For the "normal" multi-processed mode, you may want to look into `RestartingEventManager`
|
/// For the "normal" multi-processed mode, you may want to look into `RestartingEventManager`
|
||||||
pub trait EventManager<I>
|
pub trait EventManager<E, I, S>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
{
|
{
|
||||||
@ -158,13 +155,7 @@ where
|
|||||||
|
|
||||||
/// Lookup for incoming events and process them.
|
/// Lookup for incoming events and process them.
|
||||||
/// Return the number of processes events or an error
|
/// Return the number of processes events or an error
|
||||||
fn process<E, S>(
|
fn process(&mut self, state: &mut S, executor: &mut E) -> Result<usize, Error>;
|
||||||
&mut self,
|
|
||||||
state: &mut S,
|
|
||||||
executor: &mut E,
|
|
||||||
) -> Result<usize, Error>
|
|
||||||
where
|
|
||||||
E: Executor<I>;
|
|
||||||
|
|
||||||
/// Serialize all observers for this type and manager
|
/// Serialize all observers for this type and manager
|
||||||
fn serialize_observers<OT>(&mut self, observers: &OT) -> Result<Vec<u8>, Error>
|
fn serialize_observers<OT>(&mut self, observers: &OT) -> Result<Vec<u8>, Error>
|
||||||
@ -184,10 +175,7 @@ where
|
|||||||
|
|
||||||
/// For restarting event managers, implement a way to forward state to their next peers.
|
/// For restarting event managers, implement a way to forward state to their next peers.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn on_restart<S>(
|
fn on_restart(&mut self, _state: &mut S) -> Result<(), Error> {
|
||||||
&mut self,
|
|
||||||
_state: &mut S,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,38 +184,26 @@ where
|
|||||||
fn await_restart_safe(&mut self) {}
|
fn await_restart_safe(&mut self) {}
|
||||||
|
|
||||||
/// Send off an event to the broker
|
/// Send off an event to the broker
|
||||||
fn fire<S>(
|
fn fire(&mut self, state: &mut S, event: Event<I>) -> Result<(), Error>;
|
||||||
&mut self,
|
|
||||||
state: &mut S,
|
|
||||||
event: Event<I>,
|
|
||||||
) -> Result<(), Error>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An eventmgr for tests, and as placeholder if you really don't need an event manager.
|
/// An eventmgr for tests, and as placeholder if you really don't need an event manager.
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct NopEventManager<I> {
|
pub struct NopEventManager<E, I, S> {
|
||||||
phantom: PhantomData<I>,
|
phantom: PhantomData<(E, I, S)>,
|
||||||
}
|
}
|
||||||
impl<I> EventManager<I> for NopEventManager<I>
|
impl<E, I, S> EventManager<E, I, S> for NopEventManager<E, I, S>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
{
|
{
|
||||||
fn process<E, S>(
|
fn process(&mut self, _state: &mut S, _executor: &mut E) -> Result<usize, Error>
|
||||||
&mut self,
|
|
||||||
_state: &mut S,
|
|
||||||
_executor: &mut E,
|
|
||||||
) -> Result<usize, Error>
|
|
||||||
where
|
where
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
{
|
{
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fire<S>(
|
fn fire(&mut self, _state: &mut S, _event: Event<I>) -> Result<(), Error> {
|
||||||
&mut self,
|
|
||||||
_state: &mut S,
|
|
||||||
_event: Event<I>,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,20 @@
|
|||||||
use core::{marker::PhantomData};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
corpus::{CorpusScheduler, Corpus},
|
corpus::{Corpus, CorpusScheduler},
|
||||||
events::{Event, EventManager},
|
events::{Event, EventManager},
|
||||||
executors::{Executor},
|
executors::Executor,
|
||||||
inputs::Input,
|
inputs::Input,
|
||||||
stages::StagesTuple,
|
stages::StagesTuple,
|
||||||
state::{HasRand, HasCorpus, HasExecutions},
|
state::{HasCorpus, HasExecutions, HasRand},
|
||||||
utils::{Rand, current_milliseconds, current_time},
|
utils::{current_milliseconds, current_time, Rand},
|
||||||
Error
|
Error,
|
||||||
};
|
};
|
||||||
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
/// Holds a set of stages
|
/// Holds a set of stages
|
||||||
pub trait HasStages<ST, I>
|
pub trait HasStages<ST, I>
|
||||||
where
|
where
|
||||||
ST: StagesTuple<I>,
|
ST: StagesTuple<I>,
|
||||||
I: Input
|
I: Input,
|
||||||
{
|
{
|
||||||
fn stages(&self) -> &ST;
|
fn stages(&self) -> &ST;
|
||||||
|
|
||||||
@ -37,12 +36,12 @@ pub trait Fuzzer<CS, ST, I>: HasCorpusScheduler<CS> + HasStages<ST, I>
|
|||||||
where
|
where
|
||||||
CS: CorpusScheduler,
|
CS: CorpusScheduler,
|
||||||
ST: StagesTuple<I>,
|
ST: StagesTuple<I>,
|
||||||
I: Input
|
I: Input,
|
||||||
{
|
{
|
||||||
fn fuzz_one<E, EM, S>(
|
fn fuzz_one<E, EM, S>(
|
||||||
&mut self,
|
&self,
|
||||||
executor: &mut E,
|
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
|
executor: &mut E,
|
||||||
manager: &mut EM,
|
manager: &mut EM,
|
||||||
) -> Result<usize, Error>
|
) -> Result<usize, Error>
|
||||||
where
|
where
|
||||||
@ -50,9 +49,9 @@ where
|
|||||||
E: Executor<I>;
|
E: Executor<I>;
|
||||||
|
|
||||||
fn fuzz_loop<E, EM, S>(
|
fn fuzz_loop<E, EM, S>(
|
||||||
&mut self,
|
&self,
|
||||||
executor: &mut E,
|
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
|
executor: &mut E,
|
||||||
manager: &mut EM,
|
manager: &mut EM,
|
||||||
) -> Result<usize, Error>
|
) -> Result<usize, Error>
|
||||||
where
|
where
|
||||||
@ -66,18 +65,18 @@ pub struct StdFuzzer<CS, ST, I>
|
|||||||
where
|
where
|
||||||
CS: CorpusScheduler,
|
CS: CorpusScheduler,
|
||||||
ST: StagesTuple<I>,
|
ST: StagesTuple<I>,
|
||||||
I: Input
|
I: Input,
|
||||||
{
|
{
|
||||||
scheduler: CS,
|
scheduler: CS,
|
||||||
stages: ST,
|
stages: ST,
|
||||||
phantom: PhantomData<I>
|
phantom: PhantomData<I>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<CS, ST, I> HasStages<ST, I> for StdFuzzer<CS, ST, I>
|
impl<CS, ST, I> HasStages<ST, I> for StdFuzzer<CS, ST, I>
|
||||||
where
|
where
|
||||||
CS: CorpusScheduler,
|
CS: CorpusScheduler,
|
||||||
ST: StagesTuple<I>,
|
ST: StagesTuple<I>,
|
||||||
I: Input
|
I: Input,
|
||||||
{
|
{
|
||||||
fn stages(&self) -> &ST {
|
fn stages(&self) -> &ST {
|
||||||
&self.stages
|
&self.stages
|
||||||
@ -92,7 +91,7 @@ impl<CS, ST, I> HasCorpusScheduler<CS> for StdFuzzer<CS, ST, I>
|
|||||||
where
|
where
|
||||||
CS: CorpusScheduler,
|
CS: CorpusScheduler,
|
||||||
ST: StagesTuple<I>,
|
ST: StagesTuple<I>,
|
||||||
I: Input
|
I: Input,
|
||||||
{
|
{
|
||||||
fn scheduler(&self) -> &CS {
|
fn scheduler(&self) -> &CS {
|
||||||
&self.scheduler
|
&self.scheduler
|
||||||
@ -107,12 +106,12 @@ impl<CS, ST, I> Fuzzer<CS, ST, I> for StdFuzzer<CS, ST, I>
|
|||||||
where
|
where
|
||||||
CS: CorpusScheduler,
|
CS: CorpusScheduler,
|
||||||
ST: StagesTuple<I>,
|
ST: StagesTuple<I>,
|
||||||
I: Input
|
I: Input,
|
||||||
{
|
{
|
||||||
fn fuzz_one<C, E, EM, R, S>(
|
fn fuzz_one<C, E, EM, R, S>(
|
||||||
&mut self,
|
&self,
|
||||||
executor: &mut E,
|
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
|
executor: &mut E,
|
||||||
manager: &mut EM,
|
manager: &mut EM,
|
||||||
) -> Result<usize, Error>
|
) -> Result<usize, Error>
|
||||||
where
|
where
|
||||||
@ -120,21 +119,21 @@ where
|
|||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
S: HasCorpus<C, I> + HasRand<R>,
|
S: HasCorpus<C, I> + HasRand<R>,
|
||||||
C: Corpus<I>,
|
C: Corpus<I>,
|
||||||
R: Rand
|
R: Rand,
|
||||||
{
|
{
|
||||||
let idx = self.scheduler().next(state)?;
|
let idx = self.scheduler().next(state)?;
|
||||||
|
|
||||||
self.stages()
|
self.stages()
|
||||||
.perform_all(executor, state, manager, idx)?;
|
.perform_all(self, state, executor, manager, idx)?;
|
||||||
|
|
||||||
manager.process(state, executor)?;
|
manager.process(state, executor)?;
|
||||||
Ok(idx)
|
Ok(idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fuzz_loop<C, E, EM, R, S>(
|
fn fuzz_loop<C, E, EM, R, S>(
|
||||||
&mut self,
|
&self,
|
||||||
executor: &mut E,
|
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
|
executor: &mut E,
|
||||||
manager: &mut EM,
|
manager: &mut EM,
|
||||||
) -> Result<usize, Error>
|
) -> Result<usize, Error>
|
||||||
where
|
where
|
||||||
@ -142,11 +141,11 @@ where
|
|||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
S: HasCorpus<C, I> + HasRand<R> + HasExecutions,
|
S: HasCorpus<C, I> + HasRand<R> + HasExecutions,
|
||||||
C: Corpus<I>,
|
C: Corpus<I>,
|
||||||
R: Rand
|
R: Rand,
|
||||||
{
|
{
|
||||||
let mut last = current_milliseconds();
|
let mut last = current_milliseconds();
|
||||||
loop {
|
loop {
|
||||||
self.fuzz_one(executor, state, manager)?;
|
self.fuzz_one(state, executor, manager)?;
|
||||||
let cur = current_milliseconds();
|
let cur = current_milliseconds();
|
||||||
if cur - last > 60 * 100 {
|
if cur - last > 60 * 100 {
|
||||||
last = cur;
|
last = cur;
|
||||||
@ -163,18 +162,17 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<CS, ST, I> StdFuzzer<CS, ST, I>
|
impl<CS, ST, I> StdFuzzer<CS, ST, I>
|
||||||
where
|
where
|
||||||
CS: CorpusScheduler,
|
CS: CorpusScheduler,
|
||||||
ST: StagesTuple<I>,
|
ST: StagesTuple<I>,
|
||||||
I: Input
|
I: Input,
|
||||||
{
|
{
|
||||||
pub fn new(scheduler: CS, stages: ST) -> Self {
|
pub fn new(scheduler: CS, stages: ST) -> Self {
|
||||||
Self {
|
Self {
|
||||||
scheduler: scheduler,
|
scheduler: scheduler,
|
||||||
stages: stages,
|
stages: stages,
|
||||||
phantom: PhantomData
|
phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
inputs::{HasBytesVec, Input},
|
|
||||||
corpus::Corpus,
|
corpus::Corpus,
|
||||||
|
inputs::{HasBytesVec, Input},
|
||||||
mutators::*,
|
mutators::*,
|
||||||
state::{HasRand, HasCorpus},
|
state::{HasCorpus, HasRand},
|
||||||
utils::Rand,
|
utils::Rand,
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
@ -27,21 +27,21 @@ pub enum MutationResult {
|
|||||||
|
|
||||||
// TODO maybe the mutator arg is not needed
|
// TODO maybe the mutator arg is not needed
|
||||||
/// The generic function type that identifies mutations
|
/// The generic function type that identifies mutations
|
||||||
pub type MutationFunction<I, F, M, S> =
|
pub type MutationFunction<F, I, M, S> =
|
||||||
fn(&mut M, &F, &mut S, &mut I) -> Result<MutationResult, Error>;
|
fn(&mut M, &F, &mut S, &mut I) -> Result<MutationResult, Error>;
|
||||||
|
|
||||||
pub trait ComposedByMutations<I, F, S>
|
pub trait ComposedByMutations<F, I, S>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
{
|
{
|
||||||
/// Get a mutation by index
|
/// Get a mutation by index
|
||||||
fn mutation_by_idx(&self, index: usize) -> MutationFunction<I, F, Self, S>;
|
fn mutation_by_idx(&self, index: usize) -> MutationFunction<F, I, Self, S>;
|
||||||
|
|
||||||
/// Get the number of mutations
|
/// Get the number of mutations
|
||||||
fn mutations_count(&self) -> usize;
|
fn mutations_count(&self) -> usize;
|
||||||
|
|
||||||
/// Add a mutation
|
/// Add a mutation
|
||||||
fn add_mutation(&mut self, mutation: MutationFunction<I, F, Self, S>);
|
fn add_mutation(&mut self, mutation: MutationFunction<F, I, Self, S>);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mem move in the own vec
|
/// Mem move in the own vec
|
||||||
@ -87,7 +87,6 @@ fn buffer_set(data: &mut [u8], from: usize, len: usize, val: u8) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const ARITH_MAX: u64 = 35;
|
const ARITH_MAX: u64 = 35;
|
||||||
|
|
||||||
const INTERESTING_8: [i8; 9] = [-128, -1, 0, 1, 16, 32, 64, 100, 127];
|
const INTERESTING_8: [i8; 9] = [-128, -1, 0, 1, 16, 32, 64, 100, 127];
|
||||||
@ -125,15 +124,16 @@ const INTERESTING_32: [i32; 27] = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
/// Bitflip mutation for inputs with a bytes vector
|
/// Bitflip mutation for inputs with a bytes vector
|
||||||
pub fn mutation_bitflip<I, M, R, S>(
|
pub fn mutation_bitflip<F, I, M, R, S>(
|
||||||
_: &mut M,
|
_: &mut M,
|
||||||
|
fuzzer: &F,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
input: &mut I,
|
input: &mut I,
|
||||||
) -> Result<MutationResult, Error>
|
) -> Result<MutationResult, Error>
|
||||||
where
|
where
|
||||||
I: Input + HasBytesVec,
|
I: Input + HasBytesVec,
|
||||||
S: HasRand<R>,
|
S: HasRand<R>,
|
||||||
R: Rand
|
R: Rand,
|
||||||
{
|
{
|
||||||
if input.bytes().len() == 0 {
|
if input.bytes().len() == 0 {
|
||||||
Ok(MutationResult::Skipped)
|
Ok(MutationResult::Skipped)
|
||||||
@ -147,9 +147,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mutation_byteflip<I, M, R, S>(
|
pub fn mutation_byteflip<F, I, M, R, S>(
|
||||||
_: &mut M,
|
_: &mut M,
|
||||||
|
fuzzer: &F,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
input: &mut I,
|
input: &mut I,
|
||||||
) -> Result<MutationResult, Error>
|
) -> Result<MutationResult, Error>
|
||||||
@ -170,9 +170,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mutation_byteinc<I, M, R, S>(
|
pub fn mutation_byteinc<F, I, M, R, S>(
|
||||||
_: &mut M,
|
_: &mut M,
|
||||||
|
fuzzer: &F,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
input: &mut I,
|
input: &mut I,
|
||||||
) -> Result<MutationResult, Error>
|
) -> Result<MutationResult, Error>
|
||||||
@ -194,9 +194,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mutation_bytedec<I, M, R, S>(
|
pub fn mutation_bytedec<F, I, M, R, S>(
|
||||||
_: &mut M,
|
_: &mut M,
|
||||||
|
fuzzer: &F,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
input: &mut I,
|
input: &mut I,
|
||||||
) -> Result<MutationResult, Error>
|
) -> Result<MutationResult, Error>
|
||||||
@ -218,9 +218,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mutation_byteneg<I, M, R, S>(
|
pub fn mutation_byteneg<F, I, M, R, S>(
|
||||||
_: &mut M,
|
_: &mut M,
|
||||||
|
fuzzer: &F,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
input: &mut I,
|
input: &mut I,
|
||||||
) -> Result<MutationResult, Error>
|
) -> Result<MutationResult, Error>
|
||||||
@ -241,9 +241,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mutation_byterand<I, M, R, S>(
|
pub fn mutation_byterand<F, I, M, R, S>(
|
||||||
_: &mut M,
|
_: &mut M,
|
||||||
|
fuzzer: &F,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
input: &mut I,
|
input: &mut I,
|
||||||
) -> Result<MutationResult, Error>
|
) -> Result<MutationResult, Error>
|
||||||
@ -264,9 +264,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mutation_byteadd<I, M, R, S>(
|
pub fn mutation_byteadd<F, I, M, R, S>(
|
||||||
_: &mut M,
|
_: &mut M,
|
||||||
|
fuzzer: &F,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
input: &mut I,
|
input: &mut I,
|
||||||
) -> Result<MutationResult, Error>
|
) -> Result<MutationResult, Error>
|
||||||
@ -292,9 +292,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mutation_wordadd<I, M, R, S>(
|
pub fn mutation_wordadd<F, I, M, R, S>(
|
||||||
_: &mut M,
|
_: &mut M,
|
||||||
|
fuzzer: &F,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
input: &mut I,
|
input: &mut I,
|
||||||
) -> Result<MutationResult, Error>
|
) -> Result<MutationResult, Error>
|
||||||
@ -322,9 +322,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mutation_dwordadd<I, M, R, S>(
|
pub fn mutation_dwordadd<F, I, M, R, S>(
|
||||||
_: &mut M,
|
_: &mut M,
|
||||||
|
fuzzer: &F,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
input: &mut I,
|
input: &mut I,
|
||||||
) -> Result<MutationResult, Error>
|
) -> Result<MutationResult, Error>
|
||||||
@ -352,9 +352,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mutation_qwordadd<I, M, R, S>(
|
pub fn mutation_qwordadd<F, I, M, R, S>(
|
||||||
_: &mut M,
|
_: &mut M,
|
||||||
|
fuzzer: &F,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
input: &mut I,
|
input: &mut I,
|
||||||
) -> Result<MutationResult, Error>
|
) -> Result<MutationResult, Error>
|
||||||
@ -382,9 +382,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mutation_byteinteresting<I, M, R, S>(
|
pub fn mutation_byteinteresting<F, I, M, R, S>(
|
||||||
_: &mut M,
|
_: &mut M,
|
||||||
|
fuzzer: &F,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
input: &mut I,
|
input: &mut I,
|
||||||
) -> Result<MutationResult, Error>
|
) -> Result<MutationResult, Error>
|
||||||
@ -406,9 +406,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mutation_wordinteresting<I, M, R, S>(
|
pub fn mutation_wordinteresting<F, I, M, R, S>(
|
||||||
_: &mut M,
|
_: &mut M,
|
||||||
|
fuzzer: &F,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
input: &mut I,
|
input: &mut I,
|
||||||
) -> Result<MutationResult, Error>
|
) -> Result<MutationResult, Error>
|
||||||
@ -421,7 +421,8 @@ where
|
|||||||
Ok(MutationResult::Skipped)
|
Ok(MutationResult::Skipped)
|
||||||
} else {
|
} else {
|
||||||
let idx = state.rand_mut().below(input.bytes().len() as u64 - 1) as usize;
|
let idx = state.rand_mut().below(input.bytes().len() as u64 - 1) as usize;
|
||||||
let val = INTERESTING_16[state.rand_mut().below(INTERESTING_8.len() as u64) as usize] as u16;
|
let val =
|
||||||
|
INTERESTING_16[state.rand_mut().below(INTERESTING_8.len() as u64) as usize] as u16;
|
||||||
unsafe {
|
unsafe {
|
||||||
// Moar speed, no bound check
|
// Moar speed, no bound check
|
||||||
let ptr = input.bytes_mut().get_unchecked_mut(idx) as *mut _ as *mut u16;
|
let ptr = input.bytes_mut().get_unchecked_mut(idx) as *mut _ as *mut u16;
|
||||||
@ -435,9 +436,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mutation_dwordinteresting<I, M, R, S>(
|
pub fn mutation_dwordinteresting<F, I, M, R, S>(
|
||||||
_: &mut M,
|
_: &mut M,
|
||||||
|
fuzzer: &F,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
input: &mut I,
|
input: &mut I,
|
||||||
) -> Result<MutationResult, Error>
|
) -> Result<MutationResult, Error>
|
||||||
@ -450,7 +451,8 @@ where
|
|||||||
Ok(MutationResult::Skipped)
|
Ok(MutationResult::Skipped)
|
||||||
} else {
|
} else {
|
||||||
let idx = state.rand_mut().below(input.bytes().len() as u64 - 3) as usize;
|
let idx = state.rand_mut().below(input.bytes().len() as u64 - 3) as usize;
|
||||||
let val = INTERESTING_32[state.rand_mut().below(INTERESTING_8.len() as u64) as usize] as u32;
|
let val =
|
||||||
|
INTERESTING_32[state.rand_mut().below(INTERESTING_8.len() as u64) as usize] as u32;
|
||||||
unsafe {
|
unsafe {
|
||||||
// Moar speed, no bound check
|
// Moar speed, no bound check
|
||||||
let ptr = input.bytes_mut().get_unchecked_mut(idx) as *mut _ as *mut u32;
|
let ptr = input.bytes_mut().get_unchecked_mut(idx) as *mut _ as *mut u32;
|
||||||
@ -464,9 +466,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mutation_bytesdelete<I, M, R, S>(
|
pub fn mutation_bytesdelete<F, I, M, R, S>(
|
||||||
_: &mut M,
|
_: &mut M,
|
||||||
|
fuzzer: &F,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
input: &mut I,
|
input: &mut I,
|
||||||
) -> Result<MutationResult, Error>
|
) -> Result<MutationResult, Error>
|
||||||
@ -487,9 +489,9 @@ where
|
|||||||
Ok(MutationResult::Mutated)
|
Ok(MutationResult::Mutated)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mutation_bytesexpand<I, M, R, S>(
|
pub fn mutation_bytesexpand<F, I, M, R, S>(
|
||||||
// TODO: max_size instead of mutator?
|
|
||||||
mutator: &mut M,
|
mutator: &mut M,
|
||||||
|
fuzzer: &F,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
input: &mut I,
|
input: &mut I,
|
||||||
) -> Result<MutationResult, Error>
|
) -> Result<MutationResult, Error>
|
||||||
@ -517,8 +519,9 @@ where
|
|||||||
Ok(MutationResult::Mutated)
|
Ok(MutationResult::Mutated)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mutation_bytesinsert<I, M, R, S>(
|
pub fn mutation_bytesinsert<F, I, M, R, S>(
|
||||||
mutator: &mut M,
|
mutator: &mut M,
|
||||||
|
fuzzer: &F,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
input: &mut I,
|
input: &mut I,
|
||||||
) -> Result<MutationResult, Error>
|
) -> Result<MutationResult, Error>
|
||||||
@ -549,9 +552,9 @@ where
|
|||||||
Ok(MutationResult::Mutated)
|
Ok(MutationResult::Mutated)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mutation_bytesrandinsert<I, M, R, S>(
|
pub fn mutation_bytesrandinsert<F, I, M, R, S>(
|
||||||
mutator: &mut M,
|
mutator: &mut M,
|
||||||
|
fuzzer: &F,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
input: &mut I,
|
input: &mut I,
|
||||||
) -> Result<MutationResult, Error>
|
) -> Result<MutationResult, Error>
|
||||||
@ -582,9 +585,9 @@ where
|
|||||||
Ok(MutationResult::Mutated)
|
Ok(MutationResult::Mutated)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mutation_bytesset<I, M, R, S>(
|
pub fn mutation_bytesset<F, I, M, R, S>(
|
||||||
_: &mut M,
|
_: &mut M,
|
||||||
|
fuzzer: &F,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
input: &mut I,
|
input: &mut I,
|
||||||
) -> Result<MutationResult, Error>
|
) -> Result<MutationResult, Error>
|
||||||
@ -607,9 +610,9 @@ where
|
|||||||
Ok(MutationResult::Mutated)
|
Ok(MutationResult::Mutated)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mutation_bytesrandset<I, M, R, S>(
|
pub fn mutation_bytesrandset<F, I, M, R, S>(
|
||||||
_: &mut M,
|
_: &mut M,
|
||||||
|
fuzzer: &F,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
input: &mut I,
|
input: &mut I,
|
||||||
) -> Result<MutationResult, Error>
|
) -> Result<MutationResult, Error>
|
||||||
@ -632,9 +635,9 @@ where
|
|||||||
Ok(MutationResult::Mutated)
|
Ok(MutationResult::Mutated)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mutation_bytescopy<I, M, R, S>(
|
pub fn mutation_bytescopy<F, I, M, R, S>(
|
||||||
_: &mut M,
|
_: &mut M,
|
||||||
|
fuzzer: &F,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
input: &mut I,
|
input: &mut I,
|
||||||
) -> Result<MutationResult, Error>
|
) -> Result<MutationResult, Error>
|
||||||
@ -657,9 +660,9 @@ where
|
|||||||
Ok(MutationResult::Mutated)
|
Ok(MutationResult::Mutated)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mutation_bytesswap<I, M, R, S>(
|
pub fn mutation_bytesswap<F, I, M, R, S>(
|
||||||
_: &mut M,
|
_: &mut M,
|
||||||
|
fuzzer: &F,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
input: &mut I,
|
input: &mut I,
|
||||||
) -> Result<MutationResult, Error>
|
) -> Result<MutationResult, Error>
|
||||||
@ -685,8 +688,9 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Crossover insert mutation
|
/// Crossover insert mutation
|
||||||
pub fn mutation_crossover_insert<C, I, M, R, S>(
|
pub fn mutation_crossover_insert<C, F, I, M, R, S>(
|
||||||
mutator: &mut M,
|
mutator: &mut M,
|
||||||
|
fuzzer: &F,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
input: &mut I,
|
input: &mut I,
|
||||||
) -> Result<MutationResult, Error>
|
) -> Result<MutationResult, Error>
|
||||||
@ -733,9 +737,9 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Crossover replace mutation
|
/// Crossover replace mutation
|
||||||
pub fn mutation_crossover_replace<C, I, M, R, S>(
|
pub fn mutation_crossover_replace<C, F, I, M, R, S>(
|
||||||
_: &mut M,
|
_: &mut M,
|
||||||
|
fuzzer: &F,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
input: &mut I,
|
input: &mut I,
|
||||||
) -> Result<MutationResult, Error>
|
) -> Result<MutationResult, Error>
|
||||||
@ -787,9 +791,9 @@ fn locate_diffs(this: &[u8], other: &[u8]) -> (i64, i64) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Splicing mutation from AFL
|
/// Splicing mutation from AFL
|
||||||
pub fn mutation_splice<C, I, M, R, S>(
|
pub fn mutation_splice<C, F, I, M, R, S>(
|
||||||
_: &mut M,
|
_: &mut M,
|
||||||
|
fuzzer: &F,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
input: &mut I,
|
input: &mut I,
|
||||||
) -> Result<MutationResult, Error>
|
) -> Result<MutationResult, Error>
|
||||||
@ -821,7 +825,9 @@ where
|
|||||||
counter += 1;
|
counter += 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
let split_at = state.rand_mut().between(first_diff as u64, last_diff as u64) as usize;
|
let split_at = state
|
||||||
|
.rand_mut()
|
||||||
|
.between(first_diff as u64, last_diff as u64) as usize;
|
||||||
input
|
input
|
||||||
.bytes_mut()
|
.bytes_mut()
|
||||||
.splice(split_at.., other.bytes()[split_at..].iter().cloned());
|
.splice(split_at.., other.bytes()[split_at..].iter().cloned());
|
||||||
@ -1056,4 +1062,4 @@ token2="B"
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
use crate::inputs::HasBytesVec;
|
use crate::inputs::HasBytesVec;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::{fmt, default::Default, marker::PhantomData};
|
use core::{default::Default, fmt, marker::PhantomData};
|
||||||
use fmt::Debug;
|
use fmt::Debug;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
inputs::{Input},
|
|
||||||
mutators::{Mutator, HasMaxSize, DEFAULT_MAX_SIZE},
|
|
||||||
state::{HasRand, HasCorpus, HasMetadata},
|
|
||||||
corpus::Corpus,
|
corpus::Corpus,
|
||||||
|
inputs::Input,
|
||||||
|
mutators::{HasMaxSize, Mutator, DEFAULT_MAX_SIZE},
|
||||||
|
state::{HasCorpus, HasMetadata, HasRand},
|
||||||
utils::Rand,
|
utils::Rand,
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
@ -15,7 +15,7 @@ use crate::{
|
|||||||
pub use crate::mutators::mutations::*;
|
pub use crate::mutators::mutations::*;
|
||||||
pub use crate::mutators::token_mutations::*;
|
pub use crate::mutators::token_mutations::*;
|
||||||
|
|
||||||
pub trait ScheduledMutator<I, S>: Mutator<I> + ComposedByMutations<I, S>
|
pub trait ScheduledMutator<F, I, S>: Mutator<I> + ComposedByMutations<F, I, S>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
{
|
{
|
||||||
@ -34,7 +34,7 @@ where
|
|||||||
|
|
||||||
/// New default implementation for mutate
|
/// New default implementation for mutate
|
||||||
/// Implementations must forward mutate() to this method
|
/// Implementations must forward mutate() to this method
|
||||||
fn scheduled_mutate<F>(
|
fn scheduled_mutate(
|
||||||
&mut self,
|
&mut self,
|
||||||
fuzzer: &F,
|
fuzzer: &F,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
@ -44,27 +44,24 @@ where
|
|||||||
let num = self.iterations(state, input);
|
let num = self.iterations(state, input);
|
||||||
for _ in 0..num {
|
for _ in 0..num {
|
||||||
let idx = self.schedule(self.mutations_count(), state, input);
|
let idx = self.schedule(self.mutations_count(), state, input);
|
||||||
self.mutation_by_idx(idx)(self, state, input)?;
|
self.mutation_by_idx(idx)(self, fuzzer, state, input)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct StdScheduledMutator<I, R, S>
|
pub struct StdScheduledMutator<F, I, S>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
{
|
||||||
S: HasRand<R>,{
|
mutations: Vec<MutationFunction<F, I, Self, S>>,
|
||||||
mutations: Vec<MutationFunction<I, Self, S>>,
|
|
||||||
max_size: usize,
|
max_size: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, R, S> Debug for StdScheduledMutator<I, R, S>
|
impl<F, I, S> Debug for StdScheduledMutator<F, I, S>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
|
||||||
S: HasRand<R>,
|
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
@ -77,31 +74,27 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, R, S> Mutator<I> for StdScheduledMutator<I, R, S>
|
impl<F, I, S> Mutator<I> for StdScheduledMutator<F, I, S>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
|
||||||
S: HasRand<R>,
|
|
||||||
{
|
{
|
||||||
fn mutate(
|
fn mutate(
|
||||||
&mut self,
|
&mut self,
|
||||||
rand: &mut R,
|
fuzzer: &F,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
input: &mut I,
|
input: &mut I,
|
||||||
_stage_idx: i32,
|
_stage_idx: i32,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
self.scheduled_mutate(state, input, _stage_idx)
|
self.scheduled_mutate(fuzzer, state, input, _stage_idx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, R, S> ComposedByMutations<I, S> for StdScheduledMutator<I, R, S>
|
impl<F, I, S> ComposedByMutations<F, I, S> for StdScheduledMutator<F, I, S>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
|
||||||
S: HasRand<R>,
|
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mutation_by_idx(&self, index: usize) -> MutationFunction<I, Self, S> {
|
fn mutation_by_idx(&self, index: usize) -> MutationFunction<F, I, Self, S> {
|
||||||
self.mutations[index]
|
self.mutations[index]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,25 +104,21 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn add_mutation(&mut self, mutation: MutationFunction<I, Self, S>) {
|
fn add_mutation(&mut self, mutation: MutationFunction<F, I, Self, S>) {
|
||||||
self.mutations.push(mutation)
|
self.mutations.push(mutation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, R, S> ScheduledMutator<I, S> for StdScheduledMutator<I, R, S>
|
impl<F, I, S> ScheduledMutator<F, I, S> for StdScheduledMutator<F, I, S>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
|
||||||
S: HasRand<R>,
|
|
||||||
{
|
{
|
||||||
// Just use the default methods
|
// Just use the default methods
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, R, S> HasMaxSize for StdScheduledMutator<I, R, S>
|
impl<F, I, S> HasMaxSize for StdScheduledMutator<F, I, S>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
|
||||||
S: HasRand<R>,
|
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn max_size(&self) -> usize {
|
fn max_size(&self) -> usize {
|
||||||
@ -142,11 +131,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, R, S> StdScheduledMutator<I, R, S>
|
impl<F, I, S> StdScheduledMutator<F, I, S>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
|
||||||
S: HasRand<R>,
|
|
||||||
{
|
{
|
||||||
/// Create a new StdScheduledMutator instance without mutations and corpus
|
/// Create a new StdScheduledMutator instance without mutations and corpus
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
@ -157,7 +144,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new StdScheduledMutator instance specifying mutations
|
/// Create a new StdScheduledMutator instance specifying mutations
|
||||||
pub fn with_mutations(mutations: Vec<MutationFunction<I, Self, S>>) -> Self {
|
pub fn with_mutations(mutations: Vec<MutationFunction<F, I, Self, S>>) -> Self {
|
||||||
StdScheduledMutator {
|
StdScheduledMutator {
|
||||||
mutations: mutations,
|
mutations: mutations,
|
||||||
max_size: DEFAULT_MAX_SIZE,
|
max_size: DEFAULT_MAX_SIZE,
|
||||||
@ -167,21 +154,21 @@ where
|
|||||||
|
|
||||||
/// Schedule some selected byte level mutations given a ScheduledMutator type
|
/// Schedule some selected byte level mutations given a ScheduledMutator type
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct HavocBytesMutator<C, I, R, S, SM>
|
pub struct HavocBytesMutator<C, F, I, R, S, SM>
|
||||||
where
|
where
|
||||||
SM: ScheduledMutator<I, S> + HasMaxSize,
|
SM: ScheduledMutator<F, I, S> + HasMaxSize,
|
||||||
I: Input + HasBytesVec,
|
I: Input + HasBytesVec,
|
||||||
S: HasRand<R> + HasCorpus<C, I> + HasMetadata,
|
S: HasRand<R> + HasCorpus<C, I> + HasMetadata,
|
||||||
C: Corpus<I>,
|
C: Corpus<I>,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
scheduled: SM,
|
scheduled: SM,
|
||||||
phantom: PhantomData<(C, I, R, S)>,
|
phantom: PhantomData<(C, F, I, R, S)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, I, R, S, SM> Mutator<I> for HavocBytesMutator<C, I, R, S, SM>
|
impl<C, F, I, R, S, SM> Mutator<I> for HavocBytesMutator<C, F, I, R, S, SM>
|
||||||
where
|
where
|
||||||
SM: ScheduledMutator<I, S> + HasMaxSize,
|
SM: ScheduledMutator<F, I, S> + HasMaxSize,
|
||||||
I: Input + HasBytesVec,
|
I: Input + HasBytesVec,
|
||||||
S: HasRand<R> + HasCorpus<C, I> + HasMetadata,
|
S: HasRand<R> + HasCorpus<C, I> + HasMetadata,
|
||||||
C: Corpus<I>,
|
C: Corpus<I>,
|
||||||
@ -190,12 +177,12 @@ where
|
|||||||
/// Mutate bytes
|
/// Mutate bytes
|
||||||
fn mutate(
|
fn mutate(
|
||||||
&mut self,
|
&mut self,
|
||||||
rand: &mut R,
|
fuzzer: &mut F,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
input: &mut I,
|
input: &mut I,
|
||||||
stage_idx: i32,
|
stage_idx: i32,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
self.scheduled.mutate(state, input, stage_idx)?;
|
self.scheduled.mutate(fuzzer, state, input, stage_idx)?;
|
||||||
/*let num = self.scheduled.iterations(state, input);
|
/*let num = self.scheduled.iterations(state, input);
|
||||||
for _ in 0..num {
|
for _ in 0..num {
|
||||||
let idx = self.scheduled.schedule(14, state, input);
|
let idx = self.scheduled.schedule(14, state, input);
|
||||||
@ -221,9 +208,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, I, R, S, SM> HasMaxSize for HavocBytesMutator<C, I, R, S, SM>
|
impl<C, F, I, R, S, SM> HasMaxSize for HavocBytesMutator<C, F, I, R, S, SM>
|
||||||
where
|
where
|
||||||
SM: ScheduledMutator<I, S> + HasMaxSize,
|
SM: ScheduledMutator<F, I, S> + HasMaxSize,
|
||||||
I: Input + HasBytesVec,
|
I: Input + HasBytesVec,
|
||||||
S: HasRand<R> + HasCorpus<C, I> + HasMetadata,
|
S: HasRand<R> + HasCorpus<C, I> + HasMetadata,
|
||||||
C: Corpus<I>,
|
C: Corpus<I>,
|
||||||
@ -240,9 +227,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, I, R, S, SM> HavocBytesMutator<C, I, R, S, SM>
|
impl<C, F, I, R, S, SM> HavocBytesMutator<C, F, I, R, S, SM>
|
||||||
where
|
where
|
||||||
SM: ScheduledMutator<I, S> + HasMaxSize,
|
SM: ScheduledMutator<F, I, S> + HasMaxSize,
|
||||||
I: Input + HasBytesVec,
|
I: Input + HasBytesVec,
|
||||||
S: HasRand<R> + HasCorpus<C, I> + HasMetadata,
|
S: HasRand<R> + HasCorpus<C, I> + HasMetadata,
|
||||||
C: Corpus<I>,
|
C: Corpus<I>,
|
||||||
@ -259,7 +246,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, I, R, S> Default for HavocBytesMutator<C, I, R, S, StdScheduledMutator<I, R, S>>
|
impl<C, F, I, R, S> Default for HavocBytesMutator<C, F, I, R, S, StdScheduledMutator<F, I, S>>
|
||||||
where
|
where
|
||||||
I: Input + HasBytesVec,
|
I: Input + HasBytesVec,
|
||||||
S: HasRand<R> + HasCorpus<C, I> + HasMetadata,
|
S: HasRand<R> + HasCorpus<C, I> + HasMetadata,
|
||||||
@ -268,7 +255,7 @@ where
|
|||||||
{
|
{
|
||||||
/// Create a new HavocBytesMutator instance wrapping StdScheduledMutator
|
/// Create a new HavocBytesMutator instance wrapping StdScheduledMutator
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let mut scheduled = StdScheduledMutator::<I, R, S>::new();
|
let mut scheduled = StdScheduledMutator::<F, I, S>::new();
|
||||||
scheduled.add_mutation(mutation_bitflip);
|
scheduled.add_mutation(mutation_bitflip);
|
||||||
scheduled.add_mutation(mutation_byteflip);
|
scheduled.add_mutation(mutation_byteflip);
|
||||||
scheduled.add_mutation(mutation_byteinc);
|
scheduled.add_mutation(mutation_byteinc);
|
||||||
@ -384,4 +371,4 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
@ -2,90 +2,64 @@ pub mod mutational;
|
|||||||
pub use mutational::StdMutationalStage;
|
pub use mutational::StdMutationalStage;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
bolts::tuples::TupleList,
|
bolts::tuples::TupleList, corpus::Corpus, events::EventManager, executors::Executor,
|
||||||
corpus::Corpus,
|
inputs::Input, Error,
|
||||||
events::EventManager,
|
|
||||||
executors::{Executor},
|
|
||||||
inputs::Input,
|
|
||||||
Error,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A stage is one step in the fuzzing process.
|
/// A stage is one step in the fuzzing process.
|
||||||
/// Multiple stages will be scheduled one by one for each input.
|
/// Multiple stages will be scheduled one by one for each input.
|
||||||
pub trait Stage<I>
|
pub trait Stage<E, EM, F, S> {
|
||||||
where
|
|
||||||
I: Input
|
|
||||||
{
|
|
||||||
/// Run the stage
|
/// Run the stage
|
||||||
fn perform<E, EM, F, S>(
|
fn perform(
|
||||||
&self,
|
&self,
|
||||||
fuzzer: &F,
|
fuzzer: &F,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
executor: &mut E,
|
executor: &mut E,
|
||||||
manager: &mut EM,
|
manager: &mut EM,
|
||||||
corpus_idx: usize,
|
corpus_idx: usize,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>;
|
||||||
where
|
|
||||||
EM: EventManager<I>,
|
|
||||||
E: Executor<I>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait StagesTuple<I>
|
pub trait StagesTuple<E, EM, F, S> {
|
||||||
where
|
fn perform_all(
|
||||||
I: Input
|
|
||||||
{
|
|
||||||
fn perform_all<E, EM, F, S>(
|
|
||||||
&self,
|
&self,
|
||||||
fuzzer: &F,
|
fuzzer: &F,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
executor: &mut E,
|
executor: &mut E,
|
||||||
manager: &mut EM,
|
manager: &mut EM,
|
||||||
corpus_idx: usize,
|
corpus_idx: usize,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>;
|
||||||
where
|
|
||||||
EM: EventManager<I>,
|
|
||||||
E: Executor<I>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I> StagesTuple<I> for ()
|
impl<E, EM, F, S> StagesTuple<E, EM, F, S> for () {
|
||||||
where
|
fn perform_all(
|
||||||
I: Input
|
|
||||||
{
|
|
||||||
fn perform_all<E, EM, F, S>(
|
|
||||||
&self,
|
&self,
|
||||||
fuzzer: &F,
|
fuzzer: &F,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
executor: &mut E,
|
executor: &mut E,
|
||||||
manager: &mut EM,
|
manager: &mut EM,
|
||||||
corpus_idx: usize,
|
corpus_idx: usize,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error> {
|
||||||
where
|
|
||||||
EM: EventManager<I>,
|
|
||||||
E: Executor<I>
|
|
||||||
{
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Head, Tail, I> StagesTuple<I> for (Head, Tail)
|
impl<Head, Tail, E, EM, F, S> StagesTuple<E, EM, F, S> for (Head, Tail)
|
||||||
where
|
where
|
||||||
Head: Stage<I>,
|
Head: Stage<E, EM, F, S>,
|
||||||
Tail: StagesTuple<I> + TupleList,
|
Tail: StagesTuple<E, EM, F, S> + TupleList,
|
||||||
I: Input
|
|
||||||
{
|
{
|
||||||
fn perform_all<E, EM, F, S>(
|
fn perform_all(
|
||||||
&self,
|
&self,
|
||||||
fuzzer: &F,
|
fuzzer: &F,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
executor: &mut E,
|
executor: &mut E,
|
||||||
manager: &mut EM,
|
manager: &mut EM,
|
||||||
corpus_idx: usize,
|
corpus_idx: usize,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error> {
|
||||||
where
|
self.0
|
||||||
EM: EventManager<I>,
|
.perform(fuzzer, state, executor, manager, corpus_idx)?;
|
||||||
E: Executor<I>
|
self.1
|
||||||
{
|
.perform_all(fuzzer, state, executor, manager, corpus_idx)
|
||||||
self.0.perform(fuzzer, state, executor, manager, corpus_idx)?;
|
|
||||||
self.1 .perform_all(fuzzer, state, executor, manager, corpus_idx)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,14 +2,14 @@ use core::marker::PhantomData;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
events::EventManager,
|
events::EventManager,
|
||||||
executors::{Executor},
|
executors::Executor,
|
||||||
inputs::Input,
|
inputs::Input,
|
||||||
mutators::Mutator,
|
mutators::Mutator,
|
||||||
stages::Corpus,
|
stages::Corpus,
|
||||||
stages::Stage,
|
stages::Stage,
|
||||||
state::{HasRand},
|
state::HasRand,
|
||||||
|
state::{Evaluator, HasCorpus},
|
||||||
utils::Rand,
|
utils::Rand,
|
||||||
state::{HasCorpus, Evaluator},
|
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ where
|
|||||||
EM: EventManager<I>,
|
EM: EventManager<I>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
S: HasCorpus<C, I> + Evaluator<I>,
|
S: HasCorpus<C, I> + Evaluator<I>,
|
||||||
C: Corpus<I>
|
C: Corpus<I>,
|
||||||
{
|
{
|
||||||
let num = self.iterations(state);
|
let num = self.iterations(state);
|
||||||
for i in 0..num {
|
for i in 0..num {
|
||||||
@ -56,11 +56,12 @@ where
|
|||||||
.load_input()?
|
.load_input()?
|
||||||
.clone();
|
.clone();
|
||||||
self.mutator_mut()
|
self.mutator_mut()
|
||||||
.mutate(state, &mut input_mut, i as i32)?;
|
.mutate(fuzzer, state, &mut input_mut, i as i32)?;
|
||||||
|
|
||||||
let fitness = state.evaluate_input(input_mut, executor, manager)?;
|
let fitness = state.evaluate_input(input_mut, executor, manager)?;
|
||||||
|
|
||||||
self.mutator_mut().post_exec(state, fitness, i as i32)?;
|
self.mutator_mut()
|
||||||
|
.post_exec(fuzzer, state, fitness, i as i32)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -100,7 +101,7 @@ where
|
|||||||
fn iterations<R, S>(&mut self, state: &mut S) -> usize
|
fn iterations<R, S>(&mut self, state: &mut S) -> usize
|
||||||
where
|
where
|
||||||
S: HasRand<R>,
|
S: HasRand<R>,
|
||||||
R: Rand
|
R: Rand,
|
||||||
{
|
{
|
||||||
1 + state.rand_mut().below(DEFAULT_MUTATIONAL_MAX_ITERATIONS) as usize
|
1 + state.rand_mut().below(DEFAULT_MUTATIONAL_MAX_ITERATIONS) as usize
|
||||||
}
|
}
|
||||||
@ -124,7 +125,7 @@ where
|
|||||||
EM: EventManager<I>,
|
EM: EventManager<I>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
S: HasCorpus<C, I> + Evaluator<I>,
|
S: HasCorpus<C, I> + Evaluator<I>,
|
||||||
C: Corpus<I>
|
C: Corpus<I>,
|
||||||
{
|
{
|
||||||
self.perform_mutational(fuzzer, state, executor, manager, corpus_idx)
|
self.perform_mutational(fuzzer, state, executor, manager, corpus_idx)
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ use crate::{
|
|||||||
generators::Generator,
|
generators::Generator,
|
||||||
inputs::Input,
|
inputs::Input,
|
||||||
observers::ObserversTuple,
|
observers::ObserversTuple,
|
||||||
utils::{current_milliseconds, Rand},
|
utils::Rand,
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ pub trait HasMetadata {
|
|||||||
pub trait HasFeedbacks<FT, I>
|
pub trait HasFeedbacks<FT, I>
|
||||||
where
|
where
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
I: Input
|
I: Input,
|
||||||
{
|
{
|
||||||
/// The feedbacks tuple
|
/// The feedbacks tuple
|
||||||
fn feedbacks(&self) -> &FT;
|
fn feedbacks(&self) -> &FT;
|
||||||
@ -97,7 +97,11 @@ where
|
|||||||
|
|
||||||
/// Creates a new testcase, appending the metadata from each feedback
|
/// Creates a new testcase, appending the metadata from each feedback
|
||||||
#[inline]
|
#[inline]
|
||||||
fn testcase_with_feedbacks_metadata(&mut self, input: I, fitness: u32) -> Result<Testcase<I>, Error> {
|
fn testcase_with_feedbacks_metadata(
|
||||||
|
&mut self,
|
||||||
|
input: I,
|
||||||
|
fitness: u32,
|
||||||
|
) -> Result<Testcase<I>, Error> {
|
||||||
let mut testcase = Testcase::with_fitness(input, fitness);
|
let mut testcase = Testcase::with_fitness(input, fitness);
|
||||||
self.feedbacks_mut().append_metadata_all(&mut testcase)?;
|
self.feedbacks_mut().append_metadata_all(&mut testcase)?;
|
||||||
Ok(testcase)
|
Ok(testcase)
|
||||||
@ -108,7 +112,7 @@ where
|
|||||||
pub trait HasObjectives<FT, I>
|
pub trait HasObjectives<FT, I>
|
||||||
where
|
where
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
I: Input
|
I: Input,
|
||||||
{
|
{
|
||||||
/// The objective feedbacks tuple
|
/// The objective feedbacks tuple
|
||||||
fn objectives(&self) -> &FT;
|
fn objectives(&self) -> &FT;
|
||||||
@ -118,8 +122,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Trait for the execution counter
|
/// Trait for the execution counter
|
||||||
pub trait HasExecutions
|
pub trait HasExecutions {
|
||||||
{
|
|
||||||
/// The executions counter
|
/// The executions counter
|
||||||
fn executions(&self) -> &usize;
|
fn executions(&self) -> &usize;
|
||||||
|
|
||||||
@ -128,8 +131,7 @@ pub trait HasExecutions
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Trait for the starting time
|
/// Trait for the starting time
|
||||||
pub trait HasStartTime
|
pub trait HasStartTime {
|
||||||
{
|
|
||||||
/// The starting time
|
/// The starting time
|
||||||
fn start_time(&self) -> &Duration;
|
fn start_time(&self) -> &Duration;
|
||||||
|
|
||||||
@ -140,7 +142,7 @@ pub trait HasStartTime
|
|||||||
/// Add to the state if interesting
|
/// Add to the state if interesting
|
||||||
pub trait IfInteresting<I>
|
pub trait IfInteresting<I>
|
||||||
where
|
where
|
||||||
I: Input
|
I: Input,
|
||||||
{
|
{
|
||||||
/// Evaluate if a set of observation channels has an interesting state
|
/// Evaluate if a set of observation channels has an interesting state
|
||||||
fn is_interesting<OT>(
|
fn is_interesting<OT>(
|
||||||
@ -205,7 +207,6 @@ where
|
|||||||
phantom: PhantomData<I>,
|
phantom: PhantomData<I>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<C, FT, I, OFT, R, SC> HasRand<R> for State<C, FT, I, OFT, R, SC>
|
impl<C, FT, I, OFT, R, SC> HasRand<R> for State<C, FT, I, OFT, R, SC>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
C: Corpus<I>,
|
||||||
@ -228,7 +229,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<C, FT, I, OFT, R, SC> HasCorpus<C, I> for State<C, FT, I, OFT, R, SC>
|
impl<C, FT, I, OFT, R, SC> HasCorpus<C, I> for State<C, FT, I, OFT, R, SC>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
C: Corpus<I>,
|
||||||
@ -471,7 +471,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<C, FT, OFT, R, SC> State<C, FT, BytesInput, OFT, R, SC>
|
impl<C, FT, OFT, R, SC> State<C, FT, BytesInput, OFT, R, SC>
|
||||||
where
|
where
|
||||||
@ -551,7 +550,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<C, FT, I, OFT, R, SC> State<C, FT, I, OFT, R, SC>
|
impl<C, FT, I, OFT, R, SC> State<C, FT, I, OFT, R, SC>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
C: Corpus<I>,
|
||||||
@ -584,13 +582,14 @@ where
|
|||||||
executor.post_exec_observers()?;
|
executor.post_exec_observers()?;
|
||||||
|
|
||||||
let observers = executor.observers();
|
let observers = executor.observers();
|
||||||
|
|
||||||
let fitness = self
|
let fitness = self
|
||||||
.feedbacks_mut()
|
.feedbacks_mut()
|
||||||
.is_interesting_all(&input, observers, exit_kind)?;
|
.is_interesting_all(&input, observers, exit_kind)?;
|
||||||
|
|
||||||
let is_solution = self.objectives_mut().is_interesting_all(&input, observers, exit_kind.clone())? > 0;
|
|
||||||
|
|
||||||
|
let is_solution =
|
||||||
|
self.objectives_mut()
|
||||||
|
.is_interesting_all(&input, observers, exit_kind.clone())?
|
||||||
|
> 0;
|
||||||
Ok((fitness, is_solution))
|
Ok((fitness, is_solution))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -629,7 +628,7 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(rand: R, corpus: C, feedbacks: FT, solutions: SC, objectives: OFT) -> Self {
|
pub fn new(rand: R, corpus: C, feedbacks: FT, solutions: SC, objectives: OFT) -> Self {
|
||||||
Self {
|
Self {
|
||||||
rand,
|
rand,
|
||||||
executions: 0,
|
executions: 0,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user