diff --git a/fuzzers/FRET/src/debug.rs b/fuzzers/FRET/src/debug.rs new file mode 100644 index 0000000000..e5fbdbacbf --- /dev/null +++ b/fuzzers/FRET/src/debug.rs @@ -0,0 +1,167 @@ +use libafl::*; +use libafl_bolts::*; +use std::borrow::Cow; +use serde::*; +use serde::ser::Serialize; +use libafl::prelude::Feedback; +use libafl::prelude::Testcase; +use libafl::prelude::*; +use std::marker::PhantomData; + +#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq)] +pub struct DebugMetadata { + pub val: bool +} +libafl_bolts::impl_serdeany!(DebugMetadata); + +//================================================================================================== + +/// The [`DebugFeedback`] reports the same value, always. +/// It can be used to enable or disable feedback results through composition. +#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq)] +pub enum DebugFeedback { + /// Always returns `true` + True, + /// Alsways returns `false` + False, +} + +static mut counter : usize = 10; + +impl Feedback for DebugFeedback +where + S: State, +{ + #[inline] + #[allow(clippy::wrong_self_convention)] + fn is_interesting( + &mut self, + _state: &mut S, + _manager: &mut EM, + _input: &S::Input, + _observers: &OT, + _exit_kind: &ExitKind, + ) -> Result + where + EM: EventFirer, + OT: ObserversTuple, + { + if unsafe { counter } > 0 { + unsafe { counter -= 1; } + return Ok(true); + } else { + return Ok(false); + } + Ok((*self).into()) + } + + #[cfg(feature = "track_hit_feedbacks")] + fn last_result(&self) -> Result { + Ok((*self).into()) + } + + fn append_metadata( + &mut self, + state: &mut S, + _manager: &mut EM, + _observers: &OT, + testcase: &mut Testcase<::Input>, + ) -> Result<(), Error> + where + OT: ObserversTuple, + EM: EventFirer, + { + testcase.metadata_map_mut().insert(DebugMetadata { val: true }); + eprintln!("Attach: {:?}",testcase.metadata::()); + Ok(()) + } +} + +impl Named for DebugFeedback { + #[inline] + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("DebugFeedback"); + &NAME + } +} + +impl DebugFeedback { + /// Creates a new [`DebugFeedback`] from the given boolean + #[must_use] + pub fn new(val: bool) -> Self { + Self::from(val) + } +} + +impl From for DebugFeedback { + fn from(val: bool) -> Self { + if val { + Self::True + } else { + Self::False + } + } +} + +impl From for bool { + fn from(value: DebugFeedback) -> Self { + match value { + DebugFeedback::True => true, + DebugFeedback::False => false, + } + } +} + +//================================================================================================== + +/// The default mutational stage +#[derive(Clone, Debug, Default)] +pub struct DebugStage { + #[allow(clippy::type_complexity)] + phantom: PhantomData<(E, OT)>, +} + +impl UsesState for DebugStage +where + E: UsesState, +{ + type State = E::State; +} + +impl DebugStage +{ + pub fn new() -> Self { + Self { phantom: PhantomData} + } +} + +impl Stage for DebugStage +where + E: Executor + HasObservers, + EM: EventFirer, + OT: ObserversTuple, + Self::State: HasCorpus + HasMetadata + HasNamedMetadata + HasExecutions, + Z: Evaluator, +{ + fn perform( + &mut self, + fuzzer: &mut Z, + executor: &mut E, + state: &mut Self::State, + manager: &mut EM + ) -> Result<(), Error> { + // eprintln!("DebugStage {:?}", state.current_testcase()); + let testcase = state.current_testcase()?; + eprintln!("Stage: {:?}",testcase.metadata::()); + + 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(()) + } +} \ No newline at end of file