libfuzzer_dummy
This commit is contained in:
parent
98601d6c02
commit
bc49d94616
1
fuzzers/libfuzzer_dummy/.gitignore
vendored
Normal file
1
fuzzers/libfuzzer_dummy/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
libpng-*
|
35
fuzzers/libfuzzer_dummy/Cargo.toml
Normal file
35
fuzzers/libfuzzer_dummy/Cargo.toml
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
[package]
|
||||||
|
name = "libfuzzer_dummy"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Andrea Fioraldi <andreafioraldi@gmail.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[workspace]
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["std"]
|
||||||
|
std = []
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
lto = true
|
||||||
|
codegen-units = 1
|
||||||
|
opt-level = 3
|
||||||
|
debug = true
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
cc = { version = "1.0", features = ["parallel"] }
|
||||||
|
num_cpus = "1.0"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
clap = "2.32.0"
|
||||||
|
serde = { version = "1.0", default-features = false, features = ["alloc"] }
|
||||||
|
postcard = { version = "0.5.1", features = ["alloc"] }
|
||||||
|
afl = { path = "../../afl/" }
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "libfuzzer"
|
||||||
|
path = "./src/mod.rs"
|
||||||
|
test = false
|
||||||
|
bench = false
|
1
fuzzers/libfuzzer_dummy/corpus/test
Normal file
1
fuzzers/libfuzzer_dummy/corpus/test
Normal file
@ -0,0 +1 @@
|
|||||||
|
0000
|
110
fuzzers/libfuzzer_dummy/src/mod.rs
Normal file
110
fuzzers/libfuzzer_dummy/src/mod.rs
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
//! A libfuzzer-like fuzzer with llmp-multithreading support and restarts
|
||||||
|
//! The example harness is built for libpng.
|
||||||
|
|
||||||
|
use std::{path::PathBuf};
|
||||||
|
|
||||||
|
use afl::{
|
||||||
|
bolts::{tuples::tuple_list, shmem::AflShmem},
|
||||||
|
corpus::{Corpus, InMemoryCorpus},
|
||||||
|
events::setup_restarting_mgr,
|
||||||
|
events::{SimpleStats},
|
||||||
|
executors::{inprocess::InProcessExecutor, Executor, ExitKind},
|
||||||
|
feedbacks::MaxMapFeedback,
|
||||||
|
inputs::Input,
|
||||||
|
mutators::{scheduled::HavocBytesMutator, HasMaxSize},
|
||||||
|
observers::StdMapObserver,
|
||||||
|
stages::mutational::StdMutationalStage,
|
||||||
|
state::{HasCorpus, State},
|
||||||
|
utils::StdRand,
|
||||||
|
AflError, Fuzzer, StdFuzzer,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// The name of the coverage map observer, to find it again in the observer list
|
||||||
|
const NAME_COV_MAP: &str = "cov_map";
|
||||||
|
|
||||||
|
static mut __lafl_edges_map: [u8; 32] = [0; 32];
|
||||||
|
static __lafl_max_edges_size: u32 = 32;
|
||||||
|
|
||||||
|
/// The wrapped harness function, calling out to the llvm-style libfuzzer harness
|
||||||
|
fn harness<E, I>(_executor: &E, buf: &[u8]) -> ExitKind
|
||||||
|
where
|
||||||
|
E: Executor<I>,
|
||||||
|
I: Input,
|
||||||
|
{
|
||||||
|
println!("{:?}", buf);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
__lafl_edges_map[0] = 1;
|
||||||
|
if buf.len() > 0 && buf[0] == 'a' as u8 {
|
||||||
|
__lafl_edges_map[2] = 1;
|
||||||
|
if buf.len() > 1 && buf[1] == 'b' as u8 {
|
||||||
|
__lafl_edges_map[3] = 1;
|
||||||
|
std::process::abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ExitKind::Ok
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The main fn, parsing parameters, and starting the fuzzer
|
||||||
|
pub fn main() {
|
||||||
|
fuzz(Some(vec![PathBuf::from("./corpus")]), 1337).expect("An error occurred while fuzzing");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The actual fuzzer
|
||||||
|
fn fuzz(input: Option<Vec<PathBuf>>, broker_port: u16) -> Result<(), AflError> {
|
||||||
|
let mut rand = StdRand::new(0);
|
||||||
|
// 'While the stats are state, they are usually used in the broker - which is likely never restarted
|
||||||
|
let stats = SimpleStats::new(|s| println!("{}", s));
|
||||||
|
|
||||||
|
// The restarting state will spawn the same process again as child, then restartet it each time it crashes.
|
||||||
|
let (state_opt, mut restarting_mgr) =
|
||||||
|
setup_restarting_mgr::<_, _, _, _, AflShmem, _>(stats, broker_port).expect("Failed to setup the restarter".into());
|
||||||
|
|
||||||
|
let edges_observer =
|
||||||
|
StdMapObserver::new_from_ptr(&NAME_COV_MAP, unsafe { &mut __lafl_edges_map[0] as *mut u8 }, __lafl_max_edges_size as usize);
|
||||||
|
|
||||||
|
let mut state = match state_opt {
|
||||||
|
Some(s) => s,
|
||||||
|
None => {
|
||||||
|
State::new(
|
||||||
|
InMemoryCorpus::new(),
|
||||||
|
tuple_list!(MaxMapFeedback::new_with_observer(
|
||||||
|
&NAME_COV_MAP,
|
||||||
|
&edges_observer
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
println!("We're a client, let's fuzz :)");
|
||||||
|
|
||||||
|
let mut mutator = HavocBytesMutator::new_default();
|
||||||
|
mutator.set_max_size(4096);
|
||||||
|
let stage = StdMutationalStage::new(mutator);
|
||||||
|
let mut fuzzer = StdFuzzer::new(tuple_list!(stage));
|
||||||
|
|
||||||
|
// Create the executor
|
||||||
|
let mut executor = InProcessExecutor::new(
|
||||||
|
"Libfuzzer",
|
||||||
|
harness,
|
||||||
|
tuple_list!(edges_observer),
|
||||||
|
&mut state,
|
||||||
|
&mut restarting_mgr,
|
||||||
|
);
|
||||||
|
|
||||||
|
// The actual target run starts here.
|
||||||
|
|
||||||
|
// in case the corpus is empty (on first run), reset
|
||||||
|
if state.corpus().count() < 1 {
|
||||||
|
match input {
|
||||||
|
Some(x) => state
|
||||||
|
.load_initial_inputs(&mut executor, &mut restarting_mgr, &x)
|
||||||
|
.expect(&format!("Failed to load initial corpus at {:?}", &x)),
|
||||||
|
None => (),
|
||||||
|
}
|
||||||
|
println!("We imported {} inputs from disk.", state.corpus().count());
|
||||||
|
}
|
||||||
|
|
||||||
|
fuzzer.fuzz_loop(&mut rand, &mut executor, &mut state, &mut restarting_mgr)
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user