report interrupt mutation statistics

This commit is contained in:
Alwin Berger 2024-10-10 15:15:23 +02:00
parent 7586c51f6f
commit 04cfa7cea2

View File

@ -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, LogSeverity}, fuzzer::Evaluator, inputs::{HasMutatorBytes, HasTargetBytes, Input, MultipartInput}, mark_feature_time, prelude::{new_hash_feedback, CorpusId, MutationResult, Mutator, UsesInput}, stages::Stage, start_timer, state::{HasCorpus, HasRand, MaybeHasClientPerfMonitor, UsesState}, Error common::{HasMetadata, HasNamedMetadata}, corpus::{self, Corpus}, events::{Event, EventFirer, 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}};
@ -126,6 +126,38 @@ where
} }
} }
static mut num_stage_execs : u64 = 0;
static mut sum_reruns : u64 = 0;
static mut sum_interesting_reruns : u64 = 0;
impl<E, EM, Z, I> InterruptShiftStage<E, EM, Z>
where
E: UsesState<State = Z::State>,
EM: UsesState<State = Z::State>,
EM: EventFirer,
Z: Evaluator<E, EM>,
Z::State: MaybeHasClientPerfMonitor + HasCorpus + HasRand + HasMetadata + HasNamedMetadata,
<Z::State as UsesInput>::Input: Input,
Z::State: UsesInput<Input = MultipartInput<I>>,
I: HasMutatorBytes + Default
{
fn report_stats(&self, state: &mut <InterruptShiftStage<E, EM, Z> as UsesState>::State, manager: &mut EM) {
unsafe {
let _ = manager.fire(
state,
Event::UpdateUserStats {
name: Cow::from("InterruptShiftStage"),
value: UserStats::new(
UserStatsValue::String(Cow::from(format!("{} -> {}/{} {:.1}% ", num_stage_execs, sum_interesting_reruns, sum_reruns, sum_interesting_reruns as f32 * 100.0 / sum_reruns as f32))),
AggregatorOps::None,
),
phantom: PhantomData,
},
);
}
}
}
impl<E, EM, Z, I> Stage<E, EM, Z> for InterruptShiftStage<E, EM, Z> impl<E, EM, Z, I> Stage<E, EM, Z> for InterruptShiftStage<E, EM, Z>
where where
E: UsesState<State = Z::State>, E: UsesState<State = Z::State>,
@ -147,16 +179,20 @@ where
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());
unsafe {num_stage_execs+=1;}
let mut rerun_count = 0; // count how many times we rerun the executor let mut rerun_count = 0; // count how many times we rerun the executor
// Try many times to find a mutation that is not already in the corpus // Try many times to find a mutation that is not already in the corpus
let loopbound = 50; let loopbound = 5;
for _ in 0..loopbound { for _ in 0..loopbound {
// Choose which isr to mutate // Choose which isr to mutate
let interrup_config = match myrand.choose(&self.interrup_config) { let interrup_config = match myrand.choose(&self.interrup_config) {
Some(s) => s, Some(s) => s,
Option::None => return Ok(()) Option::None => {
self.report_stats(state, manager);
return Ok(())
}
}; };
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))?;
@ -375,9 +411,14 @@ where
if do_rerun { if do_rerun {
rerun_count+=1; rerun_count+=1;
let (_, corpus_idx) = fuzzer.evaluate_input(state, executor, manager, new_input)?; let (_, corpus_idx) = fuzzer.evaluate_input(state, executor, manager, new_input)?;
if corpus_idx.is_some() { unsafe{sum_interesting_reruns+=1;}} else
if corpus_idx.is_none() && loopbound<=0 { break;} if corpus_idx.is_none() && loopbound<=0 { break;}
} else {if loopbound<=0 {break;}} } else {if loopbound<=0 {break;}}
} }
unsafe {
sum_reruns+=rerun_count;
}
self.report_stats(state, manager);
Ok(()) Ok(())
} }