working on restarts
This commit is contained in:
parent
e628bf1806
commit
13fd3776fd
@ -858,7 +858,13 @@ where
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub fn setup_restarting_state<I, C, FT, R, SH, ST>(
|
pub fn setup_restarting_state<I, C, FT, R, SH, ST>(
|
||||||
mgr: &mut LlmpEventManager<I, SH, ST>,
|
mgr: &mut LlmpEventManager<I, SH, ST>,
|
||||||
) -> Result<(Option<State<C, I, R, FT>>, LlmpRestartingEventManager<I, SH, ST>), AflError>
|
) -> Result<
|
||||||
|
(
|
||||||
|
Option<State<C, I, R, FT>>,
|
||||||
|
LlmpRestartingEventManager<I, SH, ST>,
|
||||||
|
),
|
||||||
|
AflError,
|
||||||
|
>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
@ -908,15 +914,17 @@ where
|
|||||||
None => {
|
None => {
|
||||||
println!("First run. Let's set it all up");
|
println!("First run. Let's set it all up");
|
||||||
// Mgr to send and receive msgs from/to all other fuzzer instances
|
// Mgr to send and receive msgs from/to all other fuzzer instances
|
||||||
let client_mgr =
|
let client_mgr = LlmpEventManager::<I, SH, ST>::existing_client_from_env(
|
||||||
LlmpEventManager::<I, SH, ST>::existing_client_from_env(ENV_FUZZER_BROKER_CLIENT_INITIAL)?;
|
ENV_FUZZER_BROKER_CLIENT_INITIAL,
|
||||||
|
)?;
|
||||||
|
|
||||||
(None, LlmpRestartingEventManager::new(client_mgr, sender))
|
(None, LlmpRestartingEventManager::new(client_mgr, sender))
|
||||||
}
|
}
|
||||||
// Restoring from a previous run, deserialize state and corpus.
|
// Restoring from a previous run, deserialize state and corpus.
|
||||||
Some((_sender, _tag, msg)) => {
|
Some((_sender, _tag, msg)) => {
|
||||||
println!("Subsequent run. Let's load all data from shmem (received {} bytes from previous instance)", msg.len());
|
println!("Subsequent run. Let's load all data from shmem (received {} bytes from previous instance)", msg.len());
|
||||||
let (state, mgr): (State<C, I, R, FT>, LlmpEventManager<I, SH, ST>) = deserialize_state_mgr(&msg)?;
|
let (state, mgr): (State<C, I, R, FT>, LlmpEventManager<I, SH, ST>) =
|
||||||
|
deserialize_state_mgr(&msg)?;
|
||||||
|
|
||||||
(Some(state), LlmpRestartingEventManager::new(mgr, sender))
|
(Some(state), LlmpRestartingEventManager::new(mgr, sender))
|
||||||
}
|
}
|
||||||
|
@ -80,15 +80,13 @@ where
|
|||||||
R: Rand,
|
R: Rand,
|
||||||
FT: FeedbacksTuple<BytesInput>,
|
FT: FeedbacksTuple<BytesInput>,
|
||||||
{
|
{
|
||||||
pub fn load_from_directory<G, E, OT, EM>(
|
pub fn load_from_directory<E, OT, EM>(
|
||||||
&mut self,
|
&mut self,
|
||||||
executor: &mut E,
|
executor: &mut E,
|
||||||
generator: &mut G,
|
|
||||||
manager: &mut EM,
|
manager: &mut EM,
|
||||||
in_dir: &Path,
|
in_dir: &Path,
|
||||||
) -> Result<(), AflError>
|
) -> Result<(), AflError>
|
||||||
where
|
where
|
||||||
G: Generator<BytesInput, R>,
|
|
||||||
C: Corpus<BytesInput, R>,
|
C: Corpus<BytesInput, R>,
|
||||||
E: Executor<BytesInput> + HasObservers<OT>,
|
E: Executor<BytesInput> + HasObservers<OT>,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
@ -114,29 +112,27 @@ where
|
|||||||
println!("File {:?} was not interesting, skipped.", &path);
|
println!("File {:?} was not interesting, skipped.", &path);
|
||||||
}
|
}
|
||||||
} else if attr.is_dir() {
|
} else if attr.is_dir() {
|
||||||
self.load_from_directory(executor, generator, manager, &path)?;
|
self.load_from_directory(executor, manager, &path)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_initial_inputs<G, E, OT, EM>(
|
pub fn load_initial_inputs<E, OT, EM>(
|
||||||
&mut self,
|
&mut self,
|
||||||
executor: &mut E,
|
executor: &mut E,
|
||||||
generator: &mut G,
|
|
||||||
manager: &mut EM,
|
manager: &mut EM,
|
||||||
in_dirs: &[PathBuf],
|
in_dirs: &[PathBuf],
|
||||||
) -> Result<(), AflError>
|
) -> Result<(), AflError>
|
||||||
where
|
where
|
||||||
G: Generator<BytesInput, R>,
|
|
||||||
C: Corpus<BytesInput, R>,
|
C: Corpus<BytesInput, R>,
|
||||||
E: Executor<BytesInput> + HasObservers<OT>,
|
E: Executor<BytesInput> + HasObservers<OT>,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
EM: EventManager<BytesInput>,
|
EM: EventManager<BytesInput>,
|
||||||
{
|
{
|
||||||
for in_dir in in_dirs {
|
for in_dir in in_dirs {
|
||||||
self.load_from_directory(executor, generator, manager, in_dir)?;
|
self.load_from_directory(executor, manager, in_dir)?;
|
||||||
}
|
}
|
||||||
manager.fire(
|
manager.fire(
|
||||||
self,
|
self,
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#define HAS_BUG 1
|
||||||
|
|
||||||
#define PNG_INTERNAL
|
#define PNG_INTERNAL
|
||||||
#include "png.h"
|
#include "png.h"
|
||||||
|
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
//! A libfuzzer-like fuzzer with llmp-multithreading support and restarts
|
||||||
|
//! The example harness is built for libpng.
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate clap;
|
extern crate clap;
|
||||||
|
|
||||||
@ -6,6 +9,7 @@ use std::{env, path::PathBuf, process::Command};
|
|||||||
|
|
||||||
use afl::{
|
use afl::{
|
||||||
corpus::{Corpus, InMemoryCorpus},
|
corpus::{Corpus, InMemoryCorpus},
|
||||||
|
events::setup_restarting_state,
|
||||||
events::{LlmpEventManager, SimpleStats},
|
events::{LlmpEventManager, SimpleStats},
|
||||||
executors::{inprocess::InProcessExecutor, Executor, ExitKind},
|
executors::{inprocess::InProcessExecutor, Executor, ExitKind},
|
||||||
feedbacks::MaxMapFeedback,
|
feedbacks::MaxMapFeedback,
|
||||||
@ -17,8 +21,7 @@ use afl::{
|
|||||||
stages::mutational::StdMutationalStage,
|
stages::mutational::StdMutationalStage,
|
||||||
state::{HasCorpus, State},
|
state::{HasCorpus, State},
|
||||||
tuples::tuple_list,
|
tuples::tuple_list,
|
||||||
utils::{ StdRand},
|
utils::StdRand,
|
||||||
events::setup_restarting_state,
|
|
||||||
AflError, Fuzzer, StdFuzzer,
|
AflError, Fuzzer, StdFuzzer,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -116,7 +119,7 @@ pub fn main() {
|
|||||||
/// The actual fuzzer
|
/// The actual fuzzer
|
||||||
fn fuzz(input: Option<Vec<PathBuf>>, broker_port: u16) -> Result<(), AflError> {
|
fn fuzz(input: Option<Vec<PathBuf>>, broker_port: u16) -> Result<(), AflError> {
|
||||||
let mut rand = StdRand::new(0);
|
let mut rand = StdRand::new(0);
|
||||||
let mut generator = RandPrintablesGenerator::new(32);
|
/// TODO: Don't the stats need to be serialized, too?
|
||||||
let stats = SimpleStats::new(|s| println!("{}", s));
|
let stats = SimpleStats::new(|s| println!("{}", s));
|
||||||
|
|
||||||
let mut mgr = LlmpEventManager::new_on_port_std(stats, broker_port)?;
|
let mut mgr = LlmpEventManager::new_on_port_std(stats, broker_port)?;
|
||||||
@ -126,27 +129,33 @@ fn fuzz(input: Option<Vec<PathBuf>>, broker_port: u16) -> Result<(), AflError> {
|
|||||||
mgr.broker_loop()?;
|
mgr.broker_loop()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("We're a client, let's fuzz :)");
|
|
||||||
|
|
||||||
// Call LLVMFUzzerInitialize() if present.
|
|
||||||
unsafe {
|
|
||||||
if afl_libfuzzer_init() == -1 {
|
|
||||||
println!("Warning: LLVMFuzzerInitialize failed with -1")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let edges_observer =
|
let edges_observer =
|
||||||
StdMapObserver::new_from_ptr(&NAME_COV_MAP, unsafe { __lafl_edges_map }, unsafe {
|
StdMapObserver::new_from_ptr(&NAME_COV_MAP, unsafe { __lafl_edges_map }, unsafe {
|
||||||
__lafl_max_edges_size as usize
|
__lafl_max_edges_size as usize
|
||||||
});
|
});
|
||||||
|
|
||||||
let (state_opt, mut restarting_mgr) = setup_restarting_state(&mut mgr).expect("Failed to setup the restarter".into());
|
let mut mutator = HavocBytesMutator::new_default();
|
||||||
|
mutator.set_max_size(4096);
|
||||||
|
let stage = StdMutationalStage::new(mutator);
|
||||||
|
let mut fuzzer = StdFuzzer::new(tuple_list!(stage));
|
||||||
|
|
||||||
|
// 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_state(&mut mgr).expect("Failed to setup the restarter".into());
|
||||||
let mut state = match state_opt {
|
let mut state = match state_opt {
|
||||||
Some(s) => s,
|
Some(s) => s,
|
||||||
None => State::new(InMemoryCorpus::new(), tuple_list!(MaxMapFeedback::new_with_observer(&NAME_COV_MAP, &edges_observer)))
|
None => State::new(
|
||||||
|
InMemoryCorpus::new(),
|
||||||
|
tuple_list!(MaxMapFeedback::new_with_observer(
|
||||||
|
&NAME_COV_MAP,
|
||||||
|
&edges_observer
|
||||||
|
)),
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create the engine
|
println!("We're a client, let's fuzz :)");
|
||||||
|
|
||||||
|
// Create the executor
|
||||||
let mut executor = InProcessExecutor::new(
|
let mut executor = InProcessExecutor::new(
|
||||||
"Libfuzzer",
|
"Libfuzzer",
|
||||||
harness,
|
harness,
|
||||||
@ -155,29 +164,35 @@ fn fuzz(input: Option<Vec<PathBuf>>, broker_port: u16) -> Result<(), AflError> {
|
|||||||
&mut restarting_mgr,
|
&mut restarting_mgr,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// The actual target run starts here.
|
||||||
|
|
||||||
|
// Call LLVMFUzzerInitialize() if present.
|
||||||
|
unsafe {
|
||||||
|
if afl_libfuzzer_init() == -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
|
||||||
if state.corpus().count() < 1 {
|
if state.corpus().count() < 1 {
|
||||||
match input {
|
match input {
|
||||||
Some(x) => state
|
Some(x) => state
|
||||||
.load_initial_inputs(&mut executor, &mut generator, &mut restarting_mgr, &x)
|
.load_initial_inputs(&mut executor, &mut restarting_mgr, &x)
|
||||||
.expect(&format!("Failed to load initial corpus at {:?}", &x)),
|
.expect(&format!("Failed to load initial corpus at {:?}", &x)),
|
||||||
None => (),
|
None => (),
|
||||||
}
|
}
|
||||||
println!("We imported {} inputs from disk.", state.corpus().count());
|
println!("We imported {} inputs from disk.", state.corpus().count());
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
if state.corpus().count() < 1 {
|
if state.corpus().count() < 1 {
|
||||||
println!("Generating random inputs");
|
println!("Generating random inputs");
|
||||||
|
let mut generator = RandPrintablesGenerator::new(32);
|
||||||
state
|
state
|
||||||
.generate_initial_inputs(&mut rand, &mut executor, &mut generator, &mut restarting_mgr, 4)
|
.generate_initial_inputs(&mut rand, &mut executor, &mut generator, &mut restarting_mgr, 4)
|
||||||
.expect("Failed to generate initial inputs");
|
.expect("Failed to generate initial inputs");
|
||||||
println!("We generated {} inputs.", state.corpus().count());
|
println!("We generated {} inputs.", state.corpus().count());
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
let mut mutator = HavocBytesMutator::new_default();
|
|
||||||
mutator.set_max_size(4096);
|
|
||||||
|
|
||||||
let stage = StdMutationalStage::new(mutator);
|
|
||||||
let mut fuzzer = StdFuzzer::new(tuple_list!(stage));
|
|
||||||
|
|
||||||
fuzzer.fuzz_loop(&mut rand, &mut executor, &mut state, &mut restarting_mgr)
|
fuzzer.fuzz_loop(&mut rand, &mut executor, &mut state, &mut restarting_mgr)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user