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:
parent
3a1e499d9d
commit
75f12bd0eb
3
.github/workflows/build_and_test.yml
vendored
3
.github/workflows/build_and_test.yml
vendored
@ -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
|
||||||
|
@ -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,
|
||||||
));
|
));
|
||||||
```
|
```
|
||||||
|
@ -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();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -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`.
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -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,
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
pub mod libafl_cc;
|
pub mod libafl_cc;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
libafl_cc::main()
|
libafl_cc::main();
|
||||||
}
|
}
|
||||||
|
@ -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)?;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -3,5 +3,5 @@ pub mod fuzzer;
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
fuzzer::main()
|
fuzzer::main();
|
||||||
}
|
}
|
||||||
|
@ -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");
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
pub mod libafl_cc;
|
pub mod libafl_cc;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
libafl_cc::main()
|
libafl_cc::main();
|
||||||
}
|
}
|
||||||
|
@ -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!(
|
||||||
|
@ -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();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
pub mod libafl_cc;
|
pub mod libafl_cc;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
libafl_cc::main()
|
libafl_cc::main();
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
pub mod libafl_cc;
|
pub mod libafl_cc;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
libafl_cc::main()
|
libafl_cc::main();
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
pub mod libafl_cc;
|
pub mod libafl_cc;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
libafl_cc::main()
|
libafl_cc::main();
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
pub mod libafl_cc;
|
pub mod libafl_cc;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
libafl_cc::main()
|
libafl_cc::main();
|
||||||
}
|
}
|
||||||
|
@ -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");
|
||||||
|
@ -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();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
pub mod libafl_cc;
|
pub mod libafl_cc;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
libafl_cc::main()
|
libafl_cc::main();
|
||||||
}
|
}
|
||||||
|
@ -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");
|
||||||
|
@ -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();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
pub mod libafl_cc;
|
pub mod libafl_cc;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
libafl_cc::main()
|
libafl_cc::main();
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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]
|
||||||
|
@ -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
|
||||||
|
@ -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");
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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 \
|
||||||
|
@ -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()
|
||||||
|
@ -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()
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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());
|
||||||
|
@ -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();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
pub mod libafl_cc;
|
pub mod libafl_cc;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
libafl_cc::main()
|
libafl_cc::main();
|
||||||
}
|
}
|
||||||
|
@ -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}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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");
|
||||||
|
@ -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"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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::*;
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
// ====================
|
// ====================
|
||||||
|
|
||||||
|
@ -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());
|
||||||
|
@ -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) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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>) =
|
||||||
|
@ -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"),
|
||||||
)),
|
)),
|
||||||
|
@ -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),
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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};
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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(),
|
||||||
))
|
))
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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(())
|
||||||
}
|
}
|
||||||
|
@ -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"))]
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user