port to libafl 0.10.1
This commit is contained in:
parent
900ce0bc92
commit
53ef9ae96e
@ -138,7 +138,7 @@ where
|
|||||||
unsafe { self.end_tick = emu::icount_get_raw() };
|
unsafe { self.end_tick = emu::icount_get_raw() };
|
||||||
// println!("clock post {}", self.end_tick);
|
// println!("clock post {}", self.end_tick);
|
||||||
// println!("Number of Ticks: {} <- {} {}",self.end_tick - self.start_tick, self.end_tick, self.start_tick);
|
// println!("Number of Ticks: {} <- {} {}",self.end_tick - self.start_tick, self.end_tick, self.start_tick);
|
||||||
let metadata =_state.metadata_mut();
|
let metadata =_state.metadata_map_mut();
|
||||||
let hist = metadata.get_mut::<IcHist>();
|
let hist = metadata.get_mut::<IcHist>();
|
||||||
let timestamp = SystemTime::now().duration_since(unsafe {FUZZ_START_TIMESTAMP}).unwrap().as_millis();
|
let timestamp = SystemTime::now().duration_since(unsafe {FUZZ_START_TIMESTAMP}).unwrap().as_millis();
|
||||||
match hist {
|
match hist {
|
||||||
@ -226,9 +226,10 @@ where
|
|||||||
|
|
||||||
/// Append to the testcase the generated metadata in case of a new corpus item
|
/// Append to the testcase the generated metadata in case of a new corpus item
|
||||||
#[inline]
|
#[inline]
|
||||||
fn append_metadata(
|
fn append_metadata<OT>(
|
||||||
&mut self,
|
&mut self,
|
||||||
_state: &mut S,
|
_state: &mut S,
|
||||||
|
observers: &OT,
|
||||||
testcase: &mut Testcase<S::Input>,
|
testcase: &mut Testcase<S::Input>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
*testcase.exec_time_mut() = self.exec_time;
|
*testcase.exec_time_mut() = self.exec_time;
|
||||||
@ -296,7 +297,7 @@ where
|
|||||||
let observer = _observers.match_name::<QemuClockObserver>("clock")
|
let observer = _observers.match_name::<QemuClockObserver>("clock")
|
||||||
.expect("QemuClockObserver not found");
|
.expect("QemuClockObserver not found");
|
||||||
let clock_state = state
|
let clock_state = state
|
||||||
.named_metadata_mut()
|
.named_metadata_map_mut()
|
||||||
.get_mut::<MaxIcountMetadata>(&self.name)
|
.get_mut::<MaxIcountMetadata>(&self.name)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
if observer.last_runtime() > clock_state.max_icount_seen {
|
if observer.last_runtime() > clock_state.max_icount_seen {
|
||||||
@ -309,7 +310,7 @@ where
|
|||||||
|
|
||||||
/// Append to the testcase the generated metadata in case of a new corpus item
|
/// Append to the testcase the generated metadata in case of a new corpus item
|
||||||
#[inline]
|
#[inline]
|
||||||
fn append_metadata(&mut self, _state: &mut S, testcase: &mut Testcase<S::Input>) -> Result<(), Error> {
|
fn append_metadata<OT>(&mut self, _state: &mut S, observers: &OT, testcase: &mut Testcase<S::Input>) -> Result<(), Error> {
|
||||||
// testcase.metadata_mut().insert(QemuIcountMetadata{runtime: self.last_runtime});
|
// testcase.metadata_mut().insert(QemuIcountMetadata{runtime: self.last_runtime});
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! A fuzzer using qemu in systemmode for binary-only coverage of kernels
|
//! A fuzzer using qemu in systemmode for binary-only coverage of kernels
|
||||||
//!
|
//!
|
||||||
use core::time::Duration;
|
use core::time::Duration;
|
||||||
use std::{env, path::PathBuf, process::{self, abort}, io::{Read, Write}, fs::{self, OpenOptions}, cmp::{min, max}, mem::transmute_copy, collections::btree_map::Range};
|
use std::{env, path::PathBuf, process::{self, abort}, io::{Read, Write}, fs::{self, OpenOptions}, cmp::{min, max}, mem::transmute_copy, collections::btree_map::Range, ptr::addr_of_mut};
|
||||||
|
|
||||||
use libafl::{
|
use libafl::{
|
||||||
bolts::{
|
bolts::{
|
||||||
@ -26,10 +26,10 @@ use libafl::{
|
|||||||
schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler},
|
schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler},
|
||||||
state::{HasCorpus, StdState, HasMetadata, HasNamedMetadata},
|
state::{HasCorpus, StdState, HasMetadata, HasNamedMetadata},
|
||||||
Error,
|
Error,
|
||||||
prelude::{SimpleMonitor, SimpleEventManager, AsMutSlice, RandBytesGenerator, Generator, SimpleRestartingEventManager, HasBytesVec, minimizer::TopRatedsMetadata, havoc_mutations, StdScheduledMutator, HitcountsMapObserver}, Evaluator, stages::StdMutationalStage,
|
prelude::{SimpleMonitor, SimpleEventManager, AsMutSlice, RandBytesGenerator, Generator, SimpleRestartingEventManager, HasBytesVec, minimizer::TopRatedsMetadata, havoc_mutations, StdScheduledMutator, HitcountsMapObserver, CorpusId}, Evaluator, stages::StdMutationalStage,
|
||||||
};
|
};
|
||||||
use libafl_qemu::{
|
use libafl_qemu::{
|
||||||
edges, edges::QemuEdgeCoverageHelper, elf::EasyElf, emu::Emulator, GuestPhysAddr, QemuExecutor,
|
edges::{self, edges_map_mut_slice, MAX_EDGES_NUM}, edges::QemuEdgeCoverageHelper, elf::EasyElf, emu::Emulator, GuestPhysAddr, QemuExecutor,
|
||||||
QemuHooks, Regs, QemuInstrumentationFilter, GuestAddr,
|
QemuHooks, Regs, QemuInstrumentationFilter, GuestAddr,
|
||||||
emu::libafl_qemu_set_native_breakpoint, emu::libafl_qemu_remove_native_breakpoint,
|
emu::libafl_qemu_set_native_breakpoint, emu::libafl_qemu_remove_native_breakpoint,
|
||||||
};
|
};
|
||||||
@ -174,7 +174,7 @@ pub fn fuzz() {
|
|||||||
// Initialize QEMU
|
// Initialize QEMU
|
||||||
let args: Vec<String> = env::args().collect();
|
let args: Vec<String> = env::args().collect();
|
||||||
let env: Vec<(String, String)> = env::vars().collect();
|
let env: Vec<(String, String)> = env::vars().collect();
|
||||||
let emu = Emulator::new(&args, &env);
|
let emu = Emulator::new(&args, &env).expect("Emulator creation failed");
|
||||||
|
|
||||||
if let Some(main_addr) = main_addr {
|
if let Some(main_addr) = main_addr {
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -242,9 +242,11 @@ pub fn fuzz() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Create an observation channel using the coverage map
|
// Create an observation channel using the coverage map
|
||||||
let edges = unsafe { &mut edges::EDGES_MAP };
|
let edges_observer = unsafe { VariableMapObserver::from_mut_slice(
|
||||||
let edges_counter = unsafe { &mut edges::MAX_EDGES_NUM };
|
"edges",
|
||||||
let edges_observer = VariableMapObserver::new("edges", edges, edges_counter);
|
edges_map_mut_slice(),
|
||||||
|
addr_of_mut!(MAX_EDGES_NUM)
|
||||||
|
)};
|
||||||
#[cfg(feature = "observer_hitcounts")]
|
#[cfg(feature = "observer_hitcounts")]
|
||||||
let edges_observer = HitcountsMapObserver::new(edges_observer);
|
let edges_observer = HitcountsMapObserver::new(edges_observer);
|
||||||
|
|
||||||
@ -393,7 +395,7 @@ pub fn fuzz() {
|
|||||||
.create(true)
|
.create(true)
|
||||||
.append(true)
|
.append(true)
|
||||||
.open(td).expect("Could not open timedump");
|
.open(td).expect("Could not open timedump");
|
||||||
if let Some(ichist) = state.metadata_mut().get_mut::<IcHist>() {
|
if let Ok(ichist) = state.metadata_mut::<IcHist>() {
|
||||||
for i in ichist.0.drain(..) {
|
for i in ichist.0.drain(..) {
|
||||||
writeln!(file, "{},{}", i.0, i.1).expect("Write to dump failed");
|
writeln!(file, "{},{}", i.0, i.1).expect("Write to dump failed");
|
||||||
}
|
}
|
||||||
@ -473,7 +475,7 @@ pub fn fuzz() {
|
|||||||
.create(true)
|
.create(true)
|
||||||
.append(true)
|
.append(true)
|
||||||
.open(td).expect("Could not open timedump");
|
.open(td).expect("Could not open timedump");
|
||||||
if let Some(ichist) = state.metadata_mut().get_mut::<IcHist>() {
|
if let Some(ichist) = state.metadata_map_mut().get_mut::<IcHist>() {
|
||||||
for i in ichist.0.drain(..) {
|
for i in ichist.0.drain(..) {
|
||||||
writeln!(file, "{},{}", i.0, i.1).expect("Write to dump failed");
|
writeln!(file, "{},{}", i.0, i.1).expect("Write to dump failed");
|
||||||
}
|
}
|
||||||
@ -485,7 +487,7 @@ pub fn fuzz() {
|
|||||||
let mut worst = Duration::new(0,0);
|
let mut worst = Duration::new(0,0);
|
||||||
let mut worst_input = None;
|
let mut worst_input = None;
|
||||||
for i in 0..corpus.count() {
|
for i in 0..corpus.count() {
|
||||||
let tc = corpus.get(i).expect("Could not get element from corpus").borrow();
|
let tc = corpus.get(i.into()).expect("Could not get element from corpus").borrow();
|
||||||
if worst < tc.exec_time().expect("Testcase missing duration") {
|
if worst < tc.exec_time().expect("Testcase missing duration") {
|
||||||
worst_input = Some(tc.input().as_ref().unwrap().bytes().to_owned());
|
worst_input = Some(tc.input().as_ref().unwrap().bytes().to_owned());
|
||||||
worst = tc.exec_time().expect("Testcase missing duration");
|
worst = tc.exec_time().expect("Testcase missing duration");
|
||||||
@ -510,8 +512,8 @@ pub fn fuzz() {
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
let mut gd = String::from(&td);
|
let mut gd = String::from(&td);
|
||||||
if let Some(md) = state.metadata_mut().get_mut::<TopRatedsMetadata>() {
|
if let Some(md) = state.metadata_map_mut().get_mut::<TopRatedsMetadata>() {
|
||||||
let mut uniq: Vec<usize> = md.map.values().map(|x| x.clone()).collect();
|
let mut uniq: Vec<CorpusId> = md.map.values().map(|x| x.clone()).collect();
|
||||||
uniq.sort();
|
uniq.sort();
|
||||||
uniq.dedup();
|
uniq.dedup();
|
||||||
gd.push_str(&format!(".{}.toprated{}", uniq.len(), marker));
|
gd.push_str(&format!(".{}.toprated{}", uniq.len(), marker));
|
||||||
@ -523,13 +525,13 @@ pub fn fuzz() {
|
|||||||
dumper(format!(".iter_{}",t));
|
dumper(format!(".iter_{}",t));
|
||||||
}
|
}
|
||||||
println!("Start running until saturation");
|
println!("Start running until saturation");
|
||||||
let mut last = state.metadata().get::<IcHist>().unwrap().1;
|
let mut last = state.metadata_map().get::<IcHist>().unwrap().1;
|
||||||
while SystemTime::now().duration_since(unsafe {FUZZ_START_TIMESTAMP}).unwrap().as_millis() < last.1 + Duration::from_secs(10800).as_millis() {
|
while SystemTime::now().duration_since(unsafe {FUZZ_START_TIMESTAMP}).unwrap().as_millis() < last.1 + Duration::from_secs(10800).as_millis() {
|
||||||
starttime=starttime.checked_add(Duration::from_secs(30)).unwrap();
|
starttime=starttime.checked_add(Duration::from_secs(30)).unwrap();
|
||||||
fuzzer
|
fuzzer
|
||||||
.fuzz_loop_until(&mut stages, &mut executor, &mut state, &mut mgr, starttime)
|
.fuzz_loop_until(&mut stages, &mut executor, &mut state, &mut mgr, starttime)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let after = state.metadata().get::<IcHist>().unwrap().1;
|
let after = state.metadata_map().get::<IcHist>().unwrap().1;
|
||||||
if after.0 > last.0 {
|
if after.0 > last.0 {
|
||||||
last=after;
|
last=after;
|
||||||
}
|
}
|
||||||
@ -539,7 +541,7 @@ pub fn fuzz() {
|
|||||||
let mut worst = Duration::new(0,0);
|
let mut worst = Duration::new(0,0);
|
||||||
let mut worst_input = None;
|
let mut worst_input = None;
|
||||||
for i in 0..corpus.count() {
|
for i in 0..corpus.count() {
|
||||||
let tc = corpus.get(i).expect("Could not get element from corpus").borrow();
|
let tc = corpus.get(i.into()).expect("Could not get element from corpus").borrow();
|
||||||
if worst < tc.exec_time().expect("Testcase missing duration") {
|
if worst < tc.exec_time().expect("Testcase missing duration") {
|
||||||
worst_input = Some(tc.input().as_ref().unwrap().bytes().to_owned());
|
worst_input = Some(tc.input().as_ref().unwrap().bytes().to_owned());
|
||||||
worst = tc.exec_time().expect("Testcase missing duration");
|
worst = tc.exec_time().expect("Testcase missing duration");
|
||||||
@ -563,8 +565,8 @@ pub fn fuzz() {
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
let mut gd = String::from(&td);
|
let mut gd = String::from(&td);
|
||||||
if let Some(md) = state.metadata_mut().get_mut::<TopRatedsMetadata>() {
|
if let Some(md) = state.metadata_map_mut().get_mut::<TopRatedsMetadata>() {
|
||||||
let mut uniq: Vec<usize> = md.map.values().map(|x| x.clone()).collect();
|
let mut uniq: Vec<CorpusId> = md.map.values().map(|x| x.clone()).collect();
|
||||||
uniq.sort();
|
uniq.sort();
|
||||||
uniq.dedup();
|
uniq.dedup();
|
||||||
gd.push_str(&format!(".{}.toprated", uniq.len()));
|
gd.push_str(&format!(".{}.toprated", uniq.len()));
|
||||||
@ -582,7 +584,7 @@ pub fn fuzz() {
|
|||||||
.create(true)
|
.create(true)
|
||||||
.append(true)
|
.append(true)
|
||||||
.open(td).expect("Could not open timedump");
|
.open(td).expect("Could not open timedump");
|
||||||
if let Some(ichist) = state.metadata_mut().get_mut::<IcHist>() {
|
if let Ok(ichist) = state.metadata_mut::<IcHist>() {
|
||||||
for i in ichist.0.drain(..) {
|
for i in ichist.0.drain(..) {
|
||||||
writeln!(file, "{},{}", i.0, i.1).expect("Write to dump failed");
|
writeln!(file, "{},{}", i.0, i.1).expect("Write to dump failed");
|
||||||
}
|
}
|
||||||
@ -594,7 +596,7 @@ pub fn fuzz() {
|
|||||||
let mut worst = Duration::new(0,0);
|
let mut worst = Duration::new(0,0);
|
||||||
let mut worst_input = None;
|
let mut worst_input = None;
|
||||||
for i in 0..corpus.count() {
|
for i in 0..corpus.count() {
|
||||||
let tc = corpus.get(i).expect("Could not get element from corpus").borrow();
|
let tc = corpus.get(i.into()).expect("Could not get element from corpus").borrow();
|
||||||
if worst < tc.exec_time().expect("Testcase missing duration") {
|
if worst < tc.exec_time().expect("Testcase missing duration") {
|
||||||
worst_input = Some(tc.input().as_ref().unwrap().bytes().to_owned());
|
worst_input = Some(tc.input().as_ref().unwrap().bytes().to_owned());
|
||||||
worst = tc.exec_time().expect("Testcase missing duration");
|
worst = tc.exec_time().expect("Testcase missing duration");
|
||||||
@ -618,8 +620,8 @@ pub fn fuzz() {
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
let mut gd = String::from(&td);
|
let mut gd = String::from(&td);
|
||||||
if let Some(md) = state.metadata_mut().get_mut::<TopRatedsMetadata>() {
|
if let Ok(md) = state.metadata_mut::<TopRatedsMetadata>() {
|
||||||
let mut uniq: Vec<usize> = md.map.values().map(|x| x.clone()).collect();
|
let mut uniq: Vec<CorpusId> = md.map.values().map(|x| x.clone()).collect();
|
||||||
uniq.sort();
|
uniq.sort();
|
||||||
uniq.dedup();
|
uniq.dedup();
|
||||||
gd.push_str(&format!(".{}.toprated", uniq.len()));
|
gd.push_str(&format!(".{}.toprated", uniq.len()));
|
||||||
@ -639,7 +641,7 @@ pub fn fuzz() {
|
|||||||
// Initialize QEMU
|
// Initialize QEMU
|
||||||
let args: Vec<String> = env::args().collect();
|
let args: Vec<String> = env::args().collect();
|
||||||
let env: Vec<(String, String)> = env::vars().collect();
|
let env: Vec<(String, String)> = env::vars().collect();
|
||||||
let emu = Emulator::new(&args, &env);
|
let emu = Emulator::new(&args, &env).expect("Emu creation failed");
|
||||||
|
|
||||||
if let Some(main_addr) = main_addr {
|
if let Some(main_addr) = main_addr {
|
||||||
unsafe { libafl_qemu_set_native_breakpoint(main_addr); }// BREAKPOINT
|
unsafe { libafl_qemu_set_native_breakpoint(main_addr); }// BREAKPOINT
|
||||||
|
@ -12,7 +12,7 @@ use libafl::{
|
|||||||
stages::{Stage},
|
stages::{Stage},
|
||||||
start_timer,
|
start_timer,
|
||||||
state::{HasClientPerfMonitor, HasCorpus, HasRand, UsesState, HasMetadata},
|
state::{HasClientPerfMonitor, HasCorpus, HasRand, UsesState, HasMetadata},
|
||||||
Error, prelude::{HasBytesVec, UsesInput, new_hash_feedback, StdRand, RandomSeed, MutationResult, Mutator},
|
Error, prelude::{HasBytesVec, UsesInput, new_hash_feedback, StdRand, RandomSeed, MutationResult, Mutator, CorpusId},
|
||||||
};
|
};
|
||||||
use crate::{systemstate::{FreeRTOSSystemStateMetadata, RefinedFreeRTOSSystemState}, fuzzer::DO_NUM_INTERRUPT, clock::IcHist};
|
use crate::{systemstate::{FreeRTOSSystemStateMetadata, RefinedFreeRTOSSystemState}, fuzzer::DO_NUM_INTERRUPT, clock::IcHist};
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ where
|
|||||||
executor: &mut E,
|
executor: &mut E,
|
||||||
state: &mut Self::State,
|
state: &mut Self::State,
|
||||||
manager: &mut EM,
|
manager: &mut EM,
|
||||||
corpus_idx: usize,
|
corpus_idx: CorpusId,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let mut _input = state
|
let mut _input = state
|
||||||
.corpus()
|
.corpus()
|
||||||
@ -103,7 +103,7 @@ where
|
|||||||
// let mut suffix : Vec<u8> = vec![];
|
// let mut suffix : Vec<u8> = vec![];
|
||||||
#[cfg(feature = "feed_systemtrace")]
|
#[cfg(feature = "feed_systemtrace")]
|
||||||
{
|
{
|
||||||
let tmp = _input.metadata().get::<FreeRTOSSystemStateMetadata>();
|
let tmp = _input.metadata_map().get::<FreeRTOSSystemStateMetadata>();
|
||||||
if tmp.is_some() {
|
if tmp.is_some() {
|
||||||
let trace = tmp.expect("FreeRTOSSystemStateMetadata not found");
|
let trace = tmp.expect("FreeRTOSSystemStateMetadata not found");
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ where
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
fn post_exec(&mut self, emulator: &Emulator, _input: &S::Input) {
|
fn post_exec<OT>(&mut self, emulator: &Emulator, _input: &S::Input, _observers: &mut OT, _exit_kind: &mut ExitKind) {
|
||||||
// unsafe { println!("snapshot post {}",emu::icount_get_raw()) };
|
// unsafe { println!("snapshot post {}",emu::icount_get_raw()) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,13 +81,13 @@ where
|
|||||||
let clock_observer = observers.match_name::<QemuClockObserver>("clocktime") //TODO not fixed
|
let clock_observer = observers.match_name::<QemuClockObserver>("clocktime") //TODO not fixed
|
||||||
.expect("QemuClockObserver not found");
|
.expect("QemuClockObserver not found");
|
||||||
let feedbackstate = match state
|
let feedbackstate = match state
|
||||||
.named_metadata_mut()
|
.named_metadata_map_mut()
|
||||||
.get_mut::<SystemStateFeedbackState>("systemstate") {
|
.get_mut::<SystemStateFeedbackState>("systemstate") {
|
||||||
Some(s) => s,
|
Some(s) => s,
|
||||||
None => {
|
None => {
|
||||||
let n=SystemStateFeedbackState::default();
|
let n=SystemStateFeedbackState::default();
|
||||||
state.named_metadata_mut().insert(n, "systemstate");
|
state.named_metadata_map_mut().insert(n, "systemstate");
|
||||||
state.named_metadata_mut().get_mut::<SystemStateFeedbackState>("systemstate").unwrap()
|
state.named_metadata_map_mut().get_mut::<SystemStateFeedbackState>("systemstate").unwrap()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// let feedbackstate = state
|
// let feedbackstate = state
|
||||||
@ -123,10 +123,10 @@ where
|
|||||||
|
|
||||||
/// Append to the testcase the generated metadata in case of a new corpus item
|
/// Append to the testcase the generated metadata in case of a new corpus item
|
||||||
#[inline]
|
#[inline]
|
||||||
fn append_metadata(&mut self, _state: &mut S, testcase: &mut Testcase<S::Input>) -> Result<(), Error> {
|
fn append_metadata<OT>(&mut self, _state: &mut S, observers: &OT, testcase: &mut Testcase<S::Input>) -> Result<(), Error> {
|
||||||
let a = self.last_trace.take();
|
let a = self.last_trace.take();
|
||||||
match a {
|
match a {
|
||||||
Some(s) => testcase.metadata_mut().insert(FreeRTOSSystemStateMetadata::new(s)),
|
Some(s) => testcase.metadata_map_mut().insert(FreeRTOSSystemStateMetadata::new(s)),
|
||||||
None => (),
|
None => (),
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -257,11 +257,11 @@ where
|
|||||||
}
|
}
|
||||||
/// Append to the testcase the generated metadata in case of a new corpus item
|
/// Append to the testcase the generated metadata in case of a new corpus item
|
||||||
#[inline]
|
#[inline]
|
||||||
fn append_metadata(&mut self, _state: &mut S, testcase: &mut Testcase<S::Input>) -> Result<(), Error> {
|
fn append_metadata<OT>(&mut self, _state: &mut S, observers: &OT, testcase: &mut Testcase<S::Input>) -> Result<(), Error> {
|
||||||
if !self.dump_metadata {return Ok(());}
|
if !self.dump_metadata {return Ok(());}
|
||||||
let a = self.last_trace.take();
|
let a = self.last_trace.take();
|
||||||
match a {
|
match a {
|
||||||
Some(s) => testcase.metadata_mut().insert(FreeRTOSSystemStateMetadata::new(s)),
|
Some(s) => testcase.metadata_map_mut().insert(FreeRTOSSystemStateMetadata::new(s)),
|
||||||
None => (),
|
None => (),
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -281,13 +281,13 @@ where
|
|||||||
let observer = observers.match_name::<QemuSystemStateObserver>("systemstate")
|
let observer = observers.match_name::<QemuSystemStateObserver>("systemstate")
|
||||||
.expect("QemuSystemStateObserver not found");
|
.expect("QemuSystemStateObserver not found");
|
||||||
let feedbackstate = match state
|
let feedbackstate = match state
|
||||||
.named_metadata_mut()
|
.named_metadata_map_mut()
|
||||||
.get_mut::<SysGraphFeedbackState>("SysMap") {
|
.get_mut::<SysGraphFeedbackState>("SysMap") {
|
||||||
Some(s) => s,
|
Some(s) => s,
|
||||||
None => {
|
None => {
|
||||||
let n=SysGraphFeedbackState::default();
|
let n=SysGraphFeedbackState::default();
|
||||||
state.named_metadata_mut().insert(n, "SysMap");
|
state.named_metadata_map_mut().insert(n, "SysMap");
|
||||||
state.named_metadata_mut().get_mut::<SysGraphFeedbackState>("SysMap").unwrap()
|
state.named_metadata_map_mut().get_mut::<SysGraphFeedbackState>("SysMap").unwrap()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let ret = feedbackstate.update(&observer.last_run, &observer.last_input);
|
let ret = feedbackstate.update(&observer.last_run, &observer.last_input);
|
||||||
@ -297,10 +297,10 @@ where
|
|||||||
|
|
||||||
/// Append to the testcase the generated metadata in case of a new corpus item
|
/// Append to the testcase the generated metadata in case of a new corpus item
|
||||||
#[inline]
|
#[inline]
|
||||||
fn append_metadata(&mut self, _state: &mut S, testcase: &mut Testcase<S::Input>) -> Result<(), Error> {
|
fn append_metadata<OT>(&mut self, _state: &mut S, observers: &OT, testcase: &mut Testcase<S::Input>) -> Result<(), Error> {
|
||||||
let a = self.last_trace.take();
|
let a = self.last_trace.take();
|
||||||
match a {
|
match a {
|
||||||
Some(s) => testcase.metadata_mut().insert(SysGraphMetadata::new(s)),
|
Some(s) => testcase.metadata_map_mut().insert(SysGraphMetadata::new(s)),
|
||||||
None => (),
|
None => (),
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use std::cell::UnsafeCell;
|
use std::cell::UnsafeCell;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
use libafl::prelude::ExitKind;
|
||||||
use libafl::prelude::UsesInput;
|
use libafl::prelude::UsesInput;
|
||||||
use libafl_qemu::Emulator;
|
use libafl_qemu::Emulator;
|
||||||
use libafl_qemu::GuestAddr;
|
use libafl_qemu::GuestAddr;
|
||||||
@ -82,7 +83,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn post_exec(&mut self, emulator: &Emulator, _input: &S::Input) {
|
fn post_exec<OT>(&mut self, emulator: &Emulator, _input: &S::Input, _observers: &mut OT, _exit_kind: &mut ExitKind) {
|
||||||
trigger_collection(emulator, self)
|
trigger_collection(emulator, self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ use libafl::{
|
|||||||
inputs::UsesInput,
|
inputs::UsesInput,
|
||||||
schedulers::{Scheduler, TestcaseScore, minimizer::DEFAULT_SKIP_NON_FAVORED_PROB },
|
schedulers::{Scheduler, TestcaseScore, minimizer::DEFAULT_SKIP_NON_FAVORED_PROB },
|
||||||
state::{HasCorpus, HasMetadata, HasRand, UsesState, State},
|
state::{HasCorpus, HasMetadata, HasRand, UsesState, State},
|
||||||
Error, SerdeAny, prelude::HasLen,
|
Error, SerdeAny, prelude::{HasLen, CorpusId},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -55,51 +55,51 @@ where
|
|||||||
CS::State: HasCorpus + HasMetadata + HasRand,
|
CS::State: HasCorpus + HasMetadata + HasRand,
|
||||||
{
|
{
|
||||||
/// Add an entry to the corpus and return its index
|
/// Add an entry to the corpus and return its index
|
||||||
fn on_add(&self, state: &mut CS::State, idx: usize) -> Result<(), Error> {
|
fn on_add(&mut self, state: &mut CS::State, idx: CorpusId) -> Result<(), Error> {
|
||||||
let l = state.corpus()
|
let l = state.corpus()
|
||||||
.get(idx)?
|
.get(idx)?
|
||||||
.borrow()
|
.borrow()
|
||||||
.metadata()
|
.metadata_map()
|
||||||
.get::<FreeRTOSSystemStateMetadata>().map_or(0, |x| x.trace_length);
|
.get::<FreeRTOSSystemStateMetadata>().map_or(0, |x| x.trace_length);
|
||||||
self.get_update_trace_length(state,l);
|
self.get_update_trace_length(state,l);
|
||||||
self.base.on_add(state, idx)
|
self.base.on_add(state, idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Replaces the testcase at the given idx
|
/// Replaces the testcase at the given idx
|
||||||
fn on_replace(
|
// fn on_replace(
|
||||||
&self,
|
// &mut self,
|
||||||
state: &mut CS::State,
|
// state: &mut CS::State,
|
||||||
idx: usize,
|
// idx: CorpusId,
|
||||||
testcase: &Testcase<<CS::State as UsesInput>::Input>,
|
// testcase: &Testcase<<CS::State as UsesInput>::Input>,
|
||||||
) -> Result<(), Error> {
|
// ) -> Result<(), Error> {
|
||||||
let l = state.corpus()
|
// let l = state.corpus()
|
||||||
.get(idx)?
|
// .get(idx)?
|
||||||
.borrow()
|
// .borrow()
|
||||||
.metadata()
|
// .metadata()
|
||||||
.get::<FreeRTOSSystemStateMetadata>().map_or(0, |x| x.trace_length);
|
// .get::<FreeRTOSSystemStateMetadata>().map_or(0, |x| x.trace_length);
|
||||||
self.get_update_trace_length(state, l);
|
// self.get_update_trace_length(state, l);
|
||||||
self.base.on_replace(state, idx, testcase)
|
// self.base.on_replace(state, idx, testcase)
|
||||||
}
|
// }
|
||||||
|
|
||||||
/// Removes an entry from the corpus, returning M if M was present.
|
/// Removes an entry from the corpus, returning M if M was present.
|
||||||
fn on_remove(
|
// fn on_remove(
|
||||||
&self,
|
// &self,
|
||||||
state: &mut CS::State,
|
// state: &mut CS::State,
|
||||||
idx: usize,
|
// idx: usize,
|
||||||
testcase: &Option<Testcase<<CS::State as UsesInput>::Input>>,
|
// testcase: &Option<Testcase<<CS::State as UsesInput>::Input>>,
|
||||||
) -> Result<(), Error> {
|
// ) -> Result<(), Error> {
|
||||||
self.base.on_remove(state, idx, testcase)?;
|
// self.base.on_remove(state, idx, testcase)?;
|
||||||
Ok(())
|
// Ok(())
|
||||||
}
|
// }
|
||||||
|
|
||||||
/// Gets the next entry
|
/// Gets the next entry
|
||||||
fn next(&self, state: &mut CS::State) -> Result<usize, Error> {
|
fn next(&mut self, state: &mut CS::State) -> Result<CorpusId, Error> {
|
||||||
let mut idx = self.base.next(state)?;
|
let mut idx = self.base.next(state)?;
|
||||||
while {
|
while {
|
||||||
let l = state.corpus()
|
let l = state.corpus()
|
||||||
.get(idx)?
|
.get(idx)?
|
||||||
.borrow()
|
.borrow()
|
||||||
.metadata()
|
.metadata_map()
|
||||||
.get::<FreeRTOSSystemStateMetadata>().map_or(0, |x| x.trace_length);
|
.get::<FreeRTOSSystemStateMetadata>().map_or(0, |x| x.trace_length);
|
||||||
let m = self.get_update_trace_length(state,l);
|
let m = self.get_update_trace_length(state,l);
|
||||||
state.rand_mut().below(m) > l as u64
|
state.rand_mut().below(m) > l as u64
|
||||||
@ -118,7 +118,7 @@ where
|
|||||||
{
|
{
|
||||||
pub fn get_update_trace_length(&self, state: &mut CS::State, par: usize) -> u64 {
|
pub fn get_update_trace_length(&self, state: &mut CS::State, par: usize) -> u64 {
|
||||||
// Create a new top rated meta if not existing
|
// Create a new top rated meta if not existing
|
||||||
if let Some(td) = state.metadata_mut().get_mut::<LongestTracesMetadata>() {
|
if let Some(td) = state.metadata_map_mut().get_mut::<LongestTracesMetadata>() {
|
||||||
let m = max(td.max_trace_length, par);
|
let m = max(td.max_trace_length, par);
|
||||||
td.max_trace_length = m;
|
td.max_trace_length = m;
|
||||||
m as u64
|
m as u64
|
||||||
@ -172,18 +172,18 @@ where
|
|||||||
{
|
{
|
||||||
/// get first element in current gen,
|
/// get first element in current gen,
|
||||||
/// if current_gen is empty, swap lists, sort by FavFactor, take top k and return first
|
/// if current_gen is empty, swap lists, sort by FavFactor, take top k and return first
|
||||||
fn next(&self, state: &mut Self::State) -> Result<usize, Error> {
|
fn next(&mut self, state: &mut Self::State) -> Result<CorpusId, Error> {
|
||||||
let mut to_remove : Vec<(usize, f64)> = vec![];
|
let mut to_remove : Vec<(usize, f64)> = vec![];
|
||||||
let mut to_return : usize = 0;
|
let mut to_return : usize = 0;
|
||||||
let c = state.corpus().count();
|
let c = state.corpus().count();
|
||||||
let gm = state.metadata_mut().get_mut::<GeneticMetadata>().expect("Corpus Scheduler empty");
|
let gm = state.metadata_map_mut().get_mut::<GeneticMetadata>().expect("Corpus Scheduler empty");
|
||||||
// println!("index: {} curr: {:?} next: {:?} gen: {} corp: {}", gm.current_cursor, gm.current_gen.len(), gm.next_gen.len(), gm.gen,
|
// println!("index: {} curr: {:?} next: {:?} gen: {} corp: {}", gm.current_cursor, gm.current_gen.len(), gm.next_gen.len(), gm.gen,
|
||||||
// c);
|
// c);
|
||||||
match gm.current_gen.get(gm.current_cursor) {
|
match gm.current_gen.get(gm.current_cursor) {
|
||||||
Some(c) => {
|
Some(c) => {
|
||||||
gm.current_cursor+=1;
|
gm.current_cursor+=1;
|
||||||
// println!("normal next: {}", (*c).0);
|
// println!("normal next: {}", (*c).0);
|
||||||
return Ok((*c).0)
|
return Ok((*c).0.into())
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
swap(&mut to_remove, &mut gm.current_gen);
|
swap(&mut to_remove, &mut gm.current_gen);
|
||||||
@ -207,53 +207,53 @@ where
|
|||||||
to_remove.sort_by(|x,y| x.0.cmp(&(*y).0));
|
to_remove.sort_by(|x,y| x.0.cmp(&(*y).0));
|
||||||
to_remove.reverse();
|
to_remove.reverse();
|
||||||
for i in to_remove {
|
for i in to_remove {
|
||||||
state.corpus_mut().remove(i.0).unwrap();
|
state.corpus_mut().remove(i.0.into()).unwrap();
|
||||||
}
|
}
|
||||||
// println!("switch next: {to_return}");
|
// println!("switch next: {to_return}");
|
||||||
return Ok(to_return);
|
return Ok(to_return.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add the new input to the next generation
|
/// Add the new input to the next generation
|
||||||
fn on_add(
|
fn on_add(
|
||||||
&self,
|
&mut self,
|
||||||
state: &mut Self::State,
|
state: &mut Self::State,
|
||||||
idx: usize
|
idx: CorpusId
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
// println!("On Add {idx}");
|
// println!("On Add {idx}");
|
||||||
let mut tc = state.corpus_mut().get(idx).unwrap().borrow_mut().clone();
|
let mut tc = state.corpus_mut().get(idx).unwrap().borrow_mut().clone();
|
||||||
let ff = MaxTimeFavFactor::compute(&mut tc, state).unwrap();
|
let ff = MaxTimeFavFactor::compute(state, &mut tc).unwrap();
|
||||||
if let Some(gm) = state.metadata_mut().get_mut::<GeneticMetadata>() {
|
if let Some(gm) = state.metadata_map_mut().get_mut::<GeneticMetadata>() {
|
||||||
gm.next_gen.push((idx,ff));
|
gm.next_gen.push((idx.into(),ff));
|
||||||
} else {
|
} else {
|
||||||
state.add_metadata(GeneticMetadata::new(vec![], vec![(idx,ff)]));
|
state.add_metadata(GeneticMetadata::new(vec![], vec![(idx.into(),ff)]));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn on_replace(
|
// fn on_replace(
|
||||||
&self,
|
// &self,
|
||||||
_state: &mut Self::State,
|
// _state: &mut Self::State,
|
||||||
_idx: usize,
|
// _idx: usize,
|
||||||
_prev: &Testcase<<Self::State as UsesInput>::Input>
|
// _prev: &Testcase<<Self::State as UsesInput>::Input>
|
||||||
) -> Result<(), Error> {
|
// ) -> Result<(), Error> {
|
||||||
// println!("On Replace {_idx}");
|
// // println!("On Replace {_idx}");
|
||||||
Ok(())
|
// Ok(())
|
||||||
}
|
// }
|
||||||
|
|
||||||
fn on_remove(
|
// fn on_remove(
|
||||||
&self,
|
// &self,
|
||||||
state: &mut Self::State,
|
// state: &mut Self::State,
|
||||||
idx: usize,
|
// idx: usize,
|
||||||
_testcase: &Option<Testcase<<Self::State as UsesInput>::Input>>
|
// _testcase: &Option<Testcase<<Self::State as UsesInput>::Input>>
|
||||||
) -> Result<(), Error> {
|
// ) -> Result<(), Error> {
|
||||||
// println!("On Remove {idx}");
|
// // println!("On Remove {idx}");
|
||||||
if let Some(gm) = state.metadata_mut().get_mut::<GeneticMetadata>() {
|
// if let Some(gm) = state.metadata_mut().get_mut::<GeneticMetadata>() {
|
||||||
gm.next_gen = gm.next_gen.drain(..).into_iter().filter(|x| (*x).0 != idx).collect::<Vec<(usize, f64)>>();
|
// gm.next_gen = gm.next_gen.drain(..).into_iter().filter(|x| (*x).0 != idx).collect::<Vec<(usize, f64)>>();
|
||||||
gm.current_gen = gm.current_gen.drain(..).into_iter().filter(|x| (*x).0 != idx).collect::<Vec<(usize, f64)>>();
|
// gm.current_gen = gm.current_gen.drain(..).into_iter().filter(|x| (*x).0 != idx).collect::<Vec<(usize, f64)>>();
|
||||||
} else {
|
// } else {
|
||||||
state.add_metadata(GeneticMetadata::new(vec![], vec![]));
|
// state.add_metadata(GeneticMetadata::new(vec![], vec![]));
|
||||||
}
|
// }
|
||||||
Ok(())
|
// Ok(())
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> GenerationScheduler<S>
|
impl<S> GenerationScheduler<S>
|
||||||
|
@ -54,7 +54,7 @@ where
|
|||||||
S: HasCorpus + HasMetadata,
|
S: HasCorpus + HasMetadata,
|
||||||
S::Input: HasLen,
|
S::Input: HasLen,
|
||||||
{
|
{
|
||||||
fn compute(entry: &mut Testcase<<S as UsesInput>::Input>, state: &S) -> Result<f64, Error> {
|
fn compute(state: &S, entry: &mut Testcase<<S as UsesInput>::Input>) -> Result<f64, Error> {
|
||||||
// TODO maybe enforce entry.exec_time().is_some()
|
// TODO maybe enforce entry.exec_time().is_some()
|
||||||
let et = entry.exec_time().expect("testcase.exec_time is needed for scheduler");
|
let et = entry.exec_time().expect("testcase.exec_time is needed for scheduler");
|
||||||
let tns : i64 = et.as_nanos().try_into().expect("failed to convert time");
|
let tns : i64 = et.as_nanos().try_into().expect("failed to convert time");
|
||||||
@ -84,9 +84,9 @@ where
|
|||||||
S: HasCorpus + HasMetadata,
|
S: HasCorpus + HasMetadata,
|
||||||
S::Input: HasLen,
|
S::Input: HasLen,
|
||||||
{
|
{
|
||||||
fn compute(entry: &mut Testcase<S::Input>, state: &S) -> Result<f64, Error> {
|
fn compute( state: &S, entry: &mut Testcase<S::Input>) -> Result<f64, Error> {
|
||||||
let execs_per_hour = (3600.0/entry.exec_time().expect("testcase.exec_time is needed for scheduler").as_secs_f64());
|
let execs_per_hour = (3600.0/entry.exec_time().expect("testcase.exec_time is needed for scheduler").as_secs_f64());
|
||||||
let execs_times_length_per_hour = execs_per_hour*entry.cached_len()? as f64;
|
let execs_times_length_per_hour = execs_per_hour*entry.cached_len().unwrap() as f64;
|
||||||
Ok(execs_times_length_per_hour)
|
Ok(execs_times_length_per_hour)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -301,9 +301,10 @@ where
|
|||||||
Ok(false)
|
Ok(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn append_metadata(
|
fn append_metadata<OT>(
|
||||||
&mut self,
|
&mut self,
|
||||||
_state: &mut S,
|
_state: &mut S,
|
||||||
|
observers: &OT,
|
||||||
testcase: &mut Testcase<<S as UsesInput>::Input>,
|
testcase: &mut Testcase<<S as UsesInput>::Input>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
#[cfg(feature = "feed_afl")]
|
#[cfg(feature = "feed_afl")]
|
||||||
|
@ -246,21 +246,21 @@ where
|
|||||||
state: &mut EM::State,
|
state: &mut EM::State,
|
||||||
manager: &mut EM,
|
manager: &mut EM,
|
||||||
time: Duration
|
time: Duration
|
||||||
) -> Result<usize, Error> {
|
) -> Result<CorpusId, Error> {
|
||||||
if time==Duration::ZERO {
|
if time==Duration::ZERO {
|
||||||
return Err(Error::illegal_argument(
|
return Err(Error::illegal_argument(
|
||||||
"Cannot fuzz for 0 duration!".to_string(),
|
"Cannot fuzz for 0 duration!".to_string(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut ret = 0;
|
let mut ret = None;
|
||||||
let mut last = current_time();
|
let mut last = current_time();
|
||||||
let monitor_timeout = STATS_TIMEOUT_DEFAULT;
|
let monitor_timeout = STATS_TIMEOUT_DEFAULT;
|
||||||
|
|
||||||
let starttime = std::time::Instant::now();
|
let starttime = std::time::Instant::now();
|
||||||
|
|
||||||
while std::time::Instant::now().duration_since(starttime) < time {
|
while std::time::Instant::now().duration_since(starttime) < time {
|
||||||
ret = self.fuzz_one(stages, executor, state, manager)?;
|
ret = Some(self.fuzz_one(stages, executor, state, manager)?);
|
||||||
last = manager.maybe_report_progress(state, last, monitor_timeout)?;
|
last = manager.maybe_report_progress(state, last, monitor_timeout)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,7 +269,7 @@ where
|
|||||||
// But as the state may grow to a few megabytes,
|
// But as the state may grow to a few megabytes,
|
||||||
// for now we won' and the user has to do it (unless we find a way to do this on `Drop`).
|
// for now we won' and the user has to do it (unless we find a way to do this on `Drop`).
|
||||||
|
|
||||||
Ok(ret)
|
Ok(ret.unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fuzz for n iterations.
|
/// Fuzz for n iterations.
|
||||||
@ -288,13 +288,13 @@ where
|
|||||||
state: &mut EM::State,
|
state: &mut EM::State,
|
||||||
manager: &mut EM,
|
manager: &mut EM,
|
||||||
time: std::time::Instant
|
time: std::time::Instant
|
||||||
) -> Result<usize, Error> {
|
) -> Result<CorpusId, Error> {
|
||||||
let mut ret = 0;
|
let mut ret = None;
|
||||||
let mut last = current_time();
|
let mut last = current_time();
|
||||||
let monitor_timeout = STATS_TIMEOUT_DEFAULT;
|
let monitor_timeout = STATS_TIMEOUT_DEFAULT;
|
||||||
|
|
||||||
while std::time::Instant::now() < time {
|
while std::time::Instant::now() < time {
|
||||||
ret = self.fuzz_one(stages, executor, state, manager)?;
|
ret = Some(self.fuzz_one(stages, executor, state, manager)?);
|
||||||
last = manager.maybe_report_progress(state, last, monitor_timeout)?;
|
last = manager.maybe_report_progress(state, last, monitor_timeout)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,7 +303,7 @@ where
|
|||||||
// But as the state may grow to a few megabytes,
|
// But as the state may grow to a few megabytes,
|
||||||
// for now we won' and the user has to do it (unless we find a way to do this on `Drop`).
|
// for now we won' and the user has to do it (unless we find a way to do this on `Drop`).
|
||||||
|
|
||||||
Ok(ret)
|
Ok(ret.unwrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user