still not working

This commit is contained in:
Andrea Fioraldi 2021-02-09 11:45:57 +01:00
parent 9ec8f1238f
commit e628bf1806

View File

@ -11,23 +11,17 @@ use afl::{
feedbacks::MaxMapFeedback, feedbacks::MaxMapFeedback,
generators::RandPrintablesGenerator, generators::RandPrintablesGenerator,
inputs::{BytesInput, Input}, inputs::{BytesInput, Input},
llmp::{LlmpReceiver, LlmpSender},
mutators::{scheduled::HavocBytesMutator, HasMaxSize}, mutators::{scheduled::HavocBytesMutator, HasMaxSize},
observers::StdMapObserver, observers::StdMapObserver,
shmem::{AflShmem, ShMem}, shmem::{AflShmem, ShMem},
stages::mutational::StdMutationalStage, stages::mutational::StdMutationalStage,
state::{HasCorpus, State}, state::{HasCorpus, State},
tuples::tuple_list, tuples::tuple_list,
utils::{deserialize_state_corpus_mgr, StdRand}, utils::{ StdRand},
events::setup_restarting_state,
AflError, Fuzzer, StdFuzzer, AflError, Fuzzer, StdFuzzer,
}; };
/// The llmp connection from the actual fuzzer to the process supervising it
const ENV_FUZZER_SENDER: &str = &"_AFL_ENV_FUZZER_SENDER";
const ENV_FUZZER_RECEIVER: &str = &"_AFL_ENV_FUZZER_RECEIVER";
/// The llmp (2 way) connection from a fuzzer to the broker (broadcasting all other fuzzer messages)
const ENV_FUZZER_BROKER_CLIENT_INITIAL: &str = &"_AFL_ENV_FUZZER_BROKER_CLIENT";
/// The name of the coverage map observer, to find it again in the observer list /// The name of the coverage map observer, to find it again in the observer list
const NAME_COV_MAP: &str = "cov_map"; const NAME_COV_MAP: &str = "cov_map";
@ -124,59 +118,16 @@ 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); let mut generator = RandPrintablesGenerator::new(32);
let stats = SimpleStats::new(|s| println!("{}", s)); let stats = SimpleStats::new(|s| println!("{}", s));
let mut mgr;
// We start ourself as child process to actually fuzz let mut mgr = LlmpEventManager::new_on_port_std(stats, broker_port)?;
if std::env::var(ENV_FUZZER_SENDER).is_err() {
// We are either the broker, or the parent of the fuzzing instance
mgr = LlmpEventManager::new_on_port_std(broker_port, stats.clone())?;
if mgr.is_broker() { if mgr.is_broker() {
// Yep, broker. Just loop here. // Yep, broker. Just loop here.
println!("Doing broker things. Run this tool again to start fuzzing in a client."); println!("Doing broker things. Run this tool again to start fuzzing in a client.");
mgr.broker_loop()?; mgr.broker_loop()?;
} else {
// we are one of the fuzzing instances. Let's launch the fuzzer.
// First, store the mgr to an env so the client can use it
mgr.to_env(ENV_FUZZER_BROKER_CLIENT_INITIAL);
// First, create a channel from the fuzzer (sender) to us (receiver) to report its state for restarts.
let sender = LlmpSender::new(0, false)?;
let receiver = LlmpReceiver::on_existing_map(
AflShmem::clone_ref(&sender.out_maps.last().unwrap().shmem)?,
None,
)?;
// Store the information to a map.
sender.to_env(ENV_FUZZER_SENDER)?;
receiver.to_env(ENV_FUZZER_RECEIVER)?;
let mut ctr = 0;
loop {
dbg!("Spawning next client");
Command::new(env::current_exe()?)
.current_dir(env::current_dir()?)
.args(env::args())
.status()?;
ctr += 1;
if ctr == 10 {
return Ok(());
}
}
}
} }
println!("We're a client, let's fuzz :)"); println!("We're a client, let's fuzz :)");
// We are the fuzzing instance, first, connect to our own restore map.
// A sender and a receiver for single communication
let mut receiver = LlmpReceiver::<AflShmem>::on_existing_from_env(ENV_FUZZER_RECEIVER)?;
let mut sender = LlmpSender::<AflShmem>::on_existing_from_env(ENV_FUZZER_SENDER)?;
let edges_observer =
StdMapObserver::new_from_ptr(&NAME_COV_MAP, unsafe { __lafl_edges_map }, unsafe {
__lafl_max_edges_size as usize
});
// Call LLVMFUzzerInitialize() if present. // Call LLVMFUzzerInitialize() if present.
unsafe { unsafe {
if afl_libfuzzer_init() == -1 { if afl_libfuzzer_init() == -1 {
@ -184,49 +135,16 @@ fn fuzz(input: Option<Vec<PathBuf>>, broker_port: u16) -> Result<(), AflError> {
} }
} }
// If we're restarting, deserialize the old state. let edges_observer =
let (mut state, mut mgr) = match receiver.recv_buf()? { StdMapObserver::new_from_ptr(&NAME_COV_MAP, unsafe { __lafl_edges_map }, unsafe {
None => { __lafl_max_edges_size as usize
println!("First run. Let's set it all up"); });
// Mgr to send and receive msgs from/to all other fuzzer instances
mgr = LlmpEventManager::<BytesInput, _, _>::existing_client_from_env_std(
ENV_FUZZER_BROKER_CLIENT_INITIAL,
stats,
)?;
// Initial execution, read or generate initial state, corpus, and feedbacks let (state_opt, mut restarting_mgr) = setup_restarting_state(&mut mgr).expect("Failed to setup the restarter".into());
let edges_feedback = MaxMapFeedback::new_with_observer(&NAME_COV_MAP, &edges_observer); let mut state = match state_opt {
let corpus = InMemoryCorpus::new(); Some(s) => s,
let state = State::new(corpus, tuple_list!(edges_feedback)); None => State::new(InMemoryCorpus::new(), tuple_list!(MaxMapFeedback::new_with_observer(&NAME_COV_MAP, &edges_observer)))
(state, mgr)
}
// 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());
deserialize_state_corpus_mgr(&msg, stats)?
}
}; };
// We reset the sender, the next sender and receiver (after crash) will reuse the page from the initial message.
unsafe { sender.reset_last_page() };
/*
move |exit_kind, input, state, corpus, mgr| {
match exit_kind {
ExitKind::Timeout => mgr.timeout(input).expect(&format!(
"Error sending Timeout event for input {:?}",
input
)),
ExitKind::Crash => mgr
.crash(input)
.expect(&format!("Error sending crash event for input {:?}", input)),
_ => (),
}
println!("foo");
let state_corpus_serialized = serialize_state_corpus_mgr(state, corpus, mgr).unwrap();
println!("bar: {:?}", &state_corpus_serialized);
sender.send_buf(0x1, &state_corpus_serialized).unwrap();
}
*/
// Create the engine // Create the engine
let mut executor = InProcessExecutor::new( let mut executor = InProcessExecutor::new(
@ -234,14 +152,14 @@ fn fuzz(input: Option<Vec<PathBuf>>, broker_port: u16) -> Result<(), AflError> {
harness, harness,
tuple_list!(edges_observer), tuple_list!(edges_observer),
&mut state, &mut state,
&mut mgr, &mut restarting_mgr,
); );
// 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 mgr, &x) .load_initial_inputs(&mut executor, &mut generator, &mut restarting_mgr, &x)
.expect(&format!("Failed to load initial corpus at {:?}", &x)), .expect(&format!("Failed to load initial corpus at {:?}", &x)),
None => (), None => (),
} }
@ -250,7 +168,7 @@ fn fuzz(input: Option<Vec<PathBuf>>, broker_port: u16) -> Result<(), AflError> {
if state.corpus().count() < 1 { if state.corpus().count() < 1 {
println!("Generating random inputs"); println!("Generating random inputs");
state state
.generate_initial_inputs(&mut rand, &mut executor, &mut generator, &mut 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());
} }
@ -261,5 +179,5 @@ fn fuzz(input: Option<Vec<PathBuf>>, broker_port: u16) -> Result<(), AflError> {
let stage = StdMutationalStage::new(mutator); let stage = StdMutationalStage::new(mutator);
let mut fuzzer = StdFuzzer::new(tuple_list!(stage)); let mut fuzzer = StdFuzzer::new(tuple_list!(stage));
fuzzer.fuzz_loop(&mut rand, &mut executor, &mut state, &mut mgr) fuzzer.fuzz_loop(&mut rand, &mut executor, &mut state, &mut restarting_mgr)
} }