Better documentation headers (clippy) (#2501)
* Better documentation headers (clippy) * more doc * more fixes * Even more * more * even more * concrete * fmt * even more more * tiny typo * more * more * More * more * more docs? * more docs
This commit is contained in:
parent
07db74b416
commit
e2cc78f274
@ -1,4 +1,5 @@
|
|||||||
//! The [`InMemoryOnDiskCorpus`] stores [`Testcase`]s to disk.
|
//! The [`InMemoryOnDiskCorpus`] stores [`Testcase`]s to disk.
|
||||||
|
//!
|
||||||
//! Additionally, _all_ of them are kept in memory.
|
//! Additionally, _all_ of them are kept in memory.
|
||||||
//! For a lower memory footprint, consider using [`crate::corpus::CachedOnDiskCorpus`]
|
//! For a lower memory footprint, consider using [`crate::corpus::CachedOnDiskCorpus`]
|
||||||
//! which only stores a certain number of [`Testcase`]s and removes additional ones in a FIFO manner.
|
//! which only stores a certain number of [`Testcase`]s and removes additional ones in a FIFO manner.
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
//! The [`OnDiskCorpus`] stores all [`Testcase`]s to disk.
|
//! The [`OnDiskCorpus`] stores all [`Testcase`]s to disk.
|
||||||
|
//!
|
||||||
//! It _never_ keeps any of them in memory.
|
//! It _never_ keeps any of them in memory.
|
||||||
//! This is a good solution for solutions that are never reused, or for *very* memory-constraint environments.
|
//! This is a good solution for solutions that are never reused, or for *very* memory-constraint environments.
|
||||||
//! For any other occasions, consider using [`crate::corpus::CachedOnDiskCorpus`]
|
//! For any other occasions, consider using [`crate::corpus::CachedOnDiskCorpus`]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
//! Hooks for event managers, especifically these are used to hook before `handle_in_client`.
|
//! Hooks for event managers, especifically these are used to hook before `handle_in_client`.
|
||||||
|
//!
|
||||||
//! This will allow user to define pre/post-processing code when the event manager receives any message from
|
//! This will allow user to define pre/post-processing code when the event manager receives any message from
|
||||||
//! other clients
|
//! other clients
|
||||||
use libafl_bolts::ClientId;
|
use libafl_bolts::ClientId;
|
||||||
|
@ -480,6 +480,8 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A Launcher that minimizes re-execution of shared testcases.
|
||||||
|
///
|
||||||
/// Provides a Launcher, which can be used to launch a fuzzing run on a specified list of cores with a single main and multiple secondary nodes
|
/// Provides a Launcher, which can be used to launch a fuzzing run on a specified list of cores with a single main and multiple secondary nodes
|
||||||
/// This is for centralized, the 4th argument of the closure should mean if this is the main node.
|
/// This is for centralized, the 4th argument of the closure should mean if this is the main node.
|
||||||
#[cfg(all(unix, feature = "std", feature = "fork"))]
|
#[cfg(all(unix, feature = "std", feature = "fork"))]
|
||||||
|
@ -338,6 +338,7 @@ pub enum ManagerKind {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Sets up a restarting fuzzer, using the [`StdShMemProvider`], and standard features.
|
/// Sets up a restarting fuzzer, using the [`StdShMemProvider`], and standard features.
|
||||||
|
///
|
||||||
/// The restarting mgr is a combination of restarter and runner, that can be used on systems with and without `fork` support.
|
/// The restarting mgr is a combination of restarter and runner, that can be used on systems with and without `fork` support.
|
||||||
/// The restarter will spawn a new process each time the child crashes or timeouts.
|
/// The restarter will spawn a new process each time the child crashes or timeouts.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
@ -368,6 +369,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Sets up a restarting fuzzer, using the [`StdShMemProvider`], and standard features.
|
/// Sets up a restarting fuzzer, using the [`StdShMemProvider`], and standard features.
|
||||||
|
///
|
||||||
/// The restarting mgr is a combination of restarter and runner, that can be used on systems with and without `fork` support.
|
/// The restarting mgr is a combination of restarter and runner, that can be used on systems with and without `fork` support.
|
||||||
/// The restarter will spawn a new process each time the child crashes or timeouts.
|
/// The restarter will spawn a new process each time the child crashes or timeouts.
|
||||||
/// This one, additionally uses the timeobserver for the adaptive serialization
|
/// This one, additionally uses the timeobserver for the adaptive serialization
|
||||||
@ -400,7 +402,9 @@ where
|
|||||||
.launch()
|
.launch()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Provides a `builder` which can be used to build a [`RestartingMgr`], which is a combination of a
|
/// Provides a `builder` which can be used to build a [`RestartingMgr`].
|
||||||
|
///
|
||||||
|
/// The [`RestartingMgr`] is is a combination of a
|
||||||
/// `restarter` and `runner`, that can be used on systems both with and without `fork` support. The
|
/// `restarter` and `runner`, that can be used on systems both with and without `fork` support. The
|
||||||
/// `restarter` will start a new process each time the child crashes or times out.
|
/// `restarter` will start a new process each time the child crashes or times out.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
|
@ -68,7 +68,8 @@ pub mod multi_machine;
|
|||||||
#[cfg(all(unix, feature = "std"))]
|
#[cfg(all(unix, feature = "std"))]
|
||||||
pub static mut EVENTMGR_SIGHANDLER_STATE: ShutdownSignalData = ShutdownSignalData {};
|
pub static mut EVENTMGR_SIGHANDLER_STATE: ShutdownSignalData = ShutdownSignalData {};
|
||||||
|
|
||||||
/// A signal handler for catching ctrl-c.
|
/// A signal handler for catching `ctrl-c`.
|
||||||
|
///
|
||||||
/// The purpose of this signal handler is solely for calling `exit()` with a specific exit code 100
|
/// The purpose of this signal handler is solely for calling `exit()` with a specific exit code 100
|
||||||
/// In this way, the restarting manager can tell that we really want to exit
|
/// In this way, the restarting manager can tell that we really want to exit
|
||||||
#[cfg(all(unix, feature = "std"))]
|
#[cfg(all(unix, feature = "std"))]
|
||||||
|
@ -310,7 +310,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Provides a `builder` which can be used to build a [`SimpleRestartingEventManager`], which is a combination of a
|
/// Provides a `builder` which can be used to build a [`SimpleRestartingEventManager`].
|
||||||
|
///
|
||||||
|
/// The [`SimpleRestartingEventManager`] is a combination of a
|
||||||
/// `restarter` and `runner`, that can be used on systems both with and without `fork` support. The
|
/// `restarter` and `runner`, that can be used on systems both with and without `fork` support. The
|
||||||
/// `restarter` will start a new process each time the child crashes or times out.
|
/// `restarter` will start a new process each time the child crashes or times out.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
|
@ -1074,7 +1074,8 @@ pub enum TcpManagerKind {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Sets up a restarting fuzzer, using the [`StdShMemProvider`], and standard features.
|
/// Sets up a restarting fuzzer, using the [`StdShMemProvider`], and standard features.
|
||||||
/// The restarting mgr is a combination of restarter and runner, that can be used on systems with and without `fork` support.
|
///
|
||||||
|
/// The [`TcpRestartingEventManager`] is a combination of restarter and runner, that can be used on systems with and without `fork` support.
|
||||||
/// The restarter will spawn a new process each time the child crashes or timeouts.
|
/// The restarter will spawn a new process each time the child crashes or timeouts.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
@ -1103,7 +1104,9 @@ where
|
|||||||
.launch()
|
.launch()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Provides a `builder` which can be used to build a [`TcpRestartingMgr`], which is a combination of a
|
/// Provides a `builder` which can be used to build a [`TcpRestartingMgr`].
|
||||||
|
///
|
||||||
|
/// The [`TcpRestartingMgr`] is a combination of a
|
||||||
/// `restarter` and `runner`, that can be used on systems both with and without `fork` support. The
|
/// `restarter` and `runner`, that can be used on systems both with and without `fork` support. The
|
||||||
/// `restarter` will start a new process each time the child crashes or times out.
|
/// `restarter` will start a new process each time the child crashes or times out.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
|
@ -154,6 +154,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A `CommandExecutor` is a wrapper around [`std::process::Command`] to execute a target as a child process.
|
/// A `CommandExecutor` is a wrapper around [`std::process::Command`] to execute a target as a child process.
|
||||||
|
///
|
||||||
/// Construct a `CommandExecutor` by implementing [`CommandConfigurator`] for a type of your choice and calling [`CommandConfigurator::into_executor`] on it.
|
/// Construct a `CommandExecutor` by implementing [`CommandConfigurator`] for a type of your choice and calling [`CommandConfigurator::into_executor`] on it.
|
||||||
/// Instead, you can use [`CommandExecutor::builder()`] to construct a [`CommandExecutor`] backed by a [`StdCommandConfigurator`].
|
/// Instead, you can use [`CommandExecutor::builder()`] to construct a [`CommandExecutor`] backed by a [`StdCommandConfigurator`].
|
||||||
pub struct CommandExecutor<OT, S, T> {
|
pub struct CommandExecutor<OT, S, T> {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
//! Executor for differential fuzzing.
|
//! Executor for differential fuzzing.
|
||||||
|
//!
|
||||||
//! It wraps two executors that will be run after each other with the same input.
|
//! It wraps two executors that will be run after each other with the same input.
|
||||||
//! In comparison to the [`crate::executors::CombinedExecutor`] it also runs the secondary executor in `run_target`.
|
//! In comparison to the [`crate::executors::CombinedExecutor`] it also runs the secondary executor in `run_target`.
|
||||||
//!
|
//!
|
||||||
|
@ -531,6 +531,7 @@ impl Forkserver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// This [`Executor`] can run binaries compiled for AFL/AFL++ that make use of a forkserver.
|
/// This [`Executor`] can run binaries compiled for AFL/AFL++ that make use of a forkserver.
|
||||||
|
///
|
||||||
/// Shared memory feature is also available, but you have to set things up in your code.
|
/// Shared memory feature is also available, but you have to set things up in your code.
|
||||||
/// Please refer to AFL++'s docs. <https://github.com/AFLplusplus/AFLplusplus/blob/stable/instrumentation/README.persistent_mode.md>
|
/// Please refer to AFL++'s docs. <https://github.com/AFLplusplus/AFLplusplus/blob/stable/instrumentation/README.persistent_mode.md>
|
||||||
pub struct ForkserverExecutor<OT, S, SP>
|
pub struct ForkserverExecutor<OT, S, SP>
|
||||||
|
@ -37,10 +37,11 @@ pub(crate) type ForkHandlerFuncPtr = unsafe fn(
|
|||||||
|
|
||||||
/// The inner structure of `InProcessForkExecutor`.
|
/// The inner structure of `InProcessForkExecutor`.
|
||||||
pub mod inner;
|
pub mod inner;
|
||||||
/// A version of `InProcessForkExecutor` with a state accessible from the harness.
|
|
||||||
pub mod stateful;
|
pub mod stateful;
|
||||||
|
|
||||||
/// The `InProcessForkExecutor` with no user hooks. On Linux, when fuzzing a Rust target, set `panic = "abort"` in your `Cargo.toml` (see [Cargo documentation](https://doc.rust-lang.org/cargo/reference/profiles.html#panic)).
|
/// The `InProcessForkExecutor` with no user hooks.
|
||||||
|
///
|
||||||
|
/// On Linux, when fuzzing a Rust target, set `panic = "abort"` in your `Cargo.toml` (see [Cargo documentation](https://doc.rust-lang.org/cargo/reference/profiles.html#panic)).
|
||||||
/// Else panics can not be caught by `LibAFL`.
|
/// Else panics can not be caught by `LibAFL`.
|
||||||
pub type InProcessForkExecutor<'a, H, OT, S, SP, EM, Z> =
|
pub type InProcessForkExecutor<'a, H, OT, S, SP, EM, Z> =
|
||||||
GenericInProcessForkExecutor<'a, H, (), OT, S, SP, EM, Z>;
|
GenericInProcessForkExecutor<'a, H, (), OT, S, SP, EM, Z>;
|
||||||
@ -80,7 +81,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`GenericInProcessForkExecutor`] is an executor that forks the current process before each execution. On Linux, when fuzzing a Rust target, set `panic = "abort"` in your `Cargo.toml` (see [Cargo documentation](https://doc.rust-lang.org/cargo/reference/profiles.html#panic)).
|
/// [`GenericInProcessForkExecutor`] is an executor that forks the current process before each execution.
|
||||||
|
///
|
||||||
|
/// On Linux, when fuzzing a Rust target, set `panic = "abort"` in your `Cargo.toml` (see [Cargo documentation](https://doc.rust-lang.org/cargo/reference/profiles.html#panic)).
|
||||||
/// Else panics can not be caught by `LibAFL`.
|
/// Else panics can not be caught by `LibAFL`.
|
||||||
pub struct GenericInProcessForkExecutor<'a, H, HT, OT, S, SP, EM, Z>
|
pub struct GenericInProcessForkExecutor<'a, H, HT, OT, S, SP, EM, Z>
|
||||||
where
|
where
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
//! The `StatefulGenericInProcessForkExecutor` to do forking before executing the harness in-processly. Harness can access internal state.
|
//! A version of `InProcessForkExecutor` with a state accessible from the harness.
|
||||||
|
//!
|
||||||
|
//! The `StatefulGenericInProcessForkExecutor` to do forking before executing the harness in-process.
|
||||||
|
//! The harness can access internal state.
|
||||||
use core::{
|
use core::{
|
||||||
fmt::{self, Debug, Formatter},
|
fmt::{self, Debug, Formatter},
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
//! Concolic feedback for concolic fuzzing.
|
//! Concolic feedback for concolic fuzzing.
|
||||||
|
//!
|
||||||
//! It is used to attach concolic tracing metadata to the testcase.
|
//! It is used to attach concolic tracing metadata to the testcase.
|
||||||
//! This feedback should be used in combination with another feedback as this feedback always considers testcases
|
//! This feedback should be used in combination with another feedback as this feedback always considers testcases
|
||||||
//! to be not interesting.
|
//! to be not interesting.
|
||||||
@ -23,6 +24,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// The concolic feedback. It is used to attach concolic tracing metadata to the testcase.
|
/// The concolic feedback. It is used to attach concolic tracing metadata to the testcase.
|
||||||
|
///
|
||||||
/// This feedback should be used in combination with another feedback as this feedback always considers testcases
|
/// This feedback should be used in combination with another feedback as this feedback always considers testcases
|
||||||
/// to be not interesting.
|
/// to be not interesting.
|
||||||
/// Requires a [`ConcolicObserver`] to observe the concolic trace.
|
/// Requires a [`ConcolicObserver`] to observe the concolic trace.
|
||||||
|
@ -19,6 +19,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// A [`CustomFilenameToTestcaseFeedback`] takes a closure which returns a filename for the testcase.
|
/// A [`CustomFilenameToTestcaseFeedback`] takes a closure which returns a filename for the testcase.
|
||||||
|
///
|
||||||
/// Is never interesting (use with an Eager OR).
|
/// Is never interesting (use with an Eager OR).
|
||||||
/// Note: Use only in conjunction with a `Corpus` type that writes to disk.
|
/// Note: Use only in conjunction with a `Corpus` type that writes to disk.
|
||||||
/// Note: If used as part of the `Objective` chain, then it will only apply to testcases which are
|
/// Note: If used as part of the `Objective` chain, then it will only apply to testcases which are
|
||||||
|
@ -720,8 +720,9 @@ pub type FastAndFeedback<A, B, S> = CombinedFeedback<A, B, LogicFastAnd, S>;
|
|||||||
/// will call all feedbacks functions even if not necessary to conclude the result
|
/// will call all feedbacks functions even if not necessary to conclude the result
|
||||||
pub type EagerOrFeedback<A, B, S> = CombinedFeedback<A, B, LogicEagerOr, S>;
|
pub type EagerOrFeedback<A, B, S> = CombinedFeedback<A, B, LogicEagerOr, S>;
|
||||||
|
|
||||||
/// Combine two feedbacks with an fast OR operation,
|
/// Combine two feedbacks with an fast OR operation - fast.
|
||||||
/// might skip calling feedbacks functions if not necessary to conclude the result.
|
///
|
||||||
|
/// This might skip calling feedbacks functions if not necessary to conclude the result.
|
||||||
/// This means any feedback that is not first might be skipped, use caution when using with
|
/// This means any feedback that is not first might be skipped, use caution when using with
|
||||||
/// `TimeFeedback`
|
/// `TimeFeedback`
|
||||||
pub type FastOrFeedback<A, B, S> = CombinedFeedback<A, B, LogicFastOr, S>;
|
pub type FastOrFeedback<A, B, S> = CombinedFeedback<A, B, LogicFastOr, S>;
|
||||||
@ -1141,6 +1142,8 @@ impl<T> FeedbackFactory<DiffExitKindFeedback, T> for DiffExitKindFeedback {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A [`Feedback`] to track execution time.
|
||||||
|
///
|
||||||
/// Nop feedback that annotates execution time in the new testcase, if any
|
/// Nop feedback that annotates execution time in the new testcase, if any
|
||||||
/// for this Feedback, the testcase is never interesting (use with an OR).
|
/// for this Feedback, the testcase is never interesting (use with an OR).
|
||||||
/// It decides, if the given [`TimeObserver`] value of a run is interesting.
|
/// It decides, if the given [`TimeObserver`] value of a run is interesting.
|
||||||
|
@ -16,7 +16,9 @@ use crate::{
|
|||||||
pub const TRANSFERRED_FEEDBACK_NAME: Cow<'static, str> =
|
pub const TRANSFERRED_FEEDBACK_NAME: Cow<'static, str> =
|
||||||
Cow::Borrowed("transferred_feedback_internal");
|
Cow::Borrowed("transferred_feedback_internal");
|
||||||
|
|
||||||
/// Metadata which denotes whether we are currently transferring an input. Implementors of
|
/// Metadata which denotes whether we are currently transferring an input.
|
||||||
|
///
|
||||||
|
/// Implementors of
|
||||||
/// multi-node communication systems (like [`crate::events::LlmpEventManager`]) should wrap any
|
/// multi-node communication systems (like [`crate::events::LlmpEventManager`]) should wrap any
|
||||||
/// [`crate::EvaluatorObservers::evaluate_input_with_observers`] or
|
/// [`crate::EvaluatorObservers::evaluate_input_with_observers`] or
|
||||||
/// [`crate::ExecutionProcessor::process_execution`] calls with setting this metadata to true/false
|
/// [`crate::ExecutionProcessor::process_execution`] calls with setting this metadata to true/false
|
||||||
|
@ -15,6 +15,7 @@ use crate::inputs::HasMutatorBytes;
|
|||||||
|
|
||||||
/// The [`BytesSubInput`] makes it possible to use [`crate::mutators::Mutator`]`s` that work on
|
/// The [`BytesSubInput`] makes it possible to use [`crate::mutators::Mutator`]`s` that work on
|
||||||
/// inputs implementing the [`HasMutatorBytes`] for a sub-range of this input.
|
/// inputs implementing the [`HasMutatorBytes`] for a sub-range of this input.
|
||||||
|
///
|
||||||
/// For example, we can do the following:
|
/// For example, we can do the following:
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # extern crate alloc;
|
/// # extern crate alloc;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
//! The `EncodedInput` is the "normal" input, a map of codes, that can be sent directly to the client
|
//! The `EncodedInput` is the "normal" input, a map of codes, that can be sent directly to the client.
|
||||||
//! (As opposed to other, more abstract, inputs, like an Grammar-Based AST Input)
|
//!
|
||||||
|
//! This is different to other, more abstract inputs, like an Grammar-Based AST Input.
|
||||||
//! See also [the paper on token-level fuzzing](https://www.usenix.org/system/files/sec21-salls.pdf)
|
//! See also [the paper on token-level fuzzing](https://www.usenix.org/system/files/sec21-salls.pdf)
|
||||||
|
|
||||||
#[cfg(feature = "regex")]
|
#[cfg(feature = "regex")]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
//! [`GramatronRandomMutator`] ist a random mutator using grammar automatons to perform grammar-aware fuzzing.
|
//! [`GramatronRandomMutator`] is a random mutator using grammar automatons to perform grammar-aware fuzzing.
|
||||||
|
//!
|
||||||
//! See the original gramatron repo [`Gramatron`](https://github.com/HexHive/Gramatron) for more details.
|
//! See the original gramatron repo [`Gramatron`](https://github.com/HexHive/Gramatron) for more details.
|
||||||
use alloc::{borrow::Cow, vec::Vec};
|
use alloc::{borrow::Cow, vec::Vec};
|
||||||
use core::cmp::max;
|
use core::cmp::max;
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
//! [`Mutator`]`s` mutate input during fuzzing. These can be used standalone or in combination with other mutators to explore the input space more effectively.
|
//! [`Mutator`]`s` mutate input during fuzzing.
|
||||||
|
//!
|
||||||
|
//! These can be used standalone or in combination with other mutators to explore the input space more effectively.
|
||||||
//! You can read more about mutators in the [libAFL book](https://aflplus.plus/libafl-book/core_concepts/mutator.html)
|
//! You can read more about mutators in the [libAFL book](https://aflplus.plus/libafl-book/core_concepts/mutator.html)
|
||||||
pub mod scheduled;
|
pub mod scheduled;
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
//! The `MOpt` mutation scheduler used in AFL++. It uses a modified Particle Swarm Optimization algorithm to determine an optimal distribution of mutators.
|
//! The `MOpt` mutation scheduler used in AFL++.
|
||||||
|
//!
|
||||||
|
//! It uses a modified Particle Swarm Optimization algorithm to determine an optimal distribution of mutators.
|
||||||
//! See <https://github.com/puppet-meteor/MOpt-AFL> and <https://www.usenix.org/conference/usenixsecurity19/presentation/lyu>
|
//! See <https://github.com/puppet-meteor/MOpt-AFL> and <https://www.usenix.org/conference/usenixsecurity19/presentation/lyu>
|
||||||
use alloc::{borrow::Cow, string::ToString, vec::Vec};
|
use alloc::{borrow::Cow, string::ToString, vec::Vec};
|
||||||
use core::{
|
use core::{
|
||||||
@ -21,6 +23,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// A Struct for managing MOpt-mutator parameters.
|
/// A Struct for managing MOpt-mutator parameters.
|
||||||
|
///
|
||||||
/// There are 2 modes for `MOpt` scheduler, the core fuzzing mode and the pilot fuzzing mode.
|
/// There are 2 modes for `MOpt` scheduler, the core fuzzing mode and the pilot fuzzing mode.
|
||||||
/// In short, in the pilot fuzzing mode, the fuzzer employs several `swarms` to compute the probability to choose the mutation operator.
|
/// In short, in the pilot fuzzing mode, the fuzzer employs several `swarms` to compute the probability to choose the mutation operator.
|
||||||
/// On the other hand, in the core fuzzing mode, the fuzzer chooses the best `swarms`, which was determined during the pilot fuzzing mode, to compute the probability to choose the mutation operator.
|
/// On the other hand, in the core fuzzing mode, the fuzzer chooses the best `swarms`, which was determined during the pilot fuzzing mode, to compute the probability to choose the mutation operator.
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
//! An extension to the `ScheduledMutator` which schedules multiple mutations internally.
|
//! An extension to the `ScheduledMutator` which schedules multiple mutations internally.
|
||||||
|
//!
|
||||||
//! Instead of a random mutator for a random amount of iterations, we can run
|
//! Instead of a random mutator for a random amount of iterations, we can run
|
||||||
//! a specific mutator for a specified amount of iterations
|
//! a specific mutator for a specified amount of iterations
|
||||||
|
|
||||||
|
@ -9,7 +9,9 @@ use core::{
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// A `SymExprRef` identifies a [`SymExpr`] in a trace. Reading a `SymExpr` from a trace will always also yield its
|
/// A `SymExprRef` identifies a [`SymExpr`] in a trace.
|
||||||
|
///
|
||||||
|
/// Reading a `SymExpr` from a trace will always also yield its
|
||||||
/// `SymExprRef`, which can be used later in the trace to identify the `SymExpr`.
|
/// `SymExprRef`, which can be used later in the trace to identify the `SymExpr`.
|
||||||
/// It is also never zero, which allows for efficient use of `Option<SymExprRef>`.
|
/// It is also never zero, which allows for efficient use of `Option<SymExprRef>`.
|
||||||
///
|
///
|
||||||
@ -17,7 +19,9 @@ use serde::{Deserialize, Serialize};
|
|||||||
/// `SymExprRef`s are not valid across traces.
|
/// `SymExprRef`s are not valid across traces.
|
||||||
pub type SymExprRef = NonZeroUsize;
|
pub type SymExprRef = NonZeroUsize;
|
||||||
|
|
||||||
/// [`Location`]s are code locations encountered during concolic tracing, that are constructed from pointers, but not always in a meaningful way.
|
/// [`Location`]s are code locations encountered during concolic tracing
|
||||||
|
///
|
||||||
|
/// [`Location`]s are constructed from pointers, but not always in a meaningful way.
|
||||||
/// Therefore, a location is an opaque value that can only be compared against itself.
|
/// Therefore, a location is an opaque value that can only be compared against itself.
|
||||||
///
|
///
|
||||||
/// It is possible to get at the underlying value using [`Into::into`], should this restriction be too inflexible for your usecase.
|
/// It is possible to get at the underlying value using [`Into::into`], should this restriction be too inflexible for your usecase.
|
||||||
|
@ -35,13 +35,15 @@ pub use multi_map::*;
|
|||||||
pub mod owned_map;
|
pub mod owned_map;
|
||||||
pub use owned_map::*;
|
pub use owned_map::*;
|
||||||
|
|
||||||
|
/// A trait indicating tracking of observed map values after testcase execution
|
||||||
|
///
|
||||||
/// Trait marker which indicates that this [`MapObserver`] is tracked for indices or novelties.
|
/// Trait marker which indicates that this [`MapObserver`] is tracked for indices or novelties.
|
||||||
/// Implementors of feedbacks similar to [`crate::feedbacks::MapFeedback`] may wish to use this to
|
/// Implementors of feedbacks similar to [`crate::feedbacks::MapFeedback`] may wish to use this to
|
||||||
/// ensure that edge metadata is recorded as is appropriate for the provided observer.
|
/// ensure that edge metadata is recorded as is appropriate for the provided observer.
|
||||||
///
|
///
|
||||||
/// If you get a type constraint failure for your map due to this type being unfulfilled, you must
|
/// If you get a type constraint failure for your map due to this type being unfulfilled, you must
|
||||||
/// call [`CanTrack::track_indices`] or [`CanTrack::track_novelties`] **at
|
/// call [`CanTrack::track_indices`] or [`CanTrack::track_novelties`] **at
|
||||||
/// the initialisation site of your map**.
|
/// the initialization site of your map**.
|
||||||
///
|
///
|
||||||
/// This trait allows various components which interact with map metadata to ensure that the
|
/// This trait allows various components which interact with map metadata to ensure that the
|
||||||
/// information they need is actually recorded by the map feedback.
|
/// information they need is actually recorded by the map feedback.
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
//! Observers for `stdout` and `stderr`
|
||||||
|
//!
|
||||||
//! The [`StdOutObserver`] and [`StdErrObserver`] observers look at the stdout of a program
|
//! The [`StdOutObserver`] and [`StdErrObserver`] observers look at the stdout of a program
|
||||||
//! The executor must explicitly support these observers.
|
//! The executor must explicitly support these observers.
|
||||||
//! For example, they are supported on the [`crate::executors::CommandExecutor`].
|
//! For example, they are supported on the [`crate::executors::CommandExecutor`].
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//! The Minimizer schedulers are a family of corpus schedulers that feed the fuzzer
|
//! The [`MinimizerScheduler`]`s` are a family of corpus schedulers that feed the fuzzer
|
||||||
//! with testcases only from a subset of the total corpus.
|
//! with [`Testcase`]`s` only from a subset of the total [`Corpus`].
|
||||||
|
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::{any::type_name, cmp::Ordering, marker::PhantomData};
|
use core::{any::type_name, cmp::Ordering, marker::PhantomData};
|
||||||
@ -68,8 +68,9 @@ impl Default for TopRatedsMetadata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The [`MinimizerScheduler`] employs a genetic algorithm to compute a subset of the
|
/// The [`MinimizerScheduler`] employs a genetic algorithm to compute a subset of the
|
||||||
/// corpus that exercise all the requested features (e.g. all the coverage seen so far)
|
/// corpus that exercise all the requested features.
|
||||||
/// prioritizing [`Testcase`]`s` using [`TestcaseScore`]
|
///
|
||||||
|
/// E.g., it can use all the coverage seen so far to prioritize [`Testcase`]`s` using a [`TestcaseScore`].
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct MinimizerScheduler<CS, F, M, O> {
|
pub struct MinimizerScheduler<CS, F, M, O> {
|
||||||
base: CS,
|
base: CS,
|
||||||
@ -93,7 +94,7 @@ where
|
|||||||
<Self as UsesState>::State: HasCorpus + HasMetadata + HasRand,
|
<Self as UsesState>::State: HasCorpus + HasMetadata + HasRand,
|
||||||
O: CanTrack,
|
O: CanTrack,
|
||||||
{
|
{
|
||||||
/// Replaces the testcase at the given id
|
/// Replaces the [`Testcase`] at the given [`CorpusId`]
|
||||||
fn on_replace(
|
fn on_replace(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut <Self as UsesState>::State,
|
state: &mut <Self as UsesState>::State,
|
||||||
|
@ -270,5 +270,6 @@ impl<S> Default for RandScheduler<S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A [`StdScheduler`] uses the default scheduler in `LibAFL` to schedule [`Testcase`]s.
|
/// A [`StdScheduler`] uses the default scheduler in `LibAFL` to schedule [`Testcase`]s.
|
||||||
|
///
|
||||||
/// The current `Std` is a [`RandScheduler`], although this may change in the future, if another [`Scheduler`] delivers better results.
|
/// The current `Std` is a [`RandScheduler`], although this may change in the future, if another [`Scheduler`] delivers better results.
|
||||||
pub type StdScheduler<S> = RandScheduler<S>;
|
pub type StdScheduler<S> = RandScheduler<S>;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
//! An AFL++-style scheduler with a weighted queue.
|
||||||
|
//!
|
||||||
//! The queue corpus scheduler with weighted queue item selection [from AFL++](https://github.com/AFLplusplus/AFLplusplus/blob/1d4f1e48797c064ee71441ba555b29fc3f467983/src/afl-fuzz-queue.c#L32).
|
//! The queue corpus scheduler with weighted queue item selection [from AFL++](https://github.com/AFLplusplus/AFLplusplus/blob/1d4f1e48797c064ee71441ba555b29fc3f467983/src/afl-fuzz-queue.c#L32).
|
||||||
//! This queue corpus scheduler needs calibration stage.
|
//! This queue corpus scheduler needs calibration stage.
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
//! The [`GenStage`] generates a single input and evaluates it.
|
||||||
|
//!
|
||||||
//! A [`Stage`] that generates a single input via a
|
//! A [`Stage`] that generates a single input via a
|
||||||
//! [`crate::generators::Generator`] and evaluates it using the fuzzer, possibly
|
//! [`crate::generators::Generator`] and evaluates it using the fuzzer, possibly
|
||||||
//! adding it to the corpus.
|
//! adding it to the corpus.
|
||||||
|
@ -68,7 +68,6 @@ pub mod concolic;
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub mod dump;
|
pub mod dump;
|
||||||
pub mod generalization;
|
pub mod generalization;
|
||||||
/// The [`generation::GenStage`] generates a single input and evaluates it.
|
|
||||||
pub mod generation;
|
pub mod generation;
|
||||||
pub mod logics;
|
pub mod logics;
|
||||||
pub mod power;
|
pub mod power;
|
||||||
|
@ -16,7 +16,8 @@ use crate::{
|
|||||||
use crate::{events::EventRestarter, state::Stoppable};
|
use crate::{events::EventRestarter, state::Stoppable};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
/// The stage to probablistically disable a corpus entry.
|
/// The stage to probabilistically disable a corpus entry.
|
||||||
|
///
|
||||||
/// This stage should be wrapped in a if stage and run only when the fuzzer perform restarting
|
/// This stage should be wrapped in a if stage and run only when the fuzzer perform restarting
|
||||||
/// The idea comes from `https://mschloegel.me/paper/schiller2023fuzzerrestarts.pdf`
|
/// The idea comes from `https://mschloegel.me/paper/schiller2023fuzzerrestarts.pdf`
|
||||||
pub struct CorpusPruning<EM> {
|
pub struct CorpusPruning<EM> {
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
//! [`PushStage`]`s` return inputs instead of calling an executor
|
||||||
|
//!
|
||||||
//! While normal stages call the executor over and over again, push stages turn this concept upside down:
|
//! While normal stages call the executor over and over again, push stages turn this concept upside down:
|
||||||
//! A push stage instead returns an iterator that generates a new result for each time it gets called.
|
//! A push stage instead returns an iterator that generates a new result for each time it gets called.
|
||||||
//! With the new testcase, you will have to take care about testcase execution, manually.
|
//! With the new testcase, you will have to take care about testcase execution, manually.
|
||||||
|
@ -29,7 +29,9 @@ use crate::{monitors::PerfFeature, state::HasClientPerfMonitor};
|
|||||||
|
|
||||||
/// The default maximum number of mutations to perform per input.
|
/// The default maximum number of mutations to perform per input.
|
||||||
pub static DEFAULT_MUTATIONAL_MAX_ITERATIONS: usize = 128;
|
pub static DEFAULT_MUTATIONAL_MAX_ITERATIONS: usize = 128;
|
||||||
|
|
||||||
/// A Mutational push stage is the stage in a fuzzing run that mutates inputs.
|
/// A Mutational push stage is the stage in a fuzzing run that mutates inputs.
|
||||||
|
///
|
||||||
/// Mutational push stages will usually have a range of mutations that are
|
/// Mutational push stages will usually have a range of mutations that are
|
||||||
/// being applied to the input one by one, between executions.
|
/// being applied to the input one by one, between executions.
|
||||||
/// The push version, in contrast to the normal stage, will return each testcase, instead of executing it.
|
/// The push version, in contrast to the normal stage, will return each testcase, instead of executing it.
|
||||||
|
@ -29,6 +29,8 @@ pub fn get_unique_std_input_file() -> String {
|
|||||||
format!("{}_{}", INPUTFILE_STD, std::process::id())
|
format!("{}_{}", INPUTFILE_STD, std::process::id())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Write a file atomically
|
||||||
|
///
|
||||||
/// Creates a `.{file_name}.tmp` file, and writes all bytes to it.
|
/// Creates a `.{file_name}.tmp` file, and writes all bytes to it.
|
||||||
/// After all bytes have been written, the tmp-file is moved to it's original `path`.
|
/// After all bytes have been written, the tmp-file is moved to it's original `path`.
|
||||||
/// This way, on the majority of operating systems, the final file will never be incomplete or racey.
|
/// This way, on the majority of operating systems, the final file will never be incomplete or racey.
|
||||||
|
@ -80,7 +80,9 @@
|
|||||||
#[cfg(not(feature = "alloc"))]
|
#[cfg(not(feature = "alloc"))]
|
||||||
type String = &'static str;
|
type String = &'static str;
|
||||||
|
|
||||||
/// We also need a non-allocating format...
|
/// A simple non-allocating "format" string wrapper for no-std.
|
||||||
|
///
|
||||||
|
/// Problem is that we really need a non-allocating format...
|
||||||
/// This one simply returns the `fmt` string.
|
/// This one simply returns the `fmt` string.
|
||||||
/// Good enough for simple errors, for anything else, use the `alloc` feature.
|
/// Good enough for simple errors, for anything else, use the `alloc` feature.
|
||||||
#[cfg(not(feature = "alloc"))]
|
#[cfg(not(feature = "alloc"))]
|
||||||
@ -257,6 +259,8 @@ fn display_error_backtrace(_f: &mut fmt::Formatter, _err: &ErrorBacktrace) -> fm
|
|||||||
fmt::Result::Ok(())
|
fmt::Result::Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the standard input [`Hasher`]
|
||||||
|
///
|
||||||
/// Returns the hasher for the input with a given hash, depending on features:
|
/// Returns the hasher for the input with a given hash, depending on features:
|
||||||
/// [`xxh3_64`](https://docs.rs/xxhash-rust/latest/xxhash_rust/xxh3/fn.xxh3_64.html)
|
/// [`xxh3_64`](https://docs.rs/xxhash-rust/latest/xxhash_rust/xxh3/fn.xxh3_64.html)
|
||||||
/// if the `xxh3` feature is used, /// else [`ahash`](https://docs.rs/ahash/latest/ahash/).
|
/// if the `xxh3` feature is used, /// else [`ahash`](https://docs.rs/ahash/latest/ahash/).
|
||||||
@ -269,6 +273,8 @@ pub fn hasher_std() -> impl Hasher + Clone {
|
|||||||
RandomState::with_seeds(0, 0, 0, 0).build_hasher()
|
RandomState::with_seeds(0, 0, 0, 0).build_hasher()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Hashes the input with a given hash
|
||||||
|
///
|
||||||
/// Hashes the input with a given hash, depending on features:
|
/// Hashes the input with a given hash, depending on features:
|
||||||
/// [`xxh3_64`](https://docs.rs/xxhash-rust/latest/xxhash_rust/xxh3/fn.xxh3_64.html)
|
/// [`xxh3_64`](https://docs.rs/xxhash-rust/latest/xxhash_rust/xxh3/fn.xxh3_64.html)
|
||||||
/// if the `xxh3` feature is used, /// else [`ahash`](https://docs.rs/ahash/latest/ahash/).
|
/// if the `xxh3` feature is used, /// else [`ahash`](https://docs.rs/ahash/latest/ahash/).
|
||||||
|
@ -441,6 +441,7 @@ unsafe fn handle_signal(sig: c_int, info: *mut siginfo_t, void: *mut c_void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Setup signal handlers in a somewhat rusty way.
|
/// Setup signal handlers in a somewhat rusty way.
|
||||||
|
///
|
||||||
/// This will allocate a signal stack and set the signal handlers accordingly.
|
/// This will allocate a signal stack and set the signal handlers accordingly.
|
||||||
/// It is, for example, used in `LibAFL's` `InProcessExecutor` to restart the fuzzer in case of a crash,
|
/// It is, for example, used in `LibAFL's` `InProcessExecutor` to restart the fuzzer in case of a crash,
|
||||||
/// or to handle `SIGINT` in the broker process.
|
/// or to handle `SIGINT` in the broker process.
|
||||||
@ -496,6 +497,7 @@ pub unsafe fn setup_signal_handler<T: 'static + Handler>(handler: *mut T) -> Res
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Function to get the current [`ucontext_t`] for this process.
|
/// Function to get the current [`ucontext_t`] for this process.
|
||||||
|
///
|
||||||
/// This calls the libc `getcontext` function under the hood.
|
/// This calls the libc `getcontext` function under the hood.
|
||||||
/// It can be useful, for example for `dump_regs`.
|
/// It can be useful, for example for `dump_regs`.
|
||||||
/// Note that calling this method may, of course, alter the state.
|
/// Note that calling this method may, of course, alter the state.
|
||||||
|
@ -1,14 +1,17 @@
|
|||||||
//! The random number generators of `LibAFL`
|
//! The random number generators of `LibAFL`
|
||||||
|
|
||||||
#[cfg(target_has_atomic = "ptr")]
|
#[cfg(all(not(feature = "std"), target_has_atomic = "ptr"))]
|
||||||
use core::sync::atomic::Ordering;
|
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||||
use core::{debug_assert, fmt::Debug, sync::atomic::AtomicUsize};
|
use core::{debug_assert, fmt::Debug};
|
||||||
|
|
||||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
pub mod loaded_dice;
|
pub mod loaded_dice;
|
||||||
|
|
||||||
|
#[cfg(all(not(feature = "std"), target_has_atomic = "ptr"))]
|
||||||
|
static SEED_COUNTER: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
|
||||||
/// Return a pseudo-random seed. For `no_std` environments, a single deterministic sequence is used.
|
/// Return a pseudo-random seed. For `no_std` environments, a single deterministic sequence is used.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[allow(unreachable_code)]
|
#[allow(unreachable_code)]
|
||||||
@ -21,10 +24,7 @@ pub fn random_seed() -> u64 {
|
|||||||
4
|
4
|
||||||
}
|
}
|
||||||
|
|
||||||
static SEED_COUNTER: AtomicUsize = AtomicUsize::new(0);
|
#[cfg(all(not(feature = "std"), target_has_atomic = "ptr"))]
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
#[cfg(target_has_atomic = "ptr")]
|
|
||||||
fn random_seed_deterministic() -> u64 {
|
fn random_seed_deterministic() -> u64 {
|
||||||
let mut seed = SEED_COUNTER.fetch_add(1, Ordering::Relaxed) as u64;
|
let mut seed = SEED_COUNTER.fetch_add(1, Ordering::Relaxed) as u64;
|
||||||
splitmix64(&mut seed)
|
splitmix64(&mut seed)
|
||||||
@ -49,7 +49,8 @@ fn splitmix64(x: &mut u64) -> u64 {
|
|||||||
z ^ (z >> 31)
|
z ^ (z >> 31)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The standard rand implementation for `LibAFL`.
|
/// The standard [`Rand`] implementation for `LibAFL`.
|
||||||
|
///
|
||||||
/// It is usually the right choice, with very good speed and a reasonable randomness.
|
/// It is usually the right choice, with very good speed and a reasonable randomness.
|
||||||
/// Not cryptographically secure (which is not what you want during fuzzing ;) )
|
/// Not cryptographically secure (which is not what you want during fuzzing ;) )
|
||||||
pub type StdRand = RomuDuoJrRand;
|
pub type StdRand = RomuDuoJrRand;
|
||||||
|
@ -102,8 +102,10 @@ impl ShMemDescription {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The id describing shared memory for the current provider
|
||||||
|
///
|
||||||
/// An id associated with a given shared memory mapping ([`ShMem`]), which can be used to
|
/// An id associated with a given shared memory mapping ([`ShMem`]), which can be used to
|
||||||
/// establish shared-mappings between proccesses.
|
/// establish shared-mappings between processes.
|
||||||
/// Id is a file descriptor if you use `MmapShMem` or `AshmemShMem`.
|
/// Id is a file descriptor if you use `MmapShMem` or `AshmemShMem`.
|
||||||
/// That means you have to use shmem server to access to the shmem segment from other processes in these cases.
|
/// That means you have to use shmem server to access to the shmem segment from other processes in these cases.
|
||||||
/// On the other hand, id is a unique identifier if you use `CommonUnixShMem` or `Win32ShMem`.
|
/// On the other hand, id is a unique identifier if you use `CommonUnixShMem` or `Win32ShMem`.
|
||||||
@ -193,6 +195,7 @@ impl Display for ShMemId {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A [`ShMem`] is an interface to shared maps.
|
/// A [`ShMem`] is an interface to shared maps.
|
||||||
|
///
|
||||||
/// They are the backbone of [`crate::llmp`] for inter-process communication.
|
/// They are the backbone of [`crate::llmp`] for inter-process communication.
|
||||||
/// All you need for scaling on a new target is to implement this interface, as well as the respective [`ShMemProvider`].
|
/// All you need for scaling on a new target is to implement this interface, as well as the respective [`ShMemProvider`].
|
||||||
pub trait ShMem: Sized + Debug + Clone + DerefMut<Target = [u8]> {
|
pub trait ShMem: Sized + Debug + Clone + DerefMut<Target = [u8]> {
|
||||||
@ -239,6 +242,7 @@ pub trait ShMem: Sized + Debug + Clone + DerefMut<Target = [u8]> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A [`ShMemProvider`] provides access to shared maps.
|
/// A [`ShMemProvider`] provides access to shared maps.
|
||||||
|
///
|
||||||
/// They are the backbone of [`crate::llmp`] for inter-process communication.
|
/// They are the backbone of [`crate::llmp`] for inter-process communication.
|
||||||
/// All you need for scaling on a new target is to implement this interface, as well as the respective [`ShMem`].
|
/// All you need for scaling on a new target is to implement this interface, as well as the respective [`ShMem`].
|
||||||
pub trait ShMemProvider: Clone + Default + Debug {
|
pub trait ShMemProvider: Clone + Default + Debug {
|
||||||
@ -317,6 +321,7 @@ pub trait ShMemProvider: Clone + Default + Debug {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// An [`ShMemProvider`] that does not provide any [`ShMem`].
|
/// An [`ShMemProvider`] that does not provide any [`ShMem`].
|
||||||
|
///
|
||||||
/// This is mainly for testing and type magic.
|
/// This is mainly for testing and type magic.
|
||||||
/// The resulting [`NopShMem`] is backed by a simple byte buffer to do some simple non-shared things with.
|
/// The resulting [`NopShMem`] is backed by a simple byte buffer to do some simple non-shared things with.
|
||||||
/// Calling [`NopShMemProvider::shmem_from_id_and_size`] will return new maps for the same id every time.
|
/// Calling [`NopShMemProvider::shmem_from_id_and_size`] will return new maps for the same id every time.
|
||||||
|
@ -60,6 +60,7 @@ impl StateShMemContent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A [`StateRestorer`] saves and restores bytes to a shared map.
|
/// A [`StateRestorer`] saves and restores bytes to a shared map.
|
||||||
|
///
|
||||||
/// If the state gets larger than the preallocated [`ShMem`] shared map,
|
/// If the state gets larger than the preallocated [`ShMem`] shared map,
|
||||||
/// it will instead write to disk, and store the file name into the map.
|
/// it will instead write to disk, and store the file name into the map.
|
||||||
/// Writing to [`StateRestorer`] multiple times is not allowed.
|
/// Writing to [`StateRestorer`] multiple times is not allowed.
|
||||||
|
@ -35,7 +35,9 @@ macro_rules! rust_filter_function_declaration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A [`Filter`] can decide for each expression whether the expression should be traced symbolically or be
|
/// A [`Filter`] can decide for each expression whether the expression should be traced symbolically or be
|
||||||
/// concretized. This allows to implement filtering mechanisms that reduce the amount of traced expressions by
|
/// concretized.
|
||||||
|
///
|
||||||
|
/// This allows us to implement filtering mechanisms that reduce the amount of traced expressions by
|
||||||
/// concretizing uninteresting expressions.
|
/// concretizing uninteresting expressions.
|
||||||
/// If a filter concretizes an expression that would have later been used as part of another expression that
|
/// If a filter concretizes an expression that would have later been used as part of another expression that
|
||||||
/// is still symbolic, a concrete instead of a symbolic value is received.
|
/// is still symbolic, a concrete instead of a symbolic value is received.
|
||||||
@ -78,8 +80,9 @@ pub trait Filter {
|
|||||||
invoke_macro_with_rust_runtime_exports!(rust_filter_function_declaration;);
|
invoke_macro_with_rust_runtime_exports!(rust_filter_function_declaration;);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A `FilterRuntime` wraps a [`Runtime`] with a [`Filter`], applying the filter before passing expressions to the inner
|
/// A `FilterRuntime` wraps a [`Runtime`] with a [`Filter`].
|
||||||
/// runtime.
|
///
|
||||||
|
/// It applies the filter before passing expressions to the inner runtime.
|
||||||
/// It also implements [`Runtime`], allowing for composing multiple [`Filter`]'s in a chain.
|
/// It also implements [`Runtime`], allowing for composing multiple [`Filter`]'s in a chain.
|
||||||
#[allow(clippy::module_name_repetitions)]
|
#[allow(clippy::module_name_repetitions)]
|
||||||
pub struct FilterRuntime<F, RT> {
|
pub struct FilterRuntime<F, RT> {
|
||||||
|
@ -207,7 +207,9 @@ impl Runtime for NopRuntime {
|
|||||||
invoke_macro_with_rust_runtime_exports!(impl_nop_runtime_fn;);
|
invoke_macro_with_rust_runtime_exports!(impl_nop_runtime_fn;);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This runtime can be constructed from an [`Option`] of a runtime, concretizing all expressions in the `None` case and forwarding expressions to the respective runtime in the `Some` case.
|
/// This runtime can be constructed from an [`Option`] of a runtime.
|
||||||
|
///
|
||||||
|
/// It concretizes all expressions in the `None` case and forwards expressions to the respective runtime in the `Some` case.
|
||||||
/// This is especially useful for parts of the processing pipeline that should be activated based on a runtime configuration, such as an environment variable.
|
/// This is especially useful for parts of the processing pipeline that should be activated based on a runtime configuration, such as an environment variable.
|
||||||
pub struct OptionalRuntime<RT> {
|
pub struct OptionalRuntime<RT> {
|
||||||
inner: Option<RT>,
|
inner: Option<RT>,
|
||||||
|
@ -6,6 +6,7 @@ use libafl::observers::concolic::SymExpr;
|
|||||||
use crate::{RSymExpr, Runtime};
|
use crate::{RSymExpr, Runtime};
|
||||||
|
|
||||||
/// Traces the expressions according to the format described in [`libafl::observers::concolic::serialization_format`].
|
/// Traces the expressions according to the format described in [`libafl::observers::concolic::serialization_format`].
|
||||||
|
///
|
||||||
/// The format can be read from elsewhere to perform processing of the expressions outside of the runtime.
|
/// The format can be read from elsewhere to perform processing of the expressions outside of the runtime.
|
||||||
pub struct TracingRuntime {
|
pub struct TracingRuntime {
|
||||||
writer: StdShMemMessageFileWriter,
|
writer: StdShMemMessageFileWriter,
|
||||||
|
@ -70,7 +70,9 @@ pub fn libafl_serdeany_derive(input: TokenStream) -> TokenStream {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Derive macro to implement `Display` for a struct where all fields implement `Display`.
|
/// A derive macro to implement `Display`
|
||||||
|
///
|
||||||
|
/// Derive macro to implement [`core::fmt::Display`] for a struct where all fields implement `Display`.
|
||||||
/// The result is the space separated concatenation of all fields' display.
|
/// The result is the space separated concatenation of all fields' display.
|
||||||
/// Order of declaration is preserved.
|
/// Order of declaration is preserved.
|
||||||
/// Specifically handled cases:
|
/// Specifically handled cases:
|
||||||
|
@ -65,12 +65,13 @@ extern "C" {
|
|||||||
fn tls_ptr() -> *const c_void;
|
fn tls_ptr() -> *const c_void;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The count of registers that need to be saved by the asan runtime
|
/// The count of registers that need to be saved by the `ASan` runtime.
|
||||||
/// sixteen general purpose registers are put in this order, rax, rbx, rcx, rdx, rbp, rsp, rsi, rdi, r8-r15, plus instrumented rip, accessed memory addr and true rip
|
///
|
||||||
|
/// Sixteen general purpose registers are put in this order, `rax`, `rbx`, `rcx`, `rdx`, `rbp`, `rsp`, `rsi`, `rdi`, `r8-r15`, plus instrumented `rip`, accessed memory addr and true `rip`
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
pub const ASAN_SAVE_REGISTER_COUNT: usize = 19;
|
pub const ASAN_SAVE_REGISTER_COUNT: usize = 19;
|
||||||
|
|
||||||
/// The registers that need to be saved by the asan runtime, as names
|
/// The registers that need to be saved by the `ASan` runtime, as names
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
pub const ASAN_SAVE_REGISTER_NAMES: [&str; ASAN_SAVE_REGISTER_COUNT] = [
|
pub const ASAN_SAVE_REGISTER_NAMES: [&str; ASAN_SAVE_REGISTER_COUNT] = [
|
||||||
"rax",
|
"rax",
|
||||||
@ -109,8 +110,9 @@ const ASAN_EH_FRAME_FDE_OFFSET: u32 = 20;
|
|||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
const ASAN_EH_FRAME_FDE_ADDRESS_OFFSET: u32 = 28;
|
const ASAN_EH_FRAME_FDE_ADDRESS_OFFSET: u32 = 28;
|
||||||
|
|
||||||
/// The frida address sanitizer runtime, providing address sanitization.
|
/// The `FRIDA` address sanitizer runtime, providing address sanitization.
|
||||||
/// When executing in `ASAN`, each memory access will get checked, using frida stalker under the hood.
|
///
|
||||||
|
/// When executing in `ASan`, each memory access will get checked, using `FRIDA` stalker under the hood.
|
||||||
/// The runtime can report memory errors that occurred during execution,
|
/// The runtime can report memory errors that occurred during execution,
|
||||||
/// even if the target would not have crashed under normal conditions.
|
/// even if the target would not have crashed under normal conditions.
|
||||||
/// this helps finding mem errors early.
|
/// this helps finding mem errors early.
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
//! The [`FRIDA`](https://frida.re) `CmpLog` runtime
|
||||||
|
//!
|
||||||
//! Functionality for [`frida`](https://frida.re)-based binary-only `CmpLog`.
|
//! Functionality for [`frida`](https://frida.re)-based binary-only `CmpLog`.
|
||||||
//! With it, a fuzzer can collect feedback about each compare that happened in the target
|
//! With it, a fuzzer can collect feedback about each compare that happened in the target
|
||||||
//! This allows the fuzzer to potentially solve the compares, if a compare value is directly
|
//! This allows the fuzzer to potentially solve the compares, if a compare value is directly
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/*!
|
/*!
|
||||||
The [`Frida`](https://frida.re) executor is a binary-only mode for `LibAFL`.
|
The [`Frida`](https://frida.re) executor is a binary-only mode for `LibAFL`.
|
||||||
|
|
||||||
It can report coverage and, on supported architectures, even reports memory access errors.
|
It can report coverage and, on supported architectures, even reports memory access errors.
|
||||||
|
|
||||||
Additional documentation is available in [the `LibAFL` book](https://aflplus.plus/libafl-book/advanced_features/frida.html).
|
Additional documentation is available in [the `LibAFL` book](https://aflplus.plus/libafl-book/advanced_features/frida.html).
|
||||||
@ -81,7 +82,6 @@ pub mod coverage_rt;
|
|||||||
pub mod pthread_hook;
|
pub mod pthread_hook;
|
||||||
|
|
||||||
#[cfg(feature = "cmplog")]
|
#[cfg(feature = "cmplog")]
|
||||||
/// The frida cmplog runtime
|
|
||||||
pub mod cmplog_rt;
|
pub mod cmplog_rt;
|
||||||
|
|
||||||
/// The `LibAFL` firda helper
|
/// The `LibAFL` firda helper
|
||||||
|
@ -184,9 +184,10 @@ pub fn get_register(context: &CpuContext, reg: X86Register) -> u64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The writer registers
|
/// The writer registers.
|
||||||
/// frida registers: <https://docs.rs/frida-gum/latest/frida_gum/instruction_writer/enum.X86Register.html>
|
///
|
||||||
/// capstone registers: <https://docs.rs/capstone-sys/latest/capstone_sys/x86_reg/index.html>
|
/// `FRIDA` registers: <https://docs.rs/frida-gum/latest/frida_gum/instruction_writer/enum.X86Register.html>
|
||||||
|
/// `capstone` registers: <https://docs.rs/capstone-sys/latest/capstone_sys/x86_reg/index.html>
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -201,7 +202,7 @@ pub fn writer_register(reg: RegSpec) -> X86Register {
|
|||||||
X86Register::None
|
X86Register::None
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Translates a frida instruction to a disassembled instruction.
|
/// Translates a `FRIDA` instruction to a disassembled instruction.
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
pub(crate) fn frida_to_cs(
|
pub(crate) fn frida_to_cs(
|
||||||
decoder: InstDecoder,
|
decoder: InstDecoder,
|
||||||
@ -224,7 +225,7 @@ pub(crate) fn frida_to_cs(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
/// Get the base, idx, scale, disp for each operand
|
/// Get the `base`, `idx`, `scale`, `disp` for each operand
|
||||||
pub fn operand_details(operand: &Operand) -> Option<(X86Register, X86Register, u8, i32)> {
|
pub fn operand_details(operand: &Operand) -> Option<(X86Register, X86Register, u8, i32)> {
|
||||||
match operand {
|
match operand {
|
||||||
Operand::RegDeref(base) => {
|
Operand::RegDeref(base) => {
|
||||||
|
@ -253,7 +253,9 @@ fn include_path(build_dir: &Path, path: &str) -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If `fresh_content` != `content_file_to_update` (the file is read directly if `content_file_to_update` is None), update the file. prefix is not considered for comparison.
|
/// If `fresh_content` != `content_file_to_update` (the file is read directly if `content_file_to_update` is None), update the file.
|
||||||
|
///
|
||||||
|
/// The prefix is not considered for comparison.
|
||||||
/// If a prefix is given, it will be added as the first line of the file.
|
/// If a prefix is given, it will be added as the first line of the file.
|
||||||
pub fn store_generated_content_if_different(
|
pub fn store_generated_content_if_different(
|
||||||
file_to_update: &Path,
|
file_to_update: &Path,
|
||||||
|
@ -80,12 +80,13 @@ pub struct CmpLogHeader {
|
|||||||
// VALS
|
// VALS
|
||||||
|
|
||||||
/// The AFL++ `cmp_operands` struct
|
/// The AFL++ `cmp_operands` struct
|
||||||
#[derive(Default, Debug, Clone, Copy)]
|
///
|
||||||
#[repr(C, packed)]
|
|
||||||
/// Comparison operands, represented as either two (left and right of comparison) u64 values or
|
/// Comparison operands, represented as either two (left and right of comparison) u64 values or
|
||||||
/// two (left and right of comparison) u128 values, split into two u64 values. If the left and
|
/// two (left and right of comparison) u128 values, split into two u64 values. If the left and
|
||||||
/// right values are smaller than u64, they can be sign or zero extended to 64 bits, as the actual
|
/// right values are smaller than u64, they can be sign or zero extended to 64 bits, as the actual
|
||||||
/// comparison size is determined by the `hits` field of the associated `AFLppCmpLogHeader`.
|
/// comparison size is determined by the `hits` field of the associated `AFLppCmpLogHeader`.
|
||||||
|
#[derive(Default, Debug, Clone, Copy)]
|
||||||
|
#[repr(C, packed)]
|
||||||
pub struct AFLppCmpLogOperands {
|
pub struct AFLppCmpLogOperands {
|
||||||
v0: u64,
|
v0: u64,
|
||||||
v0_128: u64,
|
v0_128: u64,
|
||||||
|
@ -29,6 +29,7 @@ pub static mut __afl_acc_memop_ptr_local: [u32; ACCOUNTING_MAP_SIZE] = [0; ACCOU
|
|||||||
pub use __afl_acc_memop_ptr_local as ACCOUNTING_MEMOP_MAP;
|
pub use __afl_acc_memop_ptr_local as ACCOUNTING_MEMOP_MAP;
|
||||||
|
|
||||||
/// The max count of edges found.
|
/// The max count of edges found.
|
||||||
|
///
|
||||||
/// This is either computed during the compilation time or at runtime (in this case this is used to shrink the map).
|
/// This is either computed during the compilation time or at runtime (in this case this is used to shrink the map).
|
||||||
/// You can use this for the initial map size for the observer only if you compute this time at compilation time.
|
/// You can use this for the initial map size for the observer only if you compute this time at compilation time.
|
||||||
pub static mut MAX_EDGES_FOUND: usize = 0;
|
pub static mut MAX_EDGES_FOUND: usize = 0;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
//! [`DrCov`](https://dynamorio.org/page_drcov.html) support for `LibAFL` frida mode,
|
//! [`DrCov`](https://dynamorio.org/page_drcov.html) support for `LibAFL` `FRIDA` mode.
|
||||||
//! writing basic-block trace files to be read by coverage analysis tools, such as [Lighthouse](https://github.com/gaasedelen/lighthouse),
|
//!
|
||||||
|
//! It's writing basic-block trace files to be read by coverage analysis tools, such as [Lighthouse](https://github.com/gaasedelen/lighthouse),
|
||||||
//! [bncov](https://github.com/ForAllSecure/bncov), [dragondance](https://github.com/0ffffffffh/dragondance), etc.
|
//! [bncov](https://github.com/ForAllSecure/bncov), [dragondance](https://github.com/0ffffffffh/dragondance), etc.
|
||||||
|
|
||||||
use alloc::{string::String, vec::Vec};
|
use alloc::{string::String, vec::Vec};
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
//! [`Libfuzzer`](https://www.llvm.org/docs/LibFuzzer.html)-style runtime wrapper for `LibAFL`.
|
//! [`Libfuzzer`](https://www.llvm.org/docs/LibFuzzer.html)-style runtime wrapper for `LibAFL`.
|
||||||
|
//!
|
||||||
//! This makes `LibAFL` interoperable with harnesses written for other fuzzers like `Libfuzzer` and [`AFLplusplus`](aflplus.plus).
|
//! This makes `LibAFL` interoperable with harnesses written for other fuzzers like `Libfuzzer` and [`AFLplusplus`](aflplus.plus).
|
||||||
//! We will interact with a C++ target, so use external c functionality
|
//! We will interact with a C++ target, so use external c functionality
|
||||||
|
|
||||||
|
@ -197,7 +197,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A mutator which invokes a libFuzzer-like custom mutator or crossover. The `CROSSOVER` constant
|
/// A mutator which invokes a libFuzzer-like custom mutator or crossover.
|
||||||
|
///
|
||||||
|
/// The `CROSSOVER` constant
|
||||||
/// controls whether this mutator invokes `LLVMFuzzerCustomMutate` and `LLVMFuzzerCustomCrossover`.
|
/// controls whether this mutator invokes `LLVMFuzzerCustomMutate` and `LLVMFuzzerCustomCrossover`.
|
||||||
/// You should avoid using crossover-like mutators with custom mutators as this may lead to the
|
/// You should avoid using crossover-like mutators with custom mutators as this may lead to the
|
||||||
/// injection of some input portions to another in ways which violate structure.
|
/// injection of some input portions to another in ways which violate structure.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user