small improvements
This commit is contained in:
parent
b3b8e81190
commit
9a1251875f
@ -1,5 +1,6 @@
|
||||
//! A singlethreaded QEMU fuzzer that can auto-restart.
|
||||
|
||||
use libafl_qemu::QemuClockObserver;
|
||||
use libafl::feedbacks::Feedback;
|
||||
use crate::worst::HitImprovingFeedback;
|
||||
use crate::worst::HitFeedback;
|
||||
@ -152,7 +153,7 @@ pub fn main() {
|
||||
}
|
||||
}
|
||||
let mut crashes = out_dir.clone();
|
||||
crashes.push("crashes");
|
||||
crashes.push("wcets");
|
||||
out_dir.push("queue");
|
||||
|
||||
let in_dir = PathBuf::from(res.value_of("in").unwrap().to_string());
|
||||
@ -292,6 +293,7 @@ fn fuzz(
|
||||
|
||||
// Create an observation channel to keep track of the execution time
|
||||
let time_observer = TimeObserver::new("time");
|
||||
let clock_observer = QemuClockObserver::default();
|
||||
|
||||
// Create an observation channel using cmplog map
|
||||
let cmplog_observer = CmpLogObserver::new("cmplog", unsafe { &mut cmplog::CMPLOG_MAP }, true);
|
||||
@ -387,7 +389,7 @@ fn fuzz(
|
||||
//QemuAsanHelper::new(),
|
||||
QemuSysSnapshotHelper::new()
|
||||
),
|
||||
tuple_list!(edges_observer, time_observer),
|
||||
tuple_list!(edges_observer, time_observer, clock_observer),
|
||||
&mut fuzzer,
|
||||
&mut state,
|
||||
&mut mgr,
|
||||
|
@ -1,3 +1,4 @@
|
||||
#![feature(iter_advance_by)]
|
||||
#[cfg(target_os = "linux")]
|
||||
pub mod fuzzer;
|
||||
pub mod showmap;
|
||||
|
@ -1,5 +1,12 @@
|
||||
//! A singlethreaded QEMU fuzzer that can auto-restart.
|
||||
|
||||
use crate::worst::DumpMapFeedback;
|
||||
use crate::worst::DummyFeedback;
|
||||
use libafl::corpus::Corpus;
|
||||
use libafl::state::HasCorpus;
|
||||
use libafl::Fuzzer;
|
||||
use libafl::mutators::BitFlipMutator;
|
||||
use libafl::stages::StdMutationalStage;
|
||||
use libafl_qemu::QemuInstrumentationFilter;
|
||||
use crate::system_trace::QemuSystemStateHelper;
|
||||
use libafl::feedbacks::CrashFeedback;
|
||||
@ -258,7 +265,7 @@ fn fuzz(
|
||||
let feedback = DumpMapFeedback::with_dump(dump_edges);
|
||||
|
||||
// A feedback to choose if an input is a solution or not
|
||||
let objective = QemuClockIncreaseFeedback::new();
|
||||
let objective = DummyFeedback::new(false);
|
||||
|
||||
// create a State from scratch
|
||||
let mut state = StdState::new(
|
||||
@ -330,67 +337,28 @@ fn fuzz(
|
||||
true => seed_dir.clone().read_dir().expect("Directory not a directory?").next().expect("Directory empty?").expect("File not in directory?").path(),
|
||||
false => seed_dir.clone()
|
||||
};
|
||||
// let secondinput = match seed_dir.clone().is_dir() {
|
||||
// true => {
|
||||
// let mut a = seed_dir.clone().read_dir().expect("Directory not a directory?");
|
||||
// a.advance_by(1);
|
||||
// a.next().unwrap().expect("File not in directory?").path()
|
||||
// },
|
||||
// false => seed_dir.clone()
|
||||
// };
|
||||
fuzzer.evaluate_input(&mut state, &mut executor, &mut mgr, Input::from_file(&firstinput).expect("Could not load file")).expect("Evaluation failed");
|
||||
// fuzzer.evaluate_input(&mut state, &mut executor, &mut mgr, Input::from_file(&secondinput).expect("Could not load file")).expect("Evaluation failed");
|
||||
// println!("Nach Eval");
|
||||
// if state.corpus().count() < 1 {
|
||||
// state
|
||||
// .load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &[seed_dir.clone()])
|
||||
// .unwrap_or_else(|_| {
|
||||
// println!("Failed to load initial corpus at {:?}", &seed_dir);
|
||||
// return;
|
||||
// });
|
||||
// println!("We imported {} inputs from disk.", state.corpus().count());
|
||||
// }
|
||||
// fuzzer
|
||||
// .fuzz_one(&mut tuple_list!(StdMutationalStage::new(BitFlipMutator::new())), &mut executor, &mut state, &mut mgr)
|
||||
// .expect("Error in the fuzzing loop");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
//=========================== Debugging Feedback
|
||||
/// A [`Feedback`] meant to dump the edgemap for debugging.
|
||||
#[derive(Debug)]
|
||||
pub struct DumpMapFeedback {
|
||||
dumpfile: Option<PathBuf>
|
||||
}
|
||||
|
||||
impl<I, S> Feedback<I, S> for DumpMapFeedback
|
||||
where
|
||||
I: Input,
|
||||
S: HasClientPerfMonitor,
|
||||
{
|
||||
fn is_interesting<EM, OT>(
|
||||
&mut self,
|
||||
_state: &mut S,
|
||||
_manager: &mut EM,
|
||||
_input: &I,
|
||||
_observers: &OT,
|
||||
_exit_kind: &ExitKind,
|
||||
) -> Result<bool, Error>
|
||||
where
|
||||
EM: EventFirer<I>,
|
||||
OT: ObserversTuple<I, S>,
|
||||
{
|
||||
let observer = _observers.match_name::<HitcountsMapObserver<VariableMapObserver<u8>>>("edges")
|
||||
.expect("HitcountsMapObserver not found");
|
||||
match &self.dumpfile {
|
||||
Some(s) => {
|
||||
fs::write(s,ron::to_string(&observer.edgemap).expect("Error serializing hashmap")).expect("Can not dump to file");
|
||||
self.dumpfile = None
|
||||
},
|
||||
None => println!("{:#?}",observer.edgemap),
|
||||
};
|
||||
Ok(true)
|
||||
}
|
||||
}
|
||||
|
||||
impl Named for DumpMapFeedback {
|
||||
#[inline]
|
||||
fn name(&self) -> &str {
|
||||
"HitFeedback"
|
||||
}
|
||||
}
|
||||
|
||||
impl DumpMapFeedback {
|
||||
/// Creates a new [`HitFeedback`]
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
Self {dumpfile: None}
|
||||
}
|
||||
pub fn with_dump(dumpfile: Option<PathBuf>) -> Self {
|
||||
Self {dumpfile: dumpfile}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for DumpMapFeedback {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
use std::path::PathBuf;
|
||||
use std::fs;
|
||||
use libafl::observers::VariableMapObserver;
|
||||
use hashbrown::{HashMap};
|
||||
use libafl::observers::ObserversTuple;
|
||||
@ -182,7 +184,8 @@ where
|
||||
}
|
||||
}
|
||||
let mean_sum_of_squares = (sum_of_square_difference as f64) / (self.target_map.len() as f64);
|
||||
let hit_target = mean_sum_of_squares <= 1.0;
|
||||
let hit_target = mean_sum_of_squares <= self.target_msd;
|
||||
eprintln!("hit target: {} {} {:?}",hit_target,mean_sum_of_squares, _input);
|
||||
if hit_target {
|
||||
Ok(true)
|
||||
} else {
|
||||
@ -312,7 +315,7 @@ where
|
||||
}
|
||||
let mean_sum_of_squares = (sum_of_square_difference as f64) / (self.target_map.len() as f64);
|
||||
let hit_target = mean_sum_of_squares <= self.best_msd;
|
||||
eprintln!("in worst, {}",hit_target);
|
||||
eprintln!("improving: {}",hit_target);
|
||||
if hit_target {
|
||||
self.best_msd = mean_sum_of_squares;
|
||||
Ok(true)
|
||||
@ -341,4 +344,115 @@ impl Default for HitImprovingFeedback {
|
||||
fn default() -> Self {
|
||||
Self::new(HashMap::new())
|
||||
}
|
||||
}
|
||||
|
||||
//=========================== Debugging Feedback
|
||||
/// A [`Feedback`] meant to dump the edgemap for debugging.
|
||||
#[derive(Debug)]
|
||||
pub struct DumpMapFeedback {
|
||||
dumpfile: Option<PathBuf>
|
||||
}
|
||||
|
||||
impl<I, S> Feedback<I, S> for DumpMapFeedback
|
||||
where
|
||||
I: Input,
|
||||
S: HasClientPerfMonitor,
|
||||
{
|
||||
fn is_interesting<EM, OT>(
|
||||
&mut self,
|
||||
_state: &mut S,
|
||||
_manager: &mut EM,
|
||||
_input: &I,
|
||||
_observers: &OT,
|
||||
_exit_kind: &ExitKind,
|
||||
) -> Result<bool, Error>
|
||||
where
|
||||
EM: EventFirer<I>,
|
||||
OT: ObserversTuple<I, S>,
|
||||
{
|
||||
let observer = _observers.match_name::<HitcountsMapObserver<VariableMapObserver<u8>>>("edges")
|
||||
.expect("HitcountsMapObserver not found");
|
||||
match &self.dumpfile {
|
||||
Some(s) => {
|
||||
fs::write(s,ron::to_string(&observer.edgemap).expect("Error serializing hashmap")).expect("Can not dump to file");
|
||||
self.dumpfile = None
|
||||
},
|
||||
None => ()//println!("{:#?}",observer.edgemap),
|
||||
};
|
||||
Ok(true)
|
||||
}
|
||||
}
|
||||
|
||||
impl Named for DumpMapFeedback {
|
||||
#[inline]
|
||||
fn name(&self) -> &str {
|
||||
"HitFeedback"
|
||||
}
|
||||
}
|
||||
|
||||
impl DumpMapFeedback {
|
||||
/// Creates a new [`HitFeedback`]
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
Self {dumpfile: None}
|
||||
}
|
||||
pub fn with_dump(dumpfile: Option<PathBuf>) -> Self {
|
||||
Self {dumpfile: dumpfile}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for DumpMapFeedback {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
//=========================== Debugging Feedback
|
||||
/// A [`Feedback`] meant to dump the edgemap for debugging.
|
||||
#[derive(Debug)]
|
||||
pub struct DummyFeedback {
|
||||
response: bool
|
||||
}
|
||||
|
||||
impl<I, S> Feedback<I, S> for DummyFeedback
|
||||
where
|
||||
I: Input,
|
||||
S: HasClientPerfMonitor,
|
||||
{
|
||||
fn is_interesting<EM, OT>(
|
||||
&mut self,
|
||||
_state: &mut S,
|
||||
_manager: &mut EM,
|
||||
_input: &I,
|
||||
_observers: &OT,
|
||||
_exit_kind: &ExitKind,
|
||||
) -> Result<bool, Error>
|
||||
where
|
||||
EM: EventFirer<I>,
|
||||
OT: ObserversTuple<I, S>,
|
||||
{
|
||||
eprintln!("Input was: {:?}",_input);
|
||||
Ok(self.response)
|
||||
}
|
||||
}
|
||||
|
||||
impl Named for DummyFeedback {
|
||||
#[inline]
|
||||
fn name(&self) -> &str {
|
||||
"DummyFeedback"
|
||||
}
|
||||
}
|
||||
|
||||
impl DummyFeedback {
|
||||
/// Creates a new [`HitFeedback`]
|
||||
#[must_use]
|
||||
pub fn new(response: bool) -> Self {
|
||||
Self {response: response}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for DummyFeedback {
|
||||
fn default() -> Self {
|
||||
Self::new(true)
|
||||
}
|
||||
}
|
@ -28,6 +28,16 @@ use libafl::events::EventFirer;
|
||||
use libafl::state::HasClientPerfMonitor;
|
||||
use libafl::inputs::Input;
|
||||
use libafl::feedbacks::Feedback;
|
||||
use libafl::SerdeAny;
|
||||
use libafl::state::HasMetadata;
|
||||
use libafl::corpus::testcase::Testcase;
|
||||
|
||||
//========== Metadata
|
||||
#[derive(Debug, Serialize, Deserialize, SerdeAny)]
|
||||
pub struct QemuIcountMetadata {
|
||||
runtime: i64,
|
||||
}
|
||||
// libafl::impl_serdeany!(QemuIcountMetadata);
|
||||
|
||||
//========== Observer
|
||||
|
||||
@ -55,7 +65,11 @@ impl QemuClockObserver {
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, S> Observer<I, S> for QemuClockObserver {
|
||||
impl<I, S> Observer<I, S> for QemuClockObserver
|
||||
where
|
||||
I: Input,
|
||||
S: HasMetadata,
|
||||
{
|
||||
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
|
||||
self.last_runtime=0;
|
||||
Ok(())
|
||||
@ -63,6 +77,12 @@ impl<I, S> Observer<I, S> for QemuClockObserver {
|
||||
|
||||
fn post_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
|
||||
unsafe { self.last_runtime = emu::libafl_get_clock() };
|
||||
// if !_state.has_metadata::<QemuIcountMetadata>() {
|
||||
// _state.add_metadata(QemuIcountMetadata{runtime: self.last_runtime()});
|
||||
// println!("Added Metadata");
|
||||
// } else {
|
||||
// println!("Found Metadata");
|
||||
// }
|
||||
println!("Observer Clock: {}",self.last_runtime());
|
||||
Ok(())
|
||||
}
|
||||
@ -84,12 +104,13 @@ impl Default for QemuClockObserver {
|
||||
}
|
||||
}
|
||||
|
||||
//========== Observer
|
||||
//========== Feedback
|
||||
|
||||
/// A [`Feedback`] rewarding increasing the execution cycles on Qemu.
|
||||
#[derive(Debug)]
|
||||
pub struct QemuClockIncreaseFeedback {
|
||||
maximum: i64
|
||||
maximum: i64,
|
||||
last_runtime: i64,
|
||||
}
|
||||
|
||||
impl<I, S> Feedback<I, S> for QemuClockIncreaseFeedback
|
||||
@ -111,12 +132,26 @@ where
|
||||
{
|
||||
let observer = _observers.match_name::<QemuClockObserver>("clock")
|
||||
.expect("QemuClockObserver not found");
|
||||
if observer.last_runtime() >= self.maximum {
|
||||
if observer.last_runtime() > self.maximum {
|
||||
self.maximum = observer.last_runtime();
|
||||
return Ok(true);
|
||||
}
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
/// Append to the testcase the generated metadata in case of a new corpus item
|
||||
#[inline]
|
||||
fn append_metadata(&mut self, _state: &mut S, testcase: &mut Testcase<I>) -> Result<(), Error> {
|
||||
testcase.metadata_mut().insert(QemuIcountMetadata{runtime: self.last_runtime});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Discard the stored metadata in case that the testcase is not added to the corpus
|
||||
#[inline]
|
||||
fn discard_metadata(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl Named for QemuClockIncreaseFeedback {
|
||||
@ -130,7 +165,7 @@ impl QemuClockIncreaseFeedback {
|
||||
/// Creates a new [`HitFeedback`]
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
Self {maximum: 0}
|
||||
Self {maximum: 0, last_runtime: 0}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user