QoL Types and Changes (#3124)
* Nop executor * Qol types * no stage * A new() for NopStage * clippy * clippy again --------- Co-authored-by: Dongjia "toka" Zhang <tokazerkje@outlook.com>
This commit is contained in:
parent
0fdfa1d7a1
commit
db7ce822dc
@ -28,6 +28,7 @@ pub mod differential;
|
|||||||
#[cfg(all(feature = "std", feature = "fork", unix))]
|
#[cfg(all(feature = "std", feature = "fork", unix))]
|
||||||
pub mod forkserver;
|
pub mod forkserver;
|
||||||
pub mod inprocess;
|
pub mod inprocess;
|
||||||
|
pub mod nop;
|
||||||
/// SAND(<https://github.com/wtdcode/sand-aflpp>) implementation
|
/// SAND(<https://github.com/wtdcode/sand-aflpp>) implementation
|
||||||
pub mod sand;
|
pub mod sand;
|
||||||
|
|
||||||
|
75
libafl/src/executors/nop.rs
Normal file
75
libafl/src/executors/nop.rs
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
//! Trivial Constant Executor
|
||||||
|
|
||||||
|
use core::time::Duration;
|
||||||
|
|
||||||
|
use libafl_bolts::tuples::RefIndexable;
|
||||||
|
|
||||||
|
use super::{Executor, ExitKind, HasObservers, HasTimeout};
|
||||||
|
|
||||||
|
/// [`NopExecutor`] is an executor that does nothing
|
||||||
|
pub type NopExecutor = ConstantExecutor<()>;
|
||||||
|
|
||||||
|
/// Constant Executor that returns a fixed value. Mostly helpful
|
||||||
|
/// when you need it to satisfy some bounds like [`crate::fuzzer::NopFuzzer`]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ConstantExecutor<OT = ()> {
|
||||||
|
exit: ExitKind,
|
||||||
|
tm: Duration,
|
||||||
|
ot: OT,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<OT> ConstantExecutor<OT> {
|
||||||
|
/// Construct a [`ConstantExecutor`]
|
||||||
|
#[must_use]
|
||||||
|
pub fn new(exit: ExitKind, tm: Duration, ot: OT) -> Self {
|
||||||
|
Self { exit, tm, ot }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ConstantExecutor<()> {
|
||||||
|
/// Construct a [`ConstantExecutor`] that always returns Ok
|
||||||
|
#[must_use]
|
||||||
|
pub fn ok() -> Self {
|
||||||
|
Self::new(ExitKind::Ok, Duration::default(), ())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a [`ConstantExecutor`] that always returns Crash
|
||||||
|
#[must_use]
|
||||||
|
pub fn crash() -> Self {
|
||||||
|
Self::new(ExitKind::Crash, Duration::default(), ())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// These are important to allow [`ConstantExecutor`] to be used with other components
|
||||||
|
impl<OT> HasObservers for ConstantExecutor<OT> {
|
||||||
|
type Observers = OT;
|
||||||
|
fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> {
|
||||||
|
RefIndexable::from(&self.ot)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn observers_mut(&mut self) -> RefIndexable<&mut Self::Observers, Self::Observers> {
|
||||||
|
RefIndexable::from(&mut self.ot)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<OT> HasTimeout for ConstantExecutor<OT> {
|
||||||
|
fn timeout(&self) -> Duration {
|
||||||
|
self.tm
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_timeout(&mut self, timeout: Duration) {
|
||||||
|
self.tm = timeout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<OT, EM, I, S, Z> Executor<EM, I, S, Z> for ConstantExecutor<OT> {
|
||||||
|
fn run_target(
|
||||||
|
&mut self,
|
||||||
|
_fuzzer: &mut Z,
|
||||||
|
_state: &mut S,
|
||||||
|
_mgr: &mut EM,
|
||||||
|
_input: &I,
|
||||||
|
) -> Result<ExitKind, libafl_bolts::Error> {
|
||||||
|
Ok(self.exit)
|
||||||
|
}
|
||||||
|
}
|
51
libafl/src/stages/dynamic.rs
Normal file
51
libafl/src/stages/dynamic.rs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
//! A stage implementation that can have dynamic stage runtime
|
||||||
|
|
||||||
|
use super::{Restartable, Stage};
|
||||||
|
|
||||||
|
/// A dynamic stage implementation. This explicity uses enum so that rustc can better
|
||||||
|
/// reason about the bounds.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum DynamicStage<T1, T2> {
|
||||||
|
/// One stage
|
||||||
|
Stage1(T1),
|
||||||
|
/// The alernative stage
|
||||||
|
Stage2(T2),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T1, T2, E, EM, S, Z> Stage<E, EM, S, Z> for DynamicStage<T1, T2>
|
||||||
|
where
|
||||||
|
T1: Stage<E, EM, S, Z>,
|
||||||
|
T2: Stage<E, EM, S, Z>,
|
||||||
|
{
|
||||||
|
fn perform(
|
||||||
|
&mut self,
|
||||||
|
fuzzer: &mut Z,
|
||||||
|
executor: &mut E,
|
||||||
|
state: &mut S,
|
||||||
|
manager: &mut EM,
|
||||||
|
) -> Result<(), libafl_bolts::Error> {
|
||||||
|
match self {
|
||||||
|
Self::Stage1(st1) => st1.perform(fuzzer, executor, state, manager),
|
||||||
|
Self::Stage2(st2) => st2.perform(fuzzer, executor, state, manager),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T1, T2, S> Restartable<S> for DynamicStage<T1, T2>
|
||||||
|
where
|
||||||
|
T1: Restartable<S>,
|
||||||
|
T2: Restartable<S>,
|
||||||
|
{
|
||||||
|
fn should_restart(&mut self, state: &mut S) -> Result<bool, libafl_bolts::Error> {
|
||||||
|
match self {
|
||||||
|
Self::Stage1(st1) => st1.should_restart(state),
|
||||||
|
Self::Stage2(st2) => st2.should_restart(state),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn clear_progress(&mut self, state: &mut S) -> Result<(), libafl_bolts::Error> {
|
||||||
|
match self {
|
||||||
|
Self::Stage1(st1) => st1.clear_progress(state),
|
||||||
|
Self::Stage2(st2) => st2.clear_progress(state),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -71,9 +71,11 @@ pub mod colorization;
|
|||||||
pub mod concolic;
|
pub mod concolic;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub mod dump;
|
pub mod dump;
|
||||||
|
pub mod dynamic;
|
||||||
pub mod generalization;
|
pub mod generalization;
|
||||||
pub mod generation;
|
pub mod generation;
|
||||||
pub mod logics;
|
pub mod logics;
|
||||||
|
pub mod nop;
|
||||||
pub mod power;
|
pub mod power;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub mod sync;
|
pub mod sync;
|
||||||
|
37
libafl/src/stages/nop.rs
Normal file
37
libafl/src/stages/nop.rs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
//! A nop stage does nothing
|
||||||
|
|
||||||
|
use super::{Restartable, Stage};
|
||||||
|
|
||||||
|
/// A stage that does nothing
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct NopStage {}
|
||||||
|
|
||||||
|
impl NopStage {
|
||||||
|
/// Create a [`NopStage`]
|
||||||
|
#[must_use]
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E, EM, S, Z> Stage<E, EM, S, Z> for NopStage {
|
||||||
|
fn perform(
|
||||||
|
&mut self,
|
||||||
|
_fuzzer: &mut Z,
|
||||||
|
_executor: &mut E,
|
||||||
|
_state: &mut S,
|
||||||
|
_manager: &mut EM,
|
||||||
|
) -> Result<(), libafl_bolts::Error> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S> Restartable<S> for NopStage {
|
||||||
|
fn clear_progress(&mut self, _state: &mut S) -> Result<(), libafl_bolts::Error> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn should_restart(&mut self, _state: &mut S) -> Result<bool, libafl_bolts::Error> {
|
||||||
|
Ok(true)
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user