forked from AFLplusplus/LibAFL
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Clean up documentation on the baby fuzzer
Since the baby fuzzer chapter of the documentation is done in a "tutorial", step-by-step fashion, it would be nice to be able to see where exactly new lines have to be placed in the existing code. To that end, the code used in the tutorial is moved to snippets (as is done in the Rust Book), as it allows for much more convenient maintenance of the snippets, as well as easy hiding of the non-important code on any given snippet. Furthermore, a few minor fixes are applied; a typo on a comment and a missing unsafe block.
- Loading branch information
Showing
14 changed files
with
510 additions
and
214 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
book | ||
!listings/**/* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
[package] | ||
name = "baby_fuzzer" | ||
version = "0.1.0" | ||
authors = ["Your Name <[email protected]>"] | ||
edition = "2018" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
fn main() { | ||
println!("Hello, world!"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
[package] | ||
name = "baby_fuzzer" | ||
version = "0.1.0" | ||
authors = ["Your Name <[email protected]>"] | ||
edition = "2018" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
libafl = { path = "path/to/libafl/" } | ||
|
||
[profile.dev] | ||
panic = "abort" | ||
|
||
[profile.release] | ||
panic = "abort" | ||
lto = true | ||
codegen-units = 1 | ||
opt-level = 3 | ||
debug = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
fn main() { | ||
println!("Hello, world!"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
[package] | ||
name = "baby_fuzzer" | ||
version = "0.1.0" | ||
authors = ["Your Name <[email protected]>"] | ||
edition = "2018" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
libafl = { path = "path/to/libafl/" } | ||
|
||
[profile.dev] | ||
panic = "abort" | ||
|
||
[profile.release] | ||
panic = "abort" | ||
lto = true | ||
codegen-units = 1 | ||
opt-level = 3 | ||
debug = true | ||
|
||
[features] | ||
panic = [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
extern crate libafl; | ||
use libafl::{ | ||
bolts::AsSlice, | ||
executors::ExitKind, | ||
inputs::{BytesInput, HasTargetBytes}, | ||
}; | ||
|
||
fn main() { | ||
let mut harness = |input: &BytesInput| { | ||
let target = input.target_bytes(); | ||
let buf = target.as_slice(); | ||
if buf.len() > 0 && buf[0] == 'a' as u8 { | ||
if buf.len() > 1 && buf[1] == 'b' as u8 { | ||
if buf.len() > 2 && buf[2] == 'c' as u8 { | ||
panic!("=)"); | ||
} | ||
} | ||
} | ||
ExitKind::Ok | ||
}; | ||
// To test the panic: | ||
let input = BytesInput::new(Vec::from("abc")); | ||
#[cfg(feature = "panic")] | ||
harness(&input); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
[package] | ||
name = "baby_fuzzer" | ||
version = "0.1.0" | ||
authors = ["Your Name <[email protected]>"] | ||
edition = "2018" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
libafl = { path = "path/to/libafl/" } | ||
|
||
[profile.dev] | ||
panic = "abort" | ||
|
||
[profile.release] | ||
panic = "abort" | ||
lto = true | ||
codegen-units = 1 | ||
opt-level = 3 | ||
debug = true | ||
|
||
[features] | ||
panic = [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
/* ANCHOR: use */ | ||
extern crate libafl; | ||
|
||
use libafl::{ | ||
bolts::{current_nanos, rands::StdRand, AsSlice}, | ||
corpus::{InMemoryCorpus, OnDiskCorpus}, | ||
events::SimpleEventManager, | ||
executors::{inprocess::InProcessExecutor, ExitKind}, | ||
fuzzer::StdFuzzer, | ||
generators::RandPrintablesGenerator, | ||
inputs::{BytesInput, HasTargetBytes}, | ||
monitors::SimpleMonitor, | ||
schedulers::QueueScheduler, | ||
state::StdState, | ||
}; | ||
use std::path::PathBuf; | ||
/* ANCHOR_END: use */ | ||
|
||
fn main() { | ||
let mut harness = |input: &BytesInput| { | ||
let target = input.target_bytes(); | ||
let buf = target.as_slice(); | ||
if buf.len() > 0 && buf[0] == 'a' as u8 { | ||
if buf.len() > 1 && buf[1] == 'b' as u8 { | ||
if buf.len() > 2 && buf[2] == 'c' as u8 { | ||
panic!("=)"); | ||
} | ||
} | ||
} | ||
ExitKind::Ok | ||
}; | ||
// To test the panic: | ||
let input = BytesInput::new(Vec::from("abc")); | ||
#[cfg(feature = "panic")] | ||
harness(&input); | ||
|
||
/* ANCHOR: state */ | ||
// create a State from scratch | ||
let mut state = StdState::new( | ||
// RNG | ||
StdRand::with_seed(current_nanos()), | ||
// Corpus that will be evolved, we keep it in memory for performance | ||
InMemoryCorpus::new(), | ||
// Corpus in which we store solutions (crashes in this example), | ||
// on disk so the user can get them after stopping the fuzzer | ||
OnDiskCorpus::new(PathBuf::from("./crashes")).unwrap(), | ||
&mut (), | ||
&mut (), | ||
) | ||
.unwrap(); | ||
/* ANCHOR_END: state */ | ||
|
||
/* ANCHOR: event_manager */ | ||
// The Monitor trait defines how the fuzzer stats are displayed to the user | ||
let mon = SimpleMonitor::new(|s| println!("{s}")); | ||
|
||
// The event manager handles the various events generated during the fuzzing loop | ||
// such as the notification of the addition of a new item to the corpus | ||
let mut mgr = SimpleEventManager::new(mon); | ||
/* ANCHOR_END: event_manager */ | ||
|
||
/* ANCHOR: scheduler_fuzzer */ | ||
// A queue policy to get testcasess from the corpus | ||
let scheduler = QueueScheduler::new(); | ||
|
||
// A fuzzer with feedbacks and a corpus scheduler | ||
let mut fuzzer = StdFuzzer::new(scheduler, (), ()); | ||
/* ANCHOR_END: scheduler_fuzzer */ | ||
|
||
/* ANCHOR: executor */ | ||
// Create the executor for an in-process function | ||
let mut executor = InProcessExecutor::new(&mut harness, (), &mut fuzzer, &mut state, &mut mgr) | ||
.expect("Failed to create the Executor"); | ||
/* ANCHOR_END: executor */ | ||
|
||
/* ANCHOR: generator */ | ||
// Generator of printable bytearrays of max size 32 | ||
let mut generator = RandPrintablesGenerator::new(32); | ||
|
||
// Generate 8 initial inputs | ||
state | ||
.generate_initial_inputs(&mut fuzzer, &mut executor, &mut generator, &mut mgr, 8) | ||
.expect("Failed to generate the initial corpus"); | ||
/* ANCHOR_END: generator */ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
[package] | ||
name = "baby_fuzzer" | ||
version = "0.1.0" | ||
authors = ["Your Name <[email protected]>"] | ||
edition = "2018" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
libafl = { path = "path/to/libafl/" } | ||
|
||
[profile.dev] | ||
panic = "abort" | ||
|
||
[profile.release] | ||
panic = "abort" | ||
lto = true | ||
codegen-units = 1 | ||
opt-level = 3 | ||
debug = true | ||
|
||
[features] | ||
panic = [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
/* ANCHOR: use */ | ||
extern crate libafl; | ||
|
||
use libafl::{ | ||
bolts::{current_nanos, rands::StdRand, tuples::tuple_list, AsSlice}, | ||
corpus::{InMemoryCorpus, OnDiskCorpus}, | ||
events::SimpleEventManager, | ||
executors::{inprocess::InProcessExecutor, ExitKind}, | ||
feedbacks::{CrashFeedback, MaxMapFeedback}, | ||
fuzzer::StdFuzzer, | ||
generators::RandPrintablesGenerator, | ||
inputs::{BytesInput, HasTargetBytes}, | ||
monitors::SimpleMonitor, | ||
observers::StdMapObserver, | ||
schedulers::QueueScheduler, | ||
state::StdState, | ||
}; | ||
use std::path::PathBuf; | ||
/* ANCHOR_END: use */ | ||
|
||
/* ANCHOR: signals */ | ||
// Coverage map with explicit assignments due to the lack of instrumentation | ||
static mut SIGNALS: [u8; 16] = [0; 16]; | ||
|
||
fn signals_set(idx: usize) { | ||
unsafe { SIGNALS[idx] = 1 }; | ||
} | ||
|
||
fn main() { | ||
// The closure that we want to fuzz | ||
let mut harness = |input: &BytesInput| { | ||
let target = input.target_bytes(); | ||
let buf = target.as_slice(); | ||
signals_set(0); // set SIGNALS[0] | ||
if buf.len() > 0 && buf[0] == 'a' as u8 { | ||
signals_set(1); // set SIGNALS[1] | ||
if buf.len() > 1 && buf[1] == 'b' as u8 { | ||
signals_set(2); // set SIGNALS[2] | ||
if buf.len() > 2 && buf[2] == 'c' as u8 { | ||
panic!("=)"); | ||
} | ||
} | ||
} | ||
ExitKind::Ok | ||
}; | ||
/* ANCHOR_END: signals */ | ||
// To test the panic: | ||
let input = BytesInput::new(Vec::from("abc")); | ||
#[cfg(feature = "panic")] | ||
harness(&input); | ||
|
||
/* ANCHOR: observer */ | ||
// Create an observation channel using the signals map | ||
let observer = unsafe { StdMapObserver::new("signals", unsafe { &mut SIGNALS }) }; | ||
/* ANCHOR_END: observer */ | ||
|
||
/* ANCHOR: state_with_feedback_and_objective */ | ||
// Feedback to rate the interestingness of an input | ||
let mut feedback = MaxMapFeedback::new(&observer); | ||
|
||
// A feedback to choose if an input is a solution or not | ||
let mut objective = CrashFeedback::new(); | ||
|
||
// create a State from scratch | ||
let mut state = StdState::new( | ||
// RNG | ||
StdRand::with_seed(current_nanos()), | ||
// Corpus that will be evolved, we keep it in memory for performance | ||
InMemoryCorpus::new(), | ||
// Corpus in which we store solutions (crashes in this example), | ||
// on disk so the user can get them after stopping the fuzzer | ||
OnDiskCorpus::new(PathBuf::from("./crashes")).unwrap(), | ||
&mut feedback, | ||
&mut objective, | ||
) | ||
.unwrap(); | ||
/* ANCHOR_END: state_with_feedback_and_objective */ | ||
|
||
// The Monitor trait defines how the fuzzer stats are displayed to the user | ||
let mon = SimpleMonitor::new(|s| println!("{s}")); | ||
|
||
// The event manager handles the various events generated during the fuzzing loop | ||
// such as the notification of the addition of a new item to the corpus | ||
let mut mgr = SimpleEventManager::new(mon); | ||
|
||
// A queue policy to get testcasess from the corpus | ||
let scheduler = QueueScheduler::new(); | ||
/* ANCHOR: state_with_feedback_and_objective */ | ||
|
||
// A fuzzer with feedbacks and a corpus scheduler | ||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); | ||
/* ANCHOR_END: state_with_feedback_and_objective */ | ||
|
||
/* ANCHOR: executor_with_observer */ | ||
// Create the executor for an in-process function with just one observer | ||
let mut executor = InProcessExecutor::new( | ||
&mut harness, | ||
tuple_list!(observer), | ||
&mut fuzzer, | ||
&mut state, | ||
&mut mgr, | ||
) | ||
.expect("Failed to create the Executor"); | ||
/* ANCHOR_END: executor_with_observer */ | ||
|
||
// Generator of printable bytearrays of max size 32 | ||
let mut generator = RandPrintablesGenerator::new(32); | ||
|
||
// Generate 8 initial inputs | ||
state | ||
.generate_initial_inputs(&mut fuzzer, &mut executor, &mut generator, &mut mgr, 8) | ||
.expect("Failed to generate the initial corpus"); | ||
/* ANCHOR: signals */ | ||
} | ||
/* ANCHOR_END: signals */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
[package] | ||
name = "baby_fuzzer" | ||
version = "0.1.0" | ||
authors = ["Your Name <[email protected]>"] | ||
edition = "2018" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
libafl = { path = "path/to/libafl/" } | ||
|
||
[profile.dev] | ||
panic = "abort" | ||
|
||
[profile.release] | ||
panic = "abort" | ||
lto = true | ||
codegen-units = 1 | ||
opt-level = 3 | ||
debug = true | ||
|
||
[features] | ||
panic = [] |
Oops, something went wrong.