working on restarts

This commit is contained in:
Dominik Maier 2021-02-10 12:12:03 +01:00
parent e628bf1806
commit 13fd3776fd
4 changed files with 56 additions and 35 deletions

View File

@ -858,7 +858,13 @@ where
#[cfg(feature = "std")]
pub fn setup_restarting_state<I, C, FT, R, 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
I: Input,
C: Corpus<I, R>,
@ -908,16 +914,18 @@ where
None => {
println!("First run. Let's set it all up");
// Mgr to send and receive msgs from/to all other fuzzer instances
let client_mgr =
LlmpEventManager::<I, SH, ST>::existing_client_from_env(ENV_FUZZER_BROKER_CLIENT_INITIAL)?;
let client_mgr = LlmpEventManager::<I, SH, ST>::existing_client_from_env(
ENV_FUZZER_BROKER_CLIENT_INITIAL,
)?;
(None, LlmpRestartingEventManager::new(client_mgr, sender))
}
// Restoring from a previous run, deserialize state and corpus.
Some((_sender, _tag, msg)) => {
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))
}
};

View File

@ -80,15 +80,13 @@ where
R: Rand,
FT: FeedbacksTuple<BytesInput>,
{
pub fn load_from_directory<G, E, OT, EM>(
pub fn load_from_directory<E, OT, EM>(
&mut self,
executor: &mut E,
generator: &mut G,
manager: &mut EM,
in_dir: &Path,
) -> Result<(), AflError>
where
G: Generator<BytesInput, R>,
C: Corpus<BytesInput, R>,
E: Executor<BytesInput> + HasObservers<OT>,
OT: ObserversTuple,
@ -114,29 +112,27 @@ where
println!("File {:?} was not interesting, skipped.", &path);
}
} else if attr.is_dir() {
self.load_from_directory(executor, generator, manager, &path)?;
self.load_from_directory(executor, manager, &path)?;
}
}
Ok(())
}
pub fn load_initial_inputs<G, E, OT, EM>(
pub fn load_initial_inputs<E, OT, EM>(
&mut self,
executor: &mut E,
generator: &mut G,
manager: &mut EM,
in_dirs: &[PathBuf],
) -> Result<(), AflError>
where
G: Generator<BytesInput, R>,
C: Corpus<BytesInput, R>,
E: Executor<BytesInput> + HasObservers<OT>,
OT: ObserversTuple,
EM: EventManager<BytesInput>,
{
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(
self,

View File

@ -20,6 +20,8 @@
#include <vector>
#define HAS_BUG 1
#define PNG_INTERNAL
#include "png.h"

View File

@ -1,3 +1,6 @@
//! A libfuzzer-like fuzzer with llmp-multithreading support and restarts
//! The example harness is built for libpng.
#[macro_use]
extern crate clap;
@ -6,6 +9,7 @@ use std::{env, path::PathBuf, process::Command};
use afl::{
corpus::{Corpus, InMemoryCorpus},
events::setup_restarting_state,
events::{LlmpEventManager, SimpleStats},
executors::{inprocess::InProcessExecutor, Executor, ExitKind},
feedbacks::MaxMapFeedback,
@ -17,8 +21,7 @@ use afl::{
stages::mutational::StdMutationalStage,
state::{HasCorpus, State},
tuples::tuple_list,
utils::{ StdRand},
events::setup_restarting_state,
utils::StdRand,
AflError, Fuzzer, StdFuzzer,
};
@ -116,7 +119,7 @@ pub fn main() {
/// The actual fuzzer
fn fuzz(input: Option<Vec<PathBuf>>, broker_port: u16) -> Result<(), AflError> {
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 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()?;
}
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 =
StdMapObserver::new_from_ptr(&NAME_COV_MAP, unsafe { __lafl_edges_map }, unsafe {
__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 {
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(
"Libfuzzer",
harness,
@ -155,29 +164,35 @@ fn fuzz(input: Option<Vec<PathBuf>>, broker_port: u16) -> Result<(), AflError> {
&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
if state.corpus().count() < 1 {
match input {
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)),
None => (),
}
println!("We imported {} inputs from disk.", state.corpus().count());
}
/*
if state.corpus().count() < 1 {
println!("Generating random inputs");
let mut generator = RandPrintablesGenerator::new(32);
state
.generate_initial_inputs(&mut rand, &mut executor, &mut generator, &mut restarting_mgr, 4)
.expect("Failed to generate initial inputs");
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)
}