diff --git a/libafl/src/stages/generation.rs b/libafl/src/stages/generation.rs new file mode 100644 index 0000000000..8df777a28a --- /dev/null +++ b/libafl/src/stages/generation.rs @@ -0,0 +1,72 @@ +//! A [`Stage`] that generates a single input via a +//! [`crate::generators::Generator`] and evaluates it using the fuzzer, possibly +//! adding it to the corpus. + +use core::marker::PhantomData; + +use crate::{ + generators::Generator, + inputs::UsesInput, + stages::Stage, + state::{HasCorpus, HasRand, UsesState}, + Error, Evaluator, +}; + +/// A [`Stage`] that generates a single input via a [`Generator`] and evaluates +/// it using the fuzzer, possibly adding it to the corpus. +/// +/// This stage can be used to construct black-box (e.g., grammar-based) fuzzers. +#[derive(Debug)] +pub struct GenStage(G, PhantomData) +where + Z: UsesState, + G: Generator<<::State as UsesInput>::Input, Z::State>; + +impl GenStage +where + Z: UsesState, + G: Generator<<::State as UsesInput>::Input, Z::State>, +{ + /// Create a new [`GenStage`]. + pub fn new(g: G) -> Self { + Self(g, PhantomData) + } +} + +impl UsesState for GenStage +where + Z: UsesState, + G: Generator<<::State as UsesInput>::Input, Z::State>, +{ + type State = Z::State; +} + +impl Stage for GenStage +where + E: UsesState, + EM: UsesState, + Z: Evaluator, + Z::State: HasCorpus + HasRand, + G: Generator<<::State as UsesInput>::Input, Z::State>, +{ + #[inline] + fn perform( + &mut self, + fuzzer: &mut Z, + executor: &mut E, + state: &mut Z::State, + manager: &mut EM, + ) -> Result<(), Error> { + let input = self.0.generate(state)?; + fuzzer.evaluate_input(state, executor, manager, input)?; + Ok(()) + } + + fn restart_progress_should_run(&mut self, _state: &mut Self::State) -> Result { + Ok(true) + } + + fn clear_restart_progress(&mut self, _state: &mut Self::State) -> Result<(), Error> { + Ok(()) + } +} diff --git a/libafl/src/stages/mod.rs b/libafl/src/stages/mod.rs index 29fc9af677..d6e711a3c0 100644 --- a/libafl/src/stages/mod.rs +++ b/libafl/src/stages/mod.rs @@ -63,6 +63,8 @@ pub mod concolic; #[cfg(feature = "std")] pub mod dump; pub mod generalization; +/// The [`generation::GenStage`] generates a single input and evaluates it. +pub mod generation; pub mod logics; pub mod power; pub mod stats;