Remodelling Observers/Examples that rely on UB, API cleanups (#950)

* Tackling UB

* PtrMut -> MutPtr, moved mapobservers to non-UB

* QEMU fixes

* test fixes

* qemu

* Change all interfaces, fix all fuzzers

* fixes

* fix more fixes

* fmt

* fix qemu sugar

* fix some qemus

* atheris

* fmt

* more fmt

* most fmt

* more fix

* nyx fyx

* fix qemu

* clippy, fixes

* more fixes

* no unfix, only fix

* fix

* fix

* more clippy

* fixes

* ListObserver

* fmt, clippy

* fix qemu on arm

* update zlib target

* fix?

* fix

* added migration guide

* ignore doc

* fix symcc

* fix new win fuzzer

* Fixes, rename PTR_SIZE to PTR_NUM

* Try fix linking on win

* Trying to fix win linking

* more cov

* trying to fix win some more

* trying to fix mac

* trying to fix mac

* Fix tests

* Fix tests

* trying to fix win

* more mac

* giving up for windows

* fmt

* python3

* mac?

* undo windows tests
This commit is contained in:
Dominik Maier 2022-12-24 14:20:44 +01:00 committed by GitHub
parent 3a1e499d9d
commit 75f12bd0eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
96 changed files with 676 additions and 537 deletions

View File

@ -174,8 +174,9 @@ jobs:
- name: Add no_std toolchain - name: Add no_std toolchain
run: rustup toolchain install nightly-x86_64-unknown-linux-gnu ; rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu run: rustup toolchain install nightly-x86_64-unknown-linux-gnu ; rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu
- name: Install python - name: Install python
# Removing macOS things already installed in CI against failed linking
if: runner.os == 'macOS' if: runner.os == 'macOS'
run: brew install --force-bottle --overwrite python@3.11 run: rm /usr/local/bin/2to3 /usr/local/bin/idle3 /usr/local/bin/pydoc3 /usr/local/bin/python3 /usr/local/bin/python3-config; brew install --force-bottle --overwrite python
- uses: lyricwulf/abc@v1 - uses: lyricwulf/abc@v1
with: with:
# todo: remove afl++-clang when nyx support samcov_pcguard # todo: remove afl++-clang when nyx support samcov_pcguard

View File

@ -53,12 +53,12 @@ Combined with any `Runtime` you'd like to use, you can initialize the `FridaInst
## Running the Fuzzer ## Running the Fuzzer
After setting up the `FridaInstrumentationHelper`. You can obtain the pointer to the coverage map by calling `map_ptr_mut()`. After setting up the `FridaInstrumentationHelper`. You can obtain the pointer to the coverage map by calling `map_mut_ptr()`.
```rust,ignore ```rust,ignore
let edges_observer = HitcountsMapObserver::new(StdMapObserver::new_from_ptr( let edges_observer = HitcountsMapObserver::new(StdMapObserver::from_mut_ptr(
"edges", "edges",
frida_helper.map_ptr_mut().unwrap(), frida_helper.map_mut_ptr().unwrap(),
MAP_SIZE, MAP_SIZE,
)); ));
``` ```

View File

@ -63,8 +63,7 @@ let mut helper = NyxHelper::new(share_dir, cpu_id, true, parallel_mode, None).un
Then, fetch `trace_bits`, create an observer and the `NyxExecutor`: Then, fetch `trace_bits`, create an observer and the `NyxExecutor`:
```rust,ignore ```rust,ignore
let trace_bits = unsafe { std::slice::from_raw_parts_mut(helper.trace_bits, helper.map_size) }; let observer = unsafe { StdMapObserver::from_mut_ptr("trace", helper.trace_bits, helper.map_size) };
let observer = StdMapObserver::new("trace", trace_bits);
let mut executor = NyxExecutor::new(&mut helper, tuple_list!(observer)).unwrap(); let mut executor = NyxExecutor::new(&mut helper, tuple_list!(observer)).unwrap();
``` ```
@ -99,9 +98,7 @@ let mut helper = NyxHelper::new(
Then you can fetch the trace_bits and create an observer and `NyxExecutor` Then you can fetch the trace_bits and create an observer and `NyxExecutor`
```rust,ignore ```rust,ignore
let trace_bits = let observer = unsafe { StdMapObserver::from_mut_ptr("trace", helper.trace_bits, helper.map_size) }
unsafe { std::slice::from_raw_parts_mut(helper.trace_bits, helper.map_size) };
let observer = StdMapObserver::new("trace", trace_bits);
let mut executor = NyxExecutor::new(&mut helper, tuple_list!(observer)).unwrap(); let mut executor = NyxExecutor::new(&mut helper, tuple_list!(observer)).unwrap();
``` ```

View File

@ -160,3 +160,26 @@ Now, `Corpus` cannot be accidentally implemented for another type other than tha
is fixed to the associated type for `UsesInput`. is fixed to the associated type for `UsesInput`.
A more complex example of migration can be found in the "Reasons for this change" section of this document. A more complex example of migration can be found in the "Reasons for this change" section of this document.
## Observer Changes
Additionally, we changed the observers API, as the API in 0.8 led to undefined behavior.
At the same time, we used the change to simplify the common case: creating an `StdMapObserver`
from libafl_target's `EDGES_MAP`.
In the future, instead of using:
```rust,ignore
let edges = unsafe { &mut EDGES_MAP[0..MAX_EDGES_NUM] };
let edges_observer = StdMapObserver::new("edges", edges);
```
creating the edges observer is as simple as using the new `std_edges_map_observer` function.
```rust,ignore
let edges_observer = unsafe { std_edges_map_observer("edges") };
```
Alternatively, `StdMapObserver::new` will still work, but now the whole method is marked as `unsafe`.
The reason is that the caller has to make sure `EDGES_MAP` (or other maps) are not moved or freed in memory,
for the lifetime of the lifetime of the `MapObserver`.
This means that the buffer should either be `static` or `Pin`.

View File

@ -30,7 +30,7 @@ fn signals_set(idx: usize) {
unsafe { SIGNALS[idx] = 1 }; unsafe { SIGNALS[idx] = 1 };
} }
#[allow(clippy::similar_names)] #[allow(clippy::similar_names, clippy::manual_assert)]
pub fn main() { pub fn main() {
// The closure that we want to fuzz // The closure that we want to fuzz
let mut harness = |input: &BytesInput| { let mut harness = |input: &BytesInput| {
@ -61,7 +61,7 @@ pub fn main() {
// Create an observation channel using the signals map // Create an observation channel using the signals map
let observer = let observer =
unsafe { StdMapObserver::new_from_ptr("signals", SIGNALS.as_mut_ptr(), SIGNALS.len()) }; unsafe { StdMapObserver::from_mut_ptr("signals", SIGNALS.as_mut_ptr(), SIGNALS.len()) };
// Feedback to rate the interestingness of an input // Feedback to rate the interestingness of an input
let mut feedback = MaxMapFeedback::new(&observer); let mut feedback = MaxMapFeedback::new(&observer);
@ -88,7 +88,7 @@ pub fn main() {
// The Monitor trait define how the fuzzer stats are displayed to the user // The Monitor trait define how the fuzzer stats are displayed to the user
#[cfg(not(feature = "tui"))] #[cfg(not(feature = "tui"))]
let mon = SimpleMonitor::new(|s| println!("{}", s)); let mon = SimpleMonitor::new(|s| println!("{s}"));
#[cfg(feature = "tui")] #[cfg(feature = "tui")]
let mon = TuiMonitor::new(String::from("Baby Fuzzer"), false); let mon = TuiMonitor::new(String::from("Baby Fuzzer"), false);

View File

@ -57,7 +57,7 @@ pub fn main() {
}; };
// Create an observation channel using the signals map // Create an observation channel using the signals map
let observer = StdMapObserver::new("signals", unsafe { &mut SIGNALS }); let observer = unsafe { StdMapObserver::new("signals", &mut SIGNALS) };
// Feedback to rate the interestingness of an input // Feedback to rate the interestingness of an input
let mut feedback = MaxMapFeedback::new(&observer); let mut feedback = MaxMapFeedback::new(&observer);
@ -83,7 +83,7 @@ pub fn main() {
.unwrap(); .unwrap();
// The Monitor trait define how the fuzzer stats are reported to the user // The Monitor trait define how the fuzzer stats are reported to the user
let monitor = SimpleMonitor::new(|s| println!("{}", s)); let monitor = SimpleMonitor::new(|s| println!("{s}"));
// The event manager handle the various events generated during the fuzzing loop // The event manager handle the various events generated during the fuzzing loop
// such as the notification of the addition of a new item to the corpus // such as the notification of the addition of a new item to the corpus

View File

@ -88,7 +88,7 @@ pub fn main() {
}; };
// Create an observation channel using the signals map // Create an observation channel using the signals map
let observer = StdMapObserver::new("signals", unsafe { &mut SIGNALS }); let observer = unsafe { StdMapObserver::new("signals", &mut SIGNALS) };
// Feedback to rate the interestingness of an input // Feedback to rate the interestingness of an input
let mut feedback = MaxMapFeedback::new_tracking(&observer, false, true); let mut feedback = MaxMapFeedback::new_tracking(&observer, false, true);
@ -118,7 +118,7 @@ pub fn main() {
} }
// The Monitor trait define how the fuzzer stats are reported to the user // The Monitor trait define how the fuzzer stats are reported to the user
let monitor = SimpleMonitor::new(|s| println!("{}", s)); let monitor = SimpleMonitor::new(|s| println!("{s}"));
// The event manager handle the various events generated during the fuzzing loop // The event manager handle the various events generated during the fuzzing loop
// such as the notification of the addition of a new item to the corpus // such as the notification of the addition of a new item to the corpus

View File

@ -33,7 +33,7 @@ pub fn main() -> Result<(), Error> {
// Create an observation channel using the signals map // Create an observation channel using the signals map
let observer = let observer =
unsafe { StdMapObserver::new_from_ptr("signals", SIGNALS.as_mut_ptr(), SIGNALS.len()) }; unsafe { StdMapObserver::from_mut_ptr("signals", SIGNALS.as_mut_ptr(), SIGNALS.len()) };
let factory = MapEqualityFactory::new_from_observer(&observer); let factory = MapEqualityFactory::new_from_observer(&observer);
@ -44,7 +44,7 @@ pub fn main() -> Result<(), Error> {
let mut objective = CrashFeedback::new(); let mut objective = CrashFeedback::new();
// The Monitor trait define how the fuzzer stats are displayed to the user // The Monitor trait define how the fuzzer stats are displayed to the user
let mon = SimpleMonitor::new(|s| println!("{}", s)); let mon = SimpleMonitor::new(|s| println!("{s}"));
let mut mgr = SimpleEventManager::new(mon); let mut mgr = SimpleEventManager::new(mon);
@ -116,7 +116,7 @@ pub fn main() -> Result<(), Error> {
.unwrap(); .unwrap();
// The Monitor trait define how the fuzzer stats are displayed to the user // The Monitor trait define how the fuzzer stats are displayed to the user
let mon = SimpleMonitor::new(|s| println!("{}", s)); let mon = SimpleMonitor::new(|s| println!("{s}"));
let mut mgr = SimpleEventManager::new(mon); let mut mgr = SimpleEventManager::new(mon);

View File

@ -46,7 +46,7 @@ pub fn main() {
}; };
// Create an observation channel using the signals map // Create an observation channel using the signals map
let observer = StdMapObserver::new("signals", unsafe { &mut SIGNALS }); let observer = unsafe { StdMapObserver::new("signals", &mut SIGNALS) };
// Feedback to rate the interestingness of an input // Feedback to rate the interestingness of an input
let mut feedback = feedback_or!( let mut feedback = feedback_or!(
@ -79,7 +79,7 @@ pub fn main() {
} }
// The Monitor trait define how the fuzzer stats are reported to the user // The Monitor trait define how the fuzzer stats are reported to the user
let monitor = SimpleMonitor::new(|s| println!("{}", s)); let monitor = SimpleMonitor::new(|s| println!("{s}"));
// The event manager handle the various events generated during the fuzzing loop // The event manager handle the various events generated during the fuzzing loop
// such as the notification of the addition of a new item to the corpus // such as the notification of the addition of a new item to the corpus

View File

@ -27,9 +27,7 @@ fn main() -> anyhow::Result<()> {
}) })
.join("release/libafl_cc"); .join("release/libafl_cc");
println!("cargo:rerun-if-changed={}", compiler.to_str().unwrap()); println!("cargo:rerun-if-changed={}", compiler.to_str().unwrap());
if !compiler.try_exists().unwrap_or(false) { if compiler.try_exists().unwrap_or(false) {
println!("cargo:warning=Can't find libafl_cc; assuming that we're building it.");
} else {
cc::Build::new() cc::Build::new()
.compiler(compiler) .compiler(compiler)
.file("first.c") .file("first.c")
@ -38,6 +36,8 @@ fn main() -> anyhow::Result<()> {
.compile("diff-target"); .compile("diff-target");
println!("cargo:rustc-link-lib=diff-target"); println!("cargo:rustc-link-lib=diff-target");
} else {
println!("cargo:warning=Can't find libafl_cc; assuming that we're building it.");
} }
} }

View File

@ -11,7 +11,7 @@ pub fn main() {
let is_cpp = match wrapper_name[wrapper_name.len()-2..].to_lowercase().as_str() { let is_cpp = match wrapper_name[wrapper_name.len()-2..].to_lowercase().as_str() {
"cc" => false, "cc" => false,
"++" | "pp" | "xx" => true, "++" | "pp" | "xx" => true,
_ => panic!("Could not figure out if c or c++ wrapper was called. Expected {:?} to end with c or cxx", dir), _ => panic!("Could not figure out if c or c++ wrapper was called. Expected {dir:?} to end with c or cxx"),
}; };
dir.pop(); dir.pop();

View File

@ -32,10 +32,11 @@ static GLOBAL: MiMalloc = MiMalloc;
// bindings to the functions defined in the target // bindings to the functions defined in the target
mod bindings { mod bindings {
#![allow(non_snake_case)]
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
#![allow(non_upper_case_globals)] #![allow(non_upper_case_globals)]
#![allow(unused)] #![allow(unused)]
#![allow(clippy::unreadable_literal)]
include!(concat!(env!("OUT_DIR"), "/bindings.rs")); include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
} }
@ -45,23 +46,26 @@ use bindings::{inspect_first, inspect_second};
mod multimap { mod multimap {
pub use libafl::observers::{HitcountsIterableMapObserver, MultiMapObserver}; pub use libafl::observers::{HitcountsIterableMapObserver, MultiMapObserver};
pub static mut FIRST_EDGES: &'static mut [u8] = &mut []; pub static mut FIRST_EDGES: &mut [u8] = &mut [];
pub static mut SECOND_EDGES: &'static mut [u8] = &mut []; pub static mut SECOND_EDGES: &mut [u8] = &mut [];
pub static mut COMBINED_EDGES: [&'static mut [u8]; 2] = [&mut [], &mut []]; pub static mut COMBINED_EDGES: [&mut [u8]; 2] = [&mut [], &mut []];
} }
#[cfg(feature = "multimap")] #[cfg(feature = "multimap")]
use multimap::*; use multimap::{
HitcountsIterableMapObserver, MultiMapObserver, COMBINED_EDGES, FIRST_EDGES, SECOND_EDGES,
};
#[cfg(not(feature = "multimap"))] #[cfg(not(feature = "multimap"))]
mod slicemap { mod slicemap {
pub use libafl::observers::HitcountsMapObserver; pub use libafl::observers::HitcountsMapObserver;
pub static mut EDGES: &'static mut [u8] = &mut []; pub static mut EDGES: &mut [u8] = &mut [];
} }
#[cfg(not(feature = "multimap"))] #[cfg(not(feature = "multimap"))]
use slicemap::*; use slicemap::{HitcountsMapObserver, EDGES};
#[allow(clippy::similar_names)] #[allow(clippy::similar_names)]
#[allow(clippy::too_many_lines)]
pub fn main() { pub fn main() {
// The closure that we want to fuzz // The closure that we want to fuzz
let mut first_harness = |input: &BytesInput| { let mut first_harness = |input: &BytesInput| {
@ -94,8 +98,8 @@ pub fn main() {
} }
// create the base maps used to observe the different executors from two independent maps // create the base maps used to observe the different executors from two independent maps
let mut first_map_observer = StdMapObserver::new("first-edges", unsafe { FIRST_EDGES }); let mut first_map_observer = unsafe { StdMapObserver::new("first-edges", FIRST_EDGES) };
let mut second_map_observer = StdMapObserver::new("second-edges", unsafe { SECOND_EDGES }); let mut second_map_observer = unsafe { StdMapObserver::new("second-edges", SECOND_EDGES) };
// create a map swapper so that we can replace the coverage map pointer (requires feature pointer_maps!) // create a map swapper so that we can replace the coverage map pointer (requires feature pointer_maps!)
let map_swapper = let map_swapper =
@ -104,10 +108,13 @@ pub fn main() {
// create a combined map observer, e.g. for calibration // create a combined map observer, e.g. for calibration
// we use MultiMapObserver::differential to indicate that we want to use the observer in // we use MultiMapObserver::differential to indicate that we want to use the observer in
// differential mode // differential mode
let map_observer = HitcountsIterableMapObserver::new(MultiMapObserver::differential( let map_observer = unsafe {
"combined-edges", HitcountsIterableMapObserver::new(MultiMapObserver::differential(
unsafe { &mut COMBINED_EDGES }, "combined-edges",
)); &mut COMBINED_EDGES,
))
};
( (
first_map_observer, first_map_observer,
second_map_observer, second_map_observer,
@ -124,10 +131,16 @@ pub fn main() {
} }
// create the base maps used to observe the different executors by splitting a slice // create the base maps used to observe the different executors by splitting a slice
let mut first_map_observer = let mut first_map_observer = unsafe {
StdMapObserver::new("first-edges", unsafe { &mut EDGES[..MAX_EDGES_NUM] }); StdMapObserver::from_mut_ptr("first-edges", EDGES.as_mut_ptr(), MAX_EDGES_NUM)
let mut second_map_observer = };
StdMapObserver::new("second-edges", unsafe { &mut EDGES[MAX_EDGES_NUM..] }); let mut second_map_observer = unsafe {
StdMapObserver::from_mut_ptr(
"second-edges",
EDGES.as_mut_ptr().add(MAX_EDGES_NUM),
MAX_EDGES_NUM,
)
};
// create a map swapper so that we can replace the coverage map pointer (requires feature pointer_maps!) // create a map swapper so that we can replace the coverage map pointer (requires feature pointer_maps!)
let map_swapper = let map_swapper =
@ -136,10 +149,14 @@ pub fn main() {
// create a combined map observer, e.g. for calibration // create a combined map observer, e.g. for calibration
// we use StdMapObserver::differential to indicate that we want to use the observer in // we use StdMapObserver::differential to indicate that we want to use the observer in
// differential mode // differential mode
let map_observer = let map_observer = unsafe {
HitcountsMapObserver::new(StdMapObserver::differential("combined-edges", unsafe { HitcountsMapObserver::new(StdMapObserver::differential_from_mut_ptr(
EDGES "combined-edges",
})); EDGES.as_mut_ptr(),
MAX_EDGES_NUM * 2,
))
};
( (
first_map_observer, first_map_observer,
second_map_observer, second_map_observer,
@ -174,7 +191,7 @@ pub fn main() {
// The Monitor trait define how the fuzzer stats are displayed to the user // The Monitor trait define how the fuzzer stats are displayed to the user
#[cfg(not(feature = "tui"))] #[cfg(not(feature = "tui"))]
let mon = SimpleMonitor::new(|s| println!("{}", s)); let mon = SimpleMonitor::new(|s| println!("{s}"));
#[cfg(feature = "tui")] #[cfg(feature = "tui")]
let mon = TuiMonitor::new(String::from("Baby Fuzzer"), false); let mon = TuiMonitor::new(String::from("Baby Fuzzer"), false);

View File

@ -65,7 +65,8 @@ pub fn main() {
}; };
// Create an observation channel using the signals map // Create an observation channel using the signals map
let observer = StdMapObserver::new("signals", unsafe { &mut SIGNALS }); let observer =
unsafe { StdMapObserver::from_mut_ptr("signals", SIGNALS.as_mut_ptr(), SIGNALS.len()) };
// Feedback to rate the interestingness of an input // Feedback to rate the interestingness of an input
let mut feedback = MaxMapFeedback::new(&observer); let mut feedback = MaxMapFeedback::new(&observer);
@ -91,7 +92,7 @@ pub fn main() {
.unwrap(); .unwrap();
// The Monitor trait define how the fuzzer stats are reported to the user // The Monitor trait define how the fuzzer stats are reported to the user
let monitor = SimpleMonitor::new(|s| println!("{}", s)); let monitor = SimpleMonitor::new(|s| println!("{s}"));
// The event manager handle the various events generated during the fuzzing loop // The event manager handle the various events generated during the fuzzing loop
// such as the notification of the addition of a new item to the corpus // such as the notification of the addition of a new item to the corpus

View File

@ -64,7 +64,7 @@ pub fn main() {
}; };
// Create an observation channel using the signals map // Create an observation channel using the signals map
let observer = StdMapObserver::new("signals", signals_clone.as_mut_slice()); let observer = unsafe { StdMapObserver::new("signals", signals_clone.as_mut_slice()) };
// Create a stacktrace observer to add the observers tuple // Create a stacktrace observer to add the observers tuple
// Feedback to rate the interestingness of an input, obtained by ANDing the interestingness of both feedbacks // Feedback to rate the interestingness of an input, obtained by ANDing the interestingness of both feedbacks
@ -91,7 +91,7 @@ pub fn main() {
.unwrap(); .unwrap();
// The Monitor trait define how the fuzzer stats are displayed to the user // The Monitor trait define how the fuzzer stats are displayed to the user
let mon = SimpleMonitor::new(|s| println!("{}", s)); let mon = SimpleMonitor::new(|s| println!("{s}"));
// The event manager handle the various events generated during the fuzzing loop // The event manager handle the various events generated during the fuzzing loop
// such as the notification of the addition of a new item to the corpus // such as the notification of the addition of a new item to the corpus

View File

@ -87,7 +87,7 @@ pub extern "C" fn main(_argc: isize, _argv: *const *const u8) -> isize {
}; };
// Create an observation channel using the signals map // Create an observation channel using the signals map
let observer = StdMapObserver::new("signals", unsafe { &mut SIGNALS }); let observer = unsafe { StdMapObserver::new("signals", &mut SIGNALS) };
// Feedback to rate the interestingness of an input // Feedback to rate the interestingness of an input
let mut feedback = MaxMapFeedback::new(&observer); let mut feedback = MaxMapFeedback::new(&observer);

View File

@ -45,7 +45,7 @@ pub fn main() {
libafl::executors::ExitKind::Ok libafl::executors::ExitKind::Ok
}; };
// Create an observation channel using the signals map // Create an observation channel using the signals map
let observer = unsafe { ConstMapObserver::<u8, 3>::new_from_ptr("signals", map_ptr) }; let observer = unsafe { ConstMapObserver::<u8, 3>::from_mut_ptr("signals", map_ptr) };
// Create a stacktrace observer // Create a stacktrace observer
let mut bt = shmem_provider.new_shmem_object::<Option<u64>>().unwrap(); let mut bt = shmem_provider.new_shmem_object::<Option<u64>>().unwrap();
let bt_observer = BacktraceObserver::new( let bt_observer = BacktraceObserver::new(
@ -78,7 +78,7 @@ pub fn main() {
.unwrap(); .unwrap();
// The Monitor trait define how the fuzzer stats are displayed to the user // The Monitor trait define how the fuzzer stats are displayed to the user
let mon = SimpleMonitor::new(|s| println!("{}", s)); let mon = SimpleMonitor::new(|s| println!("{s}"));
// The event manager handle the various events generated during the fuzzing loop // The event manager handle the various events generated during the fuzzing loop
// such as the notification of the addition of a new item to the corpus // such as the notification of the addition of a new item to the corpus

View File

@ -35,7 +35,7 @@ pub fn main() {
libafl::executors::ExitKind::Ok libafl::executors::ExitKind::Ok
}; };
// Create an observation channel using the signals map // Create an observation channel using the signals map
let observer = unsafe { ConstMapObserver::<u8, 3>::new_from_ptr("signals", array_ptr) }; let observer = unsafe { ConstMapObserver::<u8, 3>::from_mut_ptr("signals", array_ptr) };
// Create a stacktrace observer // Create a stacktrace observer
let mut bt = None; let mut bt = None;
let bt_observer = BacktraceObserver::new( let bt_observer = BacktraceObserver::new(
@ -68,7 +68,7 @@ pub fn main() {
.unwrap(); .unwrap();
// The Monitor trait define how the fuzzer stats are displayed to the user // The Monitor trait define how the fuzzer stats are displayed to the user
let mon = SimpleMonitor::new(|s| println!("{}", s)); let mon = SimpleMonitor::new(|s| println!("{s}"));
// The event manager handle the various events generated during the fuzzing loop // The event manager handle the various events generated during the fuzzing loop
// such as the notification of the addition of a new item to the corpus // such as the notification of the addition of a new item to the corpus

View File

@ -38,7 +38,7 @@ pub fn main() {
let shmem_id = signals.id(); let shmem_id = signals.id();
// Create an observation channel using the signals map // Create an observation channel using the signals map
let observer = StdMapObserver::new("signals", signals.as_mut_slice()); let observer = unsafe { StdMapObserver::new("signals", signals.as_mut_slice()) };
// Create a stacktrace observer // Create a stacktrace observer
let bt_observer = AsanBacktraceObserver::new("AsanBacktraceObserver"); let bt_observer = AsanBacktraceObserver::new("AsanBacktraceObserver");
@ -67,7 +67,7 @@ pub fn main() {
.unwrap(); .unwrap();
// The Monitor trait define how the fuzzer stats are displayed to the user // The Monitor trait define how the fuzzer stats are displayed to the user
let mon = SimpleMonitor::new(|s| println!("{}", s)); let mon = SimpleMonitor::new(|s| println!("{s}"));
// The event manager handle the various events generated during the fuzzing loop // The event manager handle the various events generated during the fuzzing loop
// such as the notification of the addition of a new item to the corpus // such as the notification of the addition of a new item to the corpus

View File

@ -78,7 +78,7 @@ pub fn main() {
.unwrap(); .unwrap();
// The Monitor trait define how the fuzzer stats are reported to the user // The Monitor trait define how the fuzzer stats are reported to the user
let monitor = SimpleMonitor::new(|s| println!("{}", s)); let monitor = SimpleMonitor::new(|s| println!("{s}"));
// The event manager handle the various events generated during the fuzzing loop // The event manager handle the various events generated during the fuzzing loop
// such as the notification of the addition of a new item to the corpus // such as the notification of the addition of a new item to the corpus

View File

@ -65,7 +65,7 @@ pub fn main() {
}; };
// Create an observation channel using the signals map // Create an observation channel using the signals map
let observer = StdMapObserver::new("signals", signals_clone.as_mut_slice()); let observer = unsafe { StdMapObserver::new("signals", signals_clone.as_mut_slice()) };
// Create a stacktrace observer // Create a stacktrace observer
let bt_observer = BacktraceObserver::new( let bt_observer = BacktraceObserver::new(
"BacktraceObserver", "BacktraceObserver",
@ -97,7 +97,7 @@ pub fn main() {
.unwrap(); .unwrap();
// The Monitor trait define how the fuzzer stats are displayed to the user // The Monitor trait define how the fuzzer stats are displayed to the user
let mon = SimpleMonitor::new(|s| println!("{}", s)); let mon = SimpleMonitor::new(|s| println!("{s}"));
// The event manager handle the various events generated during the fuzzing loop // The event manager handle the various events generated during the fuzzing loop
// such as the notification of the addition of a new item to the corpus // such as the notification of the addition of a new item to the corpus

View File

@ -58,7 +58,7 @@ pub fn main() {
}; };
// Create an observation channel using the signals map // Create an observation channel using the signals map
let observer = StdMapObserver::new("signals", unsafe { &mut SIGNALS }); let observer = unsafe { StdMapObserver::new("signals", &mut SIGNALS) };
// Create a stacktrace observer to add the observers tuple // Create a stacktrace observer to add the observers tuple
let mut bt = None; let mut bt = None;
let bt_observer = BacktraceObserver::new( let bt_observer = BacktraceObserver::new(
@ -91,7 +91,7 @@ pub fn main() {
.unwrap(); .unwrap();
// The Monitor trait define how the fuzzer stats are displayed to the user // The Monitor trait define how the fuzzer stats are displayed to the user
let mon = SimpleMonitor::new(|s| println!("{}", s)); let mon = SimpleMonitor::new(|s| println!("{s}"));
// The event manager handle the various events generated during the fuzzing loop // The event manager handle the various events generated during the fuzzing loop
// such as the notification of the addition of a new item to the corpus // such as the notification of the addition of a new item to the corpus

View File

@ -103,7 +103,8 @@ pub fn main() {
let shmem_buf = shmem.as_mut_slice(); let shmem_buf = shmem.as_mut_slice();
// Create an observation channel using the signals map // Create an observation channel using the signals map
let edges_observer = HitcountsMapObserver::new(StdMapObserver::new("shared_mem", shmem_buf)); let edges_observer =
unsafe { HitcountsMapObserver::new(StdMapObserver::new("shared_mem", shmem_buf)) };
// Create an observation channel to keep track of the execution time // Create an observation channel to keep track of the execution time
let time_observer = TimeObserver::new("time"); let time_observer = TimeObserver::new("time");
@ -144,7 +145,7 @@ pub fn main() {
.unwrap(); .unwrap();
// The Monitor trait define how the fuzzer stats are reported to the user // The Monitor trait define how the fuzzer stats are reported to the user
let monitor = SimpleMonitor::new(|s| println!("{}", s)); let monitor = SimpleMonitor::new(|s| println!("{s}"));
// The event manager handle the various events generated during the fuzzing loop // The event manager handle the various events generated during the fuzzing loop
// such as the notification of the addition of a new item to the corpus // such as the notification of the addition of a new item to the corpus

View File

@ -51,7 +51,7 @@ use libafl_frida::{
executor::FridaInProcessExecutor, executor::FridaInProcessExecutor,
helper::FridaInstrumentationHelper, helper::FridaInstrumentationHelper,
}; };
use libafl_targets::cmplog::{CmpLogObserver, CMPLOG_MAP}; use libafl_targets::cmplog::CmpLogObserver;
/// The main fn, usually parsing parameters, and starting the fuzzer /// The main fn, usually parsing parameters, and starting the fuzzer
pub fn main() { pub fn main() {
@ -71,7 +71,7 @@ pub fn main() {
#[allow(clippy::too_many_lines, clippy::too_many_arguments)] #[allow(clippy::too_many_lines, clippy::too_many_arguments)]
unsafe fn fuzz(options: FuzzerOptions) -> Result<(), Error> { unsafe fn fuzz(options: FuzzerOptions) -> Result<(), Error> {
// 'While the stats are state, they are usually used in the broker - which is likely never restarted // 'While the stats are state, they are usually used in the broker - which is likely never restarted
let monitor = MultiMonitor::new(|s| println!("{}", s)); let monitor = MultiMonitor::new(|s| println!("{s}"));
let shmem_provider = StdShMemProvider::new()?; let shmem_provider = StdShMemProvider::new()?;
@ -108,9 +108,9 @@ unsafe fn fuzz(options: FuzzerOptions) -> Result<(), Error> {
FridaInstrumentationHelper::new(&gum, &options, tuple_list!(coverage)); FridaInstrumentationHelper::new(&gum, &options, tuple_list!(coverage));
// Create an observation channel using the coverage map // Create an observation channel using the coverage map
let edges_observer = HitcountsMapObserver::new(StdMapObserver::new_from_ptr( let edges_observer = HitcountsMapObserver::new(StdMapObserver::from_mut_ptr(
"edges", "edges",
frida_helper.map_ptr_mut().unwrap(), frida_helper.map_mut_ptr().unwrap(),
MAP_SIZE, MAP_SIZE,
)); ));
@ -228,9 +228,9 @@ unsafe fn fuzz(options: FuzzerOptions) -> Result<(), Error> {
FridaInstrumentationHelper::new(&gum, &options, tuple_list!(coverage, cmplog)); FridaInstrumentationHelper::new(&gum, &options, tuple_list!(coverage, cmplog));
// Create an observation channel using the coverage map // Create an observation channel using the coverage map
let edges_observer = HitcountsMapObserver::new(StdMapObserver::new_from_ptr( let edges_observer = HitcountsMapObserver::new(StdMapObserver::from_mut_ptr(
"edges", "edges",
frida_helper.map_ptr_mut().unwrap(), frida_helper.map_mut_ptr().unwrap(),
MAP_SIZE, MAP_SIZE,
)); ));
@ -330,7 +330,7 @@ unsafe fn fuzz(options: FuzzerOptions) -> Result<(), Error> {
} }
// Create an observation channel using cmplog map // Create an observation channel using cmplog map
let cmplog_observer = CmpLogObserver::new("cmplog", &mut CMPLOG_MAP, true); let cmplog_observer = CmpLogObserver::new("cmplog", true);
let mut executor = ShadowExecutor::new(executor, tuple_list!(cmplog_observer)); let mut executor = ShadowExecutor::new(executor, tuple_list!(cmplog_observer));
@ -361,9 +361,9 @@ unsafe fn fuzz(options: FuzzerOptions) -> Result<(), Error> {
FridaInstrumentationHelper::new(&gum, &options, tuple_list!(coverage)); FridaInstrumentationHelper::new(&gum, &options, tuple_list!(coverage));
// Create an observation channel using the coverage map // Create an observation channel using the coverage map
let edges_observer = HitcountsMapObserver::new(StdMapObserver::new_from_ptr( let edges_observer = HitcountsMapObserver::new(StdMapObserver::from_mut_ptr(
"edges", "edges",
frida_helper.map_ptr_mut().unwrap(), frida_helper.map_mut_ptr().unwrap(),
MAP_SIZE, MAP_SIZE,
)); ));

View File

@ -45,7 +45,7 @@ use libafl_frida::{
executor::FridaInProcessExecutor, executor::FridaInProcessExecutor,
helper::FridaInstrumentationHelper, helper::FridaInstrumentationHelper,
}; };
use libafl_targets::cmplog::{CmpLogObserver, CMPLOG_MAP}; use libafl_targets::cmplog::CmpLogObserver;
/// The main fn, usually parsing parameters, and starting the fuzzer /// The main fn, usually parsing parameters, and starting the fuzzer
pub fn main() { pub fn main() {
@ -65,7 +65,7 @@ pub fn main() {
#[allow(clippy::too_many_lines, clippy::too_many_arguments)] #[allow(clippy::too_many_lines, clippy::too_many_arguments)]
unsafe fn fuzz(options: FuzzerOptions) -> Result<(), Error> { unsafe fn fuzz(options: FuzzerOptions) -> Result<(), Error> {
// 'While the stats are state, they are usually used in the broker - which is likely never restarted // 'While the stats are state, they are usually used in the broker - which is likely never restarted
let monitor = MultiMonitor::new(|s| println!("{}", s)); let monitor = MultiMonitor::new(|s| println!("{s}"));
let shmem_provider = StdShMemProvider::new()?; let shmem_provider = StdShMemProvider::new()?;
@ -102,9 +102,9 @@ unsafe fn fuzz(options: FuzzerOptions) -> Result<(), Error> {
FridaInstrumentationHelper::new(&gum, &options, tuple_list!(coverage)); FridaInstrumentationHelper::new(&gum, &options, tuple_list!(coverage));
// Create an observation channel using the coverage map // Create an observation channel using the coverage map
let edges_observer = HitcountsMapObserver::new(StdMapObserver::new_from_ptr( let edges_observer = HitcountsMapObserver::new(StdMapObserver::from_mut_ptr(
"edges", "edges",
frida_helper.map_ptr_mut().unwrap(), frida_helper.map_mut_ptr().unwrap(),
MAP_SIZE, MAP_SIZE,
)); ));
@ -222,9 +222,9 @@ unsafe fn fuzz(options: FuzzerOptions) -> Result<(), Error> {
FridaInstrumentationHelper::new(&gum, &options, tuple_list!(coverage, cmplog)); FridaInstrumentationHelper::new(&gum, &options, tuple_list!(coverage, cmplog));
// Create an observation channel using the coverage map // Create an observation channel using the coverage map
let edges_observer = HitcountsMapObserver::new(StdMapObserver::new_from_ptr( let edges_observer = HitcountsMapObserver::new(StdMapObserver::from_mut_ptr(
"edges", "edges",
frida_helper.map_ptr_mut().unwrap(), frida_helper.map_mut_ptr().unwrap(),
MAP_SIZE, MAP_SIZE,
)); ));
@ -324,7 +324,7 @@ unsafe fn fuzz(options: FuzzerOptions) -> Result<(), Error> {
} }
// Create an observation channel using cmplog map // Create an observation channel using cmplog map
let cmplog_observer = CmpLogObserver::new("cmplog", &mut CMPLOG_MAP, true); let cmplog_observer = CmpLogObserver::new("cmplog", true);
let mut executor = ShadowExecutor::new(executor, tuple_list!(cmplog_observer)); let mut executor = ShadowExecutor::new(executor, tuple_list!(cmplog_observer));
@ -355,9 +355,9 @@ unsafe fn fuzz(options: FuzzerOptions) -> Result<(), Error> {
FridaInstrumentationHelper::new(&gum, &options, tuple_list!(coverage)); FridaInstrumentationHelper::new(&gum, &options, tuple_list!(coverage));
// Create an observation channel using the coverage map // Create an observation channel using the coverage map
let edges_observer = HitcountsMapObserver::new(StdMapObserver::new_from_ptr( let edges_observer = HitcountsMapObserver::new(StdMapObserver::from_mut_ptr(
"edges", "edges",
frida_helper.map_ptr_mut().unwrap(), frida_helper.map_mut_ptr().unwrap(),
MAP_SIZE, MAP_SIZE,
)); ));

View File

@ -11,7 +11,7 @@ pub fn main() {
let is_cpp = match wrapper_name[wrapper_name.len()-2..].to_lowercase().as_str() { let is_cpp = match wrapper_name[wrapper_name.len()-2..].to_lowercase().as_str() {
"cc" => false, "cc" => false,
"++" | "pp" | "xx" => true, "++" | "pp" | "xx" => true,
_ => panic!("Could not figure out if c or c++ warpper was called. Expected {:?} to end with c or cxx", dir), _ => panic!("Could not figure out if c or c++ wrapper was called. Expected {dir:?} to end with c or cxx"),
}; };
dir.pop(); dir.pop();

View File

@ -1,5 +1,5 @@
pub mod libafl_cc; pub mod libafl_cc;
fn main() { fn main() {
libafl_cc::main() libafl_cc::main();
} }

View File

@ -36,7 +36,7 @@ use libafl::{
scheduled::havoc_mutations, token_mutations::I2SRandReplace, tokens_mutations, scheduled::havoc_mutations, token_mutations::I2SRandReplace, tokens_mutations,
StdMOptMutator, StdScheduledMutator, Tokens, StdMOptMutator, StdScheduledMutator, Tokens,
}, },
observers::{HitcountsMapObserver, StdMapObserver, TimeObserver}, observers::{HitcountsMapObserver, TimeObserver},
schedulers::{ schedulers::{
powersched::PowerSchedule, IndexesLenTimeMinimizerScheduler, StdWeightedScheduler, powersched::PowerSchedule, IndexesLenTimeMinimizerScheduler, StdWeightedScheduler,
}, },
@ -50,8 +50,7 @@ use libafl::{
#[cfg(any(target_os = "linux", target_vendor = "apple"))] #[cfg(any(target_os = "linux", target_vendor = "apple"))]
use libafl_targets::autotokens; use libafl_targets::autotokens;
use libafl_targets::{ use libafl_targets::{
libfuzzer_initialize, libfuzzer_test_one_input, CmpLogObserver, CMPLOG_MAP, EDGES_MAP, libfuzzer_initialize, libfuzzer_test_one_input, std_edges_map_observer, CmpLogObserver,
MAX_EDGES_NUM,
}; };
#[cfg(unix)] #[cfg(unix)]
use nix::{self, unistd::dup}; use nix::{self, unistd::dup};
@ -121,7 +120,7 @@ pub fn libafl_main() {
); );
if let Some(filenames) = res.get_many::<String>("remaining") { if let Some(filenames) = res.get_many::<String>("remaining") {
let filenames: Vec<&str> = filenames.map(|v| v.as_str()).collect(); let filenames: Vec<&str> = filenames.map(String::as_str).collect();
if !filenames.is_empty() { if !filenames.is_empty() {
run_testcases(&filenames); run_testcases(&filenames);
return; return;
@ -167,7 +166,7 @@ pub fn libafl_main() {
.expect("Could not parse timeout in milliseconds"), .expect("Could not parse timeout in milliseconds"),
); );
fuzz(out_dir, crashes, in_dir, tokens, logfile, timeout) fuzz(out_dir, crashes, &in_dir, tokens, &logfile, timeout)
.expect("An error occurred while fuzzing"); .expect("An error occurred while fuzzing");
} }
@ -176,7 +175,7 @@ fn run_testcases(filenames: &[&str]) {
// Call LLVMFUzzerInitialize() if present. // Call LLVMFUzzerInitialize() if present.
let args: Vec<String> = env::args().collect(); let args: Vec<String> = env::args().collect();
if libfuzzer_initialize(&args) == -1 { if libfuzzer_initialize(&args) == -1 {
println!("Warning: LLVMFuzzerInitialize failed with -1") println!("Warning: LLVMFuzzerInitialize failed with -1");
} }
println!( println!(
@ -184,7 +183,7 @@ fn run_testcases(filenames: &[&str]) {
filenames.len() filenames.len()
); );
for fname in filenames { for fname in filenames {
println!("Executing {}", fname); println!("Executing {fname}");
let mut file = File::open(fname).expect("No file found"); let mut file = File::open(fname).expect("No file found");
let mut buffer = vec![]; let mut buffer = vec![];
@ -195,20 +194,16 @@ fn run_testcases(filenames: &[&str]) {
} }
/// The actual fuzzer /// The actual fuzzer
#[allow(clippy::too_many_lines)]
fn fuzz( fn fuzz(
corpus_dir: PathBuf, corpus_dir: PathBuf,
objective_dir: PathBuf, objective_dir: PathBuf,
seed_dir: PathBuf, seed_dir: &PathBuf,
tokenfile: Option<PathBuf>, tokenfile: Option<PathBuf>,
logfile: PathBuf, logfile: &PathBuf,
timeout: Duration, timeout: Duration,
) -> Result<(), Error> { ) -> Result<(), Error> {
let log = RefCell::new( let log = RefCell::new(OpenOptions::new().append(true).create(true).open(logfile)?);
OpenOptions::new()
.append(true)
.create(true)
.open(&logfile)?,
);
#[cfg(unix)] #[cfg(unix)]
let mut stdout_cpy = unsafe { let mut stdout_cpy = unsafe {
@ -221,10 +216,10 @@ fn fuzz(
// 'While the monitor are state, they are usually used in the broker - which is likely never restarted // 'While the monitor are state, they are usually used in the broker - which is likely never restarted
let monitor = SimpleMonitor::new(|s| { let monitor = SimpleMonitor::new(|s| {
#[cfg(unix)] #[cfg(unix)]
writeln!(&mut stdout_cpy, "{}", s).unwrap(); writeln!(&mut stdout_cpy, "{s}").unwrap();
#[cfg(windows)] #[cfg(windows)]
println!("{}", s); println!("{s}");
writeln!(log.borrow_mut(), "{:?} {}", current_time(), s).unwrap(); writeln!(log.borrow_mut(), "{:?} {s}", current_time()).unwrap();
}); });
// We need a shared map to store our state before a crash. // We need a shared map to store our state before a crash.
@ -240,21 +235,19 @@ fn fuzz(
return Ok(()); return Ok(());
} }
_ => { _ => {
panic!("Failed to setup the restarter: {}", err); panic!("Failed to setup the restarter: {err}");
} }
}, },
}; };
// Create an observation channel using the coverage map // Create an observation channel using the coverage map
// We don't use the hitcounts (see the Cargo.toml, we use pcguard_edges) // We don't use the hitcounts (see the Cargo.toml, we use pcguard_edges)
let edges = unsafe { &mut EDGES_MAP[0..MAX_EDGES_NUM] }; let edges_observer = HitcountsMapObserver::new(unsafe { std_edges_map_observer("edges") });
let edges_observer = HitcountsMapObserver::new(StdMapObserver::new("edges", edges));
// Create an observation channel to keep track of the execution time // Create an observation channel to keep track of the execution time
let time_observer = TimeObserver::new("time"); let time_observer = TimeObserver::new("time");
let cmplog = unsafe { &mut CMPLOG_MAP }; let cmplog_observer = CmpLogObserver::new("cmplog", true);
let cmplog_observer = CmpLogObserver::new("cmplog", cmplog, true);
let map_feedback = MaxMapFeedback::new_tracking(&edges_observer, true, false); let map_feedback = MaxMapFeedback::new_tracking(&edges_observer, true, false);
@ -297,7 +290,7 @@ fn fuzz(
// Call LLVMFUzzerInitialize() if present. // Call LLVMFUzzerInitialize() if present.
let args: Vec<String> = env::args().collect(); let args: Vec<String> = env::args().collect();
if libfuzzer_initialize(&args) == -1 { if libfuzzer_initialize(&args) == -1 {
println!("Warning: LLVMFuzzerInitialize failed with -1") println!("Warning: LLVMFuzzerInitialize failed with -1");
} }
// Setup a randomic Input2State stage // Setup a randomic Input2State stage
@ -394,12 +387,7 @@ fn fuzz(
dup2(null_fd, io::stderr().as_raw_fd())?; dup2(null_fd, io::stderr().as_raw_fd())?;
} }
// reopen file to make sure we're at the end // reopen file to make sure we're at the end
log.replace( log.replace(OpenOptions::new().append(true).create(true).open(logfile)?);
OpenOptions::new()
.append(true)
.create(true)
.open(&logfile)?,
);
fuzzer.fuzz_loop(&mut stages, &mut executor, &mut state, &mut mgr)?; fuzzer.fuzz_loop(&mut stages, &mut executor, &mut state, &mut mgr)?;

View File

@ -45,7 +45,7 @@ use libafl::{
Error, Error,
}; };
use libafl_qemu::{ use libafl_qemu::{
cmplog::{CmpLogMap, CmpLogObserver, QemuCmpLogChildHelper, CMPLOG_MAP_PTR}, cmplog::{CmpLogMap, CmpLogObserver, QemuCmpLogChildHelper},
edges::{QemuEdgeCoverageChildHelper, EDGES_MAP_PTR, EDGES_MAP_SIZE}, edges::{QemuEdgeCoverageChildHelper, EDGES_MAP_PTR, EDGES_MAP_SIZE},
elf::EasyElf, elf::EasyElf,
emu::Emulator, emu::Emulator,
@ -199,7 +199,7 @@ fn fuzz(
#[cfg(unix)] #[cfg(unix)]
writeln!(&mut stdout_cpy, "{}", s).unwrap(); writeln!(&mut stdout_cpy, "{}", s).unwrap();
#[cfg(windows)] #[cfg(windows)]
println!("{}", s); println!("{s}");
writeln!(log.borrow_mut(), "{:?} {}", current_time(), s).unwrap(); writeln!(log.borrow_mut(), "{:?} {}", current_time(), s).unwrap();
}); });
@ -213,7 +213,10 @@ fn fuzz(
.new_shmem(core::mem::size_of::<CmpLogMap>()) .new_shmem(core::mem::size_of::<CmpLogMap>())
.unwrap(); .unwrap();
let cmplog = cmp_shmem.as_mut_slice(); let cmplog = cmp_shmem.as_mut_slice();
unsafe { CMPLOG_MAP_PTR = cmplog.as_mut_ptr() as *mut CmpLogMap };
// Beginning of a page should be properly aligned.
#[allow(clippy::cast_ptr_alignment)]
let cmplog_map_ptr = cmplog.as_mut_ptr().cast::<libafl_qemu::cmplog::CmpLogMap>();
let (state, mut mgr) = match SimpleRestartingEventManager::launch(monitor, &mut shmem_provider) let (state, mut mgr) = match SimpleRestartingEventManager::launch(monitor, &mut shmem_provider)
{ {
@ -224,21 +227,24 @@ fn fuzz(
return Ok(()); return Ok(());
} }
_ => { _ => {
panic!("Failed to setup the restarter: {}", err); panic!("Failed to setup the restarter: {err}");
} }
}, },
}; };
// Create an observation channel using the coverage map // Create an observation channel using the coverage map
let edges_observer = let edges_observer = unsafe {
HitcountsMapObserver::new(ConstMapObserver::<_, EDGES_MAP_SIZE>::new("edges", edges)); HitcountsMapObserver::new(ConstMapObserver::<_, EDGES_MAP_SIZE>::from_mut_ptr(
"edges",
edges.as_mut_ptr(),
))
};
// Create an observation channel to keep track of the execution time // Create an observation channel to keep track of the execution time
let time_observer = TimeObserver::new("time"); let time_observer = TimeObserver::new("time");
// Create an observation channel using cmplog map // Create an observation channel using cmplog map
let cmplog_observer = let cmplog_observer = unsafe { CmpLogObserver::with_map_ptr("cmplog", cmplog_map_ptr, true) };
CmpLogObserver::new("cmplog", unsafe { CMPLOG_MAP_PTR.as_mut().unwrap() }, true);
let map_feedback = MaxMapFeedback::new_tracking(&edges_observer, true, false); let map_feedback = MaxMapFeedback::new_tracking(&edges_observer, true, false);

View File

@ -3,5 +3,5 @@ pub mod fuzzer;
fn main() { fn main() {
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
fuzzer::main() fuzzer::main();
} }

View File

@ -225,7 +225,7 @@ fn fuzz(
// 'While the monitor are state, they are usually used in the broker - which is likely never restarted // 'While the monitor are state, they are usually used in the broker - which is likely never restarted
let monitor = SimpleMonitor::new(|s| { let monitor = SimpleMonitor::new(|s| {
println!("{}", s); println!("{s}");
writeln!(log.borrow_mut(), "{:?} {}", current_time(), s).unwrap(); writeln!(log.borrow_mut(), "{:?} {}", current_time(), s).unwrap();
}); });
@ -243,7 +243,8 @@ fn fuzz(
let shmem_buf = shmem.as_mut_slice(); let shmem_buf = shmem.as_mut_slice();
// Create an observation channel using the hitcounts map of AFL++ // Create an observation channel using the hitcounts map of AFL++
let edges_observer = HitcountsMapObserver::new(StdMapObserver::new("shared_mem", shmem_buf)); let edges_observer =
unsafe { HitcountsMapObserver::new(StdMapObserver::new("shared_mem", shmem_buf)) };
// Create an observation channel to keep track of the execution time // Create an observation channel to keep track of the execution time
let time_observer = TimeObserver::new("time"); let time_observer = TimeObserver::new("time");

View File

@ -1,6 +1,6 @@
//! A singlethreaded QEMU fuzzer that can auto-restart. //! A singlethreaded QEMU fuzzer that can auto-restart.
use core::{cell::RefCell, time::Duration}; use core::{cell::RefCell, ptr::addr_of_mut, time::Duration};
#[cfg(unix)] #[cfg(unix)]
use std::os::unix::io::{AsRawFd, FromRawFd}; use std::os::unix::io::{AsRawFd, FromRawFd};
use std::{ use std::{
@ -45,11 +45,11 @@ use libafl::{
Error, Error,
}; };
use libafl_qemu::{ use libafl_qemu::{
//asan::{init_with_asan, QemuAsanHelper},
cmplog,
cmplog::{CmpLogObserver, QemuCmpLogHelper}, cmplog::{CmpLogObserver, QemuCmpLogHelper},
edges, //asan::{init_with_asan, QemuAsanHelper},
edges::edges_map_mut_slice,
edges::QemuEdgeCoverageHelper, edges::QemuEdgeCoverageHelper,
edges::MAX_EDGES_NUM,
elf::EasyElf, elf::EasyElf,
emu::Emulator, emu::Emulator,
filter_qemu_args, filter_qemu_args,
@ -226,7 +226,7 @@ fn fuzz(
#[cfg(unix)] #[cfg(unix)]
writeln!(&mut stdout_cpy, "{}", s).unwrap(); writeln!(&mut stdout_cpy, "{}", s).unwrap();
#[cfg(windows)] #[cfg(windows)]
println!("{}", s); println!("{s}");
writeln!(log.borrow_mut(), "{:?} {}", current_time(), s).unwrap(); writeln!(log.borrow_mut(), "{:?} {}", current_time(), s).unwrap();
}); });
@ -241,22 +241,25 @@ fn fuzz(
return Ok(()); return Ok(());
} }
_ => { _ => {
panic!("Failed to setup the restarter: {}", err); panic!("Failed to setup the restarter: {err}");
} }
}, },
}; };
// Create an observation channel using the coverage map // Create an observation channel using the coverage map
let edges = unsafe { &mut edges::EDGES_MAP }; let edges_observer = unsafe {
let edges_counter = unsafe { &mut edges::MAX_EDGES_NUM }; HitcountsMapObserver::new(VariableMapObserver::from_mut_slice(
let edges_observer = "edges",
HitcountsMapObserver::new(VariableMapObserver::new("edges", edges, edges_counter)); edges_map_mut_slice(),
addr_of_mut!(MAX_EDGES_NUM),
))
};
// Create an observation channel to keep track of the execution time // Create an observation channel to keep track of the execution time
let time_observer = TimeObserver::new("time"); let time_observer = TimeObserver::new("time");
// Create an observation channel using cmplog map // Create an observation channel using cmplog map
let cmplog_observer = CmpLogObserver::new("cmplog", unsafe { &mut cmplog::CMPLOG_MAP }, true); let cmplog_observer = CmpLogObserver::new("cmplog", true);
let map_feedback = MaxMapFeedback::new_tracking(&edges_observer, true, false); let map_feedback = MaxMapFeedback::new_tracking(&edges_observer, true, false);

View File

@ -11,7 +11,7 @@ pub fn main() {
let is_cpp = match wrapper_name[wrapper_name.len()-2..].to_lowercase().as_str() { let is_cpp = match wrapper_name[wrapper_name.len()-2..].to_lowercase().as_str() {
"cc" => false, "cc" => false,
"++" | "pp" | "xx" => true, "++" | "pp" | "xx" => true,
_ => panic!("Could not figure out if c or c++ warpper was called. Expected {:?} to end with c or cxx", dir), _ => panic!("Could not figure out if c or c++ wrapper was called. Expected {dir:?} to end with c or cxx"),
}; };
dir.pop(); dir.pop();

View File

@ -42,7 +42,7 @@ use libafl::{
token_mutations::I2SRandReplace, token_mutations::I2SRandReplace,
tokens_mutations, StdMOptMutator, StdScheduledMutator, Tokens, tokens_mutations, StdMOptMutator, StdScheduledMutator, Tokens,
}, },
observers::{HitcountsMapObserver, StdMapObserver, TimeObserver}, observers::{HitcountsMapObserver, TimeObserver},
schedulers::{ schedulers::{
powersched::PowerSchedule, IndexesLenTimeMinimizerScheduler, StdWeightedScheduler, powersched::PowerSchedule, IndexesLenTimeMinimizerScheduler, StdWeightedScheduler,
}, },
@ -56,8 +56,7 @@ use libafl::{
#[cfg(any(target_os = "linux", target_vendor = "apple"))] #[cfg(any(target_os = "linux", target_vendor = "apple"))]
use libafl_targets::autotokens; use libafl_targets::autotokens;
use libafl_targets::{ use libafl_targets::{
libfuzzer_initialize, libfuzzer_test_one_input, CmpLogObserver, CMPLOG_MAP, EDGES_MAP, libfuzzer_initialize, libfuzzer_test_one_input, std_edges_map_observer, CmpLogObserver,
MAX_EDGES_NUM,
}; };
#[cfg(unix)] #[cfg(unix)]
use nix::{self, unistd::dup}; use nix::{self, unistd::dup};
@ -286,7 +285,7 @@ fn fuzz_binary(
#[cfg(unix)] #[cfg(unix)]
writeln!(&mut stdout_cpy, "{}", s).unwrap(); writeln!(&mut stdout_cpy, "{}", s).unwrap();
#[cfg(windows)] #[cfg(windows)]
println!("{}", s); println!("{s}");
writeln!(log.borrow_mut(), "{:?} {}", current_time(), s).unwrap(); writeln!(log.borrow_mut(), "{:?} {}", current_time(), s).unwrap();
}); });
@ -303,21 +302,19 @@ fn fuzz_binary(
return Ok(()); return Ok(());
} }
_ => { _ => {
panic!("Failed to setup the restarter: {}", err); panic!("Failed to setup the restarter: {err}");
} }
}, },
}; };
// Create an observation channel using the coverage map // Create an observation channel using the coverage map
// We don't use the hitcounts (see the Cargo.toml, we use pcguard_edges) // We don't use the hitcounts (see the Cargo.toml, we use pcguard_edges)
let edges = unsafe { &mut EDGES_MAP[0..MAX_EDGES_NUM] }; let edges_observer = HitcountsMapObserver::new(unsafe { std_edges_map_observer("edges") });
let edges_observer = HitcountsMapObserver::new(StdMapObserver::new("edges", edges));
// Create an observation channel to keep track of the execution time // Create an observation channel to keep track of the execution time
let time_observer = TimeObserver::new("time"); let time_observer = TimeObserver::new("time");
let cmplog = unsafe { &mut CMPLOG_MAP }; let cmplog_observer = CmpLogObserver::new("cmplog", true);
let cmplog_observer = CmpLogObserver::new("cmplog", cmplog, true);
let map_feedback = MaxMapFeedback::new_tracking(&edges_observer, true, false); let map_feedback = MaxMapFeedback::new_tracking(&edges_observer, true, false);
@ -490,7 +487,7 @@ fn fuzz_text(
#[cfg(unix)] #[cfg(unix)]
writeln!(&mut stdout_cpy, "{}", s).unwrap(); writeln!(&mut stdout_cpy, "{}", s).unwrap();
#[cfg(windows)] #[cfg(windows)]
println!("{}", s); println!("{s}");
writeln!(log.borrow_mut(), "{:?} {}", current_time(), s).unwrap(); writeln!(log.borrow_mut(), "{:?} {}", current_time(), s).unwrap();
}); });
@ -507,21 +504,19 @@ fn fuzz_text(
return Ok(()); return Ok(());
} }
_ => { _ => {
panic!("Failed to setup the restarter: {}", err); panic!("Failed to setup the restarter: {err}");
} }
}, },
}; };
// Create an observation channel using the coverage map // Create an observation channel using the coverage map
// We don't use the hitcounts (see the Cargo.toml, we use pcguard_edges) // We don't use the hitcounts (see the Cargo.toml, we use pcguard_edges)
let edges = unsafe { &mut EDGES_MAP[0..MAX_EDGES_NUM] }; let edges_observer = HitcountsMapObserver::new(unsafe { std_edges_map_observer("edges") });
let edges_observer = HitcountsMapObserver::new(StdMapObserver::new("edges", edges));
// Create an observation channel to keep track of the execution time // Create an observation channel to keep track of the execution time
let time_observer = TimeObserver::new("time"); let time_observer = TimeObserver::new("time");
let cmplog = unsafe { &mut CMPLOG_MAP }; let cmplog_observer = CmpLogObserver::new("cmplog", true);
let cmplog_observer = CmpLogObserver::new("cmplog", cmplog, true);
// New maximization map feedback linked to the edges observer and the feedback state // New maximization map feedback linked to the edges observer and the feedback state
let map_feedback = MaxMapFeedback::new_tracking(&edges_observer, true, true); let map_feedback = MaxMapFeedback::new_tracking(&edges_observer, true, true);

View File

@ -34,7 +34,7 @@ use libafl::{
scheduled::{havoc_mutations, tokens_mutations, StdScheduledMutator}, scheduled::{havoc_mutations, tokens_mutations, StdScheduledMutator},
token_mutations::{I2SRandReplace, Tokens}, token_mutations::{I2SRandReplace, Tokens},
}, },
observers::{HitcountsMapObserver, StdMapObserver, TimeObserver}, observers::{HitcountsMapObserver, TimeObserver},
schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler}, schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler},
stages::{StdMutationalStage, TracingStage}, stages::{StdMutationalStage, TracingStage},
state::{HasCorpus, HasMetadata, StdState}, state::{HasCorpus, HasMetadata, StdState},
@ -42,7 +42,7 @@ use libafl::{
}; };
use libafl_targets::{ use libafl_targets::{
CmpLogObserver, __sanitizer_cov_trace_cmp1, __sanitizer_cov_trace_cmp2, CmpLogObserver, __sanitizer_cov_trace_cmp1, __sanitizer_cov_trace_cmp2,
__sanitizer_cov_trace_cmp4, __sanitizer_cov_trace_cmp8, CMPLOG_MAP, EDGES_MAP_PTR, __sanitizer_cov_trace_cmp4, __sanitizer_cov_trace_cmp8, std_edges_map_observer, EDGES_MAP_PTR,
MAX_EDGES_NUM, MAX_EDGES_NUM,
}; };
@ -211,26 +211,19 @@ pub fn LLVMFuzzerRunDriver(
let shmem_provider = StdShMemProvider::new().expect("Failed to init shared memory"); let shmem_provider = StdShMemProvider::new().expect("Failed to init shared memory");
let monitor = MultiMonitor::new(|s| println!("{}", s)); let monitor = MultiMonitor::new(|s| println!("{s}"));
// TODO: we need to handle Atheris calls to `exit` on errors somhow. // TODO: we need to handle Atheris calls to `exit` on errors somhow.
let mut run_client = |state: Option<_>, mut mgr, _core_id| { let mut run_client = |state: Option<_>, mut mgr, _core_id| {
// Create an observation channel using the coverage map // Create an observation channel using the coverage map
let edges_observer = unsafe { let edges_observer = unsafe { HitcountsMapObserver::new(std_edges_map_observer("edges")) };
HitcountsMapObserver::new(StdMapObserver::new_from_ptr(
"edges",
EDGES_MAP_PTR,
MAX_EDGES_NUM,
))
};
// Create an observation channel to keep track of the execution time // Create an observation channel to keep track of the execution time
let time_observer = TimeObserver::new("time"); let time_observer = TimeObserver::new("time");
// Create the Cmp observer // Create the Cmp observer
let cmplog = unsafe { &mut CMPLOG_MAP }; let cmplog_observer = CmpLogObserver::new("cmplog", true);
let cmplog_observer = CmpLogObserver::new("cmplog", cmplog, true);
// Feedback to rate the interestingness of an input // Feedback to rate the interestingness of an input
// This one is composed by two Feedbacks in OR // This one is composed by two Feedbacks in OR

View File

@ -11,7 +11,7 @@ pub fn main() {
let is_cpp = match wrapper_name[wrapper_name.len()-2..].to_lowercase().as_str() { let is_cpp = match wrapper_name[wrapper_name.len()-2..].to_lowercase().as_str() {
"cc" => false, "cc" => false,
"++" | "pp" | "xx" => true, "++" | "pp" | "xx" => true,
_ => panic!("Could not figure out if c or c++ warpper was called. Expected {:?} to end with c or cxx", dir), _ => panic!("Could not figure out if c or c++ wrapper was called. Expected {dir:?} to end with c or cxx"),
}; };
dir.pop(); dir.pop();

View File

@ -1,5 +1,5 @@
pub mod libafl_cc; pub mod libafl_cc;
fn main() { fn main() {
libafl_cc::main() libafl_cc::main();
} }

View File

@ -32,7 +32,7 @@ use libafl::{
Error, Error,
}; };
use libafl_targets::{ use libafl_targets::{
libfuzzer_initialize, libfuzzer_test_one_input, CMP_MAP, EDGES_MAP, MAX_EDGES_NUM, libfuzzer_initialize, libfuzzer_test_one_input, std_edges_map_observer, CMP_MAP,
}; };
const ALLOC_MAP_SIZE: usize = 16 * 1024; const ALLOC_MAP_SIZE: usize = 16 * 1024;
@ -62,7 +62,7 @@ pub fn libafl_main() {
/// The actual fuzzer /// The actual fuzzer
fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Result<(), Error> { fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Result<(), Error> {
// 'While the stats are state, they are usually used in the broker - which is likely never restarted // 'While the stats are state, they are usually used in the broker - which is likely never restarted
let monitor = SimpleMonitor::new(|s| println!("{}", s)); let monitor = SimpleMonitor::new(|s| println!("{s}"));
// The restarting state will spawn the same process again as child, then restarted it each time it crashes. // The restarting state will spawn the same process again as child, then restarted it each time it crashes.
let (state, mut restarting_mgr) = let (state, mut restarting_mgr) =
@ -78,14 +78,13 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
}; };
// Create an observation channel using the coverage map // Create an observation channel using the coverage map
let edges = unsafe { &mut EDGES_MAP[0..MAX_EDGES_NUM] }; let edges_observer = unsafe { std_edges_map_observer("edges") };
let edges_observer = StdMapObserver::new("edges", edges);
// Create an observation channel using the cmp map // Create an observation channel using the cmp map
let cmps_observer = StdMapObserver::new("cmps", unsafe { &mut CMP_MAP }); let cmps_observer = unsafe { StdMapObserver::new("cmps", &mut CMP_MAP) };
// Create an observation channel using the allocations map // Create an observation channel using the allocations map
let allocs_observer = StdMapObserver::new("allocs", unsafe { &mut libafl_alloc_map }); let allocs_observer = unsafe { StdMapObserver::new("allocs", &mut libafl_alloc_map) };
// Feedback to rate the interestingness of an input // Feedback to rate the interestingness of an input
let mut feedback = feedback_or!( let mut feedback = feedback_or!(

View File

@ -11,7 +11,7 @@ pub fn main() {
let is_cpp = match wrapper_name[wrapper_name.len()-2..].to_lowercase().as_str() { let is_cpp = match wrapper_name[wrapper_name.len()-2..].to_lowercase().as_str() {
"cc" => false, "cc" => false,
"++" | "pp" | "xx" => true, "++" | "pp" | "xx" => true,
_ => panic!("Could not figure out if c or c++ warpper was called. Expected {:?} to end with c or cxx", dir), _ => panic!("Could not figure out if c or c++ wrapper was called. Expected {dir:?} to end with c or cxx"),
}; };
dir.pop(); dir.pop();

View File

@ -1,5 +1,5 @@
pub mod libafl_cc; pub mod libafl_cc;
fn main() { fn main() {
libafl_cc::main() libafl_cc::main();
} }

View File

@ -62,7 +62,7 @@ pub fn libafl_main() {
#[cfg(not(test))] #[cfg(not(test))]
fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Result<(), Error> { fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Result<(), Error> {
// 'While the stats are state, they are usually used in the broker - which is likely never restarted // 'While the stats are state, they are usually used in the broker - which is likely never restarted
let monitor = MultiMonitor::new(|s| println!("{}", s)); let monitor = MultiMonitor::new(|s| println!("{s}"));
// The restarting state will spawn the same process again as child, then restarted it each time it crashes. // The restarting state will spawn the same process again as child, then restarted it each time it crashes.
let (state, mut restarting_mgr) = let (state, mut restarting_mgr) =
@ -73,14 +73,19 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
return Ok(()); return Ok(());
} }
_ => { _ => {
panic!("Failed to setup the restarter: {}", err); panic!("Failed to setup the restarter: {err}");
} }
}, },
}; };
// Create an observation channel using the coverage map // Create an observation channel using the coverage map
let edges = unsafe { &mut EDGES_MAP[0..MAX_EDGES_NUM] }; let edges_observer = unsafe {
let edges_observer = HitcountsMapObserver::new(StdMapObserver::new("edges", edges)); HitcountsMapObserver::new(StdMapObserver::from_mut_ptr(
"edges",
EDGES_MAP.as_mut_ptr(),
MAX_EDGES_NUM,
))
};
// Create an observation channel to keep track of the execution time // Create an observation channel to keep track of the execution time
let time_observer = TimeObserver::new("time"); let time_observer = TimeObserver::new("time");
@ -182,7 +187,7 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
// Call LLVMFUzzerInitialize() if present. // Call LLVMFUzzerInitialize() if present.
let args: Vec<String> = env::args().collect(); let args: Vec<String> = env::args().collect();
if libfuzzer_initialize(&args) == -1 { if libfuzzer_initialize(&args) == -1 {
println!("Warning: LLVMFuzzerInitialize failed with -1") println!("Warning: LLVMFuzzerInitialize failed with -1");
} }
// In case the corpus is empty (on first run), reset // In case the corpus is empty (on first run), reset

View File

@ -13,7 +13,7 @@ pub fn main() {
let is_cpp = match wrapper_name[wrapper_name.len()-2..].to_lowercase().as_str() { let is_cpp = match wrapper_name[wrapper_name.len()-2..].to_lowercase().as_str() {
"cc" => false, "cc" => false,
"++" | "pp" | "xx" => true, "++" | "pp" | "xx" => true,
_ => panic!("Could not figure out if c or c++ warpper was called. Expected {:?} to end with c or cxx", dir), _ => panic!("Could not figure out if c or c++ wrapper was called. Expected {dir:?} to end with c or cxx"),
}; };
dir.pop(); dir.pop();

View File

@ -1,5 +1,5 @@
pub mod libafl_cc; pub mod libafl_cc;
fn main() { fn main() {
libafl_cc::main() libafl_cc::main();
} }

View File

@ -129,12 +129,13 @@ pub fn libafl_main() {
let shmem_provider = StdShMemProvider::new().expect("Failed to init shared memory"); let shmem_provider = StdShMemProvider::new().expect("Failed to init shared memory");
let monitor = MultiMonitor::new(|s| println!("{}", s)); let monitor = MultiMonitor::new(|s| println!("{s}"));
let mut run_client = |state: Option<_>, mut restarting_mgr, _core_id| { let mut run_client = |state: Option<_>, mut restarting_mgr, _core_id| {
// Create an observation channel using the coverage map // Create an observation channel using the coverage map
let edges = unsafe { &mut EDGES_MAP[0..MAX_EDGES_NUM] }; let edges_observer = HitcountsMapObserver::new(unsafe {
let edges_observer = HitcountsMapObserver::new(StdMapObserver::new("edges", edges)); StdMapObserver::from_mut_ptr("edges", EDGES_MAP.as_mut_ptr(), MAX_EDGES_NUM)
});
// Create an observation channel to keep track of the execution time // Create an observation channel to keep track of the execution time
let time_observer = TimeObserver::new("time"); let time_observer = TimeObserver::new("time");
@ -221,7 +222,7 @@ pub fn libafl_main() {
// Call LLVMFUzzerInitialize() if present. // Call LLVMFUzzerInitialize() if present.
let args: Vec<String> = env::args().collect(); let args: Vec<String> = env::args().collect();
if libfuzzer_initialize(&args) == -1 { if libfuzzer_initialize(&args) == -1 {
println!("Warning: LLVMFuzzerInitialize failed with -1") println!("Warning: LLVMFuzzerInitialize failed with -1");
} }
// In case the corpus is empty (on first run), reset // In case the corpus is empty (on first run), reset

View File

@ -1,5 +1,5 @@
pub mod libafl_cc; pub mod libafl_cc;
fn main() { fn main() {
libafl_cc::main() libafl_cc::main();
} }

View File

@ -31,7 +31,7 @@ use libafl::{
scheduled::{havoc_mutations, tokens_mutations, StdScheduledMutator}, scheduled::{havoc_mutations, tokens_mutations, StdScheduledMutator},
token_mutations::Tokens, token_mutations::Tokens,
}, },
observers::{HitcountsMapObserver, StdMapObserver, TimeObserver}, observers::{HitcountsMapObserver, TimeObserver},
schedulers::{ schedulers::{
powersched::PowerSchedule, IndexesLenTimeMinimizerScheduler, StdWeightedScheduler, powersched::PowerSchedule, IndexesLenTimeMinimizerScheduler, StdWeightedScheduler,
}, },
@ -39,7 +39,7 @@ use libafl::{
state::{HasCorpus, HasMetadata, StdState}, state::{HasCorpus, HasMetadata, StdState},
Error, Error,
}; };
use libafl_targets::{libfuzzer_initialize, libfuzzer_test_one_input, EDGES_MAP, MAX_EDGES_NUM}; use libafl_targets::{libfuzzer_initialize, libfuzzer_test_one_input, std_edges_map_observer};
/// The main fn, `no_mangle` as it is a C main /// The main fn, `no_mangle` as it is a C main
#[cfg(not(test))] #[cfg(not(test))]
@ -65,7 +65,7 @@ pub fn libafl_main() {
#[cfg(not(test))] #[cfg(not(test))]
fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Result<(), Error> { fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Result<(), Error> {
// 'While the stats are state, they are usually used in the broker - which is likely never restarted // 'While the stats are state, they are usually used in the broker - which is likely never restarted
let monitor = MultiMonitor::new(|s| println!("{}", s)); let monitor = MultiMonitor::new(|s| println!("{s}"));
// The restarting state will spawn the same process again as child, then restarted it each time it crashes. // The restarting state will spawn the same process again as child, then restarted it each time it crashes.
let (state, mut restarting_mgr) = let (state, mut restarting_mgr) =
@ -76,14 +76,13 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
return Ok(()); return Ok(());
} }
_ => { _ => {
panic!("Failed to setup the restarter: {}", err); panic!("Failed to setup the restarter: {err}");
} }
}, },
}; };
// Create an observation channel using the coverage map // Create an observation channel using the coverage map
let edges = unsafe { &mut EDGES_MAP[0..MAX_EDGES_NUM] }; let edges_observer = HitcountsMapObserver::new(unsafe { std_edges_map_observer("edges") });
let edges_observer = HitcountsMapObserver::new(StdMapObserver::new("edges", edges));
let minimizer = StdCorpusMinimizer::new(&edges_observer); let minimizer = StdCorpusMinimizer::new(&edges_observer);

View File

@ -11,7 +11,7 @@ pub fn main() {
let is_cpp = match wrapper_name[wrapper_name.len()-2..].to_lowercase().as_str() { let is_cpp = match wrapper_name[wrapper_name.len()-2..].to_lowercase().as_str() {
"cc" => false, "cc" => false,
"++" | "pp" | "xx" => true, "++" | "pp" | "xx" => true,
_ => panic!("Could not figure out if c or c++ warpper was called. Expected {:?} to end with c or cxx", dir), _ => panic!("Could not figure out if c or c++ wrapper was called. Expected {dir:?} to end with c or cxx"),
}; };
dir.pop(); dir.pop();

View File

@ -1,5 +1,5 @@
pub mod libafl_cc; pub mod libafl_cc;
fn main() { fn main() {
libafl_cc::main() libafl_cc::main();
} }

View File

@ -38,7 +38,7 @@ use libafl::{
state::{HasCorpus, HasMetadata, StdState}, state::{HasCorpus, HasMetadata, StdState},
Error, Error,
}; };
use libafl_targets::{edges_map_from_ptr, libfuzzer_initialize, libfuzzer_test_one_input}; use libafl_targets::{libfuzzer_initialize, libfuzzer_test_one_input, std_edges_map_observer};
fn timeout_from_millis_str(time: &str) -> Result<Duration, Error> { fn timeout_from_millis_str(time: &str) -> Result<Duration, Error> {
Ok(Duration::from_millis(time.parse()?)) Ok(Duration::from_millis(time.parse()?))
@ -125,13 +125,11 @@ pub fn libafl_main() {
let shmem_provider = StdShMemProvider::new().expect("Failed to init shared memory"); let shmem_provider = StdShMemProvider::new().expect("Failed to init shared memory");
let monitor = MultiMonitor::new(|s| println!("{}", s)); let monitor = MultiMonitor::new(|s| println!("{s}"));
let mut run_client = |state: Option<_>, mut restarting_mgr, _core_id| { let mut run_client = |state: Option<_>, mut restarting_mgr, _core_id| {
// Create an observation channel using the coverage map // Create an observation channel using the coverage map
let edges = unsafe { edges_map_from_ptr() }; let edges_observer = unsafe { HitcountsMapObserver::new(std_edges_map_observer("edges")) };
let edges_observer =
HitcountsMapObserver::new(StdMapObserver::new_from_ownedref("edges", edges));
// Create an observation channel to keep track of the execution time // Create an observation channel to keep track of the execution time
let time_observer = TimeObserver::new("time"); let time_observer = TimeObserver::new("time");

View File

@ -11,7 +11,7 @@ pub fn main() {
let is_cpp = match wrapper_name[wrapper_name.len()-2..].to_lowercase().as_str() { let is_cpp = match wrapper_name[wrapper_name.len()-2..].to_lowercase().as_str() {
"cc" => false, "cc" => false,
"++" | "pp" | "xx" => true, "++" | "pp" | "xx" => true,
_ => panic!("Could not figure out if c or c++ warpper was called. Expected {:?} to end with c or cxx", dir), _ => panic!("Could not figure out if c or c++ wrapper was called. Expected {dir:?} to end with c or cxx"),
}; };
dir.pop(); dir.pop();

View File

@ -1,5 +1,5 @@
pub mod libafl_cc; pub mod libafl_cc;
fn main() { fn main() {
libafl_cc::main() libafl_cc::main();
} }

View File

@ -38,7 +38,7 @@ use libafl::{
state::{HasCorpus, HasMetadata, StdState}, state::{HasCorpus, HasMetadata, StdState},
Error, Error,
}; };
use libafl_targets::{libfuzzer_initialize, libfuzzer_test_one_input, EDGES_MAP, MAX_EDGES_NUM}; use libafl_targets::{libfuzzer_initialize, libfuzzer_test_one_input, std_edges_map_observer};
/// Parse a millis string to a [`Duration`]. Used for arg parsing. /// Parse a millis string to a [`Duration`]. Used for arg parsing.
fn timeout_from_millis_str(time: &str) -> Result<Duration, Error> { fn timeout_from_millis_str(time: &str) -> Result<Duration, Error> {
@ -129,13 +129,12 @@ pub fn libafl_main() {
let monitor = OnDiskTOMLMonitor::new( let monitor = OnDiskTOMLMonitor::new(
"./fuzzer_stats.toml", "./fuzzer_stats.toml",
MultiMonitor::new(|s| println!("{}", s)), MultiMonitor::new(|s| println!("{s}")),
); );
let mut run_client = |state: Option<_>, mut restarting_mgr, _core_id| { let mut run_client = |state: Option<_>, mut restarting_mgr, _core_id| {
// Create an observation channel using the coverage map // Create an observation channel using the coverage map
let edges = unsafe { &mut EDGES_MAP[0..MAX_EDGES_NUM] }; let edges_observer = HitcountsMapObserver::new(unsafe { std_edges_map_observer("edges") });
let edges_observer = HitcountsMapObserver::new(StdMapObserver::new("edges", edges));
// Create an observation channel to keep track of the execution time // Create an observation channel to keep track of the execution time
let time_observer = TimeObserver::new("time"); let time_observer = TimeObserver::new("time");

View File

@ -12,7 +12,7 @@ pub fn main() {
let is_cpp = match wrapper_name[wrapper_name.len()-2..].to_lowercase().as_str() { let is_cpp = match wrapper_name[wrapper_name.len()-2..].to_lowercase().as_str() {
"cc" => false, "cc" => false,
"++" | "pp" | "xx" => true, "++" | "pp" | "xx" => true,
_ => panic!("Could not figure out if c or c++ warpper was called. Expected {:?} to end with c or cxx", dir), _ => panic!("Could not figure out if c or c++ wrapper was called. Expected {dir:?} to end with c or cxx"),
}; };
dir.pop(); dir.pop();

View File

@ -1,5 +1,5 @@
pub mod libafl_cc; pub mod libafl_cc;
fn main() { fn main() {
libafl_cc::main() libafl_cc::main();
} }

View File

@ -22,7 +22,7 @@ use libafl::{
state::{HasCorpus, StdState}, state::{HasCorpus, StdState},
Error, Error,
}; };
use libafl_targets::{libfuzzer_initialize, libfuzzer_test_one_input, EDGES_MAP, MAX_EDGES_NUM}; use libafl_targets::{libfuzzer_initialize, libfuzzer_test_one_input, std_edges_map_observer};
const TARGET_SIZE: usize = 4; const TARGET_SIZE: usize = 4;
@ -52,7 +52,7 @@ pub fn libafl_main() {
/// The actual fuzzer /// The actual fuzzer
fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Result<(), Error> { fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Result<(), Error> {
// 'While the stats are state, they are usually used in the broker - which is likely never restarted // 'While the stats are state, they are usually used in the broker - which is likely never restarted
let monitor = SimpleMonitor::new(|s| println!("{}", s)); let monitor = SimpleMonitor::new(|s| println!("{s}"));
// The restarting state will spawn the same process again as child, then restarted it each time it crashes. // The restarting state will spawn the same process again as child, then restarted it each time it crashes.
let (state, mut restarting_mgr) = let (state, mut restarting_mgr) =
@ -63,17 +63,16 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
return Ok(()); return Ok(());
} }
_ => { _ => {
panic!("Failed to setup the restarter: {}", err); panic!("Failed to setup the restarter: {err}");
} }
}, },
}; };
// Create an observation channel using the coverage map // Create an observation channel using the coverage map
let edges = unsafe { &mut EDGES_MAP[0..MAX_EDGES_NUM] }; let edges_observer = HitcountsMapObserver::new(unsafe { std_edges_map_observer("edges") });
let edges_observer = HitcountsMapObserver::new(StdMapObserver::new("edges", edges));
let reachability_observer = let reachability_observer =
unsafe { StdMapObserver::new_from_ptr("png.c", __libafl_target_list, TARGET_SIZE) }; unsafe { StdMapObserver::from_mut_ptr("png.c", __libafl_target_list, TARGET_SIZE) };
// Feedback to rate the interestingness of an input // Feedback to rate the interestingness of an input
let mut feedback = MaxMapFeedback::new(&edges_observer); let mut feedback = MaxMapFeedback::new(&edges_observer);

View File

@ -27,8 +27,7 @@ use libafl::{
Error, Error,
}; };
use libafl_targets::{ use libafl_targets::{
libfuzzer_initialize, libfuzzer_test_one_input, CmpLogObserver, CMPLOG_MAP, EDGES_MAP, libfuzzer_initialize, libfuzzer_test_one_input, std_edges_map_observer, CmpLogObserver,
MAX_EDGES_NUM,
}; };
pub fn main() { pub fn main() {
@ -51,7 +50,7 @@ pub fn main() {
/// The actual fuzzer /// The actual fuzzer
fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Result<(), Error> { fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Result<(), Error> {
// 'While the stats are state, they are usually used in the broker - which is likely never restarted // 'While the stats are state, they are usually used in the broker - which is likely never restarted
let monitor = MultiMonitor::new(|s| println!("{}", s)); let monitor = MultiMonitor::new(|s| println!("{s}"));
// The restarting state will spawn the same process again as child, then restarted it each time it crashes. // The restarting state will spawn the same process again as child, then restarted it each time it crashes.
let (state, mut restarting_mgr) = let (state, mut restarting_mgr) =
@ -62,21 +61,19 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
return Ok(()); return Ok(());
} }
_ => { _ => {
panic!("Failed to setup the restarter: {}", err); panic!("Failed to setup the restarter: {err}");
} }
}, },
}; };
// Create an observation channel using the coverage map // Create an observation channel using the coverage map
// We don't use the hitcounts (see the Cargo.toml, we use pcguard_edges) // We don't use the hitcounts (see the Cargo.toml, we use pcguard_edges)
let edges = unsafe { &mut EDGES_MAP[0..MAX_EDGES_NUM] }; let edges_observer = unsafe { std_edges_map_observer("edges") };
let edges_observer = StdMapObserver::new("edges", edges);
// Create an observation channel to keep track of the execution time // Create an observation channel to keep track of the execution time
let time_observer = TimeObserver::new("time"); let time_observer = TimeObserver::new("time");
let cmplog = unsafe { &mut CMPLOG_MAP }; let cmplog_observer = CmpLogObserver::new("cmplog", true);
let cmplog_observer = CmpLogObserver::new("cmplog", cmplog, true);
// Feedback to rate the interestingness of an input // Feedback to rate the interestingness of an input
// This one is composed by two Feedbacks in OR // This one is composed by two Feedbacks in OR

View File

@ -1,8 +1,8 @@
# Variables # Variables
[env] [env]
PROJECT_DIR = { script = ["pwd"] }
CARGO_TARGET_DIR = { value = "${PROJECT_DIR}/target", condition = { env_not_set = ["CARGO_TARGET_DIR"] } } CARGO_TARGET_DIR = { value = "${PROJECT_DIR}/target", condition = { env_not_set = ["CARGO_TARGET_DIR"] } }
FUZZER_NAME='libfuzzer_stb_image_concolic' FUZZER_NAME='libfuzzer_stb_image_concolic'
PROJECT_DIR = { script = ["pwd"] }
# Compilers # Compilers
[tasks.runtime] [tasks.runtime]

View File

@ -38,7 +38,7 @@ use libafl::{
serialization_format::{DEFAULT_ENV_NAME, DEFAULT_SIZE}, serialization_format::{DEFAULT_ENV_NAME, DEFAULT_SIZE},
ConcolicObserver, ConcolicObserver,
}, },
StdMapObserver, TimeObserver, TimeObserver,
}, },
schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler}, schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler},
stages::{ stages::{
@ -49,8 +49,7 @@ use libafl::{
Error, Error,
}; };
use libafl_targets::{ use libafl_targets::{
libfuzzer_initialize, libfuzzer_test_one_input, CmpLogObserver, CMPLOG_MAP, EDGES_MAP, libfuzzer_initialize, libfuzzer_test_one_input, std_edges_map_observer, CmpLogObserver,
MAX_EDGES_NUM,
}; };
#[derive(Debug, Parser)] #[derive(Debug, Parser)]
@ -88,7 +87,7 @@ fn fuzz(
concolic: bool, concolic: bool,
) -> Result<(), Error> { ) -> Result<(), Error> {
// 'While the stats are state, they are usually used in the broker - which is likely never restarted // 'While the stats are state, they are usually used in the broker - which is likely never restarted
let monitor = MultiMonitor::new(|s| println!("{}", s)); let monitor = MultiMonitor::new(|s| println!("{s}"));
// The restarting state will spawn the same process again as child, then restarted it each time it crashes. // The restarting state will spawn the same process again as child, then restarted it each time it crashes.
let (state, mut restarting_mgr) = let (state, mut restarting_mgr) =
@ -99,21 +98,19 @@ fn fuzz(
return Ok(()); return Ok(());
} }
_ => { _ => {
panic!("Failed to setup the restarter: {}", err); panic!("Failed to setup the restarter: {err}");
} }
}, },
}; };
// Create an observation channel using the coverage map // Create an observation channel using the coverage map
// We don't use the hitcounts (see the Cargo.toml, we use pcguard_edges) // We don't use the hitcounts (see the Cargo.toml, we use pcguard_edges)
let edges = unsafe { &mut EDGES_MAP[0..MAX_EDGES_NUM] }; let edges_observer = unsafe { std_edges_map_observer("edges") };
let edges_observer = StdMapObserver::new("edges", edges);
// Create an observation channel to keep track of the execution time // Create an observation channel to keep track of the execution time
let time_observer = TimeObserver::new("time"); let time_observer = TimeObserver::new("time");
let cmplog = unsafe { &mut CMPLOG_MAP }; let cmplog_observer = CmpLogObserver::new("cmplog", true);
let cmplog_observer = CmpLogObserver::new("cmplog", cmplog, true);
// Feedback to rate the interestingness of an input // Feedback to rate the interestingness of an input
// This one is composed by two Feedbacks in OR // This one is composed by two Feedbacks in OR

View File

@ -16,20 +16,16 @@ use libafl::{
fuzzer::{Fuzzer, StdFuzzer}, fuzzer::{Fuzzer, StdFuzzer},
inputs::{BytesInput, HasTargetBytes}, inputs::{BytesInput, HasTargetBytes},
monitors::MultiMonitor, monitors::MultiMonitor,
mutators::{ mutators::scheduled::{havoc_mutations, tokens_mutations, StdScheduledMutator},
scheduled::{havoc_mutations, tokens_mutations, StdScheduledMutator}, observers::{HitcountsMapObserver, TimeObserver},
token_mutations::Tokens,
},
observers::{HitcountsMapObserver, StdMapObserver, TimeObserver},
schedulers::{ schedulers::{
powersched::PowerSchedule, IndexesLenTimeMinimizerScheduler, StdWeightedScheduler, powersched::PowerSchedule, IndexesLenTimeMinimizerScheduler, StdWeightedScheduler,
}, },
stages::{calibrate::CalibrationStage, power::StdPowerMutationalStage}, stages::{calibrate::CalibrationStage, power::StdPowerMutationalStage},
state::{HasCorpus, HasMetadata, StdState}, state::{HasCorpus, StdState},
Error, Error,
}; };
use libafl_targets::{libfuzzer_initialize, libfuzzer_test_one_input, EDGES_MAP, MAX_EDGES_NUM}; use libafl_targets::{libfuzzer_initialize, libfuzzer_test_one_input, std_edges_map_observer};
#[no_mangle] #[no_mangle]
pub fn libafl_main() { pub fn libafl_main() {
println!( println!(
@ -65,8 +61,7 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
}; };
// Create an observation channel using the coverage map // Create an observation channel using the coverage map
let edges = unsafe { &mut EDGES_MAP[0..MAX_EDGES_NUM] }; let edges_observer = unsafe { HitcountsMapObserver::new(std_edges_map_observer("edges")) };
let edges_observer = HitcountsMapObserver::new(StdMapObserver::new("edges", edges));
// Create an observation channel to keep track of the execution time // Create an observation channel to keep track of the execution time
let time_observer = TimeObserver::new("time"); let time_observer = TimeObserver::new("time");

View File

@ -11,7 +11,7 @@ pub fn main() {
let is_cpp = match wrapper_name[wrapper_name.len()-2..].to_lowercase().as_str() { let is_cpp = match wrapper_name[wrapper_name.len()-2..].to_lowercase().as_str() {
"cc" => false, "cc" => false,
"++" | "pp" | "xx" => true, "++" | "pp" | "xx" => true,
_ => panic!("Could not figure out if c or c++ warpper was called. Expected {:?} to end with c or cxx", dir), _ => panic!("Could not figure out if c or c++ wrapper was called. Expected {dir:?} to end with c or cxx"),
}; };
dir.pop(); dir.pop();

View File

@ -26,16 +26,16 @@ fn main() {
let shmem_provider = StdShMemProvider::new().expect("Failed to init shared memory"); let shmem_provider = StdShMemProvider::new().expect("Failed to init shared memory");
let broker_port = 7777; let broker_port = 7777;
let monitor = MultiMonitor::new(|s| println!("{}", s)); let monitor = MultiMonitor::new(|s| println!("{s}"));
let cores = Cores::all().expect("unable to get all core id"); let cores = Cores::all().expect("unable to get all core id");
let parent_cpu_id = cores.ids.first().expect("unable to get first core id"); let parent_cpu_id = cores.ids.first().expect("unable to get first core id");
// region: fuzzer start function // region: fuzzer start function
let mut run_client = |state: Option<_>, mut restarting_mgr, _core_id: usize| { let mut run_client = |state: Option<_>, mut restarting_mgr, core_id: usize| {
// nyx shared dir, created by nyx-fuzz/packer/packer/nyx_packer.py // nyx shared dir, created by nyx-fuzz/packer/packer/nyx_packer.py
let share_dir = Path::new("/tmp/nyx_libxml2/"); let share_dir = Path::new("/tmp/nyx_libxml2/");
let cpu_id = _core_id as u32; let cpu_id = core_id.try_into().unwrap();
let parallel_mode = true; let parallel_mode = true;
// nyx stuff // nyx stuff
let mut helper = NyxHelper::new( let mut helper = NyxHelper::new(
@ -43,12 +43,11 @@ fn main() {
cpu_id, cpu_id,
true, true,
parallel_mode, parallel_mode,
Some(parent_cpu_id.id as u32), Some(parent_cpu_id.id.try_into().unwrap()),
) )
.unwrap(); .unwrap();
let trace_bits = let observer =
unsafe { std::slice::from_raw_parts_mut(helper.trace_bits, helper.map_size) }; unsafe { StdMapObserver::from_mut_ptr("trace", helper.trace_bits, helper.map_size) };
let observer = StdMapObserver::new("trace", trace_bits);
let input = BytesInput::new(b"22".to_vec()); let input = BytesInput::new(b"22".to_vec());
let rand = StdRand::new(); let rand = StdRand::new();

View File

@ -11,7 +11,7 @@ pub fn main() {
let is_cpp = match wrapper_name[wrapper_name.len()-2..].to_lowercase().as_str() { let is_cpp = match wrapper_name[wrapper_name.len()-2..].to_lowercase().as_str() {
"cc" => false, "cc" => false,
"++" | "pp" | "xx" => true, "++" | "pp" | "xx" => true,
_ => panic!("Could not figure out if c or c++ warpper was called. Expected {:?} to end with c or cxx", dir), _ => panic!("Could not figure out if c or c++ wrapper was called. Expected {dir:?} to end with c or cxx"),
}; };
dir.pop(); dir.pop();

View File

@ -26,8 +26,8 @@ fn main() {
// nyx stuff // nyx stuff
let mut helper = NyxHelper::new(share_dir, cpu_id, true, parallel_mode, None).unwrap(); let mut helper = NyxHelper::new(share_dir, cpu_id, true, parallel_mode, None).unwrap();
let trace_bits = unsafe { std::slice::from_raw_parts_mut(helper.trace_bits, helper.map_size) }; let observer =
let observer = StdMapObserver::new("trace", trace_bits); unsafe { StdMapObserver::from_mut_ptr("trace", helper.trace_bits, helper.map_size) };
let input = BytesInput::new(b"22".to_vec()); let input = BytesInput::new(b"22".to_vec());
let rand = StdRand::new(); let rand = StdRand::new();

View File

@ -2,7 +2,7 @@
//! The target loops and the harness pulls inputs out of `LibAFL`, instead of being called by `LibAFL`. //! The target loops and the harness pulls inputs out of `LibAFL`, instead of being called by `LibAFL`.
use std::path::PathBuf; use std::path::PathBuf;
use klo_routines::*; use klo_routines::{yield_, KloRoutine};
use libafl::{ use libafl::{
bolts::{current_nanos, rands::StdRand, tuples::tuple_list, AsSlice}, bolts::{current_nanos, rands::StdRand, tuples::tuple_list, AsSlice},
corpus::{InMemoryCorpus, OnDiskCorpus}, corpus::{InMemoryCorpus, OnDiskCorpus},
@ -40,7 +40,7 @@ fn input_generator() {
}; };
// Create an observation channel using the signals map // Create an observation channel using the signals map
let observer = StdMapObserver::new("signals", unsafe { &mut SIGNALS }); let observer = unsafe { StdMapObserver::new("signals", &mut SIGNALS) };
// Feedback to rate the interestingness of an input // Feedback to rate the interestingness of an input
let mut feedback = MaxMapFeedback::new(&observer); let mut feedback = MaxMapFeedback::new(&observer);
@ -107,6 +107,7 @@ fn input_generator() {
/// the main function loops independently of the fuzzer. /// the main function loops independently of the fuzzer.
/// `Klo` internally switches between the `LibAFL` and harness coroutines to generate the inputs. /// `Klo` internally switches between the `LibAFL` and harness coroutines to generate the inputs.
#[allow(clippy::manual_assert)]
pub fn main() { pub fn main() {
// Set up the Klo-routines harness // Set up the Klo-routines harness
let mut input_generator = input_generator; let mut input_generator = input_generator;

View File

@ -1,6 +1,6 @@
//! A fuzzer that uses a `PushStage`, generating input to be subsequently executed, //! A fuzzer that uses a `PushStage`, generating input to be subsequently executed,
//! instead of executing input iteslf in a loop. //! instead of executing input iteslf in a loop.
//! Using this method, we can add LibAFL, for example, into an emulation loop //! Using this method, we can add `LibAFL`, for example, into an emulation loop
//! or use its mutations for another fuzzer. //! or use its mutations for another fuzzer.
//! This is a less hacky alternative to the `KloRoutines` based fuzzer, that will also work on non-`Unix`. //! This is a less hacky alternative to the `KloRoutines` based fuzzer, that will also work on non-`Unix`.
@ -34,7 +34,7 @@ fn signals_set(idx: usize) {
#[allow(clippy::similar_names)] #[allow(clippy::similar_names)]
pub fn main() { pub fn main() {
// Create an observation channel using the signals map // Create an observation channel using the signals map
let observer = StdMapObserver::new("signals", unsafe { &mut SIGNALS }); let observer = unsafe { StdMapObserver::new("signals", &mut SIGNALS) };
// Feedback to rate the interestingness of an input // Feedback to rate the interestingness of an input
let mut feedback = MaxMapFeedback::new(&observer); let mut feedback = MaxMapFeedback::new(&observer);

View File

@ -18,20 +18,20 @@ mac_alias = "unsupported"
windows_alias = "unsupported" windows_alias = "unsupported"
[tasks.zlib_unix_wget] [tasks.zlib_unix_wget]
condition = { files_not_exist = [ "./zlib-1.2.12" ] } condition = { files_not_exist = [ "./zlib-1.2.13" ] }
script_runner="@shell" script_runner="@shell"
# NOTE: There's no specific reason we're using an old version of zlib, # NOTE: There's no specific reason we're using an old version of zlib,
# but newer versions get moved to fossils/ after a while. # but newer versions get moved to fossils/ after a while.
script=''' script='''
wget https://zlib.net/fossils/zlib-1.2.12.tar.gz wget https://zlib.net/fossils/zlib-1.2.13.tar.gz
tar -xvf zlib-1.2.12.tar.gz tar -xvf zlib-1.2.13.tar.gz
''' '''
[tasks.zlib_unix] [tasks.zlib_unix]
condition = { files_not_exist = [ "./zlib-1.2.12/zlib/lib/libz.a" ] } condition = { files_not_exist = [ "./zlib-1.2.13/zlib/lib/libz.a" ] }
script_runner="@shell" script_runner="@shell"
script=''' script='''
cd zlib-1.2.12 && CC=$CROSS_CC ./configure --prefix=./zlib cd zlib-1.2.13 && CC=$CROSS_CC ./configure --prefix=./zlib
make install make install
''' '''
dependencies = [ "zlib_unix_wget" ] dependencies = [ "zlib_unix_wget" ]
@ -54,7 +54,7 @@ tar -xvf libpng-1.6.37.tar.xz
condition = { files_not_exist = [ "./libpng-1.6.37/.libs/libpng16.a" ] } condition = { files_not_exist = [ "./libpng-1.6.37/.libs/libpng16.a" ] }
script_runner="@shell" script_runner="@shell"
script=''' script='''
cd libpng-1.6.37 && CC=$CROSS_CC CFLAGS=-I../zlib-1.2.12/zlib/lib LDFLAGS=-L../zlib-1.2.12/zlib/lib ./configure --enable-shared=no --with-pic=yes --enable-hardware-optimizations=yes --host=arm cd libpng-1.6.37 && CC=$CROSS_CC CFLAGS=-I../zlib-1.2.13/zlib/lib LDFLAGS=-L../zlib-1.2.13/zlib/lib ./configure --enable-shared=no --with-pic=yes --enable-hardware-optimizations=yes --host=arm
make make
''' '''
dependencies = [ "zlib", "libpng_unix_wget" ] dependencies = [ "zlib", "libpng_unix_wget" ]
@ -82,10 +82,10 @@ script='''
arm-linux-gnueabi-g++ \ arm-linux-gnueabi-g++ \
./harness.cc \ ./harness.cc \
./libpng-1.6.37/.libs/libpng16.a \ ./libpng-1.6.37/.libs/libpng16.a \
./zlib-1.2.12/zlib/lib/libz.a \ ./zlib-1.2.13/zlib/lib/libz.a \
-I./libpng-1.6.37/ \ -I./libpng-1.6.37/ \
-I../zlib-1.2.12/zlib/lib \ -I../zlib-1.2.13/zlib/lib \
-L../zlib-1.2.12/zlib/lib \ -L../zlib-1.2.13/zlib/lib \
-o ${FUZZER_NAME} \ -o ${FUZZER_NAME} \
-lm \ -lm \
-static -static
@ -116,10 +116,10 @@ script='''
arm-linux-gnueabi-g++ \ arm-linux-gnueabi-g++ \
./harness.cc \ ./harness.cc \
./libpng-1.6.37/.libs/libpng16.a \ ./libpng-1.6.37/.libs/libpng16.a \
./zlib-1.2.12/zlib/lib/libz.a \ ./zlib-1.2.13/zlib/lib/libz.a \
-I./libpng-1.6.37/ \ -I./libpng-1.6.37/ \
-I../zlib-1.2.12/zlib/lib \ -I../zlib-1.2.13/zlib/lib \
-L../zlib-1.2.12/zlib/lib \ -L../zlib-1.2.13/zlib/lib \
-o ${FUZZER_NAME_CRASHING} \ -o ${FUZZER_NAME_CRASHING} \
-lm \ -lm \
-DHAS_DUMMY_CRASH \ -DHAS_DUMMY_CRASH \

View File

@ -1,6 +1,6 @@
//! A libfuzzer-like fuzzer using qemu for binary-only coverage //! A libfuzzer-like fuzzer using qemu for binary-only coverage
//! //!
use core::time::Duration; use core::{ptr::addr_of_mut, time::Duration};
use std::{env, path::PathBuf, process}; use std::{env, path::PathBuf, process};
use libafl::{ use libafl::{
@ -31,8 +31,7 @@ use libafl::{
use libafl_qemu::{ use libafl_qemu::{
drcov::QemuDrCovHelper, drcov::QemuDrCovHelper,
//asan::QemuAsanHelper, //asan::QemuAsanHelper,
edges, edges::{edges_map_mut_slice, QemuEdgeCoverageHelper, MAX_EDGES_NUM},
edges::QemuEdgeCoverageHelper,
elf::EasyElf, elf::EasyElf,
emu::Emulator, emu::Emulator,
MmapPerms, MmapPerms,
@ -109,10 +108,13 @@ pub fn fuzz() {
let mut run_client = |state: Option<_>, mut mgr, _core_id| { let mut run_client = |state: Option<_>, mut mgr, _core_id| {
// Create an observation channel using the coverage map // Create an observation channel using the coverage map
let edges = unsafe { &mut edges::EDGES_MAP }; let edges_observer = unsafe {
let edges_counter = unsafe { &mut edges::MAX_EDGES_NUM }; HitcountsMapObserver::new(VariableMapObserver::from_mut_slice(
let edges_observer = "edges",
HitcountsMapObserver::new(VariableMapObserver::new("edges", edges, edges_counter)); edges_map_mut_slice(),
addr_of_mut!(MAX_EDGES_NUM),
))
};
// Create an observation channel to keep track of the execution time // Create an observation channel to keep track of the execution time
let time_observer = TimeObserver::new("time"); let time_observer = TimeObserver::new("time");
@ -215,7 +217,7 @@ pub fn fuzz() {
let shmem_provider = StdShMemProvider::new().expect("Failed to init shared memory"); let shmem_provider = StdShMemProvider::new().expect("Failed to init shared memory");
// The stats reporter for the broker // The stats reporter for the broker
let monitor = MultiMonitor::new(|s| println!("{}", s)); let monitor = MultiMonitor::new(|s| println!("{s}"));
// Build and run a Launcher // Build and run a Launcher
match Launcher::builder() match Launcher::builder()

View File

@ -1,6 +1,6 @@
//! A libfuzzer-like fuzzer using qemu for binary-only coverage //! A libfuzzer-like fuzzer using qemu for binary-only coverage
//! //!
use core::time::Duration; use core::{ptr::addr_of_mut, time::Duration};
use std::{env, path::PathBuf, process}; use std::{env, path::PathBuf, process};
use libafl::{ use libafl::{
@ -30,13 +30,9 @@ use libafl::{
}; };
use libafl_qemu::{ use libafl_qemu::{
//asan::QemuAsanHelper, //asan::QemuAsanHelper,
cmplog, edges::{edges_map_mut_slice, QemuEdgeCoverageHelper, MAX_EDGES_NUM},
cmplog::{CmpLogObserver, QemuCmpLogHelper},
edges,
edges::QemuEdgeCoverageHelper,
elf::EasyElf, elf::EasyElf,
emu::Emulator, emu::Emulator,
filter_qemu_args,
//snapshot::QemuSnapshotHelper, //snapshot::QemuSnapshotHelper,
MmapPerms, MmapPerms,
QemuExecutor, QemuExecutor,
@ -52,7 +48,7 @@ pub fn fuzz() {
let broker_port = 1337; let broker_port = 1337;
let cores = Cores::from_cmdline("0-11").unwrap(); let cores = Cores::from_cmdline("0-11").unwrap();
let corpus_dirs = [PathBuf::from("./corpus")]; let corpus_dirs = [PathBuf::from("./corpus")];
let mut objective_dir = PathBuf::from("./crashes"); let objective_dir = PathBuf::from("./crashes");
// Initialize QEMU // Initialize QEMU
env::remove_var("LD_LIBRARY_PATH"); env::remove_var("LD_LIBRARY_PATH");
@ -116,10 +112,13 @@ pub fn fuzz() {
let mut run_client = |state: Option<_>, mut mgr, _core_id| { let mut run_client = |state: Option<_>, mut mgr, _core_id| {
// Create an observation channel using the coverage map // Create an observation channel using the coverage map
let edges = unsafe { &mut edges::EDGES_MAP }; let edges_observer = unsafe {
let edges_counter = unsafe { &mut edges::MAX_EDGES_NUM }; HitcountsMapObserver::new(VariableMapObserver::from_mut_slice(
let edges_observer = "edges",
HitcountsMapObserver::new(VariableMapObserver::new("edges", edges, edges_counter)); edges_map_mut_slice(),
addr_of_mut!(MAX_EDGES_NUM),
))
};
// Create an observation channel to keep track of the execution time // Create an observation channel to keep track of the execution time
let time_observer = TimeObserver::new("time"); let time_observer = TimeObserver::new("time");
@ -199,7 +198,7 @@ pub fn fuzz() {
let shmem_provider = StdShMemProvider::new().expect("Failed to init shared memory"); let shmem_provider = StdShMemProvider::new().expect("Failed to init shared memory");
// The stats reporter for the broker // The stats reporter for the broker
let monitor = MultiMonitor::new(|s| println!("{}", s)); let monitor = MultiMonitor::new(|s| println!("{s}"));
// Build and run a Launcher // Build and run a Launcher
match Launcher::builder() match Launcher::builder()

View File

@ -1,6 +1,6 @@
//! A fuzzer using qemu in systemmode for binary-only coverage of kernels //! A fuzzer using qemu in systemmode for binary-only coverage of kernels
//! //!
use core::time::Duration; use core::{ptr::addr_of_mut, time::Duration};
use std::{env, path::PathBuf, process}; use std::{env, path::PathBuf, process};
use libafl::{ use libafl::{
@ -22,15 +22,17 @@ use libafl::{
inputs::{BytesInput, HasTargetBytes}, inputs::{BytesInput, HasTargetBytes},
monitors::MultiMonitor, monitors::MultiMonitor,
mutators::scheduled::{havoc_mutations, StdScheduledMutator}, mutators::scheduled::{havoc_mutations, StdScheduledMutator},
observers::{TimeObserver, VariableMapObserver}, observers::{HitcountsMapObserver, TimeObserver, VariableMapObserver},
schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler}, schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler},
stages::StdMutationalStage, stages::StdMutationalStage,
state::{HasCorpus, StdState}, state::{HasCorpus, StdState},
Error, Error,
}; };
use libafl_qemu::{ use libafl_qemu::{
edges, edges::QemuEdgeCoverageHelper, elf::EasyElf, emu::Emulator, GuestPhysAddr, QemuExecutor, edges::{edges_map_mut_slice, QemuEdgeCoverageHelper, MAX_EDGES_NUM},
QemuHooks, Regs, elf::EasyElf,
emu::Emulator,
GuestPhysAddr, QemuExecutor, QemuHooks, Regs,
}; };
pub static mut MAX_INPUT_SIZE: usize = 50; pub static mut MAX_INPUT_SIZE: usize = 50;
@ -138,9 +140,13 @@ pub fn fuzz() {
}; };
// Create an observation channel using the coverage map // Create an observation channel using the coverage map
let edges = unsafe { &mut edges::EDGES_MAP }; let edges_observer = unsafe {
let edges_counter = unsafe { &mut edges::MAX_EDGES_NUM }; HitcountsMapObserver::new(VariableMapObserver::from_mut_slice(
let edges_observer = VariableMapObserver::new("edges", edges, edges_counter); "edges",
edges_map_mut_slice(),
addr_of_mut!(MAX_EDGES_NUM),
))
};
// Create an observation channel to keep track of the execution time // Create an observation channel to keep track of the execution time
let time_observer = TimeObserver::new("time"); let time_observer = TimeObserver::new("time");
@ -222,9 +228,9 @@ pub fn fuzz() {
let shmem_provider = StdShMemProvider::new().expect("Failed to init shared memory"); let shmem_provider = StdShMemProvider::new().expect("Failed to init shared memory");
// The stats reporter for the broker // The stats reporter for the broker
let monitor = MultiMonitor::new(|s| println!("{}", s)); let monitor = MultiMonitor::new(|s| println!("{s}"));
// let monitor = SimpleMonitor::new(|s| println!("{}", s)); // let monitor = SimpleMonitor::new(|s| println!("{s}"));
// let mut mgr = SimpleEventManager::new(monitor); // let mut mgr = SimpleEventManager::new(monitor);
// run_client(None, mgr, 0); // run_client(None, mgr, 0);

View File

@ -26,7 +26,7 @@ fn main() {
let args = vec![".\\test\\test.exe".to_string(), "@@".to_string()]; let args = vec![".\\test\\test.exe".to_string(), "@@".to_string()];
let observer = ListObserver::new("cov", unsafe { &mut COVERAGE }); let observer = unsafe { ListObserver::new("cov", &mut COVERAGE) };
let mut feedback = ListFeedback::new_with_observer(&observer); let mut feedback = ListFeedback::new_with_observer(&observer);
let input = BytesInput::new(b"bad".to_vec()); let input = BytesInput::new(b"bad".to_vec());

View File

@ -11,7 +11,7 @@ pub fn main() {
let is_cpp = match wrapper_name[wrapper_name.len()-2..].to_lowercase().as_str() { let is_cpp = match wrapper_name[wrapper_name.len()-2..].to_lowercase().as_str() {
"cc" => false, "cc" => false,
"++" | "pp" | "xx" => true, "++" | "pp" | "xx" => true,
_ => panic!("Could not figure out if c or c++ warpper was called. Expected {:?} to end with c or cxx", dir), _ => panic!("Could not figure out if c or c++ wrapper was called. Expected {dir:?} to end with c or cxx"),
}; };
dir.pop(); dir.pop();

View File

@ -1,5 +1,5 @@
pub mod libafl_cc; pub mod libafl_cc;
fn main() { fn main() {
libafl_cc::main() libafl_cc::main();
} }

View File

@ -52,7 +52,7 @@ impl Default for PacketType {
impl Input for PacketData { impl Input for PacketData {
fn generate_name(&self, idx: usize) -> String { fn generate_name(&self, idx: usize) -> String {
format!("id_{}", idx) format!("id_{idx}")
} }
} }

View File

@ -16,13 +16,13 @@ use libafl::{
fuzzer::StdFuzzer, fuzzer::StdFuzzer,
inputs::HasTargetBytes, inputs::HasTargetBytes,
monitors::MultiMonitor, monitors::MultiMonitor,
observers::{HitcountsMapObserver, StdMapObserver, TimeObserver}, observers::{HitcountsMapObserver, TimeObserver},
schedulers::{powersched::PowerSchedule, PowerQueueScheduler}, schedulers::{powersched::PowerSchedule, PowerQueueScheduler},
stages::{calibrate::CalibrationStage, power::StdPowerMutationalStage}, stages::{calibrate::CalibrationStage, power::StdPowerMutationalStage},
state::{HasCorpus, StdState}, state::{HasCorpus, StdState},
Error, Fuzzer, Error, Fuzzer,
}; };
use libafl_targets::{libfuzzer_initialize, libfuzzer_test_one_input, EDGES_MAP, MAX_EDGES_NUM}; use libafl_targets::{libfuzzer_initialize, libfuzzer_test_one_input, std_edges_map_observer};
mod input; mod input;
use input::*; use input::*;
@ -64,7 +64,7 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
}; };
// 'While the stats are state, they are usually used in the broker - which is likely never restarted // 'While the stats are state, they are usually used in the broker - which is likely never restarted
let monitor = MultiMonitor::new(|s| println!("{}", s)); let monitor = MultiMonitor::new(|s| println!("{s}"));
// The restarting state will spawn the same process again as child, then restarted it each time it crashes. // The restarting state will spawn the same process again as child, then restarted it each time it crashes.
let (state, mut restarting_mgr) = let (state, mut restarting_mgr) =
@ -75,14 +75,13 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
return Ok(()); return Ok(());
} }
_ => { _ => {
panic!("Failed to setup the restarter: {}", err); panic!("Failed to setup the restarter: {err}");
} }
}, },
}; };
// Create an observation channel using the coverage map // Create an observation channel using the coverage map
let edges = unsafe { &mut EDGES_MAP[0..MAX_EDGES_NUM] }; let edges_observer = HitcountsMapObserver::new(unsafe { std_edges_map_observer("edges") });
let edges_observer = HitcountsMapObserver::new(StdMapObserver::new("edges", edges));
// Create an observation channel to keep track of the execution time // Create an observation channel to keep track of the execution time
let time_observer = TimeObserver::new("time"); let time_observer = TimeObserver::new("time");

View File

@ -7,7 +7,8 @@ fn main() {
#[rustversion::not(nightly)] #[rustversion::not(nightly)]
fn main() { fn main() {
println!("cargo:rerun-if-changed=build.rs"); println!("cargo:rerun-if-changed=build.rs");
if cfg!(feature = "nautilus") { assert!(
panic!("The 'nautilus' feature of libafl requires a nightly compiler"); cfg!(not(feature = "nautilus")),
} "The 'nautilus' feature of libafl requires a nightly compiler"
);
} }

View File

@ -330,14 +330,14 @@ impl<'a, T> From<&'a [T]> for OwnedSlice<'a, T> {
} }
} }
/// Create a new [`OwnedSlice`] from a [`OwnedSliceMut`] /// Create a new [`OwnedSlice`] from a [`OwnedMutSlice`]
impl<'a, T> From<OwnedSliceMut<'a, T>> for OwnedSlice<'a, T> { impl<'a, T> From<OwnedMutSlice<'a, T>> for OwnedSlice<'a, T> {
fn from(mut_slice: OwnedSliceMut<'a, T>) -> Self { fn from(mut_slice: OwnedMutSlice<'a, T>) -> Self {
Self { Self {
inner: match mut_slice.inner { inner: match mut_slice.inner {
OwnedSliceMutInner::RefRaw(ptr, len) => OwnedSliceInner::RefRaw(ptr as _, len), OwnedMutSliceInner::RefRaw(ptr, len) => OwnedSliceInner::RefRaw(ptr as _, len),
OwnedSliceMutInner::Ref(r) => OwnedSliceInner::Ref(r as _), OwnedMutSliceInner::Ref(r) => OwnedSliceInner::Ref(r as _),
OwnedSliceMutInner::Owned(v) => OwnedSliceInner::Owned(v), OwnedMutSliceInner::Owned(v) => OwnedSliceInner::Owned(v),
}, },
} }
} }
@ -384,7 +384,7 @@ where
} }
} }
/// Create a vector from an [`OwnedSliceMut`], or return the owned vec. /// Create a vector from an [`OwnedMutSlice`], or return the owned vec.
impl<'a, T> From<OwnedSlice<'a, T>> for Vec<T> impl<'a, T> From<OwnedSlice<'a, T>> for Vec<T>
where where
T: Clone, T: Clone,
@ -400,9 +400,9 @@ where
/// Wrap a mutable slice and convert to a Vec on serialize. /// Wrap a mutable slice and convert to a Vec on serialize.
/// We use a hidden inner enum so the public API can be safe, /// We use a hidden inner enum so the public API can be safe,
/// unless the user uses the unsafe [`OwnedSliceMut::from_raw_parts_mut`] /// unless the user uses the unsafe [`OwnedMutSlice::from_raw_parts_mut`]
#[derive(Debug)] #[derive(Debug)]
pub enum OwnedSliceMutInner<'a, T: 'a + Sized> { pub enum OwnedMutSliceInner<'a, T: 'a + Sized> {
/// A raw ptr to a memory location and a length /// A raw ptr to a memory location and a length
RefRaw(*mut T, usize), RefRaw(*mut T, usize),
/// A ptr to a mutable slice of the type /// A ptr to a mutable slice of the type
@ -411,22 +411,22 @@ pub enum OwnedSliceMutInner<'a, T: 'a + Sized> {
Owned(Vec<T>), Owned(Vec<T>),
} }
impl<'a, T: 'a + Sized + Serialize> Serialize for OwnedSliceMutInner<'a, T> { impl<'a, T: 'a + Sized + Serialize> Serialize for OwnedMutSliceInner<'a, T> {
fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
where where
S: Serializer, S: Serializer,
{ {
match self { match self {
OwnedSliceMutInner::RefRaw(rr, len) => { OwnedMutSliceInner::RefRaw(rr, len) => {
unsafe { slice::from_raw_parts_mut(*rr, *len) }.serialize(se) unsafe { slice::from_raw_parts_mut(*rr, *len) }.serialize(se)
} }
OwnedSliceMutInner::Ref(r) => r.serialize(se), OwnedMutSliceInner::Ref(r) => r.serialize(se),
OwnedSliceMutInner::Owned(b) => b.serialize(se), OwnedMutSliceInner::Owned(b) => b.serialize(se),
} }
} }
} }
impl<'de, 'a, T: 'a + Sized> Deserialize<'de> for OwnedSliceMutInner<'a, T> impl<'de, 'a, T: 'a + Sized> Deserialize<'de> for OwnedMutSliceInner<'a, T>
where where
Vec<T>: Deserialize<'de>, Vec<T>: Deserialize<'de>,
{ {
@ -434,18 +434,18 @@ where
where where
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
Deserialize::deserialize(deserializer).map(OwnedSliceMutInner::Owned) Deserialize::deserialize(deserializer).map(OwnedMutSliceInner::Owned)
} }
} }
/// Wrap a mutable slice and convert to a Vec on serialize /// Wrap a mutable slice and convert to a Vec on serialize
#[allow(clippy::unsafe_derive_deserialize)] #[allow(clippy::unsafe_derive_deserialize)]
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct OwnedSliceMut<'a, T: 'a + Sized> { pub struct OwnedMutSlice<'a, T: 'a + Sized> {
inner: OwnedSliceMutInner<'a, T>, inner: OwnedMutSliceInner<'a, T>,
} }
impl<'a, 'it, T> IntoIterator for &'it mut OwnedSliceMut<'a, T> { impl<'a, 'it, T> IntoIterator for &'it mut OwnedMutSlice<'a, T> {
type Item = <IterMut<'it, T> as Iterator>::Item; type Item = <IterMut<'it, T> as Iterator>::Item;
type IntoIter = IterMut<'it, T>; type IntoIter = IterMut<'it, T>;
@ -454,7 +454,7 @@ impl<'a, 'it, T> IntoIterator for &'it mut OwnedSliceMut<'a, T> {
} }
} }
impl<'a, 'it, T> IntoIterator for &'it OwnedSliceMut<'a, T> { impl<'a, 'it, T> IntoIterator for &'it OwnedMutSlice<'a, T> {
type Item = <Iter<'it, T> as Iterator>::Item; type Item = <Iter<'it, T> as Iterator>::Item;
type IntoIter = Iter<'it, T>; type IntoIter = Iter<'it, T>;
@ -463,22 +463,22 @@ impl<'a, 'it, T> IntoIterator for &'it OwnedSliceMut<'a, T> {
} }
} }
impl<'a, T: 'a + Sized> OwnedSliceMut<'a, T> { impl<'a, T: 'a + Sized> OwnedMutSlice<'a, T> {
/// Create a new [`OwnedSliceMut`] from a raw pointer and length /// Create a new [`OwnedMutSlice`] from a raw pointer and length
/// ///
/// # Safety /// # Safety
/// ///
/// The pointer must be valid and point to a map of the size `size_of<T>() * len` /// The pointer must be valid and point to a map of the size `size_of<T>() * len`
/// The contents will be dereferenced in subsequent operations. /// The contents will be dereferenced in subsequent operations.
#[must_use] #[must_use]
pub unsafe fn from_raw_parts_mut(ptr: *mut T, len: usize) -> OwnedSliceMut<'a, T> { pub unsafe fn from_raw_parts_mut(ptr: *mut T, len: usize) -> OwnedMutSlice<'a, T> {
if ptr.is_null() || len == 0 { if ptr.is_null() || len == 0 {
Self { Self {
inner: OwnedSliceMutInner::Owned(Vec::new()), inner: OwnedMutSliceInner::Owned(Vec::new()),
} }
} else { } else {
Self { Self {
inner: OwnedSliceMutInner::RefRaw(ptr, len), inner: OwnedMutSliceInner::RefRaw(ptr, len),
} }
} }
} }
@ -486,7 +486,7 @@ impl<'a, T: 'a + Sized> OwnedSliceMut<'a, T> {
/// Downsize the inner slice or vec returning the old size on success or `None` on failure /// Downsize the inner slice or vec returning the old size on success or `None` on failure
pub fn downsize(&mut self, new_len: usize) -> Option<usize> { pub fn downsize(&mut self, new_len: usize) -> Option<usize> {
match &mut self.inner { match &mut self.inner {
OwnedSliceMutInner::RefRaw(_rr, len) => { OwnedMutSliceInner::RefRaw(_rr, len) => {
let tmp = *len; let tmp = *len;
if new_len <= tmp { if new_len <= tmp {
*len = new_len; *len = new_len;
@ -495,7 +495,7 @@ impl<'a, T: 'a + Sized> OwnedSliceMut<'a, T> {
None None
} }
} }
OwnedSliceMutInner::Ref(r) => { OwnedMutSliceInner::Ref(r) => {
let tmp = r.len(); let tmp = r.len();
if new_len <= tmp { if new_len <= tmp {
r.downsize(new_len); r.downsize(new_len);
@ -504,7 +504,7 @@ impl<'a, T: 'a + Sized> OwnedSliceMut<'a, T> {
None None
} }
} }
OwnedSliceMutInner::Owned(v) => { OwnedMutSliceInner::Owned(v) => {
let tmp = v.len(); let tmp = v.len();
if new_len <= tmp { if new_len <= tmp {
v.truncate(new_len); v.truncate(new_len);
@ -517,113 +517,113 @@ impl<'a, T: 'a + Sized> OwnedSliceMut<'a, T> {
} }
} }
impl<'a, T: Sized> AsSlice for OwnedSliceMut<'a, T> { impl<'a, T: Sized> AsSlice for OwnedMutSlice<'a, T> {
type Entry = T; type Entry = T;
/// Get the value as slice /// Get the value as slice
#[must_use] #[must_use]
fn as_slice(&self) -> &[T] { fn as_slice(&self) -> &[T] {
match &self.inner { match &self.inner {
OwnedSliceMutInner::RefRaw(rr, len) => unsafe { slice::from_raw_parts(*rr, *len) }, OwnedMutSliceInner::RefRaw(rr, len) => unsafe { slice::from_raw_parts(*rr, *len) },
OwnedSliceMutInner::Ref(r) => r, OwnedMutSliceInner::Ref(r) => r,
OwnedSliceMutInner::Owned(v) => v.as_slice(), OwnedMutSliceInner::Owned(v) => v.as_slice(),
} }
} }
} }
impl<'a, T: Sized> AsMutSlice for OwnedSliceMut<'a, T> { impl<'a, T: Sized> AsMutSlice for OwnedMutSlice<'a, T> {
type Entry = T; type Entry = T;
/// Get the value as mut slice /// Get the value as mut slice
#[must_use] #[must_use]
fn as_mut_slice(&mut self) -> &mut [T] { fn as_mut_slice(&mut self) -> &mut [T] {
match &mut self.inner { match &mut self.inner {
OwnedSliceMutInner::RefRaw(rr, len) => unsafe { slice::from_raw_parts_mut(*rr, *len) }, OwnedMutSliceInner::RefRaw(rr, len) => unsafe { slice::from_raw_parts_mut(*rr, *len) },
OwnedSliceMutInner::Ref(r) => r, OwnedMutSliceInner::Ref(r) => r,
OwnedSliceMutInner::Owned(v) => v.as_mut_slice(), OwnedMutSliceInner::Owned(v) => v.as_mut_slice(),
} }
} }
} }
impl<'a, T> IntoOwned for OwnedSliceMut<'a, T> impl<'a, T> IntoOwned for OwnedMutSlice<'a, T>
where where
T: Sized + Clone, T: Sized + Clone,
{ {
#[must_use] #[must_use]
fn is_owned(&self) -> bool { fn is_owned(&self) -> bool {
match self.inner { match self.inner {
OwnedSliceMutInner::RefRaw(_, _) | OwnedSliceMutInner::Ref(_) => false, OwnedMutSliceInner::RefRaw(_, _) | OwnedMutSliceInner::Ref(_) => false,
OwnedSliceMutInner::Owned(_) => true, OwnedMutSliceInner::Owned(_) => true,
} }
} }
#[must_use] #[must_use]
fn into_owned(self) -> Self { fn into_owned(self) -> Self {
let vec = match self.inner { let vec = match self.inner {
OwnedSliceMutInner::RefRaw(rr, len) => unsafe { OwnedMutSliceInner::RefRaw(rr, len) => unsafe {
slice::from_raw_parts_mut(rr, len).to_vec() slice::from_raw_parts_mut(rr, len).to_vec()
}, },
OwnedSliceMutInner::Ref(r) => r.to_vec(), OwnedMutSliceInner::Ref(r) => r.to_vec(),
OwnedSliceMutInner::Owned(v) => v, OwnedMutSliceInner::Owned(v) => v,
}; };
Self { Self {
inner: OwnedSliceMutInner::Owned(vec), inner: OwnedMutSliceInner::Owned(vec),
} }
} }
} }
impl<'a, T: 'a + Clone> Clone for OwnedSliceMut<'a, T> { impl<'a, T: 'a + Clone> Clone for OwnedMutSlice<'a, T> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { Self {
inner: OwnedSliceMutInner::Owned(self.as_slice().to_vec()), inner: OwnedMutSliceInner::Owned(self.as_slice().to_vec()),
} }
} }
} }
/// Create a new [`OwnedSliceMut`] from a vector /// Create a new [`OwnedMutSlice`] from a vector
impl<'a, T> From<Vec<T>> for OwnedSliceMut<'a, T> { impl<'a, T> From<Vec<T>> for OwnedMutSlice<'a, T> {
fn from(vec: Vec<T>) -> Self { fn from(vec: Vec<T>) -> Self {
Self { Self {
inner: OwnedSliceMutInner::Owned(vec), inner: OwnedMutSliceInner::Owned(vec),
} }
} }
} }
/// Create a vector from an [`OwnedSliceMut`], or return the owned vec. /// Create a vector from an [`OwnedMutSlice`], or return the owned vec.
impl<'a, T> From<OwnedSliceMut<'a, T>> for Vec<T> impl<'a, T> From<OwnedMutSlice<'a, T>> for Vec<T>
where where
T: Clone, T: Clone,
{ {
fn from(slice: OwnedSliceMut<'a, T>) -> Self { fn from(slice: OwnedMutSlice<'a, T>) -> Self {
let slice = slice.into_owned(); let slice = slice.into_owned();
match slice.inner { match slice.inner {
OwnedSliceMutInner::Owned(vec) => vec, OwnedMutSliceInner::Owned(vec) => vec,
_ => panic!("Could not own slice!"), _ => panic!("Could not own slice!"),
} }
} }
} }
/// Create a new [`OwnedSliceMut`] from a vector reference /// Create a new [`OwnedMutSlice`] from a vector reference
impl<'a, T> From<&'a mut Vec<T>> for OwnedSliceMut<'a, T> { impl<'a, T> From<&'a mut Vec<T>> for OwnedMutSlice<'a, T> {
fn from(vec: &'a mut Vec<T>) -> Self { fn from(vec: &'a mut Vec<T>) -> Self {
Self { Self {
inner: OwnedSliceMutInner::Ref(vec), inner: OwnedMutSliceInner::Ref(vec),
} }
} }
} }
/// Create a new [`OwnedSliceMut`] from a reference to ref to a slice /// Create a new [`OwnedMutSlice`] from a reference to ref to a slice
impl<'a, T> From<&'a mut [T]> for OwnedSliceMut<'a, T> { impl<'a, T> From<&'a mut [T]> for OwnedMutSlice<'a, T> {
fn from(r: &'a mut [T]) -> Self { fn from(r: &'a mut [T]) -> Self {
Self { Self {
inner: OwnedSliceMutInner::Ref(r), inner: OwnedMutSliceInner::Ref(r),
} }
} }
} }
/// Create a new [`OwnedSliceMut`] from a reference to ref to a slice /// Create a new [`OwnedMutSlice`] from a reference to ref to a slice
#[allow(clippy::mut_mut)] // This makes use in some iterators easier #[allow(clippy::mut_mut)] // This makes use in some iterators easier
impl<'a, T> From<&'a mut &'a mut [T]> for OwnedSliceMut<'a, T> { impl<'a, T> From<&'a mut &'a mut [T]> for OwnedMutSlice<'a, T> {
fn from(r: &'a mut &'a mut [T]) -> Self { fn from(r: &'a mut &'a mut [T]) -> Self {
Self { Self {
inner: OwnedSliceMutInner::Ref(r), inner: OwnedMutSliceInner::Ref(r),
} }
} }
} }
@ -691,14 +691,14 @@ where
/// Wrap a C-style mutable pointer and convert to a Box on serialize /// Wrap a C-style mutable pointer and convert to a Box on serialize
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum OwnedPtrMut<T: Sized> { pub enum OwnedMutPtr<T: Sized> {
/// A mut ptr to the content /// A mut ptr to the content
Ptr(*mut T), Ptr(*mut T),
/// An owned [`Box`] to the content /// An owned [`Box`] to the content
Owned(Box<T>), Owned(Box<T>),
} }
impl<T: Sized + Serialize> Serialize for OwnedPtrMut<T> { impl<T: Sized + Serialize> Serialize for OwnedMutPtr<T> {
fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
where where
S: Serializer, S: Serializer,
@ -707,7 +707,7 @@ impl<T: Sized + Serialize> Serialize for OwnedPtrMut<T> {
} }
} }
impl<'de, T: Sized + serde::de::DeserializeOwned> Deserialize<'de> for OwnedPtrMut<T> impl<'de, T: Sized + serde::de::DeserializeOwned> Deserialize<'de> for OwnedMutPtr<T>
where where
Vec<T>: Deserialize<'de>, Vec<T>: Deserialize<'de>,
{ {
@ -715,48 +715,48 @@ where
where where
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
Deserialize::deserialize(de).map(OwnedPtrMut::Owned) Deserialize::deserialize(de).map(OwnedMutPtr::Owned)
} }
} }
impl<T: Sized> AsRef<T> for OwnedPtrMut<T> { impl<T: Sized> AsRef<T> for OwnedMutPtr<T> {
#[must_use] #[must_use]
fn as_ref(&self) -> &T { fn as_ref(&self) -> &T {
match self { match self {
OwnedPtrMut::Ptr(p) => unsafe { p.as_ref().unwrap() }, OwnedMutPtr::Ptr(p) => unsafe { p.as_ref().unwrap() },
OwnedPtrMut::Owned(b) => b.as_ref(), OwnedMutPtr::Owned(b) => b.as_ref(),
} }
} }
} }
impl<T: Sized> AsMut<T> for OwnedPtrMut<T> { impl<T: Sized> AsMut<T> for OwnedMutPtr<T> {
fn as_mut(&mut self) -> &mut T { fn as_mut(&mut self) -> &mut T {
match self { match self {
OwnedPtrMut::Ptr(p) => unsafe { p.as_mut().unwrap() }, OwnedMutPtr::Ptr(p) => unsafe { p.as_mut().unwrap() },
OwnedPtrMut::Owned(b) => b.as_mut(), OwnedMutPtr::Owned(b) => b.as_mut(),
} }
} }
} }
impl<T> IntoOwned for OwnedPtrMut<T> impl<T> IntoOwned for OwnedMutPtr<T>
where where
T: Sized + Clone, T: Sized + Clone,
{ {
#[must_use] #[must_use]
fn is_owned(&self) -> bool { fn is_owned(&self) -> bool {
match self { match self {
OwnedPtrMut::Ptr(_) => false, OwnedMutPtr::Ptr(_) => false,
OwnedPtrMut::Owned(_) => true, OwnedMutPtr::Owned(_) => true,
} }
} }
#[must_use] #[must_use]
fn into_owned(self) -> Self { fn into_owned(self) -> Self {
match self { match self {
OwnedPtrMut::Ptr(p) => unsafe { OwnedMutPtr::Ptr(p) => unsafe {
OwnedPtrMut::Owned(Box::new(p.as_ref().unwrap().clone())) OwnedMutPtr::Owned(Box::new(p.as_ref().unwrap().clone()))
}, },
OwnedPtrMut::Owned(v) => OwnedPtrMut::Owned(v), OwnedMutPtr::Owned(v) => OwnedMutPtr::Owned(v),
} }
} }
} }

View File

@ -354,7 +354,7 @@ pub mod pybind {
use super::{HasMetadata, Testcase}; use super::{HasMetadata, Testcase};
use crate::{ use crate::{
bolts::ownedref::OwnedPtrMut, bolts::ownedref::OwnedMutPtr,
inputs::{BytesInput, HasBytesVec}, inputs::{BytesInput, HasBytesVec},
pybind::PythonMetadata, pybind::PythonMetadata,
}; };
@ -367,13 +367,13 @@ pub mod pybind {
/// Python class for Testcase /// Python class for Testcase
pub struct PythonTestcaseWrapper { pub struct PythonTestcaseWrapper {
/// Rust wrapped Testcase object /// Rust wrapped Testcase object
pub inner: OwnedPtrMut<PythonTestcase>, pub inner: OwnedMutPtr<PythonTestcase>,
} }
impl PythonTestcaseWrapper { impl PythonTestcaseWrapper {
pub fn wrap(r: &mut PythonTestcase) -> Self { pub fn wrap(r: &mut PythonTestcase) -> Self {
Self { Self {
inner: OwnedPtrMut::Ptr(r), inner: OwnedMutPtr::Ptr(r),
} }
} }
@ -392,7 +392,7 @@ pub mod pybind {
#[new] #[new]
fn new(input: Vec<u8>) -> Self { fn new(input: Vec<u8>) -> Self {
Self { Self {
inner: OwnedPtrMut::Owned(Box::new(PythonTestcase::new(BytesInput::new(input)))), inner: OwnedMutPtr::Owned(Box::new(PythonTestcase::new(BytesInput::new(input)))),
} }
} }

View File

@ -652,7 +652,7 @@ mod tests {
#[test] #[test]
fn test_event_serde() { fn test_event_serde() {
let obv = StdMapObserver::new("test", unsafe { &mut MAP }); let obv = unsafe { StdMapObserver::new("test", &mut MAP) };
let map = tuple_list!(obv); let map = tuple_list!(obv);
let observers_buf = postcard::to_allocvec(&map).unwrap(); let observers_buf = postcard::to_allocvec(&map).unwrap();

View File

@ -7,7 +7,7 @@ use core::{cell::UnsafeCell, fmt::Debug};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{
bolts::{ownedref::OwnedPtrMut, tuples::MatchName}, bolts::{ownedref::OwnedMutPtr, tuples::MatchName},
executors::{Executor, ExitKind, HasObservers}, executors::{Executor, ExitKind, HasObservers},
inputs::UsesInput, inputs::UsesInput,
observers::{DifferentialObserversTuple, ObserversTuple, UsesObservers}, observers::{DifferentialObserversTuple, ObserversTuple, UsesObservers},
@ -37,8 +37,8 @@ impl<A, B, OTA, OTB, DOT> DiffExecutor<A, B, OTA, OTB, DOT> {
primary, primary,
secondary, secondary,
observers: UnsafeCell::new(ProxyObserversTuple { observers: UnsafeCell::new(ProxyObserversTuple {
primary: OwnedPtrMut::Ptr(core::ptr::null_mut()), primary: OwnedMutPtr::Ptr(core::ptr::null_mut()),
secondary: OwnedPtrMut::Ptr(core::ptr::null_mut()), secondary: OwnedMutPtr::Ptr(core::ptr::null_mut()),
differential: observers, differential: observers,
}), }),
} }
@ -116,8 +116,8 @@ where
bound = "A: serde::Serialize + serde::de::DeserializeOwned, B: serde::Serialize + serde::de::DeserializeOwned, DOT: serde::Serialize + serde::de::DeserializeOwned" bound = "A: serde::Serialize + serde::de::DeserializeOwned, B: serde::Serialize + serde::de::DeserializeOwned, DOT: serde::Serialize + serde::de::DeserializeOwned"
)] )]
pub struct ProxyObserversTuple<A, B, DOT> { pub struct ProxyObserversTuple<A, B, DOT> {
primary: OwnedPtrMut<A>, primary: OwnedMutPtr<A>,
secondary: OwnedPtrMut<B>, secondary: OwnedMutPtr<B>,
differential: DOT, differential: DOT,
} }
@ -207,8 +207,8 @@ where
impl<A, B, DOT> ProxyObserversTuple<A, B, DOT> { impl<A, B, DOT> ProxyObserversTuple<A, B, DOT> {
fn set(&mut self, primary: &A, secondary: &B) { fn set(&mut self, primary: &A, secondary: &B) {
self.primary = OwnedPtrMut::Ptr(primary as *const A as *mut A); self.primary = OwnedMutPtr::Ptr(primary as *const A as *mut A);
self.secondary = OwnedPtrMut::Ptr(secondary as *const B as *mut B); self.secondary = OwnedMutPtr::Ptr(secondary as *const B as *mut B);
} }
} }

View File

@ -1,7 +1,8 @@
//! The feedbacks reduce observer state after each run to a single `is_interesting`-value. //! The feedbacks reduce observer state after each run to a single `is_interesting`-value.
//! If a testcase is interesting, it may be added to a Corpus. //! If a testcase is interesting, it may be added to a Corpus.
//! //!
//! TODO: make S of Feedback<S> an associated type when specialisation + AT is stable
// TODO: make S of Feedback<S> an associated type when specialisation + AT is stable
pub mod map; pub mod map;
pub use map::*; pub use map::*;

View File

@ -731,7 +731,7 @@ pub mod pybind {
use pyo3::prelude::*; use pyo3::prelude::*;
use crate::{ use crate::{
bolts::ownedref::OwnedPtrMut, bolts::ownedref::OwnedMutPtr,
events::pybind::PythonEventManager, events::pybind::PythonEventManager,
executors::pybind::PythonExecutor, executors::pybind::PythonExecutor,
feedbacks::pybind::PythonFeedback, feedbacks::pybind::PythonFeedback,
@ -756,13 +756,13 @@ pub mod pybind {
#[derive(Debug)] #[derive(Debug)]
pub struct PythonStdFuzzerWrapper { pub struct PythonStdFuzzerWrapper {
/// Rust wrapped StdFuzzer object /// Rust wrapped StdFuzzer object
pub inner: OwnedPtrMut<PythonStdFuzzer>, pub inner: OwnedMutPtr<PythonStdFuzzer>,
} }
impl PythonStdFuzzerWrapper { impl PythonStdFuzzerWrapper {
pub fn wrap(r: &mut PythonStdFuzzer) -> Self { pub fn wrap(r: &mut PythonStdFuzzer) -> Self {
Self { Self {
inner: OwnedPtrMut::Ptr(r), inner: OwnedMutPtr::Ptr(r),
} }
} }
@ -781,7 +781,7 @@ pub mod pybind {
#[new] #[new]
fn new(py_feedback: PythonFeedback, py_objective: PythonFeedback) -> Self { fn new(py_feedback: PythonFeedback, py_objective: PythonFeedback) -> Self {
Self { Self {
inner: OwnedPtrMut::Owned(Box::new(StdFuzzer::new( inner: OwnedMutPtr::Owned(Box::new(StdFuzzer::new(
QueueScheduler::new(), QueueScheduler::new(),
py_feedback, py_feedback,
py_objective, py_objective,

View File

@ -9,12 +9,16 @@
// == how to use it === // == how to use it ===
// This monitor should plug into any fuzzer similar to other monitors. // This monitor should plug into any fuzzer similar to other monitors.
// In your fuzzer, include: // In your fuzzer, include:
// ```rust,ignore
// use libafl::monitors::PrometheusMonitor; // use libafl::monitors::PrometheusMonitor;
// ```
// as well as: // as well as:
// ```rust,ignore
// let listener = "127.0.0.1:8080".to_string(); // point prometheus to scrape here in your prometheus.yml // let listener = "127.0.0.1:8080".to_string(); // point prometheus to scrape here in your prometheus.yml
// let mon = PrometheusMonitor::new(listener, |s| println!("{}", s)); // let mon = PrometheusMonitor::new(listener, |s| println!("{s}"));
// and then like with any other monitor, pass it into the event manager like so: // and then like with any other monitor, pass it into the event manager like so:
// let mut mgr = SimpleEventManager::new(mon); // let mut mgr = SimpleEventManager::new(mon);
// ```
// When using docker, you may need to point prometheus.yml to the docker0 interface or host.docker.internal // When using docker, you may need to point prometheus.yml to the docker0 interface or host.docker.internal
// ==================== // ====================

View File

@ -106,7 +106,10 @@ impl Tokens {
/// The caller must ensure that the region between `token_start` and `token_stop` /// The caller must ensure that the region between `token_start` and `token_stop`
/// is a valid region, containing autotokens in the exepcted format. /// is a valid region, containing autotokens in the exepcted format.
#[cfg(any(target_os = "linux", target_vendor = "apple"))] #[cfg(any(target_os = "linux", target_vendor = "apple"))]
pub unsafe fn from_ptrs(token_start: *const u8, token_stop: *const u8) -> Result<Self, Error> { pub unsafe fn from_mut_ptrs(
token_start: *const u8,
token_stop: *const u8,
) -> Result<Self, Error> {
let mut ret = Self::default(); let mut ret = Self::default();
if token_start.is_null() || token_stop.is_null() { if token_start.is_null() || token_stop.is_null() {
return Ok(Self::new()); return Ok(Self::new());

View File

@ -19,7 +19,7 @@ use serde::{Deserialize, Serialize};
use crate::{ use crate::{
bolts::{ bolts::{
ownedref::{OwnedRefMut, OwnedSliceMut}, ownedref::{OwnedMutPtr, OwnedMutSlice},
tuples::Named, tuples::Named,
AsIter, AsIterMut, AsMutSlice, AsSlice, HasLen, AsIter, AsIterMut, AsMutSlice, AsSlice, HasLen,
}, },
@ -192,7 +192,7 @@ pub struct StdMapObserver<'a, T, const DIFFERENTIAL: bool>
where where
T: Default + Copy + 'static + Serialize, T: Default + Copy + 'static + Serialize,
{ {
map: OwnedSliceMut<'a, T>, map: OwnedMutSlice<'a, T>,
initial: T, initial: T,
name: String, name: String,
} }
@ -444,14 +444,29 @@ where
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned, T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned,
{ {
/// Creates a new [`MapObserver`] /// Creates a new [`MapObserver`]
///
/// # Safety
/// Will get a pointer to the map and dereference it at any point in time.
/// The map must not move in memory!
#[must_use] #[must_use]
fn maybe_differential<S>(name: S, map: &'a mut [T]) -> Self unsafe fn maybe_differential<S>(name: S, map: &'a mut [T]) -> Self
where where
S: Into<String>, S: Into<String>,
{ {
Self { let len = map.len();
map: OwnedSliceMut::from(map), let ptr = map.as_mut_ptr();
Self::maybe_differential_from_mut_ptr(name, ptr, len)
}
/// Creates a new [`MapObserver`] from an [`OwnedMutSlice`]
#[must_use]
fn maybe_differential_from_mut_slice<S>(name: S, map: OwnedMutSlice<'a, T>) -> Self
where
S: Into<String>,
{
StdMapObserver {
name: name.into(), name: name.into(),
map,
initial: T::default(), initial: T::default(),
} }
} }
@ -463,18 +478,18 @@ where
S: Into<String>, S: Into<String>,
{ {
Self { Self {
map: OwnedSliceMut::from(map), map: OwnedMutSlice::from(map),
name: name.into(), name: name.into(),
initial: T::default(), initial: T::default(),
} }
} }
/// Creates a new [`MapObserver`] from an [`OwnedSliceMut`] map. /// Creates a new [`MapObserver`] from an [`OwnedMutSlice`] map.
/// ///
/// # Safety /// # Safety
/// Will dereference the owned slice with up to len elements. /// Will dereference the owned slice with up to len elements.
#[must_use] #[must_use]
fn maybe_differential_from_ownedref<S>(name: S, map: OwnedSliceMut<'a, T>) -> Self fn maybe_differential_from_ownedref<S>(name: S, map: OwnedMutSlice<'a, T>) -> Self
where where
S: Into<String>, S: Into<String>,
{ {
@ -489,24 +504,23 @@ where
/// ///
/// # Safety /// # Safety
/// Will dereference the `map_ptr` with up to len elements. /// Will dereference the `map_ptr` with up to len elements.
unsafe fn maybe_differential_from_ptr<S>(name: S, map_ptr: *mut T, len: usize) -> Self unsafe fn maybe_differential_from_mut_ptr<S>(name: S, map_ptr: *mut T, len: usize) -> Self
where where
S: Into<String>, S: Into<String>,
{ {
StdMapObserver { Self::maybe_differential_from_mut_slice(
map: OwnedSliceMut::from_raw_parts_mut(map_ptr, len), name,
name: name.into(), OwnedMutSlice::from_raw_parts_mut(map_ptr, len),
initial: T::default(), )
}
} }
/// Gets the backing for this map /// Gets the backing for this map
pub fn map(&self) -> &OwnedSliceMut<'a, T> { pub fn map(&self) -> &OwnedMutSlice<'a, T> {
&self.map &self.map
} }
/// Gets the backing for this map mutably /// Gets the backing for this map mutably
pub fn map_mut(&mut self) -> &mut OwnedSliceMut<'a, T> { pub fn map_mut(&mut self) -> &mut OwnedMutSlice<'a, T> {
&mut self.map &mut self.map
} }
} }
@ -516,14 +530,26 @@ where
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned, T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned,
{ {
/// Creates a new [`MapObserver`] /// Creates a new [`MapObserver`]
///
/// # Safety
/// The observer will keep a pointer to the map.
/// Hence, the map may never move in memory.
#[must_use] #[must_use]
pub fn new<S>(name: S, map: &'a mut [T]) -> Self pub unsafe fn new<S>(name: S, map: &'a mut [T]) -> Self
where where
S: Into<String>, S: Into<String>,
{ {
Self::maybe_differential(name, map) Self::maybe_differential(name, map)
} }
/// Creates a new [`MapObserver`] from an [`OwnedMutSlice`]
pub fn from_mut_slice<S>(name: S, map: OwnedMutSlice<'a, T>) -> Self
where
S: Into<String>,
{
Self::maybe_differential_from_mut_slice(name, map)
}
/// Creates a new [`MapObserver`] with an owned map /// Creates a new [`MapObserver`] with an owned map
#[must_use] #[must_use]
pub fn new_owned<S>(name: S, map: Vec<T>) -> Self pub fn new_owned<S>(name: S, map: Vec<T>) -> Self
@ -533,12 +559,12 @@ where
Self::maybe_differential_owned(name, map) Self::maybe_differential_owned(name, map)
} }
/// Creates a new [`MapObserver`] from an [`OwnedSliceMut`] map. /// Creates a new [`MapObserver`] from an [`OwnedMutSlice`] map.
/// ///
/// # Note /// # Note
/// Will dereference the owned slice with up to len elements. /// Will dereference the owned slice with up to len elements.
#[must_use] #[must_use]
pub fn new_from_ownedref<S>(name: S, map: OwnedSliceMut<'a, T>) -> Self pub fn from_ownedref<S>(name: S, map: OwnedMutSlice<'a, T>) -> Self
where where
S: Into<String>, S: Into<String>,
{ {
@ -549,11 +575,11 @@ where
/// ///
/// # Safety /// # Safety
/// Will dereference the `map_ptr` with up to len elements. /// Will dereference the `map_ptr` with up to len elements.
pub unsafe fn new_from_ptr<S>(name: S, map_ptr: *mut T, len: usize) -> Self pub unsafe fn from_mut_ptr<S>(name: S, map_ptr: *mut T, len: usize) -> Self
where where
S: Into<String>, S: Into<String>,
{ {
Self::maybe_differential_from_ptr(name, map_ptr, len) Self::maybe_differential_from_mut_ptr(name, map_ptr, len)
} }
} }
@ -562,8 +588,12 @@ where
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned, T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned,
{ {
/// Creates a new [`MapObserver`] in differential mode /// Creates a new [`MapObserver`] in differential mode
///
/// # Safety
/// Will get a pointer to the map and dereference it at any point in time.
/// The map must not move in memory!
#[must_use] #[must_use]
pub fn differential<S>(name: S, map: &'a mut [T]) -> Self pub unsafe fn differential<S>(name: S, map: &'a mut [T]) -> Self
where where
S: Into<String>, S: Into<String>,
{ {
@ -579,12 +609,12 @@ where
Self::maybe_differential_owned(name, map) Self::maybe_differential_owned(name, map)
} }
/// Creates a new [`MapObserver`] from an [`OwnedSliceMut`] map in differential mode. /// Creates a new [`MapObserver`] from an [`OwnedMutSlice`] map in differential mode.
/// ///
/// # Note /// # Note
/// Will dereference the owned slice with up to len elements. /// Will dereference the owned slice with up to len elements.
#[must_use] #[must_use]
pub fn differential_from_ownedref<S>(name: S, map: OwnedSliceMut<'a, T>) -> Self pub fn differential_from_ownedref<S>(name: S, map: OwnedMutSlice<'a, T>) -> Self
where where
S: Into<String>, S: Into<String>,
{ {
@ -595,11 +625,11 @@ where
/// ///
/// # Safety /// # Safety
/// Will dereference the `map_ptr` with up to len elements. /// Will dereference the `map_ptr` with up to len elements.
pub unsafe fn differential_from_ptr<S>(name: S, map_ptr: *mut T, len: usize) -> Self pub unsafe fn differential_from_mut_ptr<S>(name: S, map_ptr: *mut T, len: usize) -> Self
where where
S: Into<String>, S: Into<String>,
{ {
Self::maybe_differential_from_ptr(name, map_ptr, len) Self::maybe_differential_from_mut_ptr(name, map_ptr, len)
} }
} }
@ -628,7 +658,7 @@ pub struct ConstMapObserver<'a, T, const N: usize>
where where
T: Default + Copy + 'static + Serialize, T: Default + Copy + 'static + Serialize,
{ {
map: OwnedSliceMut<'a, T>, map: OwnedMutSlice<'a, T>,
initial: T, initial: T,
name: String, name: String,
} }
@ -853,11 +883,15 @@ where
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned, T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned,
{ {
/// Creates a new [`MapObserver`] /// Creates a new [`MapObserver`]
///
/// # Safety
/// Will get a pointer to the map and dereference it at any point in time.
/// The map must not move in memory!
#[must_use] #[must_use]
pub fn new(name: &'static str, map: &'a mut [T]) -> Self { pub fn new(name: &'static str, map: &'a mut [T]) -> Self {
assert!(map.len() >= N); assert!(map.len() >= N);
Self { Self {
map: OwnedSliceMut::from(map), map: OwnedMutSlice::from(map),
name: name.to_string(), name: name.to_string(),
initial: T::default(), initial: T::default(),
} }
@ -869,7 +903,7 @@ where
assert!(map.len() >= N); assert!(map.len() >= N);
let initial = if map.is_empty() { T::default() } else { map[0] }; let initial = if map.is_empty() { T::default() } else { map[0] };
Self { Self {
map: OwnedSliceMut::from(map), map: OwnedMutSlice::from(map),
name: name.to_string(), name: name.to_string(),
initial, initial,
} }
@ -879,9 +913,9 @@ where
/// ///
/// # Safety /// # Safety
/// Will dereference the `map_ptr` with up to len elements. /// Will dereference the `map_ptr` with up to len elements.
pub unsafe fn new_from_ptr(name: &'static str, map_ptr: *mut T) -> Self { pub unsafe fn from_mut_ptr(name: &'static str, map_ptr: *mut T) -> Self {
ConstMapObserver { ConstMapObserver {
map: OwnedSliceMut::from_raw_parts_mut(map_ptr, N), map: OwnedMutSlice::from_raw_parts_mut(map_ptr, N),
name: name.to_string(), name: name.to_string(),
initial: T::default(), initial: T::default(),
} }
@ -896,8 +930,8 @@ pub struct VariableMapObserver<'a, T>
where where
T: Default + Copy + 'static + Serialize, T: Default + Copy + 'static + Serialize,
{ {
map: OwnedSliceMut<'a, T>, map: OwnedMutSlice<'a, T>,
size: OwnedRefMut<'a, usize>, size: OwnedMutPtr<usize>,
initial: T, initial: T,
name: String, name: String,
} }
@ -1126,12 +1160,20 @@ impl<'a, T> VariableMapObserver<'a, T>
where where
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned, T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned,
{ {
/// Creates a new [`MapObserver`] /// Creates a new [`MapObserver`] from an [`OwnedMutSlice`]
pub fn new(name: &'static str, map: &'a mut [T], size: &'a mut usize) -> Self { ///
Self { /// # Safety
map: OwnedSliceMut::from(map), /// The observer will dereference the owned slice, as well as the `map_ptr`.
size: OwnedRefMut::Ref(size), /// Dereferences `map_ptr` with up to `max_len` elements of size.
pub unsafe fn from_mut_slice(
name: &'static str,
map_slice: OwnedMutSlice<'a, T>,
size: *mut usize,
) -> Self {
VariableMapObserver {
name: name.into(), name: name.into(),
map: map_slice,
size: OwnedMutPtr::Ptr(size),
initial: T::default(), initial: T::default(),
} }
} }
@ -1139,19 +1181,19 @@ where
/// Creates a new [`MapObserver`] from a raw pointer /// Creates a new [`MapObserver`] from a raw pointer
/// ///
/// # Safety /// # Safety
/// The observer will dereference the `size` ptr, as well as the `map_ptr`.
/// Dereferences `map_ptr` with up to `max_len` elements of size. /// Dereferences `map_ptr` with up to `max_len` elements of size.
pub unsafe fn new_from_ptr( pub unsafe fn from_mut_ptr(
name: &'static str, name: &'static str,
map_ptr: *mut T, map_ptr: *mut T,
max_len: usize, max_len: usize,
size: &'a mut usize, size: *mut usize,
) -> Self { ) -> Self {
VariableMapObserver { Self::from_mut_slice(
map: OwnedSliceMut::from_raw_parts_mut(map_ptr, max_len), name,
size: OwnedRefMut::Ref(size), OwnedMutSlice::from_raw_parts_mut(map_ptr, max_len),
name: name.into(), size,
initial: T::default(), )
}
} }
} }
@ -1618,7 +1660,7 @@ pub struct MultiMapObserver<'a, T, const DIFFERENTIAL: bool>
where where
T: Default + Copy + 'static + Serialize + Debug, T: Default + Copy + 'static + Serialize + Debug,
{ {
maps: Vec<OwnedSliceMut<'a, T>>, maps: Vec<OwnedMutSlice<'a, T>>,
intervals: IntervalTree<usize, usize>, intervals: IntervalTree<usize, usize>,
len: usize, len: usize,
initial: T, initial: T,
@ -1782,7 +1824,7 @@ where
idx += l; idx += l;
builder.push(r); builder.push(r);
v += 1; v += 1;
OwnedSliceMut::from(x) OwnedMutSlice::from(x)
}) })
.collect(); .collect();
Self { Self {
@ -1831,7 +1873,7 @@ where
idx += l; idx += l;
builder.push(r); builder.push(r);
v += 1; v += 1;
OwnedSliceMut::from(x) OwnedMutSlice::from(x)
}) })
.collect(); .collect();
Self { Self {
@ -1851,7 +1893,7 @@ where
'a: 'it, 'a: 'it,
{ {
type Item = T; type Item = T;
type IntoIter = Flatten<Iter<'it, OwnedSliceMut<'a, T>>>; type IntoIter = Flatten<Iter<'it, OwnedMutSlice<'a, T>>>;
fn as_iter(&'it self) -> Self::IntoIter { fn as_iter(&'it self) -> Self::IntoIter {
self.maps.iter().flatten() self.maps.iter().flatten()
@ -1864,7 +1906,7 @@ where
'a: 'it, 'a: 'it,
{ {
type Item = T; type Item = T;
type IntoIter = Flatten<IterMut<'it, OwnedSliceMut<'a, T>>>; type IntoIter = Flatten<IterMut<'it, OwnedMutSlice<'a, T>>>;
fn as_iter_mut(&'it mut self) -> Self::IntoIter { fn as_iter_mut(&'it mut self) -> Self::IntoIter {
self.maps.iter_mut().flatten() self.maps.iter_mut().flatten()
@ -1877,7 +1919,7 @@ where
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
{ {
type Item = <Iter<'it, T> as Iterator>::Item; type Item = <Iter<'it, T> as Iterator>::Item;
type IntoIter = Flatten<Iter<'it, OwnedSliceMut<'a, T>>>; type IntoIter = Flatten<Iter<'it, OwnedMutSlice<'a, T>>>;
fn into_iter(self) -> Self::IntoIter { fn into_iter(self) -> Self::IntoIter {
self.maps.iter().flatten() self.maps.iter().flatten()
@ -1890,7 +1932,7 @@ where
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
{ {
type Item = <IterMut<'it, T> as Iterator>::Item; type Item = <IterMut<'it, T> as Iterator>::Item;
type IntoIter = Flatten<IterMut<'it, OwnedSliceMut<'a, T>>>; type IntoIter = Flatten<IterMut<'it, OwnedMutSlice<'a, T>>>;
fn into_iter(self) -> Self::IntoIter { fn into_iter(self) -> Self::IntoIter {
self.maps.iter_mut().flatten() self.maps.iter_mut().flatten()
@ -2195,7 +2237,7 @@ pub mod pybind {
#[new] #[new]
fn new(name: String, ptr: usize, size: usize) -> Self { fn new(name: String, ptr: usize, size: usize) -> Self {
Self { Self {
inner: unsafe { StdMapObserver::new_from_ptr(name, ptr as *mut $datatype, size) } inner: unsafe { StdMapObserver::from_mut_ptr(name, ptr as *mut $datatype, size) }
} }
} }

View File

@ -36,7 +36,7 @@ pub use value::*;
use crate::{ use crate::{
bolts::{ bolts::{
current_time, current_time,
ownedref::OwnedRefMut, ownedref::OwnedMutPtr,
tuples::{MatchName, Named}, tuples::{MatchName, Named},
}, },
executors::ExitKind, executors::ExitKind,
@ -475,25 +475,30 @@ where
/// A simple observer with a list of things. /// A simple observer with a list of things.
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
#[serde(bound = "T: serde::de::DeserializeOwned")] #[serde(bound = "T: serde::de::DeserializeOwned")]
pub struct ListObserver<'a, T> #[allow(clippy::unsafe_derive_deserialize)]
pub struct ListObserver<T>
where where
T: Debug + Serialize, T: Debug + Serialize,
{ {
name: String, name: String,
/// The list /// The list
list: OwnedRefMut<'a, Vec<T>>, list: OwnedMutPtr<Vec<T>>,
} }
impl<'a, T> ListObserver<'a, T> impl<T> ListObserver<T>
where where
T: Debug + Serialize + serde::de::DeserializeOwned, T: Debug + Serialize + serde::de::DeserializeOwned,
{ {
/// Creates a new [`ListObserver`] with the given name. /// Creates a new [`ListObserver`] with the given name.
///
/// # Safety
/// Will dereference the list.
/// The list may not move in memory.
#[must_use] #[must_use]
pub fn new(name: &'static str, list: &'a mut Vec<T>) -> Self { pub unsafe fn new(name: &'static str, list: *mut Vec<T>) -> Self {
Self { Self {
name: name.to_string(), name: name.to_string(),
list: OwnedRefMut::Ref(list), list: OwnedMutPtr::Ptr(list),
} }
} }
@ -510,7 +515,7 @@ where
} }
} }
impl<'a, S, T> Observer<S> for ListObserver<'a, T> impl<S, T> Observer<S> for ListObserver<T>
where where
S: UsesInput, S: UsesInput,
T: Debug + Serialize + serde::de::DeserializeOwned, T: Debug + Serialize + serde::de::DeserializeOwned,
@ -521,7 +526,7 @@ where
} }
} }
impl<'a, T> Named for ListObserver<'a, T> impl<T> Named for ListObserver<T>
where where
T: Debug + Serialize + serde::de::DeserializeOwned, T: Debug + Serialize + serde::de::DeserializeOwned,
{ {
@ -1331,10 +1336,9 @@ mod tests {
#[test] #[test]
fn test_observer_serde() { fn test_observer_serde() {
let obv = tuple_list!( let obv = tuple_list!(TimeObserver::new("time"), unsafe {
TimeObserver::new("time"), StdMapObserver::new("map", &mut MAP)
StdMapObserver::new("map", unsafe { &mut MAP }) });
);
let vec = postcard::to_allocvec(&obv).unwrap(); let vec = postcard::to_allocvec(&obv).unwrap();
println!("{vec:?}"); println!("{vec:?}");
let obv2: tuple_list_type!(TimeObserver, StdMapObserver<u32, false>) = let obv2: tuple_list_type!(TimeObserver, StdMapObserver<u32, false>) =

View File

@ -689,7 +689,7 @@ pub mod pybind {
use pyo3::{prelude::*, types::PyDict}; use pyo3::{prelude::*, types::PyDict};
use crate::{ use crate::{
bolts::{ownedref::OwnedPtrMut, rands::pybind::PythonRand}, bolts::{ownedref::OwnedMutPtr, rands::pybind::PythonRand},
corpus::pybind::PythonCorpus, corpus::pybind::PythonCorpus,
events::pybind::PythonEventManager, events::pybind::PythonEventManager,
executors::pybind::PythonExecutor, executors::pybind::PythonExecutor,
@ -711,13 +711,13 @@ pub mod pybind {
/// Python class for StdState /// Python class for StdState
pub struct PythonStdStateWrapper { pub struct PythonStdStateWrapper {
/// Rust wrapped StdState object /// Rust wrapped StdState object
pub inner: OwnedPtrMut<PythonStdState>, pub inner: OwnedMutPtr<PythonStdState>,
} }
impl PythonStdStateWrapper { impl PythonStdStateWrapper {
pub fn wrap(r: &mut PythonStdState) -> Self { pub fn wrap(r: &mut PythonStdState) -> Self {
Self { Self {
inner: OwnedPtrMut::Ptr(r), inner: OwnedMutPtr::Ptr(r),
} }
} }
@ -742,7 +742,7 @@ pub mod pybind {
objective: &mut PythonFeedback, objective: &mut PythonFeedback,
) -> Self { ) -> Self {
Self { Self {
inner: OwnedPtrMut::Owned(Box::new( inner: OwnedMutPtr::Owned(Box::new(
StdState::new(py_rand, corpus, solutions, feedback, objective) StdState::new(py_rand, corpus, solutions, feedback, objective)
.expect("Failed to create a new StdState"), .expect("Failed to create a new StdState"),
)), )),

View File

@ -586,7 +586,7 @@ impl AsanErrorsObserver {
/// Creates a new `AsanErrorsObserver` from a raw ptr /// Creates a new `AsanErrorsObserver` from a raw ptr
#[must_use] #[must_use]
pub fn new_from_ptr(errors: *const Option<AsanErrors>) -> Self { pub fn from_mut_ptr(errors: *const Option<AsanErrors>) -> Self {
Self { Self {
errors: OwnedPtr::Ptr(errors), errors: OwnedPtr::Ptr(errors),
} }

View File

@ -82,7 +82,7 @@ impl CoverageRuntime {
} }
/// Retrieve the coverage map pointer /// Retrieve the coverage map pointer
pub fn map_ptr_mut(&mut self) -> *mut u8 { pub fn map_mut_ptr(&mut self) -> *mut u8 {
self.0.borrow_mut().map.as_mut_ptr() self.0.borrow_mut().map.as_mut_ptr()
} }

View File

@ -404,9 +404,9 @@ where
} }
/// Pointer to coverage map /// Pointer to coverage map
pub fn map_ptr_mut(&mut self) -> Option<*mut u8> { pub fn map_mut_ptr(&mut self) -> Option<*mut u8> {
self.runtime_mut::<CoverageRuntime>() self.runtime_mut::<CoverageRuntime>()
.map(CoverageRuntime::map_ptr_mut) .map(CoverageRuntime::map_mut_ptr)
} }
/// Ranges /// Ranges

View File

@ -1,8 +1,8 @@
use hashbrown::HashMap; use hashbrown::HashMap;
use libafl::{inputs::UsesInput, state::HasMetadata}; use libafl::{inputs::UsesInput, state::HasMetadata};
pub use libafl_targets::{ pub use libafl_targets::{
cmplog::__libafl_targets_cmplog_instructions, CmpLogMap, CmpLogObserver, CMPLOG_MAP, cmplog::__libafl_targets_cmplog_instructions, CmpLogMap, CmpLogObserver, CMPLOG_MAP_H,
CMPLOG_MAP_H, CMPLOG_MAP_PTR, CMPLOG_MAP_SIZE, CMPLOG_MAP_W, CMPLOG_MAP_PTR, CMPLOG_MAP_SIZE, CMPLOG_MAP_W,
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -3,7 +3,8 @@ use std::{cell::UnsafeCell, cmp::max};
use hashbrown::{hash_map::Entry, HashMap}; use hashbrown::{hash_map::Entry, HashMap};
use libafl::{inputs::UsesInput, state::HasMetadata}; use libafl::{inputs::UsesInput, state::HasMetadata};
pub use libafl_targets::{ pub use libafl_targets::{
edges_max_num, EDGES_MAP, EDGES_MAP_PTR, EDGES_MAP_PTR_SIZE, EDGES_MAP_SIZE, MAX_EDGES_NUM, edges_map_mut_slice, edges_max_num, EDGES_MAP, EDGES_MAP_PTR, EDGES_MAP_PTR_NUM,
EDGES_MAP_SIZE, MAX_EDGES_NUM,
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -229,7 +230,7 @@ where
} }
// GuestAddress is u32 for 32 bit guests // GuestAddress is u32 for 32 bit guests
#[allow(clippy::unnecessary_cast)] #[allow(clippy::unnecessary_cast)]
Some((hash_me(src as u64) ^ hash_me(dest as u64)) & (unsafe { EDGES_MAP_PTR_SIZE } as u64 - 1)) Some((hash_me(src as u64) ^ hash_me(dest as u64)) & (unsafe { EDGES_MAP_PTR_NUM } as u64 - 1))
} }
pub extern "C" fn trace_edge_hitcount_ptr(id: u64, _data: u64) { pub extern "C" fn trace_edge_hitcount_ptr(id: u64, _data: u64) {
@ -277,7 +278,7 @@ where
pub extern "C" fn trace_block_transition_hitcount(id: u64, _data: u64) { pub extern "C" fn trace_block_transition_hitcount(id: u64, _data: u64) {
unsafe { unsafe {
PREV_LOC.with(|prev_loc| { PREV_LOC.with(|prev_loc| {
let x = ((*prev_loc.get() ^ id) as usize) & (EDGES_MAP_PTR_SIZE - 1); let x = ((*prev_loc.get() ^ id) as usize) & (EDGES_MAP_PTR_NUM - 1);
let entry = EDGES_MAP_PTR.add(x); let entry = EDGES_MAP_PTR.add(x);
*entry = (*entry).wrapping_add(1); *entry = (*entry).wrapping_add(1);
*prev_loc.get() = id.overflowing_shr(1).0; *prev_loc.get() = id.overflowing_shr(1).0;
@ -288,7 +289,7 @@ pub extern "C" fn trace_block_transition_hitcount(id: u64, _data: u64) {
pub extern "C" fn trace_block_transition_single(id: u64, _data: u64) { pub extern "C" fn trace_block_transition_single(id: u64, _data: u64) {
unsafe { unsafe {
PREV_LOC.with(|prev_loc| { PREV_LOC.with(|prev_loc| {
let x = ((*prev_loc.get() ^ id) as usize) & (EDGES_MAP_PTR_SIZE - 1); let x = ((*prev_loc.get() ^ id) as usize) & (EDGES_MAP_PTR_NUM - 1);
let entry = EDGES_MAP_PTR.add(x); let entry = EDGES_MAP_PTR.add(x);
*entry = 1; *entry = 1;
*prev_loc.get() = id.overflowing_shr(1).0; *prev_loc.get() = id.overflowing_shr(1).0;

View File

@ -123,7 +123,7 @@ impl<'a, const MAP_SIZE: usize> ForkserverBytesCoverageSugar<'a, MAP_SIZE> {
// Create an observation channel using the coverage map // Create an observation channel using the coverage map
let edges_observer = unsafe { let edges_observer = unsafe {
HitcountsMapObserver::new(ConstMapObserver::<_, MAP_SIZE>::new_from_ptr( HitcountsMapObserver::new(ConstMapObserver::<_, MAP_SIZE>::from_mut_ptr(
"shared_mem", "shared_mem",
shmem_map.as_mut_ptr(), shmem_map.as_mut_ptr(),
)) ))

View File

@ -27,13 +27,13 @@ use libafl::{
scheduled::{havoc_mutations, tokens_mutations, StdScheduledMutator}, scheduled::{havoc_mutations, tokens_mutations, StdScheduledMutator},
token_mutations::{I2SRandReplace, Tokens}, token_mutations::{I2SRandReplace, Tokens},
}, },
observers::{HitcountsMapObserver, StdMapObserver, TimeObserver}, observers::{HitcountsMapObserver, TimeObserver},
schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler}, schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler},
stages::{ShadowTracingStage, StdMutationalStage}, stages::{ShadowTracingStage, StdMutationalStage},
state::{HasCorpus, HasMetadata, StdState}, state::{HasCorpus, HasMetadata, StdState},
Error, Error,
}; };
use libafl_targets::{CmpLogObserver, CMPLOG_MAP, EDGES_MAP, MAX_EDGES_NUM}; use libafl_targets::{std_edges_map_observer, CmpLogObserver};
use typed_builder::TypedBuilder; use typed_builder::TypedBuilder;
use crate::{CORPUS_CACHE_SIZE, DEFAULT_TIMEOUT_SECS}; use crate::{CORPUS_CACHE_SIZE, DEFAULT_TIMEOUT_SECS};
@ -143,14 +143,13 @@ where
mut mgr: LlmpRestartingEventManager<_, _>, mut mgr: LlmpRestartingEventManager<_, _>,
_core_id| { _core_id| {
// Create an observation channel using the coverage map // Create an observation channel using the coverage map
let edges = unsafe { &mut EDGES_MAP[0..MAX_EDGES_NUM] }; let edges_observer =
let edges_observer = HitcountsMapObserver::new(StdMapObserver::new("edges", edges)); HitcountsMapObserver::new(unsafe { std_edges_map_observer("edges") });
// Create an observation channel to keep track of the execution time // Create an observation channel to keep track of the execution time
let time_observer = TimeObserver::new("time"); let time_observer = TimeObserver::new("time");
let cmplog = unsafe { &mut CMPLOG_MAP }; let cmplog_observer = CmpLogObserver::new("cmplog", true);
let cmplog_observer = CmpLogObserver::new("cmplog", cmplog, true);
// Feedback to rate the interestingness of an input // Feedback to rate the interestingness of an input
// This one is composed by two Feedbacks in OR // This one is composed by two Feedbacks in OR

View File

@ -1,6 +1,9 @@
//! In-memory fuzzer with `QEMU`-based binary-only instrumentation //! In-memory fuzzer with `QEMU`-based binary-only instrumentation
//! //!
use core::fmt::{self, Debug, Formatter}; use core::{
fmt::{self, Debug, Formatter},
ptr::addr_of_mut,
};
use std::{fs, net::SocketAddr, path::PathBuf, time::Duration}; use std::{fs, net::SocketAddr, path::PathBuf, time::Duration};
use libafl::{ use libafl::{
@ -33,10 +36,8 @@ use libafl::{
state::{HasCorpus, HasMetadata, StdState}, state::{HasCorpus, HasMetadata, StdState},
}; };
pub use libafl_qemu::emu::Emulator; pub use libafl_qemu::emu::Emulator;
use libafl_qemu::{ use libafl_qemu::{edges, QemuCmpLogHelper, QemuEdgeCoverageHelper, QemuExecutor, QemuHooks};
cmplog, edges, QemuCmpLogHelper, QemuEdgeCoverageHelper, QemuExecutor, QemuHooks, use libafl_targets::{edges_map_mut_slice, CmpLogObserver};
};
use libafl_targets::CmpLogObserver;
use typed_builder::TypedBuilder; use typed_builder::TypedBuilder;
use crate::{CORPUS_CACHE_SIZE, DEFAULT_TIMEOUT_SECS}; use crate::{CORPUS_CACHE_SIZE, DEFAULT_TIMEOUT_SECS};
@ -147,17 +148,19 @@ where
mut mgr: LlmpRestartingEventManager<_, _>, mut mgr: LlmpRestartingEventManager<_, _>,
_core_id| { _core_id| {
// Create an observation channel using the coverage map // Create an observation channel using the coverage map
let edges = unsafe { &mut edges::EDGES_MAP }; let edges_observer = unsafe {
let edges_counter = unsafe { &mut edges::MAX_EDGES_NUM }; HitcountsMapObserver::new(VariableMapObserver::from_mut_slice(
let edges_observer = "edges",
HitcountsMapObserver::new(VariableMapObserver::new("edges", edges, edges_counter)); edges_map_mut_slice(),
addr_of_mut!(edges::MAX_EDGES_NUM),
))
};
// Create an observation channel to keep track of the execution time // Create an observation channel to keep track of the execution time
let time_observer = TimeObserver::new("time"); let time_observer = TimeObserver::new("time");
// Keep tracks of CMPs // Keep tracks of CMPs
let cmplog = unsafe { &mut cmplog::CMPLOG_MAP }; let cmplog_observer = CmpLogObserver::new("cmplog", true);
let cmplog_observer = CmpLogObserver::new("cmplog", cmplog, true);
// Feedback to rate the interestingness of an input // Feedback to rate the interestingness of an input
// This one is composed by two Feedbacks in OR // This one is composed by two Feedbacks in OR

View File

@ -6,7 +6,7 @@ use alloc::string::{String, ToString};
use core::fmt::{self, Debug, Formatter}; use core::fmt::{self, Debug, Formatter};
use libafl::{ use libafl::{
bolts::{ownedref::OwnedRefMut, tuples::Named}, bolts::{ownedref::OwnedMutPtr, tuples::Named},
executors::ExitKind, executors::ExitKind,
inputs::UsesInput, inputs::UsesInput,
observers::{CmpMap, CmpObserver, CmpValues, Observer}, observers::{CmpMap, CmpObserver, CmpValues, Observer},
@ -178,14 +178,14 @@ pub use libafl_cmplog_enabled as CMPLOG_ENABLED;
/// A [`CmpObserver`] observer for `CmpLog` /// A [`CmpObserver`] observer for `CmpLog`
#[derive(Debug)] #[derive(Debug)]
pub struct CmpLogObserver<'a> { pub struct CmpLogObserver {
map: OwnedRefMut<'a, CmpLogMap>, map: OwnedMutPtr<CmpLogMap>,
size: Option<OwnedRefMut<'a, usize>>, size: Option<OwnedMutPtr<usize>>,
add_meta: bool, add_meta: bool,
name: String, name: String,
} }
impl<'a, S> CmpObserver<CmpLogMap, S> for CmpLogObserver<'a> impl<S> CmpObserver<CmpLogMap, S> for CmpLogObserver
where where
S: UsesInput + HasMetadata, S: UsesInput + HasMetadata,
{ {
@ -206,7 +206,7 @@ where
} }
} }
impl<'a, S> Observer<S> for CmpLogObserver<'a> impl<S> Observer<S> for CmpLogObserver
where where
S: UsesInput + HasMetadata, S: UsesInput + HasMetadata,
Self: CmpObserver<CmpLogMap, S>, Self: CmpObserver<CmpLogMap, S>,
@ -235,23 +235,32 @@ where
} }
} }
impl<'a> Named for CmpLogObserver<'a> { impl Named for CmpLogObserver {
fn name(&self) -> &str { fn name(&self) -> &str {
&self.name &self.name
} }
} }
impl<'a> CmpLogObserver<'a> { impl CmpLogObserver {
/// Creates a new [`CmpLogObserver`] with the given name. /// Creates a new [`CmpLogObserver`] with the given map and name.
///
/// # Safety
/// Will keep a ptr to the map. The map may not move in memory!
#[must_use] #[must_use]
pub fn new(name: &'static str, map: &'a mut CmpLogMap, add_meta: bool) -> Self { pub unsafe fn with_map_ptr(name: &'static str, map: *mut CmpLogMap, add_meta: bool) -> Self {
Self { Self {
name: name.to_string(), name: name.to_string(),
size: None, size: None,
add_meta, add_meta,
map: OwnedRefMut::Ref(map), map: OwnedMutPtr::Ptr(map),
} }
} }
/// Creates a new [`CmpLogObserver`] with the given name from the default [`CMPLOG_MAP`]
#[must_use]
pub fn new(name: &'static str, add_meta: bool) -> Self {
unsafe { Self::with_map_ptr(name, libafl_cmplog_map_ptr, add_meta) }
}
// TODO with_size // TODO with_size
} }

View File

@ -1,5 +1,7 @@
//! Coverage maps as static mut array //! Coverage maps as static mut array
use alloc::string::String;
#[cfg(any(target_os = "linux", target_vendor = "apple"))] #[cfg(any(target_os = "linux", target_vendor = "apple"))]
use libafl::{mutators::Tokens, Error}; use libafl::{mutators::Tokens, Error};
@ -44,7 +46,7 @@ pub fn autotokens() -> Result<Tokens, Error> {
Ok(Tokens::default()) Ok(Tokens::default())
} else { } else {
// we can safely unwrap // we can safely unwrap
Tokens::from_ptrs(__token_start, __token_stop) Tokens::from_mut_ptrs(__token_start, __token_stop)
} }
} }
} }
@ -52,19 +54,68 @@ pub fn autotokens() -> Result<Tokens, Error> {
/// The size of the map for edges. /// The size of the map for edges.
#[no_mangle] #[no_mangle]
pub static mut __afl_map_size: usize = EDGES_MAP_SIZE; pub static mut __afl_map_size: usize = EDGES_MAP_SIZE;
pub use __afl_map_size as EDGES_MAP_PTR_SIZE; pub use __afl_map_size as EDGES_MAP_PTR_NUM;
use libafl::bolts::ownedref::OwnedSliceMut; use libafl::{bolts::ownedref::OwnedMutSlice, observers::StdMapObserver};
/// Gets the edges map from the `EDGES_MAP_PTR` raw pointer. /// Gets the edges map from the `EDGES_MAP_PTR` raw pointer.
/// Assumes a `len` of `EDGES_MAP_PTR_NUM`.
/// ///
/// # Safety /// # Safety
/// ///
/// This function will crash if `EDGES_MAP_PTR` is not a valid pointer. /// This function will crash if `edges_map_mut_ptr` is not a valid pointer.
/// The `EDGES_MAP_PTR_SIZE` needs to be smaller than, or equal to the size of the map. /// The [`edges_max_num`] needs to be smaller than, or equal to the size of the map.
#[must_use] #[must_use]
pub unsafe fn edges_map_from_ptr<'a>() -> OwnedSliceMut<'a, u8> { pub unsafe fn edges_map_mut_slice<'a>() -> OwnedMutSlice<'a, u8> {
debug_assert!(!EDGES_MAP_PTR.is_null()); OwnedMutSlice::from_raw_parts_mut(edges_map_mut_ptr(), edges_max_num())
OwnedSliceMut::from_raw_parts_mut(EDGES_MAP_PTR, EDGES_MAP_PTR_SIZE) }
/// Gets a new [`StdMapObserver`] from the current [`edges_map_mut_slice`].
/// This is roughly equivalent to running:
///
/// ```rust,ignore
/// use libafl::observers::StdMapObserver;
/// use libafl_targets::{EDGES_MAP, MAX_EDGES_NUM};
///
/// #[cfg(not(feature = "pointer_maps"))]
/// let observer = unsafe {
/// StdMapObserver::from_mut_ptr("edges", EDGES_MAP.as_mut_ptr(), MAX_EDGES_NUM)
/// };
/// ```
///
/// or, for the `pointer_maps` feature:
///
/// ```rust,ignore
/// use libafl::observers::StdMapObserver;
/// use libafl_targets::{EDGES_MAP_PTR, EDGES_MAP_PTR_NUM};
///
/// #[cfg(feature = "pointer_maps")]
/// let observer = unsafe {
/// StdMapObserver::from_mut_ptr("edges", EDGES_MAP_PTR, EDGES_MAP_PTR_NUM)
/// };
/// ```
///
/// # Safety
/// This will dereference [`edges_map_mut_ptr`] and crash if it is not a valid address.
pub unsafe fn std_edges_map_observer<'a, S>(name: S) -> StdMapObserver<'a, u8, false>
where
S: Into<String>,
{
StdMapObserver::from_mut_slice(name, edges_map_mut_slice())
}
/// Gets the current edges map pt
/// It will usually take `EDGES_MAP`, but `EDGES_MAP_PTR`,
/// if built with the `pointer_maps` feature.
#[must_use]
pub fn edges_map_mut_ptr() -> *mut u8 {
unsafe {
if cfg!(feature = "pointer_maps") {
assert!(!EDGES_MAP_PTR.is_null());
EDGES_MAP_PTR
} else {
EDGES_MAP.as_mut_ptr()
}
}
} }
/// Gets the current maximum number of edges tracked. /// Gets the current maximum number of edges tracked.
@ -76,7 +127,7 @@ pub fn edges_max_num() -> usize {
} else { } else {
#[cfg(feature = "pointer_maps")] #[cfg(feature = "pointer_maps")]
{ {
EDGES_MAP_PTR_SIZE EDGES_MAP_PTR_NUM
} }
#[cfg(not(feature = "pointer_maps"))] #[cfg(not(feature = "pointer_maps"))]
{ {
@ -95,14 +146,14 @@ mod swap {
use core::fmt::Debug; use core::fmt::Debug;
use libafl::{ use libafl::{
bolts::{ownedref::OwnedSliceMut, tuples::Named, AsMutSlice}, bolts::{ownedref::OwnedMutSlice, tuples::Named, AsMutSlice},
inputs::UsesInput, inputs::UsesInput,
observers::{DifferentialObserver, Observer, ObserversTuple, StdMapObserver}, observers::{DifferentialObserver, Observer, ObserversTuple, StdMapObserver},
Error, Error,
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use super::{EDGES_MAP_PTR, EDGES_MAP_PTR_SIZE}; use super::{EDGES_MAP_PTR, EDGES_MAP_PTR_NUM};
/// Observer to be used with `DiffExecutor`s when executing a differential target that shares /// Observer to be used with `DiffExecutor`s when executing a differential target that shares
/// the AFL map in order to swap out the maps (and thus allow for map observing the two targets /// the AFL map in order to swap out the maps (and thus allow for map observing the two targets
@ -110,8 +161,8 @@ mod swap {
#[allow(clippy::unsafe_derive_deserialize)] #[allow(clippy::unsafe_derive_deserialize)]
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct DifferentialAFLMapSwapObserver<'a, 'b> { pub struct DifferentialAFLMapSwapObserver<'a, 'b> {
first_map: OwnedSliceMut<'a, u8>, first_map: OwnedMutSlice<'a, u8>,
second_map: OwnedSliceMut<'b, u8>, second_map: OwnedMutSlice<'b, u8>,
first_name: String, first_name: String,
second_name: String, second_name: String,
name: String, name: String,
@ -129,24 +180,24 @@ mod swap {
name: format!("differential_{}_{}", first.name(), second.name()), name: format!("differential_{}_{}", first.name(), second.name()),
first_map: unsafe { first_map: unsafe {
let slice = first.map_mut().as_mut_slice(); let slice = first.map_mut().as_mut_slice();
OwnedSliceMut::from_raw_parts_mut(slice.as_mut_ptr(), slice.len()) OwnedMutSlice::from_raw_parts_mut(slice.as_mut_ptr(), slice.len())
}, },
second_map: unsafe { second_map: unsafe {
let slice = second.map_mut().as_mut_slice(); let slice = second.map_mut().as_mut_slice();
OwnedSliceMut::from_raw_parts_mut(slice.as_mut_ptr(), slice.len()) OwnedMutSlice::from_raw_parts_mut(slice.as_mut_ptr(), slice.len())
}, },
} }
} }
/// Get the first map /// Get the first map
#[must_use] #[must_use]
pub fn first_map(&self) -> &OwnedSliceMut<'a, u8> { pub fn first_map(&self) -> &OwnedMutSlice<'a, u8> {
&self.first_map &self.first_map
} }
/// Get the second map /// Get the second map
#[must_use] #[must_use]
pub fn second_map(&self) -> &OwnedSliceMut<'b, u8> { pub fn second_map(&self) -> &OwnedMutSlice<'b, u8> {
&self.second_map &self.second_map
} }
@ -182,7 +233,7 @@ mod swap {
let slice = self.first_map.as_mut_slice(); let slice = self.first_map.as_mut_slice();
unsafe { unsafe {
EDGES_MAP_PTR = slice.as_mut_ptr(); EDGES_MAP_PTR = slice.as_mut_ptr();
EDGES_MAP_PTR_SIZE = slice.len(); EDGES_MAP_PTR_NUM = slice.len();
} }
Ok(()) Ok(())
} }
@ -191,7 +242,7 @@ mod swap {
let slice = self.second_map.as_mut_slice(); let slice = self.second_map.as_mut_slice();
unsafe { unsafe {
EDGES_MAP_PTR = slice.as_mut_ptr(); EDGES_MAP_PTR = slice.as_mut_ptr();
EDGES_MAP_PTR_SIZE = slice.len(); EDGES_MAP_PTR_NUM = slice.len();
} }
Ok(()) Ok(())
} }

View File

@ -2,7 +2,7 @@
use crate::coverage::{EDGES_MAP, MAX_EDGES_NUM}; use crate::coverage::{EDGES_MAP, MAX_EDGES_NUM};
#[cfg(feature = "pointer_maps")] #[cfg(feature = "pointer_maps")]
use crate::coverage::{EDGES_MAP_PTR, EDGES_MAP_PTR_SIZE}; use crate::coverage::{EDGES_MAP_PTR, EDGES_MAP_PTR_NUM};
#[cfg(all(feature = "sancov_pcguard_edges", feature = "sancov_pcguard_hitcounts"))] #[cfg(all(feature = "sancov_pcguard_edges", feature = "sancov_pcguard_hitcounts"))]
#[cfg(not(any(doc, feature = "clippy")))] #[cfg(not(any(doc, feature = "clippy")))]
@ -54,7 +54,7 @@ pub unsafe extern "C" fn __sanitizer_cov_trace_pc_guard_init(mut start: *mut u32
#[cfg(feature = "pointer_maps")] #[cfg(feature = "pointer_maps")]
if EDGES_MAP_PTR.is_null() { if EDGES_MAP_PTR.is_null() {
EDGES_MAP_PTR = EDGES_MAP.as_mut_ptr(); EDGES_MAP_PTR = EDGES_MAP.as_mut_ptr();
EDGES_MAP_PTR_SIZE = EDGES_MAP.len(); EDGES_MAP_PTR_NUM = EDGES_MAP.len();
} }
if start == stop || *start != 0 { if start == stop || *start != 0 {
@ -67,7 +67,7 @@ pub unsafe extern "C" fn __sanitizer_cov_trace_pc_guard_init(mut start: *mut u32
#[cfg(feature = "pointer_maps")] #[cfg(feature = "pointer_maps")]
{ {
MAX_EDGES_NUM = MAX_EDGES_NUM.wrapping_add(1) % EDGES_MAP_PTR_SIZE; MAX_EDGES_NUM = MAX_EDGES_NUM.wrapping_add(1) % EDGES_MAP_PTR_NUM;
} }
#[cfg(not(feature = "pointer_maps"))] #[cfg(not(feature = "pointer_maps"))]
{ {