type fixing
This commit is contained in:
parent
b12811e1ef
commit
8d7e32559f
@ -44,7 +44,7 @@ where
|
|||||||
) -> Result<bool, Error>
|
) -> Result<bool, Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = S>,
|
EM: EventFirer<State = S>,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<I, S>,
|
||||||
{
|
{
|
||||||
if unsafe { counter } > 0 {
|
if unsafe { counter } > 0 {
|
||||||
unsafe { counter -= 1; }
|
unsafe { counter -= 1; }
|
||||||
@ -68,7 +68,7 @@ where
|
|||||||
testcase: &mut Testcase<<S>::Input>,
|
testcase: &mut Testcase<<S>::Input>,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<I, S>,
|
||||||
EM: EventFirer<State = S>,
|
EM: EventFirer<State = S>,
|
||||||
{
|
{
|
||||||
testcase.metadata_map_mut().insert(DebugMetadata { val: true });
|
testcase.metadata_map_mut().insert(DebugMetadata { val: true });
|
||||||
|
@ -9,9 +9,8 @@ core_affinity::Cores, ownedref::OwnedMutSlice, rands::StdRand, shmem::{ShMemProv
|
|||||||
use libafl::{
|
use libafl::{
|
||||||
common::{HasMetadata, HasNamedMetadata}, corpus::{Corpus, InMemoryCorpus, OnDiskCorpus}, events::{launcher::Launcher, EventConfig}, executors::ExitKind, feedback_or, feedback_or_fast, feedbacks::{CrashFeedback, MaxMapFeedback, TimeoutFeedback}, fuzzer::{Fuzzer, StdFuzzer}, inputs::{multi::MultipartInput, BytesInput, HasTargetBytes, Input}, monitors::MultiMonitor, observers::{CanTrack, VariableMapObserver}, prelude::{havoc_mutations, minimizer::TopRatedsMetadata, CorpusId, Generator, HitcountsMapObserver, RandBytesGenerator, SimpleEventManager, SimpleMonitor, SimplePrintingMonitor, SimpleRestartingEventManager, StdScheduledMutator}, schedulers::QueueScheduler, stages::StdMutationalStage, state::{HasCorpus, StdState}, Error, Evaluator
|
common::{HasMetadata, HasNamedMetadata}, corpus::{Corpus, InMemoryCorpus, OnDiskCorpus}, events::{launcher::Launcher, EventConfig}, executors::ExitKind, feedback_or, feedback_or_fast, feedbacks::{CrashFeedback, MaxMapFeedback, TimeoutFeedback}, fuzzer::{Fuzzer, StdFuzzer}, inputs::{multi::MultipartInput, BytesInput, HasTargetBytes, Input}, monitors::MultiMonitor, observers::{CanTrack, VariableMapObserver}, prelude::{havoc_mutations, minimizer::TopRatedsMetadata, CorpusId, Generator, HitcountsMapObserver, RandBytesGenerator, SimpleEventManager, SimpleMonitor, SimplePrintingMonitor, SimpleRestartingEventManager, StdScheduledMutator}, schedulers::QueueScheduler, stages::StdMutationalStage, state::{HasCorpus, StdState}, Error, Evaluator
|
||||||
};
|
};
|
||||||
use libafl_qemu::edges::EDGES_MAP_SIZE_IN_USE;
|
|
||||||
use libafl_qemu::{
|
use libafl_qemu::{
|
||||||
edges::{self, edges_map_mut_ptr, QemuEdgeCoverageHelper, MAX_EDGES_FOUND}, elf::EasyElf, emu::Emulator, GuestAddr, GuestPhysAddr, QemuExecutor, QemuExitReason, QemuFilterList, QemuHooks, Regs, StdInstrumentationFilter
|
elf::EasyElf, emu::Emulator, modules::{edges::{self}, FilterList}, GuestAddr, GuestPhysAddr, QemuExecutor, QemuExitReason, QemuHooks, Regs
|
||||||
};
|
};
|
||||||
use rand::{SeedableRng, StdRng, Rng};
|
use rand::{SeedableRng, StdRng, Rng};
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -30,6 +29,7 @@ use crate::cli::set_env_from_config;
|
|||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use log;
|
use log;
|
||||||
use rand::RngCore;
|
use rand::RngCore;
|
||||||
|
use crate::templates;
|
||||||
|
|
||||||
// Constants ================================================================================
|
// Constants ================================================================================
|
||||||
|
|
||||||
@ -248,7 +248,7 @@ let app_fn_ranges = get_all_fn_symbol_ranges(&elf, app_range.clone());
|
|||||||
let mut isr_ranges : HashMap<String,std::ops::Range<GuestAddr>> = systemstate::helpers::ISR_SYMBOLS.iter().filter_map(|x| (api_ranges.get(&x.to_string()).map(|y| (x.to_string(),y.clone())))).collect();
|
let mut isr_ranges : HashMap<String,std::ops::Range<GuestAddr>> = systemstate::helpers::ISR_SYMBOLS.iter().filter_map(|x| (api_ranges.get(&x.to_string()).map(|y| (x.to_string(),y.clone())))).collect();
|
||||||
systemstate::helpers::ISR_SYMBOLS.iter().for_each(|x| {let _ =(app_fn_ranges.get(&x.to_string()).map(|y| (x.to_string(),y.clone()))).map(|y| isr_ranges.insert(y.0,y.1));}); // add used defined isr
|
systemstate::helpers::ISR_SYMBOLS.iter().for_each(|x| {let _ =(app_fn_ranges.get(&x.to_string()).map(|y| (x.to_string(),y.clone()))).map(|y| isr_ranges.insert(y.0,y.1));}); // add used defined isr
|
||||||
let denylist : Vec<_> =isr_ranges.values().map(|x| x.clone()).collect();
|
let denylist : Vec<_> =isr_ranges.values().map(|x| x.clone()).collect();
|
||||||
let denylist = QemuFilterList::DenyList(denylist); // do not count isr jumps, which are useless
|
let denylist = FilterList::DenyList(denylist); // do not count isr jumps, which are useless
|
||||||
#[cfg(feature = "observe_systemstate")]
|
#[cfg(feature = "observe_systemstate")]
|
||||||
let mut isr_addreses : HashMap<GuestAddr, String> = systemstate::helpers::ISR_SYMBOLS.iter().filter_map(|x| (api_ranges.remove(&x.to_string()).map(|y| (y.start,x.to_string())))).collect();
|
let mut isr_addreses : HashMap<GuestAddr, String> = systemstate::helpers::ISR_SYMBOLS.iter().filter_map(|x| (api_ranges.remove(&x.to_string()).map(|y| (y.start,x.to_string())))).collect();
|
||||||
#[cfg(feature = "observe_systemstate")]
|
#[cfg(feature = "observe_systemstate")]
|
||||||
@ -319,7 +319,7 @@ let run_client = |state: Option<_>, mut mgr, _core_id| {
|
|||||||
"if=none,format=qcow2,file=dummy.qcow2",
|
"if=none,format=qcow2,file=dummy.qcow2",
|
||||||
].into_iter().map(String::from).collect();
|
].into_iter().map(String::from).collect();
|
||||||
let env: Vec<(String, String)> = env::vars().collect();
|
let env: Vec<(String, String)> = env::vars().collect();
|
||||||
let qemu = Qemu::init(&args, &env).expect("Emulator creation failed");
|
let qemu = Qemu::init(&args).expect("Emulator creation failed");
|
||||||
|
|
||||||
if let Some(main_addr) = main_addr {
|
if let Some(main_addr) = main_addr {
|
||||||
qemu.set_breakpoint(main_addr);
|
qemu.set_breakpoint(main_addr);
|
||||||
@ -343,7 +343,7 @@ let run_client = |state: Option<_>, mut mgr, _core_id| {
|
|||||||
let initial_snap = None;
|
let initial_snap = None;
|
||||||
|
|
||||||
// The wrapped harness function, calling out to the LLVM-style harness
|
// The wrapped harness function, calling out to the LLVM-style harness
|
||||||
let mut harness = |input: &MultipartInput<BytesInput>| {
|
let mut harness = |emulator: &mut Emulator<_, _, _, _, _>, state: &mut _, input: &MultipartInput<BytesInput>| {
|
||||||
unsafe {
|
unsafe {
|
||||||
#[cfg(feature = "fuzz_int")]
|
#[cfg(feature = "fuzz_int")]
|
||||||
{
|
{
|
||||||
@ -369,7 +369,7 @@ let run_client = |state: Option<_>, mut mgr, _core_id| {
|
|||||||
// Note: I could not find a difference between write_mem and write_phys_mem for my usecase
|
// Note: I could not find a difference between write_mem and write_phys_mem for my usecase
|
||||||
qemu.write_mem(input_addr, bytes);
|
qemu.write_mem(input_addr, bytes);
|
||||||
if let Some(s) = input_length_ptr {
|
if let Some(s) = input_length_ptr {
|
||||||
qemu.write_mem(s, &len.to_le_bytes())
|
qemu.write_mem(s, &len.to_le_bytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu.run();
|
qemu.run();
|
||||||
@ -496,7 +496,7 @@ let run_client = |state: Option<_>, mut mgr, _core_id| {
|
|||||||
let qhelpers = (QemuEdgeCoverageHelper::new(denylist, QemuFilterList::None), qhelpers);
|
let qhelpers = (QemuEdgeCoverageHelper::new(denylist, QemuFilterList::None), qhelpers);
|
||||||
let qhelpers = (QemuStateRestoreHelper::with_fast(initial_snap), qhelpers);
|
let qhelpers = (QemuStateRestoreHelper::with_fast(initial_snap), qhelpers);
|
||||||
|
|
||||||
let mut hooks = QemuHooks::new(qemu.clone(),qhelpers);
|
let emulator = Emulator::empty().qemu(qemu).modules(qhelpers).build().unwrap();
|
||||||
|
|
||||||
let observer_list = tuple_list!();
|
let observer_list = tuple_list!();
|
||||||
#[cfg(feature = "observe_systemstate")]
|
#[cfg(feature = "observe_systemstate")]
|
||||||
@ -507,7 +507,7 @@ let run_client = |state: Option<_>, mut mgr, _core_id| {
|
|||||||
|
|
||||||
// Create a QEMU in-process executor
|
// Create a QEMU in-process executor
|
||||||
let mut executor = QemuExecutor::new(
|
let mut executor = QemuExecutor::new(
|
||||||
&mut hooks,
|
emulator,
|
||||||
&mut harness,
|
&mut harness,
|
||||||
observer_list,
|
observer_list,
|
||||||
&mut fuzzer,
|
&mut fuzzer,
|
||||||
@ -660,7 +660,7 @@ let run_client = |state: Option<_>, mut mgr, _core_id| {
|
|||||||
// 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 = Qemu::init(&args, &env).expect("Emu creation failed");
|
let emu = Qemu::init(&args).expect("Emu creation failed");
|
||||||
|
|
||||||
if let Some(main_addr) = main_addr {
|
if let Some(main_addr) = main_addr {
|
||||||
emu.set_breakpoint(main_addr); // BREAKPOINT
|
emu.set_breakpoint(main_addr); // BREAKPOINT
|
||||||
|
@ -5,4 +5,6 @@ pub mod time;
|
|||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
pub mod systemstate;
|
pub mod systemstate;
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
mod cli;
|
mod cli;
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
pub mod templates;
|
@ -7,6 +7,8 @@ mod time;
|
|||||||
mod systemstate;
|
mod systemstate;
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
mod cli;
|
mod cli;
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
mod templates;
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
|
@ -23,6 +23,8 @@ use super::FreeRTOSSystemStateMetadata;
|
|||||||
use super::observers::QemuSystemStateObserver;
|
use super::observers::QemuSystemStateObserver;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
|
use libafl::prelude::StateInitializer;
|
||||||
|
|
||||||
//============================= Feedback
|
//============================= Feedback
|
||||||
|
|
||||||
/// Shared Metadata for a systemstateFeedback
|
/// Shared Metadata for a systemstateFeedback
|
||||||
@ -57,10 +59,14 @@ pub struct NovelSystemStateFeedback
|
|||||||
// known_traces: HashMap<u64,(u64,usize)>,
|
// known_traces: HashMap<u64,(u64,usize)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<S> StateInitializer<S> for NovelSystemStateFeedback {}
|
||||||
|
|
||||||
impl<EM, I, OT, S> Feedback<EM, I, OT, S> for NovelSystemStateFeedback
|
impl<EM, I, OT, S> Feedback<EM, I, OT, S> for NovelSystemStateFeedback
|
||||||
where
|
where
|
||||||
S: State + UsesInput + MaybeHasClientPerfMonitor + HasNamedMetadata,
|
S: State + UsesInput + MaybeHasClientPerfMonitor + HasNamedMetadata,
|
||||||
S::Input: Default,
|
S::Input: Default,
|
||||||
|
EM: EventFirer<State = S>,
|
||||||
|
OT: ObserversTuple<I, S>,
|
||||||
{
|
{
|
||||||
fn is_interesting(
|
fn is_interesting(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -71,9 +77,6 @@ where
|
|||||||
_exit_kind: &ExitKind,
|
_exit_kind: &ExitKind,
|
||||||
) -> Result<bool, Error>
|
) -> Result<bool, Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = S>,
|
|
||||||
OT: ObserversTuple<S>,
|
|
||||||
S::Input: Default
|
|
||||||
{
|
{
|
||||||
let observer : &QemuSystemStateObserver<S::Input> = observers.match_name::<QemuSystemStateObserver<S::Input>>("systemstate")
|
let observer : &QemuSystemStateObserver<S::Input> = observers.match_name::<QemuSystemStateObserver<S::Input>>("systemstate")
|
||||||
.expect("QemuSystemStateObserver not found");
|
.expect("QemuSystemStateObserver not found");
|
||||||
@ -126,7 +129,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, _manager: &mut EM, _observers: &OT, testcase: &mut Testcase<<S as UsesInput>::Input>) -> Result<(), Error> {
|
fn append_metadata(&mut self, _state: &mut S, _manager: &mut EM, _observers: &OT, testcase: &mut Testcase<I>) -> Result<(), Error> {
|
||||||
let a = self.last_trace.take();
|
let a = self.last_trace.take();
|
||||||
match a {
|
match a {
|
||||||
Some(s) => testcase.metadata_map_mut().insert(FreeRTOSSystemStateMetadata::new(s)),
|
Some(s) => testcase.metadata_map_mut().insert(FreeRTOSSystemStateMetadata::new(s)),
|
||||||
@ -170,9 +173,13 @@ pub struct DumpSystraceFeedback
|
|||||||
last_trace: Option<Vec<ExecInterval>>,
|
last_trace: Option<Vec<ExecInterval>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<S> StateInitializer<S> for DumpSystraceFeedback {}
|
||||||
|
|
||||||
impl<EM, I, OT, S> Feedback<EM, I, OT, S> for DumpSystraceFeedback
|
impl<EM, I, OT, S> Feedback<EM, I, OT, S> for DumpSystraceFeedback
|
||||||
where
|
where
|
||||||
S: State + UsesInput + MaybeHasClientPerfMonitor,
|
S: State + UsesInput + MaybeHasClientPerfMonitor,
|
||||||
|
EM: EventFirer<State = S>,
|
||||||
|
OT: ObserversTuple<I, S>
|
||||||
{
|
{
|
||||||
fn is_interesting(
|
fn is_interesting(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -183,8 +190,6 @@ where
|
|||||||
_exit_kind: &ExitKind,
|
_exit_kind: &ExitKind,
|
||||||
) -> Result<bool, Error>
|
) -> Result<bool, Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = S>,
|
|
||||||
OT: ObserversTuple<S>
|
|
||||||
{
|
{
|
||||||
if self.dumpfile.is_none() {return Ok(false)};
|
if self.dumpfile.is_none() {return Ok(false)};
|
||||||
let observer = observers.match_name::<QemuSystemStateObserver<S::Input>>("systemstate")
|
let observer = observers.match_name::<QemuSystemStateObserver<S::Input>>("systemstate")
|
||||||
@ -225,7 +230,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, _manager: &mut EM, _observers: &OT, _testcase: &mut Testcase<<S as UsesInput>::Input>) -> Result<(), Error> {
|
fn append_metadata(&mut self, _state: &mut S, _manager: &mut EM, _observers: &OT, _testcase: &mut Testcase<I>) -> 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 {
|
||||||
@ -277,10 +282,13 @@ pub struct SystraceErrorFeedback
|
|||||||
max_reports: Option<usize>,
|
max_reports: Option<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<S> StateInitializer<S> for SystraceErrorFeedback {}
|
||||||
|
|
||||||
impl<EM, I, OT, S> Feedback<EM, I, OT, S> for SystraceErrorFeedback
|
impl<EM, I, OT, S> Feedback<EM, I, OT, S> for SystraceErrorFeedback
|
||||||
where
|
where
|
||||||
S: State + UsesInput + MaybeHasClientPerfMonitor,
|
S: State + UsesInput + MaybeHasClientPerfMonitor,
|
||||||
EM: EventFirer<State = S>,
|
EM: EventFirer<State = S>,
|
||||||
|
OT: ObserversTuple<I, S>
|
||||||
{
|
{
|
||||||
fn is_interesting(
|
fn is_interesting(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -291,7 +299,6 @@ where
|
|||||||
_exit_kind: &ExitKind,
|
_exit_kind: &ExitKind,
|
||||||
) -> Result<bool, Error>
|
) -> Result<bool, Error>
|
||||||
where
|
where
|
||||||
OT: ObserversTuple<S>
|
|
||||||
{
|
{
|
||||||
#[cfg(feature = "trace_stg")]
|
#[cfg(feature = "trace_stg")]
|
||||||
{
|
{
|
||||||
@ -313,7 +320,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, _manager: &mut EM, _observers: &OT, _testcase: &mut I) -> Result<(), Error> {
|
fn append_metadata(&mut self, _state: &mut S, _manager: &mut EM, _observers: &OT, _testcase: &mut Testcase<I>) -> Result<(), Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,12 +4,14 @@ use hashbrown::HashSet;
|
|||||||
use libafl::prelude::ExitKind;
|
use libafl::prelude::ExitKind;
|
||||||
use libafl::prelude::UsesInput;
|
use libafl::prelude::UsesInput;
|
||||||
use libafl_qemu::elf::EasyElf;
|
use libafl_qemu::elf::EasyElf;
|
||||||
|
use libafl_qemu::modules::NopAddressFilter;
|
||||||
|
use libafl_qemu::modules::NopPageFilter;
|
||||||
use libafl_qemu::read_user_reg_unchecked;
|
use libafl_qemu::read_user_reg_unchecked;
|
||||||
use libafl_qemu::GuestAddr;
|
use libafl_qemu::GuestAddr;
|
||||||
use libafl_qemu::GuestPhysAddr;
|
use libafl_qemu::GuestPhysAddr;
|
||||||
use libafl_qemu::QemuHooks;
|
use libafl_qemu::QemuHooks;
|
||||||
use libafl_qemu::Hook;
|
use libafl_qemu::Hook;
|
||||||
use libafl_qemu::helpers::{QemuHelper, QemuHelperTuple};
|
use libafl_qemu::modules::{EmulatorModule, EmulatorModuleTuple};
|
||||||
use libafl_qemu::sys::TCGTemp;
|
use libafl_qemu::sys::TCGTemp;
|
||||||
use libafl_qemu::qemu::MemAccessInfo;
|
use libafl_qemu::qemu::MemAccessInfo;
|
||||||
|
|
||||||
@ -22,6 +24,8 @@ use super::freertos::rtos_struct::List_Item_struct;
|
|||||||
use super::freertos::rtos_struct::*;
|
use super::freertos::rtos_struct::*;
|
||||||
use super::freertos;
|
use super::freertos;
|
||||||
use super::CaptureEvent;
|
use super::CaptureEvent;
|
||||||
|
use libafl_qemu::EmulatorModules;
|
||||||
|
use libafl::prelude::ObserversTuple;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -156,41 +160,58 @@ impl QemuSystemStateHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> QemuHelper<S> for QemuSystemStateHelper
|
impl<S, I> EmulatorModule<S> for QemuSystemStateHelper
|
||||||
where
|
where
|
||||||
S: UsesInput,
|
S: UsesInput<Input = I> + Unpin,
|
||||||
{
|
{
|
||||||
fn first_exec<QT>(&self, _hooks: &QemuHooks)
|
fn first_exec<ET>(&mut self, _emulator_modules: &mut EmulatorModules<ET, S>, _state: &mut S)
|
||||||
where
|
where
|
||||||
QT: QemuHelperTuple<S>,
|
ET: EmulatorModuleTuple<S>,
|
||||||
{
|
{
|
||||||
// for wp in self.api_fn_addrs.keys() {
|
// for wp in self.api_fn_addrs.keys() {
|
||||||
// _hooks.instruction(*wp, Hook::Function(exec_syscall_hook::<QT, S>), false);
|
// _hooks.instruction(*wp, Hook::Function(exec_syscall_hook::<ET, S>), false);
|
||||||
// }
|
// }
|
||||||
for wp in self.isr_addrs.keys() {
|
for wp in self.isr_addrs.keys() {
|
||||||
_hooks.instruction(*wp, Hook::Function(exec_isr_hook::<QT, S>), false);
|
_emulator_modules.instructions(*wp, Hook::Function(exec_isr_hook::<ET, S>), false);
|
||||||
}
|
}
|
||||||
_hooks.jmps(Hook::Function(gen_jmp_is_syscall::<QT, S>), Hook::Function(trace_jmp::<QT, S>));
|
_emulator_modules.jmps(Hook::Function(gen_jmp_is_syscall::<ET, S>), Hook::Function(trace_jmp::<ET, S>));
|
||||||
#[cfg(feature = "trace_job_response_times")]
|
#[cfg(feature = "trace_job_response_times")]
|
||||||
_hooks.instruction(self.job_done_addrs, Hook::Function(job_done_hook::<QT, S>), false);
|
_emulator_modules.instructions(self.job_done_addrs, Hook::Function(job_done_hook::<ET, S>), false);
|
||||||
#[cfg(feature = "trace_reads")]
|
#[cfg(feature = "trace_reads")]
|
||||||
_hooks.reads(Hook::Function(gen_read_is_input::<QT, S>), Hook::Empty,Hook::Empty,Hook::Empty,Hook::Empty,Hook::Function(trace_reads::<QT, S>));
|
_emulator_modules.reads(Hook::Function(gen_read_is_input::<ET, S>), Hook::Empty,Hook::Empty,Hook::Empty,Hook::Empty,Hook::Function(trace_reads::<ET, S>));
|
||||||
unsafe { INPUT_MEM = self.input_mem.clone() };
|
unsafe { INPUT_MEM = self.input_mem.clone() };
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: refactor duplicate code
|
// TODO: refactor duplicate code
|
||||||
fn pre_exec(&mut self, _emulator: libafl_qemu::Qemu, _input: &I) {
|
fn pre_exec<ET>(
|
||||||
|
&mut self,
|
||||||
|
_emulator_modules: &mut EmulatorModules<ET, S>,
|
||||||
|
_state: &mut S,
|
||||||
|
_input: &S::Input,
|
||||||
|
) where
|
||||||
|
ET: EmulatorModuleTuple<S>,
|
||||||
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
CURRENT_SYSTEMSTATE_VEC.clear();
|
CURRENT_SYSTEMSTATE_VEC.clear();
|
||||||
JOBS_DONE.clear();
|
JOBS_DONE.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn post_exec<OT>(&mut self, emulator: libafl_qemu::Qemu, _input: &I, _observers: &mut OT, _exit_kind: &mut ExitKind) {
|
fn post_exec<OT, ET>(
|
||||||
trigger_collection(&emulator,(0, 0), CaptureEvent::End, self);
|
&mut self,
|
||||||
|
_emulator_modules: &mut EmulatorModules<ET, S>,
|
||||||
|
_state: &mut S,
|
||||||
|
_input: &S::Input,
|
||||||
|
_observers: &mut OT,
|
||||||
|
_exit_kind: &mut ExitKind,
|
||||||
|
) where
|
||||||
|
OT: ObserversTuple<S::Input, S>,
|
||||||
|
ET: EmulatorModuleTuple<S>,
|
||||||
|
{
|
||||||
|
trigger_collection(&_emulator_modules.qemu(),(0, 0), CaptureEvent::End, self);
|
||||||
unsafe {
|
unsafe {
|
||||||
let c = emulator.cpu_from_index(0);
|
let c = _emulator_modules.qemu().cpu_from_index(0);
|
||||||
let pc = c.read_reg::<i32, u32>(15).unwrap();
|
let pc = c.read_reg::<i32>(15).unwrap();
|
||||||
if CURRENT_SYSTEMSTATE_VEC.len() == 0 {return;}
|
if CURRENT_SYSTEMSTATE_VEC.len() == 0 {return;}
|
||||||
CURRENT_SYSTEMSTATE_VEC[CURRENT_SYSTEMSTATE_VEC.len()-1].edge = (pc,0);
|
CURRENT_SYSTEMSTATE_VEC[CURRENT_SYSTEMSTATE_VEC.len()-1].edge = (pc,0);
|
||||||
CURRENT_SYSTEMSTATE_VEC[CURRENT_SYSTEMSTATE_VEC.len()-1].capture_point = (CaptureEvent::End,"Breakpoint".to_string());
|
CURRENT_SYSTEMSTATE_VEC[CURRENT_SYSTEMSTATE_VEC.len()-1].capture_point = (CaptureEvent::End,"Breakpoint".to_string());
|
||||||
@ -207,6 +228,26 @@ where
|
|||||||
CURRENT_SYSTEMSTATE_VEC.drain(..index);
|
CURRENT_SYSTEMSTATE_VEC.drain(..index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ModuleAddressFilter = NopAddressFilter;
|
||||||
|
|
||||||
|
type ModulePageFilter = NopPageFilter;
|
||||||
|
|
||||||
|
fn address_filter(&self) -> &Self::ModuleAddressFilter {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn address_filter_mut(&mut self) -> &mut Self::ModuleAddressFilter {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn page_filter(&self) -> &Self::ModulePageFilter {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn page_filter_mut(&mut self) -> &mut Self::ModulePageFilter {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_freertos_list(systemstate : &mut RawFreeRTOSSystemState, emulator: &libafl_qemu::Qemu, target: GuestAddr) -> (freertos::List_t, bool) {
|
fn read_freertos_list(systemstate : &mut RawFreeRTOSSystemState, emulator: &libafl_qemu::Qemu, target: GuestAddr) -> (freertos::List_t, bool) {
|
||||||
@ -341,57 +382,57 @@ fn trigger_collection(emulator: &libafl_qemu::Qemu, edge: (GuestAddr, GuestAddr)
|
|||||||
pub static mut JOBS_DONE : Vec<(u64, String)> = vec![];
|
pub static mut JOBS_DONE : Vec<(u64, String)> = vec![];
|
||||||
|
|
||||||
pub fn job_done_hook<QT, S>(
|
pub fn job_done_hook<QT, S>(
|
||||||
hooks: &mut QemuHooks,
|
hooks: &mut EmulatorModules<QT, S>,
|
||||||
_state: Option<&mut S>,
|
_state: Option<&mut S>,
|
||||||
_pc: GuestAddr,
|
_pc: GuestAddr,
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
QT: QemuHelperTuple<S>,
|
QT: EmulatorModuleTuple<S>,
|
||||||
{
|
{
|
||||||
let emulator = hooks.qemu();
|
let emulator = hooks.qemu();
|
||||||
let h = hooks.helpers().match_first_type::<QemuSystemStateHelper>().expect("QemuSystemHelper not found in helper tupel");
|
let h = hooks.modules().match_first_type::<QemuSystemStateHelper>().expect("QemuSystemHelper not found in helper tupel");
|
||||||
let curr_tcb_addr : freertos::void_ptr = freertos::emu_lookup::lookup(emulator, h.tcb_addr);
|
let curr_tcb_addr : freertos::void_ptr = freertos::emu_lookup::lookup(&emulator, h.tcb_addr);
|
||||||
if curr_tcb_addr == 0 {
|
if curr_tcb_addr == 0 {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let current_tcb : TCB_t = freertos::emu_lookup::lookup(emulator,curr_tcb_addr);
|
let current_tcb : TCB_t = freertos::emu_lookup::lookup(&emulator,curr_tcb_addr);
|
||||||
let tmp = unsafe {std::mem::transmute::<[i8; 10],[u8; 10]>(current_tcb.pcTaskName)};
|
let tmp = unsafe {std::mem::transmute::<[i8; 10],[u8; 10]>(current_tcb.pcTaskName)};
|
||||||
let name : String = std::str::from_utf8(&tmp).expect("TCB name was not utf8").chars().filter(|x| *x != '\0').collect::<String>();
|
let name : String = std::str::from_utf8(&tmp).expect("TCB name was not utf8").chars().filter(|x| *x != '\0').collect::<String>();
|
||||||
unsafe { JOBS_DONE.push((get_icount(emulator), name)); }
|
unsafe { JOBS_DONE.push((get_icount(&emulator), name)); }
|
||||||
}
|
}
|
||||||
|
|
||||||
//============================= Trace interrupt service routines
|
//============================= Trace interrupt service routines
|
||||||
|
|
||||||
pub fn exec_isr_hook<QT, S>(
|
pub fn exec_isr_hook<QT, S>(
|
||||||
hooks: &mut QemuHooks,
|
hooks: &mut EmulatorModules<QT, S>,
|
||||||
_state: Option<&mut S>,
|
_state: Option<&mut S>,
|
||||||
pc: GuestAddr,
|
pc: GuestAddr,
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
QT: QemuHelperTuple<S>,
|
QT: EmulatorModuleTuple<S>,
|
||||||
{
|
{
|
||||||
let emulator = hooks.qemu();
|
let emulator = hooks.qemu();
|
||||||
let h = hooks.helpers().match_first_type::<QemuSystemStateHelper>().expect("QemuSystemHelper not found in helper tupel");
|
let h = hooks.modules().match_first_type::<QemuSystemStateHelper>().expect("QemuSystemHelper not found in helper tupel");
|
||||||
let src = read_rec_return_stackframe(emulator, 0xfffffffc);
|
let src = read_rec_return_stackframe(&emulator, 0xfffffffc);
|
||||||
trigger_collection(emulator, (src, pc), CaptureEvent::ISRStart, h);
|
trigger_collection(&emulator, (src, pc), CaptureEvent::ISRStart, h);
|
||||||
// println!("Exec ISR Call {:#x} {:#x} {}", src, pc, get_icount(emulator));
|
// println!("Exec ISR Call {:#x} {:#x} {}", src, pc, get_icount(emulator));
|
||||||
}
|
}
|
||||||
|
|
||||||
//============================= Trace syscalls and returns
|
//============================= Trace syscalls and returns
|
||||||
|
|
||||||
pub fn gen_jmp_is_syscall<QT, S>(
|
pub fn gen_jmp_is_syscall<QT, S>(
|
||||||
hooks: &mut QemuHooks,
|
hooks: &mut EmulatorModules<QT, S>,
|
||||||
_state: Option<&mut S>,
|
_state: Option<&mut S>,
|
||||||
src: GuestAddr,
|
src: GuestAddr,
|
||||||
dest: GuestAddr,
|
dest: GuestAddr,
|
||||||
) -> Option<u64>
|
) -> Option<u64>
|
||||||
where
|
where
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
QT: QemuHelperTuple<S>,
|
QT: EmulatorModuleTuple<S>,
|
||||||
{
|
{
|
||||||
if let Some(h) = hooks.helpers().match_first_type::<QemuSystemStateHelper>() {
|
if let Some(h) = hooks.modules().match_first_type::<QemuSystemStateHelper>() {
|
||||||
if h.app_range.contains(&src) && !h.app_range.contains(&dest) && in_any_range(&h.isr_ranges,src).is_none() {
|
if h.app_range.contains(&src) && !h.app_range.contains(&dest) && in_any_range(&h.isr_ranges,src).is_none() {
|
||||||
if let Some(_) = in_any_range(&h.api_fn_ranges,dest) {
|
if let Some(_) = in_any_range(&h.api_fn_ranges,dest) {
|
||||||
// println!("New jmp {:x} {:x}", src, dest);
|
// println!("New jmp {:x} {:x}", src, dest);
|
||||||
@ -415,18 +456,18 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn trace_jmp<QT, S>(
|
pub fn trace_jmp<QT, S>(
|
||||||
hooks: &mut QemuHooks,
|
hooks: &mut EmulatorModules<QT, S>,
|
||||||
_state: Option<&mut S>,
|
_state: Option<&mut S>,
|
||||||
src: GuestAddr, mut dest: GuestAddr, id: u64
|
src: GuestAddr, mut dest: GuestAddr, id: u64
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
QT: QemuHelperTuple<S>,
|
QT: EmulatorModuleTuple<S>,
|
||||||
{
|
{
|
||||||
let h = hooks.helpers().match_first_type::<QemuSystemStateHelper>().expect("QemuSystemHelper not found in helper tupel");
|
let h = hooks.modules().match_first_type::<QemuSystemStateHelper>().expect("QemuSystemHelper not found in helper tupel");
|
||||||
let emulator = hooks.qemu();
|
let emulator = hooks.qemu();
|
||||||
if id == 1 { // API call
|
if id == 1 { // API call
|
||||||
trigger_collection(emulator, (src, dest), CaptureEvent::APIStart, h);
|
trigger_collection(&emulator, (src, dest), CaptureEvent::APIStart, h);
|
||||||
// println!("Exec API Call {:#x} {:#x} {}", src, dest, get_icount(emulator));
|
// println!("Exec API Call {:#x} {:#x} {}", src, dest, get_icount(emulator));
|
||||||
} else if id == 2 { // API return
|
} else if id == 2 { // API return
|
||||||
// Ignore returns to other APIs or ISRs. We only account for the first call depth of API calls from user space.
|
// Ignore returns to other APIs or ISRs. We only account for the first call depth of API calls from user space.
|
||||||
@ -436,17 +477,17 @@ where
|
|||||||
edge.0=in_any_range(&h.api_fn_ranges, src).unwrap().start;
|
edge.0=in_any_range(&h.api_fn_ranges, src).unwrap().start;
|
||||||
edge.1=dest;
|
edge.1=dest;
|
||||||
|
|
||||||
trigger_collection(emulator, edge, CaptureEvent::APIEnd, h);
|
trigger_collection(&emulator, edge, CaptureEvent::APIEnd, h);
|
||||||
// println!("Exec API Return Edge {:#x} {:#x} {}", src, dest, get_icount(emulator));
|
// println!("Exec API Return Edge {:#x} {:#x} {}", src, dest, get_icount(emulator));
|
||||||
}
|
}
|
||||||
} else if id == 3 { // ISR return
|
} else if id == 3 { // ISR return
|
||||||
dest = read_rec_return_stackframe(emulator, dest);
|
dest = read_rec_return_stackframe(&emulator, dest);
|
||||||
|
|
||||||
let mut edge = (0, 0);
|
let mut edge = (0, 0);
|
||||||
edge.0=in_any_range(&h.isr_ranges, src).unwrap().start;
|
edge.0=in_any_range(&h.isr_ranges, src).unwrap().start;
|
||||||
edge.1=dest;
|
edge.1=dest;
|
||||||
|
|
||||||
trigger_collection(emulator, edge, CaptureEvent::ISREnd, h);
|
trigger_collection(&emulator, edge, CaptureEvent::ISREnd, h);
|
||||||
// println!("Exec ISR Return Edge {:#x} {:#x} {}", src, dest, get_icount(emulator));
|
// println!("Exec ISR Return Edge {:#x} {:#x} {}", src, dest, get_icount(emulator));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -454,7 +495,7 @@ where
|
|||||||
//============================= Read Hooks
|
//============================= Read Hooks
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub fn gen_read_is_input<QT, S>(
|
pub fn gen_read_is_input<QT, S>(
|
||||||
hooks: &mut QemuHooks,
|
hooks: &mut EmulatorModules<QT, S>,
|
||||||
_state: Option<&mut S>,
|
_state: Option<&mut S>,
|
||||||
pc: GuestAddr,
|
pc: GuestAddr,
|
||||||
_addr: *mut TCGTemp,
|
_addr: *mut TCGTemp,
|
||||||
@ -462,9 +503,9 @@ pub fn gen_read_is_input<QT, S>(
|
|||||||
) -> Option<u64>
|
) -> Option<u64>
|
||||||
where
|
where
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
QT: QemuHelperTuple<S>,
|
QT: EmulatorModuleTuple<S>,
|
||||||
{
|
{
|
||||||
if let Some(h) = hooks.helpers().match_first_type::<QemuSystemStateHelper>() {
|
if let Some(h) = hooks.modules().match_first_type::<QemuSystemStateHelper>() {
|
||||||
if h.app_range.contains(&pc) {
|
if h.app_range.contains(&pc) {
|
||||||
// println!("gen_read {:x}", pc);
|
// println!("gen_read {:x}", pc);
|
||||||
return Some(1);
|
return Some(1);
|
||||||
@ -478,7 +519,7 @@ static mut MEM_READ : Option<Vec<(GuestAddr, u8)>> = None;
|
|||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub fn trace_reads<QT, S>(
|
pub fn trace_reads<QT, S>(
|
||||||
hooks: &mut QemuHooks,
|
hooks: &mut EmulatorModules<QT, S>,
|
||||||
_state: Option<&mut S>,
|
_state: Option<&mut S>,
|
||||||
_id: u64,
|
_id: u64,
|
||||||
addr: GuestAddr,
|
addr: GuestAddr,
|
||||||
@ -486,7 +527,7 @@ pub fn trace_reads<QT, S>(
|
|||||||
)
|
)
|
||||||
where
|
where
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
QT: QemuHelperTuple<S>,
|
QT: EmulatorModuleTuple<S>,
|
||||||
{
|
{
|
||||||
if unsafe { INPUT_MEM.contains(&addr) } {
|
if unsafe { INPUT_MEM.contains(&addr) } {
|
||||||
let emulator = hooks.qemu();
|
let emulator = hooks.qemu();
|
||||||
|
@ -64,7 +64,7 @@ pub struct RawFreeRTOSSystemState {
|
|||||||
capture_point: (CaptureEvent,String),
|
capture_point: (CaptureEvent,String),
|
||||||
mem_reads: Vec<(u32, u8)>
|
mem_reads: Vec<(u32, u8)>
|
||||||
}
|
}
|
||||||
/// List of system state dumps from QemuHelpers
|
/// List of system state dumps from EmulatorModules
|
||||||
static mut CURRENT_SYSTEMSTATE_VEC: Vec<RawFreeRTOSSystemState> = vec![];
|
static mut CURRENT_SYSTEMSTATE_VEC: Vec<RawFreeRTOSSystemState> = vec![];
|
||||||
|
|
||||||
/// A reduced version of freertos::TCB_t
|
/// A reduced version of freertos::TCB_t
|
||||||
|
@ -9,7 +9,7 @@ use libafl_bolts::{rands::{
|
|||||||
random_seed, Rand, StdRand
|
random_seed, Rand, StdRand
|
||||||
}, Named};
|
}, Named};
|
||||||
use libafl::{
|
use libafl::{
|
||||||
common::{HasMetadata, HasNamedMetadata}, corpus::{self, Corpus}, events::{Event, EventFirer, EventProcessor, LogSeverity}, fuzzer::Evaluator, inputs::{HasMutatorBytes, HasTargetBytes, Input, MultipartInput}, mark_feature_time, {new_hash_feedback, AggregatorOps, CorpusId, MutationResult, Mutator, UserStats, UserStatsValue, UsesInput}, stages::Stage, start_timer, state::{HasCorpus, HasRand, MaybeHasClientPerfMonitor, UsesState}, Error
|
common::{HasMetadata, HasNamedMetadata}, corpus::{self, Corpus, HasCurrentCorpusId, Testcase}, events::{Event, EventFirer, EventProcessor, LogSeverity}, fuzzer::Evaluator, inputs::{HasMutatorBytes, HasTargetBytes, Input, MultipartInput}, mark_feature_time, prelude::{new_hash_feedback, AggregatorOps, CorpusId, MutationResult, Mutator, UserStats, UserStatsValue, UsesInput}, stages::Stage, start_timer, state::{HasCorpus, HasRand, MaybeHasClientPerfMonitor, UsesState}, Error
|
||||||
};
|
};
|
||||||
use libafl::prelude::State;
|
use libafl::prelude::State;
|
||||||
use petgraph::{graph::NodeIndex, graph::{self, DiGraph}};
|
use petgraph::{graph::NodeIndex, graph::{self, DiGraph}};
|
||||||
@ -163,16 +163,15 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, EM, Z, I> Stage<E, EM, Z> for InterruptShiftStage<E, EM, Z>
|
impl<S, E, EM, Z, I> Stage<E, EM, Z> for InterruptShiftStage<E, EM, Z>
|
||||||
where
|
where
|
||||||
E: UsesState<State = Z::State>,
|
E: UsesState<State = S>,
|
||||||
EM: UsesState<State = Z::State>,
|
EM: UsesState<State = S>,
|
||||||
|
Z: Evaluator<E, EM, State = S>,
|
||||||
|
S: State<Input = MultipartInput<I>> + HasRand + HasCorpus + HasCurrentTestcase + HasMetadata + HasNamedMetadata,
|
||||||
|
<<Self as UsesState>::State as HasCorpus>::Corpus: Corpus<Input = Self::Input>, //delete me
|
||||||
EM: EventFirer,
|
EM: EventFirer,
|
||||||
Z: Evaluator<E, EM>,
|
I: Default + Input + HasMutatorBytes,
|
||||||
Z::State: MaybeHasClientPerfMonitor + HasCorpus + HasRand + HasMetadata + HasNamedMetadata,
|
|
||||||
<Z::State as UsesInput>::Input: Input,
|
|
||||||
Z::State: UsesInput<Input = MultipartInput<I>>,
|
|
||||||
I: HasMutatorBytes + Default
|
|
||||||
{
|
{
|
||||||
fn perform(
|
fn perform(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -180,7 +179,8 @@ where
|
|||||||
executor: &mut E,
|
executor: &mut E,
|
||||||
state: &mut Self::State,
|
state: &mut Self::State,
|
||||||
manager: &mut EM
|
manager: &mut EM
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error>
|
||||||
|
where <Z as UsesState>::State: HasCorpus {
|
||||||
if self.interrup_config.len() == 0 {return Ok(());} // configuration implies no interrupts
|
if self.interrup_config.len() == 0 {return Ok(());} // configuration implies no interrupts
|
||||||
let mut myrand = StdRand::new();
|
let mut myrand = StdRand::new();
|
||||||
myrand.set_seed(state.rand_mut().next());
|
myrand.set_seed(state.rand_mut().next());
|
||||||
@ -203,10 +203,10 @@ where
|
|||||||
let name = format!("isr_{}_times", interrup_config.0);
|
let name = format!("isr_{}_times", interrup_config.0);
|
||||||
// manager.log(state, LogSeverity::Info, format!("Mutation {}/{}", loopbound, loopcount))?;
|
// manager.log(state, LogSeverity::Info, format!("Mutation {}/{}", loopbound, loopcount))?;
|
||||||
|
|
||||||
let curr_case = state.current_testcase()?;
|
let curr_case : std::cell::Ref<Testcase<MultipartInput<_>>> = state.current_testcase()?;
|
||||||
let curr_input = curr_case.input().as_ref().unwrap();
|
let curr_input = curr_case.input().as_ref().unwrap();
|
||||||
|
|
||||||
let mut new_input = curr_input.clone();
|
let mut new_input : MultipartInput<I> = curr_input.clone();
|
||||||
let new_interrupt_part : &mut I = if new_input.parts_by_name(&name).next().is_some() {
|
let new_interrupt_part : &mut I = if new_input.parts_by_name(&name).next().is_some() {
|
||||||
new_input.parts_by_name_mut(&name).next().unwrap()
|
new_input.parts_by_name_mut(&name).next().unwrap()
|
||||||
} else {
|
} else {
|
||||||
@ -521,7 +521,9 @@ where
|
|||||||
Z::State: MaybeHasClientPerfMonitor + HasCorpus + HasRand + HasMetadata + HasNamedMetadata,
|
Z::State: MaybeHasClientPerfMonitor + HasCorpus + HasRand + HasMetadata + HasNamedMetadata,
|
||||||
<Z::State as UsesInput>::Input: Input,
|
<Z::State as UsesInput>::Input: Input,
|
||||||
Z::State: UsesInput<Input = MultipartInput<I>>,
|
Z::State: UsesInput<Input = MultipartInput<I>>,
|
||||||
I: HasMutatorBytes + Default
|
I: HasMutatorBytes + Default,
|
||||||
|
Z::State: HasCurrentTestcase+HasCorpus+HasCurrentCorpusId,
|
||||||
|
<Z::State as HasCorpus>::Corpus: Corpus<Input = MultipartInput<I>>
|
||||||
{
|
{
|
||||||
fn perform(
|
fn perform(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -537,7 +539,7 @@ where
|
|||||||
|
|
||||||
let current_case = state.current_testcase()?;
|
let current_case = state.current_testcase()?;
|
||||||
let old_input = current_case.input().as_ref().unwrap();
|
let old_input = current_case.input().as_ref().unwrap();
|
||||||
let mut new_input = old_input.clone();
|
let mut new_input : MultipartInput<I> = old_input.clone();
|
||||||
let new_bytes = new_input.parts_by_name_mut("bytes").next().expect("bytes not found in multipart input").1.bytes_mut();
|
let new_bytes = new_input.parts_by_name_mut("bytes").next().expect("bytes not found in multipart input").1.bytes_mut();
|
||||||
// dbg!(current_case.metadata_map());
|
// dbg!(current_case.metadata_map());
|
||||||
// eprintln!("Run mutator {}", current_case.metadata_map().get::<STGNodeMetadata>().is_some());
|
// eprintln!("Run mutator {}", current_case.metadata_map().get::<STGNodeMetadata>().is_some());
|
||||||
|
@ -49,10 +49,11 @@ pub struct QemuSystemStateObserver<I>
|
|||||||
name: Cow<'static, str>,
|
name: Cow<'static, str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, S> Observer<<S as UsesInput>::Input, S> for QemuSystemStateObserver<<S as UsesInput>::Input>
|
impl<I, S> Observer<I, S> for QemuSystemStateObserver<I>
|
||||||
where
|
where
|
||||||
S: UsesInput + HasMetadata,
|
S: UsesInput<Input = I> + HasMetadata,
|
||||||
S::Input: Default
|
S::Input: Default,
|
||||||
|
I: Clone,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
|
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
|
||||||
|
@ -7,8 +7,9 @@ use libafl_bolts::current_time;
|
|||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
use libafl::{
|
use libafl::{
|
||||||
corpus::{Corpus, HasCurrentCorpusId}, events::EventFirer, schedulers::minimizer::TopRatedsMetadata, RemovableScheduler, schedulers::minimizer::IsFavoredMetadata, stages::Stage, state::{HasCorpus, HasImported, UsesState}, Error, HasMetadata, HasScheduler
|
corpus::{Corpus, HasCurrentCorpusId}, events::EventFirer, schedulers::minimizer::TopRatedsMetadata, schedulers::RemovableScheduler, schedulers::minimizer::IsFavoredMetadata, stages::Stage, state::{HasCorpus, HasImported, UsesState}, Error, HasMetadata, HasScheduler
|
||||||
};
|
};
|
||||||
|
use libafl::prelude::UsesInput;
|
||||||
use libafl::{
|
use libafl::{
|
||||||
events::Event,
|
events::Event,
|
||||||
monitors::{AggregatorOps, UserStats, UserStatsValue},
|
monitors::{AggregatorOps, UserStats, UserStatsValue},
|
||||||
@ -20,6 +21,22 @@ use libafl::prelude::mutational::MUTATION_STAGE_ITER;
|
|||||||
use libafl::prelude::mutational::MUTATION_STAGE_RETRY;
|
use libafl::prelude::mutational::MUTATION_STAGE_RETRY;
|
||||||
use libafl::prelude::mutational::MUTATION_STAGE_SUCCESS;
|
use libafl::prelude::mutational::MUTATION_STAGE_SUCCESS;
|
||||||
|
|
||||||
|
use libafl::HasNamedMetadata;
|
||||||
|
use libafl::prelude::Feedback;
|
||||||
|
use libafl::prelude::HasMaxSize;
|
||||||
|
use libafl::prelude::HasSolutions;
|
||||||
|
use libafl::prelude::HasExecutions;
|
||||||
|
use std::hash::Hash;
|
||||||
|
use libafl_bolts::HasLen;
|
||||||
|
use libafl::prelude::mutational::MutatedTransform;
|
||||||
|
use libafl::prelude::FeedbackFactory;
|
||||||
|
use serde::Serialize;
|
||||||
|
use libafl::prelude::ObserversTuple;
|
||||||
|
use libafl::prelude::HasObservers;
|
||||||
|
use libafl::HasFeedback;
|
||||||
|
use libafl::ExecutesInput;
|
||||||
|
use libafl::ExecutionProcessor;
|
||||||
|
|
||||||
/// The [`AflStatsStage`] is a simple stage that computes and reports some stats.
|
/// The [`AflStatsStage`] is a simple stage that computes and reports some stats.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct SchedulerStatsStage<E, EM, Z> {
|
pub struct SchedulerStatsStage<E, EM, Z> {
|
||||||
@ -37,13 +54,35 @@ where
|
|||||||
type State = E::State;
|
type State = E::State;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, EM, Z> Stage<E, EM, Z> for SchedulerStatsStage<E, EM, Z>
|
// impl<E, EM, Z> Stage<E, EM, Z> for SchedulerStatsStage<E, EM, Z>
|
||||||
|
// where
|
||||||
|
// E: UsesState,
|
||||||
|
// EM: UsesState<State = Self::State>,
|
||||||
|
// Z: UsesState<State = Self::State>,
|
||||||
|
// Self::State: HasNamedMetadata,
|
||||||
|
// // E: UsesState,
|
||||||
|
// // EM: EventFirer<State = Self::State>,
|
||||||
|
// // Z: UsesState<State = Self::State> + HasScheduler,
|
||||||
|
// // <Z as HasScheduler>::Scheduler: UsesState+RemovableScheduler<<<Z as HasScheduler>::Scheduler as UsesInput>::Input, Self::State>,
|
||||||
|
// // Self::State: HasImported + HasCorpus + HasMetadata,
|
||||||
|
// // <E as UsesState>::State: HasMetadata+HasImported+UsesState,
|
||||||
|
// {
|
||||||
|
impl<E, EM, IP, Z> Stage<E, EM, Z> for SchedulerStatsStage<E, EM, Z>
|
||||||
where
|
where
|
||||||
E: UsesState,
|
Z: HasScheduler + ExecutionProcessor<EM, E::Observers> + ExecutesInput<E, EM> + HasFeedback,
|
||||||
|
Z::Scheduler: RemovableScheduler<Self::Input, Self::State>,
|
||||||
|
E: HasObservers + UsesState<State = Z::State>,
|
||||||
|
E::Observers: ObserversTuple<Self::Input, Self::State> + Serialize,
|
||||||
EM: EventFirer<State = Self::State>,
|
EM: EventFirer<State = Self::State>,
|
||||||
Z: UsesState<State = Self::State> + HasScheduler,
|
// FF: FeedbackFactory<F, E::Observers>,
|
||||||
<Z as HasScheduler>::Scheduler: RemovableScheduler,
|
// F: Feedback<EM, Self::Input, E::Observers, Self::State>,
|
||||||
Self::State: HasImported + HasCorpus + HasMetadata,
|
Self::Input: MutatedTransform<Self::Input, Self::State, Post = IP> + Clone,
|
||||||
|
Z::State:
|
||||||
|
HasMetadata + HasExecutions + HasSolutions + HasCorpus + HasMaxSize + HasNamedMetadata,
|
||||||
|
Z::Feedback: Feedback<EM, Self::Input, E::Observers, Self::State>,
|
||||||
|
// M: Mutator<Self::Input, Self::State>,
|
||||||
|
// IP: MutatedTransformPost<Self::State> + Clone,
|
||||||
|
<<Self as UsesState>::State as HasCorpus>::Corpus: Corpus<Input = Self::Input>, // delete me
|
||||||
{
|
{
|
||||||
fn perform(
|
fn perform(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -45,9 +45,9 @@ where
|
|||||||
type State = CS::State;
|
type State = CS::State;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<CS> Scheduler<CS::State, CS::Input> for LongestTraceScheduler<CS>
|
impl<CS> Scheduler<CS::Input, CS::State> for LongestTraceScheduler<CS>
|
||||||
where
|
where
|
||||||
CS: UsesState + Scheduler<CS::State, CS::Input>,
|
CS: UsesState + Scheduler<CS::Input, CS::State>,
|
||||||
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
|
||||||
@ -98,7 +98,7 @@ where
|
|||||||
.metadata_map()
|
.metadata_map()
|
||||||
.get::<STGNodeMetadata>().map_or(0, |x| x.nodes().len());
|
.get::<STGNodeMetadata>().map_or(0, |x| x.nodes().len());
|
||||||
let m = self.get_update_trace_length(state,l);
|
let m = self.get_update_trace_length(state,l);
|
||||||
state.rand_mut().below(m as usize) > l
|
state.rand_mut().below(std::num::NonZero::new(m as usize+1).unwrap()) > l
|
||||||
} && state.rand_mut().coinflip(self.skip_non_favored_prob)
|
} && state.rand_mut().coinflip(self.skip_non_favored_prob)
|
||||||
{
|
{
|
||||||
idx = self.base.next(state)?;
|
idx = self.base.next(state)?;
|
||||||
@ -108,7 +108,7 @@ where
|
|||||||
|
|
||||||
fn set_current_scheduled(
|
fn set_current_scheduled(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut <<CS as UsesState>::State as UsesInput>::Input,
|
state: &mut <CS as UsesState>::State,
|
||||||
next_id: Option<libafl::corpus::CorpusId>,
|
next_id: Option<libafl::corpus::CorpusId>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
self.base.set_current_scheduled(state, next_id)
|
self.base.set_current_scheduled(state, next_id)
|
||||||
@ -117,7 +117,7 @@ where
|
|||||||
|
|
||||||
impl<CS> LongestTraceScheduler<CS>
|
impl<CS> LongestTraceScheduler<CS>
|
||||||
where
|
where
|
||||||
CS: UsesState + Scheduler<CS::State, CS::Input>,
|
CS: UsesState + Scheduler<CS::Input, CS::State>,
|
||||||
CS::State: HasCorpus + HasMetadata + HasRand,
|
CS::State: HasCorpus + HasMetadata + HasRand,
|
||||||
{
|
{
|
||||||
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 {
|
||||||
@ -173,6 +173,7 @@ where
|
|||||||
impl<I, S> Scheduler<I, S> for GenerationScheduler<S>
|
impl<I, S> Scheduler<I, S> for GenerationScheduler<S>
|
||||||
where
|
where
|
||||||
S: State + HasCorpus + HasMetadata,
|
S: State + HasCorpus + HasMetadata,
|
||||||
|
<<S as HasCorpus>::Corpus as libafl::corpus::Corpus>::Input: Clone,
|
||||||
{
|
{
|
||||||
/// 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
|
||||||
@ -247,7 +248,7 @@ where
|
|||||||
state: &mut S,
|
state: &mut S,
|
||||||
next_id: Option<libafl::corpus::CorpusId>,
|
next_id: Option<libafl::corpus::CorpusId>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
self.base.set_current_scheduled(state, next_id)
|
Ok(())
|
||||||
}
|
}
|
||||||
// fn on_replace(
|
// fn on_replace(
|
||||||
// &self,
|
// &self,
|
||||||
@ -276,7 +277,7 @@ where
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> RemovableScheduler for GenerationScheduler<S>
|
impl<I,S> RemovableScheduler<I,S> for GenerationScheduler<S>
|
||||||
where
|
where
|
||||||
S: State + HasCorpus + HasMetadata,
|
S: State + HasCorpus + HasMetadata,
|
||||||
{
|
{
|
||||||
@ -285,7 +286,7 @@ where
|
|||||||
&mut self,
|
&mut self,
|
||||||
state: &mut <Self as UsesState>::State,
|
state: &mut <Self as UsesState>::State,
|
||||||
idx: CorpusId,
|
idx: CorpusId,
|
||||||
testcase: &Testcase<<<Self as UsesState>::State as UsesInput>::Input>,
|
testcase: &Testcase<I>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -295,7 +296,7 @@ where
|
|||||||
&mut self,
|
&mut self,
|
||||||
state: &mut <Self as UsesState>::State,
|
state: &mut <Self as UsesState>::State,
|
||||||
idx: CorpusId,
|
idx: CorpusId,
|
||||||
testcase: &Option<Testcase<<<Self as UsesState>::State as UsesInput>::Input>>,
|
testcase: &Option<Testcase<I>>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,6 @@ use libafl::state::MaybeHasClientPerfMonitor;
|
|||||||
use libafl::feedbacks::Feedback;
|
use libafl::feedbacks::Feedback;
|
||||||
use libafl_bolts::Named;
|
use libafl_bolts::Named;
|
||||||
use libafl::Error;
|
use libafl::Error;
|
||||||
use libafl_qemu::edges::EDGES_MAP_SIZE_IN_USE;
|
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use libafl::{executors::ExitKind, observers::ObserversTuple, common::HasMetadata};
|
use libafl::{executors::ExitKind, observers::ObserversTuple, common::HasMetadata};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -300,8 +299,8 @@ impl HasRefCnt for STGNodeMetadata {
|
|||||||
|
|
||||||
libafl_bolts::impl_serdeany!(STGNodeMetadata);
|
libafl_bolts::impl_serdeany!(STGNodeMetadata);
|
||||||
|
|
||||||
pub type GraphMaximizerCorpusScheduler<CS, O> =
|
pub type GraphMaximizerCorpusScheduler<CS, S, O> =
|
||||||
MinimizerScheduler<CS, MaxTimeFavFactor<<CS as UsesState>::State>,STGNodeMetadata,O>;
|
MinimizerScheduler<CS, MaxTimeFavFactor<S>,STGNodeMetadata,O>;
|
||||||
|
|
||||||
// AI generated, human verified
|
// AI generated, human verified
|
||||||
/// Count the occurrences of each element in a vector, assumes the vector is sorted
|
/// Count the occurrences of each element in a vector, assumes the vector is sorted
|
||||||
@ -336,7 +335,8 @@ where
|
|||||||
|
|
||||||
//============================= Graph Feedback
|
//============================= Graph Feedback
|
||||||
|
|
||||||
pub static mut STG_MAP: [u16; EDGES_MAP_SIZE_IN_USE] = [0; EDGES_MAP_SIZE_IN_USE];
|
pub const STG_MAP_SIZE: usize = 1<<20;
|
||||||
|
pub static mut STG_MAP: [u16; STG_MAP_SIZE] = [0; STG_MAP_SIZE];
|
||||||
pub static mut MAX_STG_NUM: usize = 0;
|
pub static mut MAX_STG_NUM: usize = 0;
|
||||||
pub unsafe fn stg_map_mut_slice<'a>() -> OwnedMutSlice<'a, u16> {
|
pub unsafe fn stg_map_mut_slice<'a>() -> OwnedMutSlice<'a, u16> {
|
||||||
OwnedMutSlice::from_raw_parts_mut(STG_MAP.as_mut_ptr(), STG_MAP.len())
|
OwnedMutSlice::from_raw_parts_mut(STG_MAP.as_mut_ptr(), STG_MAP.len())
|
||||||
@ -531,7 +531,7 @@ where
|
|||||||
S: State + UsesInput + MaybeHasClientPerfMonitor + HasNamedMetadata,
|
S: State + UsesInput + MaybeHasClientPerfMonitor + HasNamedMetadata,
|
||||||
S::Input: Default,
|
S::Input: Default,
|
||||||
EM: EventFirer<State = S>,
|
EM: EventFirer<State = S>,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<I, S>,
|
||||||
{
|
{
|
||||||
#[allow(clippy::wrong_self_convention)]
|
#[allow(clippy::wrong_self_convention)]
|
||||||
fn is_interesting(
|
fn is_interesting(
|
||||||
|
159
fuzzers/FRET/src/templates.rs
Normal file
159
fuzzers/FRET/src/templates.rs
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
use libafl::{events::EventFirer, inputs::UsesInput, prelude::{Feedback, ObserversTuple, StateInitializer}};
|
||||||
|
use libafl_bolts::Named;
|
||||||
|
use libafl_qemu::{modules::EmulatorModule, EmulatorModules};
|
||||||
|
use std::borrow::Cow;
|
||||||
|
use libafl::prelude::*;
|
||||||
|
use libafl_qemu::modules::*;
|
||||||
|
use libafl_qemu::*;
|
||||||
|
|
||||||
|
//============================================== Feedback
|
||||||
|
|
||||||
|
/// Example Feedback for type correctness
|
||||||
|
#[derive(Clone, Debug, Default)]
|
||||||
|
pub struct MinimalFeedback {
|
||||||
|
/// The name
|
||||||
|
name: Cow<'static, str>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S> StateInitializer<S> for MinimalFeedback {}
|
||||||
|
|
||||||
|
impl<EM, I, OT, S> Feedback<EM, I, OT, S> for MinimalFeedback
|
||||||
|
where
|
||||||
|
S: State + UsesInput<Input=I>,
|
||||||
|
EM: EventFirer<State = S>,
|
||||||
|
OT: ObserversTuple<I, S>,
|
||||||
|
{
|
||||||
|
#[allow(clippy::wrong_self_convention)]
|
||||||
|
fn is_interesting(
|
||||||
|
&mut self,
|
||||||
|
state: &mut S,
|
||||||
|
manager: &mut EM,
|
||||||
|
input: &I,
|
||||||
|
observers: &OT,
|
||||||
|
exit_kind: &ExitKind,
|
||||||
|
) -> Result<bool, Error> {
|
||||||
|
Ok(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Named for MinimalFeedback {
|
||||||
|
#[inline]
|
||||||
|
fn name(&self) -> &Cow<'static, str> {
|
||||||
|
&self.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================================== TestcaseScore
|
||||||
|
|
||||||
|
pub struct MinimalTestcaseScore {}
|
||||||
|
|
||||||
|
impl<S> TestcaseScore<S> for MinimalTestcaseScore
|
||||||
|
where
|
||||||
|
S: HasMetadata + HasCorpus,
|
||||||
|
{
|
||||||
|
fn compute(
|
||||||
|
_state: &S,
|
||||||
|
entry: &mut Testcase<<S::Corpus as Corpus>::Input>,
|
||||||
|
) -> Result<f64, Error> {
|
||||||
|
Ok(0 as f64)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================================== EmulatorModule
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct MinimalEmulatorModule {
|
||||||
|
af: NopAddressFilter,
|
||||||
|
pf: NopPageFilter
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S> EmulatorModule<S> for MinimalEmulatorModule
|
||||||
|
where
|
||||||
|
S: UsesInput,
|
||||||
|
{
|
||||||
|
const HOOKS_DO_SIDE_EFFECTS: bool = true;
|
||||||
|
type ModuleAddressFilter = NopAddressFilter;
|
||||||
|
type ModulePageFilter = NopPageFilter;
|
||||||
|
|
||||||
|
|
||||||
|
/// Hook run **before** QEMU is initialized.
|
||||||
|
/// This is always run when Emulator gets initialized, in any case.
|
||||||
|
/// Install here hooks that should be alive for the whole execution of the VM, even before QEMU gets initialized.
|
||||||
|
fn pre_qemu_init<ET>(&self, _emulator_hooks: &mut EmulatorHooks<ET, S>)
|
||||||
|
where
|
||||||
|
ET: EmulatorModuleTuple<S>,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Hook run **after** QEMU is initialized.
|
||||||
|
/// This is always run when Emulator gets initialized, in any case.
|
||||||
|
/// Install here hooks that should be alive for the whole execution of the VM, after QEMU gets initialized.
|
||||||
|
fn post_qemu_init<ET>(&self, _emulator_modules: &mut EmulatorModules<ET, S>)
|
||||||
|
where
|
||||||
|
ET: EmulatorModuleTuple<S>,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Run once just before fuzzing starts.
|
||||||
|
/// This call can be delayed to the point at which fuzzing is supposed to start.
|
||||||
|
/// It is mostly used to avoid running hooks during VM initialization, either
|
||||||
|
/// because it is useless or it would produce wrong results.
|
||||||
|
fn first_exec<ET>(&mut self, _emulator_modules: &mut EmulatorModules<ET, S>, _state: &mut S)
|
||||||
|
where
|
||||||
|
ET: EmulatorModuleTuple<S>,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Run before a new fuzzing run starts.
|
||||||
|
/// On the first run, it is executed after [`Self::first_exec`].
|
||||||
|
fn pre_exec<ET>(
|
||||||
|
&mut self,
|
||||||
|
_emulator_modules: &mut EmulatorModules<ET, S>,
|
||||||
|
_state: &mut S,
|
||||||
|
_input: &S::Input,
|
||||||
|
) where
|
||||||
|
ET: EmulatorModuleTuple<S>,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Run after a fuzzing run ends.
|
||||||
|
fn post_exec<OT, ET>(
|
||||||
|
&mut self,
|
||||||
|
_emulator_modules: &mut EmulatorModules<ET, S>,
|
||||||
|
_state: &mut S,
|
||||||
|
_input: &S::Input,
|
||||||
|
_observers: &mut OT,
|
||||||
|
_exit_kind: &mut ExitKind,
|
||||||
|
) where
|
||||||
|
OT: ObserversTuple<S::Input, S>,
|
||||||
|
ET: EmulatorModuleTuple<S>,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// This is getting executed in a signal handler.
|
||||||
|
unsafe fn on_crash(&mut self) {}
|
||||||
|
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// This is getting executed in a signal handler.
|
||||||
|
unsafe fn on_timeout(&mut self) {}
|
||||||
|
|
||||||
|
fn address_filter(&self) -> &Self::ModuleAddressFilter {
|
||||||
|
&self.af
|
||||||
|
}
|
||||||
|
fn address_filter_mut(&mut self) -> &mut Self::ModuleAddressFilter {
|
||||||
|
&mut self.af
|
||||||
|
}
|
||||||
|
fn update_address_filter(&mut self, qemu: Qemu, filter: Self::ModuleAddressFilter) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn page_filter(&self) -> &Self::ModulePageFilter {
|
||||||
|
&self.pf
|
||||||
|
}
|
||||||
|
|
||||||
|
fn page_filter_mut(&mut self) -> &mut Self::ModulePageFilter {
|
||||||
|
&mut self.pf
|
||||||
|
}
|
||||||
|
}
|
@ -43,6 +43,8 @@ pub fn tick_to_time(ticks: u64) -> Duration {
|
|||||||
pub fn tick_to_ms(ticks: u64) -> f32 {
|
pub fn tick_to_ms(ticks: u64) -> f32 {
|
||||||
(Duration::from_nanos(ticks << QEMU_ICOUNT_SHIFT).as_micros() as f32/10.0).round()/100.0
|
(Duration::from_nanos(ticks << QEMU_ICOUNT_SHIFT).as_micros() as f32/10.0).round()/100.0
|
||||||
}
|
}
|
||||||
|
use libafl::prelude::StateInitializer;
|
||||||
|
|
||||||
|
|
||||||
//========== Metadata
|
//========== Metadata
|
||||||
#[derive(Debug, SerdeAny, Serialize, Deserialize)]
|
#[derive(Debug, SerdeAny, Serialize, Deserialize)]
|
||||||
@ -216,10 +218,14 @@ pub struct ClockTimeFeedback {
|
|||||||
name: Cow<'static, str>,
|
name: Cow<'static, str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<S> StateInitializer<S> for ClockTimeFeedback {}
|
||||||
|
|
||||||
impl<EM, I, OT, S> Feedback<EM, I, OT, S> for ClockTimeFeedback
|
impl<EM, I, OT, S> Feedback<EM, I, OT, S> for ClockTimeFeedback
|
||||||
where
|
where
|
||||||
S: State + UsesInput + MaybeHasClientPerfMonitor + HasMetadata,
|
S: State + UsesInput + MaybeHasClientPerfMonitor + HasMetadata,
|
||||||
<S as UsesInput>::Input: Default
|
<S as UsesInput>::Input: Default,
|
||||||
|
EM: EventFirer<State = S>,
|
||||||
|
OT: ObserversTuple<I, S>,
|
||||||
{
|
{
|
||||||
#[allow(clippy::wrong_self_convention)]
|
#[allow(clippy::wrong_self_convention)]
|
||||||
fn is_interesting(
|
fn is_interesting(
|
||||||
@ -231,8 +237,6 @@ where
|
|||||||
_exit_kind: &ExitKind,
|
_exit_kind: &ExitKind,
|
||||||
) -> Result<bool, Error>
|
) -> Result<bool, Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = S>,
|
|
||||||
OT: ObserversTuple<S>,
|
|
||||||
{
|
{
|
||||||
#[cfg(feature="trace_job_response_times")]
|
#[cfg(feature="trace_job_response_times")]
|
||||||
{
|
{
|
||||||
@ -255,7 +259,7 @@ where
|
|||||||
_state: &mut S,
|
_state: &mut S,
|
||||||
_manager: &mut EM,
|
_manager: &mut EM,
|
||||||
_observers: &OT,
|
_observers: &OT,
|
||||||
testcase: &mut Testcase<<S as UsesInput>::Input>,
|
testcase: &mut Testcase<I>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
*testcase.exec_time_mut() = self.exec_time;
|
*testcase.exec_time_mut() = self.exec_time;
|
||||||
self.exec_time = None;
|
self.exec_time = None;
|
||||||
@ -305,9 +309,13 @@ pub struct QemuClockIncreaseFeedback {
|
|||||||
name: Cow<'static, str>,
|
name: Cow<'static, str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<S> StateInitializer<S> for QemuClockIncreaseFeedback {}
|
||||||
|
|
||||||
impl<EM, I, OT, S> Feedback<EM, I, OT, S> for QemuClockIncreaseFeedback
|
impl<EM, I, OT, S> Feedback<EM, I, OT, S> for QemuClockIncreaseFeedback
|
||||||
where
|
where
|
||||||
S: State + UsesInput + HasNamedMetadata + MaybeHasClientPerfMonitor + Debug,
|
S: State + UsesInput + HasNamedMetadata + MaybeHasClientPerfMonitor + Debug,
|
||||||
|
EM: EventFirer<State = S>,
|
||||||
|
OT: ObserversTuple<I, S>,
|
||||||
{
|
{
|
||||||
fn is_interesting(
|
fn is_interesting(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -318,8 +326,6 @@ where
|
|||||||
_exit_kind: &ExitKind,
|
_exit_kind: &ExitKind,
|
||||||
) -> Result<bool, Error>
|
) -> Result<bool, Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = S>,
|
|
||||||
OT: ObserversTuple<S>,
|
|
||||||
{
|
{
|
||||||
let observer = _observers.match_name::<QemuClockObserver>("clock")
|
let observer = _observers.match_name::<QemuClockObserver>("clock")
|
||||||
.expect("QemuClockObserver not found");
|
.expect("QemuClockObserver not found");
|
||||||
@ -337,7 +343,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, _manager: &mut EM, _observers: &OT, _testcase: &mut Testcase<<S as UsesInput>::Input>) -> Result<(), Error> {
|
fn append_metadata(&mut self, _state: &mut S, _manager: &mut EM, _observers: &OT, _testcase: &mut Testcase<I>) -> Result<(), Error> {
|
||||||
// testcase.metadata_mut().insert(QemuIcountMetadata{runtime: self.last_runtime});
|
// testcase.metadata_mut().insert(QemuIcountMetadata{runtime: self.last_runtime});
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
use libafl::prelude::UsesInput;
|
use libafl::prelude::UsesInput;
|
||||||
|
use libafl_qemu::modules::NopAddressFilter;
|
||||||
|
use libafl_qemu::modules::NopPageFilter;
|
||||||
use libafl_qemu::sys::CPUArchState;
|
use libafl_qemu::sys::CPUArchState;
|
||||||
use libafl_qemu::FastSnapshotPtr;
|
use libafl_qemu::FastSnapshotPtr;
|
||||||
use libafl_qemu::QemuHelper;
|
use libafl_qemu::modules::EmulatorModule;
|
||||||
use libafl_qemu::QemuHelperTuple;
|
use libafl_qemu::modules::EmulatorModuleTuple;
|
||||||
use libafl::executors::ExitKind;
|
use libafl::executors::ExitKind;
|
||||||
use libafl_qemu::QemuHooks;
|
use libafl_qemu::QemuHooks;
|
||||||
|
use libafl_qemu::EmulatorModules;
|
||||||
|
use libafl::prelude::ObserversTuple;
|
||||||
|
|
||||||
// TODO be thread-safe maybe with https://amanieu.github.io/thread_local-rs/thread_local/index.html
|
// TODO be thread-safe maybe with https://amanieu.github.io/thread_local-rs/thread_local/index.html
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -39,36 +43,43 @@ impl Default for QemuStateRestoreHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> QemuHelper<S> for QemuStateRestoreHelper
|
impl<S> EmulatorModule<S> for QemuStateRestoreHelper
|
||||||
where
|
where
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
{
|
{
|
||||||
const HOOKS_DO_SIDE_EFFECTS: bool = true;
|
const HOOKS_DO_SIDE_EFFECTS: bool = true;
|
||||||
|
type ModuleAddressFilter = NopAddressFilter;
|
||||||
|
type ModulePageFilter = NopPageFilter;
|
||||||
|
|
||||||
fn init_hooks<QT>(&self, _hooks: &QemuHooks)
|
fn post_exec<OT, ET>(
|
||||||
where
|
&mut self,
|
||||||
QT: QemuHelperTuple<S>,
|
_emulator_modules: &mut EmulatorModules<ET, S>,
|
||||||
|
_state: &mut S,
|
||||||
|
_input: &S::Input,
|
||||||
|
_observers: &mut OT,
|
||||||
|
_exit_kind: &mut ExitKind,
|
||||||
|
) where
|
||||||
|
OT: ObserversTuple<S::Input, S>,
|
||||||
|
ET: EmulatorModuleTuple<S>,
|
||||||
{
|
{
|
||||||
}
|
|
||||||
|
|
||||||
fn first_exec<QT>(&self, _hooks: &QemuHooks)
|
|
||||||
where
|
|
||||||
QT: QemuHelperTuple<S>,
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
fn post_exec<OT>(&mut self, _emulator: libafl_qemu::Qemu, _input: &I, _observers: &mut OT, _exit_kind: &mut ExitKind) {
|
|
||||||
// unsafe { println!("snapshot post {}",emu::icount_get_raw()) };
|
// unsafe { println!("snapshot post {}",emu::icount_get_raw()) };
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pre_exec(&mut self, emulator: libafl_qemu::Qemu, _input: &I) {
|
fn pre_exec<ET>(
|
||||||
|
&mut self,
|
||||||
|
_emulator_modules: &mut EmulatorModules<ET, S>,
|
||||||
|
_state: &mut S,
|
||||||
|
_input: &S::Input,
|
||||||
|
) where
|
||||||
|
ET: EmulatorModuleTuple<S>,
|
||||||
|
{
|
||||||
// only restore in pre-exec, to preserve the post-execution state for inspection
|
// only restore in pre-exec, to preserve the post-execution state for inspection
|
||||||
#[cfg(feature = "snapshot_restore")]
|
#[cfg(feature = "snapshot_restore")]
|
||||||
{
|
{
|
||||||
#[cfg(feature = "snapshot_fast")]
|
#[cfg(feature = "snapshot_fast")]
|
||||||
match self.fastsnap {
|
match self.fastsnap {
|
||||||
Some(s) => unsafe { emulator.restore_fast_snapshot(s) },
|
Some(s) => unsafe { _emulator_modules.qemu().restore_fast_snapshot(s) },
|
||||||
None => {self.fastsnap = Some(emulator.create_fast_snapshot(true));},
|
None => {self.fastsnap = Some(_emulator_modules.qemu().create_fast_snapshot(true));},
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "snapshot_fast"))]
|
#[cfg(not(feature = "snapshot_fast"))]
|
||||||
if !self.has_snapshot {
|
if !self.has_snapshot {
|
||||||
@ -94,4 +105,20 @@ where
|
|||||||
|
|
||||||
// unsafe { println!("snapshot pre {}",emu::icount_get_raw()) };
|
// unsafe { println!("snapshot pre {}",emu::icount_get_raw()) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn address_filter(&self) -> &Self::ModuleAddressFilter {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn address_filter_mut(&mut self) -> &mut Self::ModuleAddressFilter {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn page_filter(&self) -> &Self::ModulePageFilter {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn page_filter_mut(&mut self) -> &mut Self::ModulePageFilter {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
}
|
}
|
@ -18,7 +18,7 @@ use libafl::prelude::State;
|
|||||||
use libafl::inputs::Input;
|
use libafl::inputs::Input;
|
||||||
use libafl::feedbacks::Feedback;
|
use libafl::feedbacks::Feedback;
|
||||||
use libafl::common::HasMetadata;
|
use libafl::common::HasMetadata;
|
||||||
use libafl_qemu::edges::QemuEdgesMapMetadata;
|
use libafl_qemu::modules::edges::EdgeCoverageModule;
|
||||||
use libafl::observers::MapObserver;
|
use libafl::observers::MapObserver;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
@ -39,6 +39,8 @@ use libafl::{
|
|||||||
use crate::time::clock::QemuClockObserver;
|
use crate::time::clock::QemuClockObserver;
|
||||||
use crate::systemstate::FreeRTOSSystemStateMetadata;
|
use crate::systemstate::FreeRTOSSystemStateMetadata;
|
||||||
|
|
||||||
|
use libafl::prelude::StateInitializer;
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
//=========================== Scheduler
|
//=========================== Scheduler
|
||||||
|
|
||||||
@ -59,7 +61,7 @@ impl<S> TestcaseScore<S> for MaxTimeFavFactor<S>
|
|||||||
where
|
where
|
||||||
S: HasCorpus + HasMetadata,
|
S: HasCorpus + HasMetadata,
|
||||||
{
|
{
|
||||||
fn compute(state: &S, entry: &mut Testcase<<S as UsesInput>::Input>) -> Result<f64, Error> {
|
fn compute(state: &S, entry: &mut Testcase<<S::Corpus as Corpus>::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");
|
||||||
@ -104,23 +106,25 @@ pub struct SortedFeedback {
|
|||||||
name: Cow<'static, str>
|
name: Cow<'static, str>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<S> StateInitializer<S> for SortedFeedback {}
|
||||||
|
|
||||||
impl<EM, I, OT, S> Feedback<EM, I, OT, S> for SortedFeedback
|
impl<EM, I, OT, S> Feedback<EM, I, OT, S> for SortedFeedback
|
||||||
where
|
where
|
||||||
S: State + UsesInput + MaybeHasClientPerfMonitor,
|
S: State + UsesInput<Input = I> + MaybeHasClientPerfMonitor,
|
||||||
S::Input: HasTargetBytes,
|
S::Input: HasTargetBytes,
|
||||||
|
EM: EventFirer<State = S>,
|
||||||
|
OT: ObserversTuple<I, S>,
|
||||||
{
|
{
|
||||||
#[allow(clippy::wrong_self_convention)]
|
#[allow(clippy::wrong_self_convention)]
|
||||||
fn is_interesting(
|
fn is_interesting(
|
||||||
&mut self,
|
&mut self,
|
||||||
_state: &mut S,
|
_state: &mut S,
|
||||||
_manager: &mut EM,
|
_manager: &mut EM,
|
||||||
_input: &I,
|
_input: &S::Input,
|
||||||
_observers: &OT,
|
_observers: &OT,
|
||||||
_exit_kind: &ExitKind,
|
_exit_kind: &ExitKind,
|
||||||
) -> Result<bool, Error>
|
) -> Result<bool, Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = S>,
|
|
||||||
OT: ObserversTuple<S>,
|
|
||||||
{
|
{
|
||||||
let t = _input.target_bytes();
|
let t = _input.target_bytes();
|
||||||
let tmp = t.as_slice();
|
let tmp = t.as_slice();
|
||||||
@ -178,9 +182,13 @@ pub struct ExecTimeReachedFeedback
|
|||||||
target_time: u64,
|
target_time: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<S> StateInitializer<S> for ExecTimeReachedFeedback {}
|
||||||
|
|
||||||
impl<EM, I, OT, S> Feedback<EM, I, OT, S> for ExecTimeReachedFeedback
|
impl<EM, I, OT, S> Feedback<EM, I, OT, S> for ExecTimeReachedFeedback
|
||||||
where
|
where
|
||||||
S: State + UsesInput + MaybeHasClientPerfMonitor,
|
S: State + UsesInput + MaybeHasClientPerfMonitor,
|
||||||
|
EM: EventFirer<State = S>,
|
||||||
|
OT: ObserversTuple<I, S>,
|
||||||
{
|
{
|
||||||
#[allow(clippy::wrong_self_convention)]
|
#[allow(clippy::wrong_self_convention)]
|
||||||
fn is_interesting(
|
fn is_interesting(
|
||||||
@ -192,8 +200,6 @@ where
|
|||||||
_exit_kind: &ExitKind,
|
_exit_kind: &ExitKind,
|
||||||
) -> Result<bool, Error>
|
) -> Result<bool, Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = S>,
|
|
||||||
OT: ObserversTuple<S>,
|
|
||||||
{
|
{
|
||||||
let observer = observers.match_name::<QemuClockObserver>("clock")
|
let observer = observers.match_name::<QemuClockObserver>("clock")
|
||||||
.expect("QemuClockObserver not found");
|
.expect("QemuClockObserver not found");
|
||||||
@ -228,9 +234,13 @@ pub struct ExecTimeCollectorFeedback
|
|||||||
name: Cow<'static, str>
|
name: Cow<'static, str>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<S> StateInitializer<S> for ExecTimeCollectorFeedback {}
|
||||||
|
|
||||||
impl<EM, I, OT, S> Feedback<EM, I, OT, S> for ExecTimeCollectorFeedback
|
impl<EM, I, OT, S> Feedback<EM, I, OT, S> for ExecTimeCollectorFeedback
|
||||||
where
|
where
|
||||||
S: State + UsesInput + MaybeHasClientPerfMonitor,
|
S: State + UsesInput + MaybeHasClientPerfMonitor,
|
||||||
|
EM: EventFirer<State = S>,
|
||||||
|
OT: ObserversTuple<I, S>,
|
||||||
{
|
{
|
||||||
#[allow(clippy::wrong_self_convention)]
|
#[allow(clippy::wrong_self_convention)]
|
||||||
fn is_interesting(
|
fn is_interesting(
|
||||||
@ -242,8 +252,6 @@ where
|
|||||||
_exit_kind: &ExitKind,
|
_exit_kind: &ExitKind,
|
||||||
) -> Result<bool, Error>
|
) -> Result<bool, Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = S>,
|
|
||||||
OT: ObserversTuple<S>,
|
|
||||||
{
|
{
|
||||||
let observer = observers.match_name::<QemuClockObserver>("clock")
|
let observer = observers.match_name::<QemuClockObserver>("clock")
|
||||||
.expect("QemuClockObserver not found");
|
.expect("QemuClockObserver not found");
|
||||||
@ -300,9 +308,13 @@ pub struct ExecTimeIncFeedback
|
|||||||
last_is_longest: bool
|
last_is_longest: bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<S> StateInitializer<S> for ExecTimeIncFeedback {}
|
||||||
|
|
||||||
impl<EM, I, OT, S> Feedback<EM, I, OT, S> for ExecTimeIncFeedback
|
impl<EM, I, OT, S> Feedback<EM, I, OT, S> for ExecTimeIncFeedback
|
||||||
where
|
where
|
||||||
S: State + UsesInput + MaybeHasClientPerfMonitor,
|
S: State + UsesInput + MaybeHasClientPerfMonitor,
|
||||||
|
EM: EventFirer<State = S>,
|
||||||
|
OT: ObserversTuple<I, S>,
|
||||||
{
|
{
|
||||||
#[allow(clippy::wrong_self_convention)]
|
#[allow(clippy::wrong_self_convention)]
|
||||||
fn is_interesting(
|
fn is_interesting(
|
||||||
@ -314,8 +326,6 @@ where
|
|||||||
_exit_kind: &ExitKind,
|
_exit_kind: &ExitKind,
|
||||||
) -> Result<bool, Error>
|
) -> Result<bool, Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = S>,
|
|
||||||
OT: ObserversTuple<S>,
|
|
||||||
{
|
{
|
||||||
let observer = observers.match_name::<QemuClockObserver>("clocktime")
|
let observer = observers.match_name::<QemuClockObserver>("clocktime")
|
||||||
.expect("QemuClockObserver not found");
|
.expect("QemuClockObserver not found");
|
||||||
@ -333,7 +343,7 @@ where
|
|||||||
_state: &mut S,
|
_state: &mut S,
|
||||||
_manager: &mut EM,
|
_manager: &mut EM,
|
||||||
observers: &OT,
|
observers: &OT,
|
||||||
testcase: &mut Testcase<<S as UsesInput>::Input>,
|
testcase: &mut Testcase<I>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
#[cfg(feature = "feed_afl")]
|
#[cfg(feature = "feed_afl")]
|
||||||
if self.last_is_longest {
|
if self.last_is_longest {
|
||||||
@ -370,9 +380,14 @@ pub struct AlwaysTrueFeedback
|
|||||||
name: Cow<'static, str>
|
name: Cow<'static, str>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<S> StateInitializer<S> for AlwaysTrueFeedback {}
|
||||||
|
|
||||||
impl<EM, I, OT, S> Feedback<EM, I, OT, S> for AlwaysTrueFeedback
|
impl<EM, I, OT, S> Feedback<EM, I, OT, S> for AlwaysTrueFeedback
|
||||||
|
|
||||||
where
|
where
|
||||||
S: State + UsesInput + MaybeHasClientPerfMonitor,
|
S: State + UsesInput + MaybeHasClientPerfMonitor,
|
||||||
|
EM: EventFirer<State = S>,
|
||||||
|
OT: ObserversTuple<I, S>,
|
||||||
{
|
{
|
||||||
#[allow(clippy::wrong_self_convention)]
|
#[allow(clippy::wrong_self_convention)]
|
||||||
fn is_interesting(
|
fn is_interesting(
|
||||||
@ -384,8 +399,6 @@ where
|
|||||||
_exit_kind: &ExitKind,
|
_exit_kind: &ExitKind,
|
||||||
) -> Result<bool, Error>
|
) -> Result<bool, Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = S>,
|
|
||||||
OT: ObserversTuple<S>,
|
|
||||||
{
|
{
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
@ -425,11 +438,15 @@ where
|
|||||||
phantom: PhantomData<S>,
|
phantom: PhantomData<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// impl<S> UsesState for TimeProbMassScheduler<S> {
|
||||||
|
// type State = S;
|
||||||
|
// }
|
||||||
|
|
||||||
impl<S> TestcaseScore<S> for TimeProbFactor<S>
|
impl<S> TestcaseScore<S> for TimeProbFactor<S>
|
||||||
where
|
where
|
||||||
S: HasCorpus + HasMetadata,
|
S: HasCorpus + HasMetadata,
|
||||||
{
|
{
|
||||||
fn compute(_state: &S, entry: &mut Testcase<<S as UsesInput>::Input>) -> Result<f64, Error> {
|
fn compute(_state: &S, entry: &mut Testcase<<S::Corpus as Corpus>::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");
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
use paste::paste;
|
||||||
|
use crate::extern_c_checked;
|
||||||
|
|
||||||
|
extern_c_checked!(
|
||||||
|
pub fn icount_get_raw() -> u64;
|
||||||
|
);
|
@ -16,6 +16,7 @@ use crate::qemu::{
|
|||||||
CrashHookClosure, CrashHookFn, PostSyscallHookClosure, PostSyscallHookFn,
|
CrashHookClosure, CrashHookFn, PostSyscallHookClosure, PostSyscallHookFn,
|
||||||
PreSyscallHookClosure, PreSyscallHookFn,
|
PreSyscallHookClosure, PreSyscallHookFn,
|
||||||
};
|
};
|
||||||
|
use crate::{JmpExecHook, JmpGenHook};
|
||||||
use crate::{
|
use crate::{
|
||||||
cpu_run_post_exec_hook_wrapper, cpu_run_pre_exec_hook_wrapper,
|
cpu_run_post_exec_hook_wrapper, cpu_run_pre_exec_hook_wrapper,
|
||||||
modules::{EmulatorModule, EmulatorModuleTuple},
|
modules::{EmulatorModule, EmulatorModuleTuple},
|
||||||
@ -765,23 +766,8 @@ where
|
|||||||
|
|
||||||
pub fn jmps(
|
pub fn jmps(
|
||||||
&mut self,
|
&mut self,
|
||||||
generation_hook: Hook<
|
generation_hook: JmpGenHook<ET, S>,
|
||||||
fn(&mut Self, Option<&mut S>, src: GuestAddr, dest: GuestAddr) -> Option<u64>,
|
execution_hook: JmpExecHook<ET, S>,
|
||||||
Box<
|
|
||||||
dyn for<'a> FnMut(
|
|
||||||
&'a mut Self,
|
|
||||||
Option<&'a mut S>,
|
|
||||||
GuestAddr,
|
|
||||||
GuestAddr,
|
|
||||||
) -> Option<u64>,
|
|
||||||
>,
|
|
||||||
extern "C" fn(*const (), src: GuestAddr, dest: GuestAddr) -> u64,
|
|
||||||
>,
|
|
||||||
execution_hook: Hook<
|
|
||||||
fn(&mut Self, Option<&mut S>, src: GuestAddr, dest: GuestAddr, id: u64),
|
|
||||||
Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, GuestAddr, GuestAddr, u64)>,
|
|
||||||
extern "C" fn(*const (), src: GuestAddr, dest: GuestAddr, id: u64),
|
|
||||||
>,
|
|
||||||
) -> JmpHookId {
|
) -> JmpHookId {
|
||||||
unsafe {
|
unsafe {
|
||||||
let gen = get_raw_hook!(
|
let gen = get_raw_hook!(
|
||||||
@ -1162,6 +1148,14 @@ where
|
|||||||
) -> NewThreadHookId {
|
) -> NewThreadHookId {
|
||||||
self.hooks.thread_creation_closure(hook)
|
self.hooks.thread_creation_closure(hook)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn jmps(
|
||||||
|
&mut self,
|
||||||
|
generation_hook: JmpGenHook<ET, S>,
|
||||||
|
execution_hook: JmpExecHook<ET, S>,
|
||||||
|
) -> JmpHookId {
|
||||||
|
self.hooks.jmps(generation_hook, execution_hook)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<ET, S> EmulatorModules<ET, S>
|
impl<ET, S> EmulatorModules<ET, S>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user