add feedback for improving msd
This commit is contained in:
parent
d2d2862727
commit
d4d86927b7
@ -1,5 +1,9 @@
|
||||
//! A singlethreaded QEMU fuzzer that can auto-restart.
|
||||
|
||||
use libafl::feedbacks::Feedback;
|
||||
use crate::worst::HitImprovingFeedback;
|
||||
use crate::worst::HitFeedback;
|
||||
use hashbrown::HashMap;
|
||||
use libafl::stats::SimpleStats;
|
||||
use libafl::events::SimpleEventManager;
|
||||
use clap::{App, Arg};
|
||||
@ -113,6 +117,11 @@ pub fn main() {
|
||||
.help("Timeout for each individual execution, in milliseconds")
|
||||
.default_value("1000"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("edges")
|
||||
.long("libafl-edges")
|
||||
.takes_value(true),
|
||||
)
|
||||
.try_get_matches_from(filter_qemu_args())
|
||||
{
|
||||
Ok(res) => res,
|
||||
@ -165,8 +174,12 @@ pub fn main() {
|
||||
);
|
||||
|
||||
let kernel = PathBuf::from(res.value_of("k").unwrap().to_string());
|
||||
let edges = match res.value_of("edges") {
|
||||
Some(st) => Some(PathBuf::from(st.to_string())),
|
||||
None => None
|
||||
};
|
||||
|
||||
fuzz(out_dir, crashes, in_dir, tokens, logfile, timeout, kernel)
|
||||
fuzz(out_dir, crashes, in_dir, tokens, logfile, timeout, kernel, edges)
|
||||
.expect("An error occurred while fuzzing");
|
||||
}
|
||||
|
||||
@ -192,6 +205,7 @@ fn fuzz(
|
||||
logfile: PathBuf,
|
||||
timeout: Duration,
|
||||
kernel: PathBuf,
|
||||
dump_edges: Option<PathBuf>,
|
||||
) -> Result<(), Error> {
|
||||
env::remove_var("LD_LIBRARY_PATH");
|
||||
|
||||
@ -286,16 +300,28 @@ fn fuzz(
|
||||
|
||||
// Feedback to rate the interestingness of an input
|
||||
// This one is composed by two Feedbacks in OR
|
||||
let target_map : HashMap<(u64,u64),u8> = match dump_edges {
|
||||
None => HashMap::new(),
|
||||
Some(ref s) => {
|
||||
let raw = fs::read(s).expect("Can not read dumped edges");
|
||||
let hmap : HashMap<(u64,u64),u8> = ron::from_str(&String::from_utf8_lossy(&raw)).expect("Can not parse HashMap");
|
||||
hmap
|
||||
},
|
||||
};
|
||||
let feedback = feedback_or!(
|
||||
// New maximization map feedback linked to the edges observer and the feedback state
|
||||
MaxMapFeedback::new_tracking(&feedback_state, &edges_observer, true, false),
|
||||
MapHitIncreaseFeedback::new(),
|
||||
// Time feedback, this one does not need a feedback state
|
||||
TimeFeedback::new_with_observer(&time_observer)
|
||||
HitImprovingFeedback::new(target_map.clone())
|
||||
);
|
||||
// let feedback = feedback_or!(
|
||||
// // New maximization map feedback linked to the edges observer and the feedback state
|
||||
// MaxMapFeedback::new_tracking(&feedback_state, &edges_observer, true, false),
|
||||
// MapHitIncreaseFeedback::new(),
|
||||
// // Time feedback, this one does not need a feedback state
|
||||
// TimeFeedback::new_with_observer(&time_observer)
|
||||
// );
|
||||
|
||||
// A feedback to choose if an input is a solution or not
|
||||
let objective = CrashFeedback::new();
|
||||
let objective = HitFeedback::new(target_map,0.0);
|
||||
|
||||
// create a State from scratch
|
||||
let mut state = {
|
||||
|
@ -1,5 +1,6 @@
|
||||
//! A singlethreaded QEMU fuzzer that can auto-restart.
|
||||
|
||||
use libafl::feedbacks::CrashFeedback;
|
||||
use std::fs::File;
|
||||
use std::path::Path;
|
||||
use libafl::corpus::Corpus;
|
||||
@ -234,7 +235,7 @@ fn fuzz(
|
||||
let feedback = DumpMapFeedback::with_dump(dump_edges);
|
||||
|
||||
// A feedback to choose if an input is a solution or not
|
||||
let objective = HitFeedback::new();
|
||||
let objective = CrashFeedback::new();
|
||||
|
||||
// create a State from scratch
|
||||
let mut state = StdState::new(
|
||||
|
@ -10,6 +10,7 @@ use libafl::state::HasMetadata;
|
||||
use libafl_qemu::edges::QemuEdgesMapMetadata;
|
||||
use libafl::observers::MapObserver;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::cmp;
|
||||
|
||||
use libafl::{
|
||||
bolts::{
|
||||
@ -145,7 +146,10 @@ where
|
||||
|
||||
/// A [`HitFeedback`] reports as interesting when all predicted worst case edges have been matched.
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct HitFeedback {}
|
||||
pub struct HitFeedback {
|
||||
target_map: HashMap<(u64,u64),u8>,
|
||||
target_msd: f64,
|
||||
}
|
||||
|
||||
impl<I, S> Feedback<I, S> for HitFeedback
|
||||
where
|
||||
@ -168,26 +172,17 @@ where
|
||||
// let observer = _observers.match_name::<HitcountsMapObserver<O>>("edges").expect("SelectedEdgeObserver not found");
|
||||
let observer = _observers.match_name::<HitcountsMapObserver<VariableMapObserver<u8>>>("edges")
|
||||
.expect("HitcountsMapObserver not found");
|
||||
let mut hit_target: bool = true;
|
||||
//check if we've hit any targets.
|
||||
// let inc : u64 = (0x401180);
|
||||
// let call1 : u64 = (0x40119f);
|
||||
// let call2 : u64 = (0x4011b0);
|
||||
// let call3 : u64 = (0x4011c8);
|
||||
let to_check : Vec<(u64,u64)> = vec![
|
||||
(0x401190,0x4011c8), // start -> call
|
||||
(0x40119b,0x4011b0), // cmp -> call
|
||||
(0x4011b5,0x40119f), // cmp -> call
|
||||
];
|
||||
let expected : Vec<u8> = vec![ 1, 1, 1];
|
||||
let combo = to_check.iter().zip(expected.iter());
|
||||
for (edg, val) in combo {
|
||||
// println!("Feedback Len: {} Cap: {}",observer.edgemap.len(),observer.edgemap.capacity());
|
||||
match observer.edgemap.get(edg) {
|
||||
Some(x) => hit_target &= val == x,
|
||||
None =>hit_target = false
|
||||
if self.target_map.len() == 0 { return Ok(true) };
|
||||
|
||||
let mut sum_of_square_difference : u64 = 0; // does not include found edges not in target
|
||||
for (edg, val) in &self.target_map {
|
||||
match observer.edgemap.get(&edg) {
|
||||
Some(x) => sum_of_square_difference+=((cmp::max(*x,*val)-cmp::min(*x,*val)) as u64).pow(2),
|
||||
None => sum_of_square_difference+=(*val as u64).pow(2),
|
||||
}
|
||||
}
|
||||
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;
|
||||
if hit_target {
|
||||
Ok(true)
|
||||
} else {
|
||||
@ -206,14 +201,14 @@ impl Named for HitFeedback {
|
||||
impl HitFeedback {
|
||||
/// Creates a new [`HitFeedback`]
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
Self {}
|
||||
pub fn new(target_map: HashMap<(u64,u64),u8>, target_msd: f64) -> Self {
|
||||
Self {target_map: target_map, target_msd: target_msd}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for HitFeedback {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
Self::new(HashMap::new(),0.0)
|
||||
}
|
||||
}
|
||||
|
||||
@ -273,4 +268,77 @@ impl Default for MapHitIncreaseFeedback {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
//===================================================================
|
||||
|
||||
|
||||
/// A [`HitFeedback`] reports as interesting when all predicted worst case edges have been matched.
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct HitImprovingFeedback {
|
||||
target_map: HashMap<(u64,u64),u8>,
|
||||
best_msd: f64,
|
||||
}
|
||||
|
||||
impl<I, S> Feedback<I, S> for HitImprovingFeedback
|
||||
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>,
|
||||
{
|
||||
// TODO Replace with match_name_type when stable
|
||||
// let observer = _observers.match_name::<HitcountsMapObserver<O>>("edges").expect("SelectedEdgeObserver not found");
|
||||
let observer = _observers.match_name::<HitcountsMapObserver<VariableMapObserver<u8>>>("edges")
|
||||
.expect("HitcountsMapObserver not found");
|
||||
if self.target_map.len() == 0 { return Ok(true) };
|
||||
|
||||
let mut sum_of_square_difference : u64 = 0; // does not include found edges not in target
|
||||
for (edg, val) in &self.target_map {
|
||||
match observer.edgemap.get(&edg) {
|
||||
Some(x) => sum_of_square_difference+=((cmp::max(*x,*val)-cmp::min(*x,*val)) as u64).pow(2),
|
||||
None => sum_of_square_difference+=(*val as u64).pow(2),
|
||||
}
|
||||
}
|
||||
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);
|
||||
if hit_target {
|
||||
self.best_msd = mean_sum_of_squares;
|
||||
Ok(true)
|
||||
} else {
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Named for HitImprovingFeedback {
|
||||
#[inline]
|
||||
fn name(&self) -> &str {
|
||||
"HitFeedback"
|
||||
}
|
||||
}
|
||||
|
||||
impl HitImprovingFeedback {
|
||||
/// Creates a new [`HitFeedback`]
|
||||
#[must_use]
|
||||
pub fn new(target_map: HashMap<(u64,u64),u8>) -> Self {
|
||||
Self {target_map: target_map, best_msd: f64::MAX}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for HitImprovingFeedback {
|
||||
fn default() -> Self {
|
||||
Self::new(HashMap::new())
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user