working refactoring with observers
This commit is contained in:
parent
de4fb23f31
commit
9111fdcf22
@ -24,10 +24,8 @@ pub trait StateMetadata: Debug {
|
|||||||
fn name(&self) -> &'static str;
|
fn name(&self) -> &'static str;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct State<C, E, I, R>
|
pub struct State<I, R>
|
||||||
where
|
where
|
||||||
C: Corpus<I, R>,
|
|
||||||
E: Executor<I>,
|
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
@ -35,16 +33,12 @@ where
|
|||||||
start_time: u64,
|
start_time: u64,
|
||||||
metadatas: HashMap<&'static str, Box<dyn StateMetadata>>,
|
metadatas: HashMap<&'static str, Box<dyn StateMetadata>>,
|
||||||
// additional_corpuses: HashMap<&'static str, Box<dyn Corpus>>,
|
// additional_corpuses: HashMap<&'static str, Box<dyn Corpus>>,
|
||||||
observers: Vec<Rc<RefCell<dyn Observer>>>,
|
|
||||||
feedbacks: Vec<Box<dyn Feedback<I>>>,
|
feedbacks: Vec<Box<dyn Feedback<I>>>,
|
||||||
executor: E,
|
phantom: PhantomData<R>,
|
||||||
phantom: PhantomData<(C, R)>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, E, I, R> State<C, E, I, R>
|
impl<I, R> State<I, R>
|
||||||
where
|
where
|
||||||
C: Corpus<I, R>,
|
|
||||||
E: Executor<I>,
|
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
@ -108,10 +102,13 @@ where
|
|||||||
self.feedbacks_mut().push(feedback);
|
self.feedbacks_mut().push(feedback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO move some of these, like evaluate_input, to FuzzingEngine
|
||||||
|
|
||||||
/// Runs the input and triggers observers and feedback
|
/// Runs the input and triggers observers and feedback
|
||||||
pub fn evaluate_input<FE, EM>(&mut self, input: &I, engine: &FE) -> Result<u32, AflError>
|
pub fn evaluate_input<C, E, EM>(&mut self, input: &I, engine: &mut Engine<EM, E, C, I, R>) -> Result<u32, AflError>
|
||||||
where
|
where
|
||||||
FE: FuzzingEngine<EM, E, C, I, R>,
|
C: Corpus<I, R>,
|
||||||
|
E: Executor<I>,
|
||||||
EM: EventManager<C, E, I, R>,
|
EM: EventManager<C, E, I, R>,
|
||||||
{
|
{
|
||||||
engine.executor_mut().reset_observers()?;
|
engine.executor_mut().reset_observers()?;
|
||||||
@ -120,7 +117,7 @@ where
|
|||||||
engine.executor_mut().post_exec_observers()?;
|
engine.executor_mut().post_exec_observers()?;
|
||||||
|
|
||||||
let mut fitness = 0;
|
let mut fitness = 0;
|
||||||
let observers = self.executor().observers();
|
let observers = engine.executor().observers();
|
||||||
for feedback in self.feedbacks_mut() {
|
for feedback in self.feedbacks_mut() {
|
||||||
fitness += feedback.is_interesting(&input, observers)?;
|
fitness += feedback.is_interesting(&input, observers)?;
|
||||||
}
|
}
|
||||||
@ -162,12 +159,15 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Adds this input to the corpus, if it's intersting
|
/// Adds this input to the corpus, if it's intersting
|
||||||
pub fn add_if_interesting(
|
pub fn add_if_interesting<C>(
|
||||||
&mut self,
|
&mut self,
|
||||||
corpus: &mut C,
|
corpus: &mut C,
|
||||||
input: I,
|
input: I,
|
||||||
fitness: u32,
|
fitness: u32,
|
||||||
) -> Result<Option<usize>, AflError> {
|
) -> Result<Option<usize>, AflError>
|
||||||
|
where
|
||||||
|
C: Corpus<I, R>
|
||||||
|
{
|
||||||
if fitness > 0 {
|
if fitness > 0 {
|
||||||
let testcase = self.input_to_testcase(input, fitness)?;
|
let testcase = self.input_to_testcase(input, fitness)?;
|
||||||
Ok(Some(corpus.add(testcase)))
|
Ok(Some(corpus.add(testcase)))
|
||||||
@ -177,45 +177,95 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_initial_inputs<G, EM>(
|
pub fn generate_initial_inputs<G, C, E, FE, EM>(
|
||||||
&mut self,
|
&mut self,
|
||||||
rand: &mut R,
|
rand: &mut R,
|
||||||
corpus: &mut C,
|
corpus: &mut C,
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
events: &mut EM,
|
engine: &mut Engine<EM, E, C, I, R>,
|
||||||
num: usize,
|
num: usize,
|
||||||
) -> Result<(), AflError>
|
) -> Result<(), AflError>
|
||||||
where
|
where
|
||||||
G: Generator<I, R>,
|
G: Generator<I, R>,
|
||||||
|
C: Corpus<I, R>,
|
||||||
|
E: Executor<I>,
|
||||||
EM: EventManager<C, E, I, R>,
|
EM: EventManager<C, E, I, R>,
|
||||||
{
|
{
|
||||||
for _ in 0..num {
|
for _ in 0..num {
|
||||||
let input = generator.generate(rand)?;
|
let input = generator.generate(rand)?;
|
||||||
let fitness = self.evaluate_input(&input)?;
|
let fitness = self.evaluate_input(&input, engine)?;
|
||||||
self.add_if_interesting(corpus, input, fitness)?;
|
self.add_if_interesting(corpus, input, fitness)?;
|
||||||
events.fire(Event::LoadInitial {
|
engine.events_manager_mut().fire(Event::LoadInitial {
|
||||||
sender_id: 0,
|
sender_id: 0,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
events.process(self, corpus)?;
|
engine.events_manager_mut().process(self, corpus)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(executor: E) -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
executions: 0,
|
executions: 0,
|
||||||
start_time: current_milliseconds(),
|
start_time: current_milliseconds(),
|
||||||
metadatas: HashMap::default(),
|
metadatas: HashMap::default(),
|
||||||
observers: vec![],
|
|
||||||
feedbacks: vec![],
|
feedbacks: vec![],
|
||||||
executor: executor,
|
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait FuzzingEngine<EM, E, C, I, R>
|
pub struct Engine<EM, E, C, I, R>
|
||||||
|
where
|
||||||
|
EM: EventManager<C, E, I, R>,
|
||||||
|
E: Executor<I>,
|
||||||
|
C: Corpus<I, R>,
|
||||||
|
I: Input,
|
||||||
|
R: Rand,
|
||||||
|
{
|
||||||
|
manager: EM,
|
||||||
|
executor: E,
|
||||||
|
phantom: PhantomData<(C, I, R)>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<EM, E, C, I, R> Engine<EM, E, C, I, R>
|
||||||
|
where
|
||||||
|
EM: EventManager<C, E, I, R>,
|
||||||
|
E: Executor<I>,
|
||||||
|
C: Corpus<I, R>,
|
||||||
|
I: Input,
|
||||||
|
R: Rand,
|
||||||
|
{
|
||||||
|
pub fn events_manager(&self) -> &EM {
|
||||||
|
&self.manager
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn events_manager_mut(&mut self) -> &mut EM {
|
||||||
|
&mut self.manager
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the executor
|
||||||
|
pub fn executor(&self) -> &E {
|
||||||
|
&self.executor
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the executor (mutable)
|
||||||
|
pub fn executor_mut(&mut self) -> &mut E {
|
||||||
|
&mut self.executor
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO additional executors, Vec<Box<dyn Executor<I>>>
|
||||||
|
|
||||||
|
pub fn new(executor: E, events_manager: EM) -> Self {
|
||||||
|
Self {
|
||||||
|
executor: executor,
|
||||||
|
manager: events_manager,
|
||||||
|
phantom: PhantomData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Fuzzer<EM, E, C, I, R>
|
||||||
where
|
where
|
||||||
EM: EventManager<C, E, I, R>,
|
EM: EventManager<C, E, I, R>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
@ -231,24 +281,12 @@ where
|
|||||||
self.stages_mut().push(stage);
|
self.stages_mut().push(stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn events_manager(&self) -> &EM;
|
|
||||||
|
|
||||||
fn events_manager_mut(&mut self) -> &mut EM;
|
|
||||||
|
|
||||||
/// Return the executor
|
|
||||||
fn executor(&self) -> &E;
|
|
||||||
|
|
||||||
/// Return the executor (mutable)
|
|
||||||
fn executor_mut(&mut self) -> &mut E;
|
|
||||||
|
|
||||||
// TODO additional executors, Vec<Box<dyn Executor<I>>>
|
|
||||||
|
|
||||||
fn fuzz_one(
|
fn fuzz_one(
|
||||||
&mut self,
|
&mut self,
|
||||||
rand: &mut R,
|
rand: &mut R,
|
||||||
state: &mut State<C, E, I, R>,
|
state: &mut State<I, R>,
|
||||||
corpus: &mut C,
|
corpus: &mut C,
|
||||||
events: &mut EM,
|
engine: &mut Engine<EM, E, C, I, R>,
|
||||||
) -> Result<usize, AflError> {
|
) -> Result<usize, AflError> {
|
||||||
let (testcase, idx) = corpus.next(rand)?;
|
let (testcase, idx) = corpus.next(rand)?;
|
||||||
match testcase.input() {
|
match testcase.input() {
|
||||||
@ -262,27 +300,27 @@ where
|
|||||||
let input = corpus.get(idx).input().as_ref().unwrap();
|
let input = corpus.get(idx).input().as_ref().unwrap();
|
||||||
|
|
||||||
for stage in self.stages_mut() {
|
for stage in self.stages_mut() {
|
||||||
stage.perform(rand, state, corpus, events, &input)?;
|
stage.perform(rand, state, corpus, engine, &input)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
events.process(state, corpus)?;
|
engine.events_manager_mut().process(state, corpus)?;
|
||||||
Ok(idx)
|
Ok(idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fuzz_loop(
|
fn fuzz_loop(
|
||||||
&mut self,
|
&mut self,
|
||||||
rand: &mut R,
|
rand: &mut R,
|
||||||
state: &mut State<C, E, I, R>,
|
state: &mut State<I, R>,
|
||||||
corpus: &mut C,
|
corpus: &mut C,
|
||||||
events: &mut EM,
|
engine: &mut Engine<EM, E, C, I, R>,
|
||||||
) -> Result<(), AflError> {
|
) -> Result<(), AflError> {
|
||||||
let mut last = current_milliseconds();
|
let mut last = current_milliseconds();
|
||||||
loop {
|
loop {
|
||||||
self.fuzz_one(rand, state, corpus, events)?;
|
self.fuzz_one(rand, state, corpus, engine)?;
|
||||||
let cur = current_milliseconds();
|
let cur = current_milliseconds();
|
||||||
if cur - last > 60 * 100 {
|
if cur - last > 60 * 100 {
|
||||||
last = cur;
|
last = cur;
|
||||||
events.fire(Event::UpdateStats {
|
engine.events_manager_mut().fire(Event::UpdateStats {
|
||||||
sender_id: 0,
|
sender_id: 0,
|
||||||
new_execs: 1,
|
new_execs: 1,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
@ -290,9 +328,10 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct StdFuzzingEngine<EM, E, C, I, R>
|
pub struct StdFuzzer<EM, E, C, I, R>
|
||||||
where
|
where
|
||||||
EM: EventManager<C, E, I, R>,
|
EM: EventManager<C, E, I, R>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
@ -301,10 +340,9 @@ where
|
|||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
stages: Vec<Box<dyn Stage<EM, E, C, I, R>>>,
|
stages: Vec<Box<dyn Stage<EM, E, C, I, R>>>,
|
||||||
phantom: PhantomData<EM>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<EM, E, C, I, R> FuzzingEngine<EM, E, C, I, R> for StdFuzzingEngine<EM, E, C, I, R>
|
impl<EM, E, C, I, R> Fuzzer<EM, E, C, I, R> for StdFuzzer<EM, E, C, I, R>
|
||||||
where
|
where
|
||||||
EM: EventManager<C, E, I, R>,
|
EM: EventManager<C, E, I, R>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
@ -321,7 +359,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<EM, E, C, I, R> StdFuzzingEngine<EM, E, C, I, R>
|
impl<EM, E, C, I, R> StdFuzzer<EM, E, C, I, R>
|
||||||
where
|
where
|
||||||
EM: EventManager<C, E, I, R>,
|
EM: EventManager<C, E, I, R>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
@ -331,12 +369,12 @@ where
|
|||||||
{
|
{
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
stages: vec![],
|
stages: vec![]
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO: no_std test
|
// TODO: no_std test
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -348,7 +386,7 @@ mod tests {
|
|||||||
use std::io::stderr;
|
use std::io::stderr;
|
||||||
|
|
||||||
use crate::corpus::{Corpus, InMemoryCorpus, Testcase};
|
use crate::corpus::{Corpus, InMemoryCorpus, Testcase};
|
||||||
use crate::engines::{Engine, StdEngine, StdState};
|
use crate::engines::{Engine, Fuzzer, StdFuzzer, State};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use crate::events::LoggerEventManager;
|
use crate::events::LoggerEventManager;
|
||||||
use crate::executors::inmemory::InMemoryExecutor;
|
use crate::executors::inmemory::InMemoryExecutor;
|
||||||
@ -371,21 +409,22 @@ mod tests {
|
|||||||
corpus.add(testcase);
|
corpus.add(testcase);
|
||||||
|
|
||||||
let executor = InMemoryExecutor::<BytesInput>::new(harness);
|
let executor = InMemoryExecutor::<BytesInput>::new(harness);
|
||||||
let mut state = StdState::new(executor);
|
let mut state = State::new();
|
||||||
|
|
||||||
let mut events_manager = LoggerEventManager::new(stderr());
|
let mut events_manager = LoggerEventManager::new(stderr());
|
||||||
|
|
||||||
let mut engine = StdEngine::new();
|
let mut engine = Engine::new(executor, events_manager);
|
||||||
let mut mutator = StdScheduledMutator::new();
|
let mut mutator = StdScheduledMutator::new();
|
||||||
mutator.add_mutation(mutation_bitflip);
|
mutator.add_mutation(mutation_bitflip);
|
||||||
let stage = StdMutationalStage::new(mutator);
|
let stage = StdMutationalStage::new(mutator);
|
||||||
engine.add_stage(Box::new(stage));
|
let mut fuzzer = StdFuzzer::new();
|
||||||
|
fuzzer.add_stage(Box::new(stage));
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
for i in 0..1000 {
|
for i in 0..1000 {
|
||||||
engine
|
fuzzer
|
||||||
.fuzz_one(&mut rand, &mut state, &mut corpus, &mut events_manager)
|
.fuzz_one(&mut rand, &mut state, &mut corpus, &mut engine)
|
||||||
.expect(&format!("Error in iter {}", i));
|
.expect(&format!("Error in iter {}", i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,35 +60,33 @@ pub unsafe fn llmp_tcp_server_clientloop(client: *mut LlmpClient, _data: *mut c_
|
|||||||
|
|
||||||
/// Eventmanager for multi-processed application
|
/// Eventmanager for multi-processed application
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub struct LLMPEventManager<S, C, E, I, R>
|
pub struct LLMPEventManager<C, E, I, R>
|
||||||
where
|
where
|
||||||
S: State<C, E, I, R>,
|
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
I: Input,
|
I: Input,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
//CE: CustomEvent<S, C, E, I, R>,
|
//CE: CustomEvent<C, E, I, R>,
|
||||||
{
|
{
|
||||||
// TODO...
|
// TODO...
|
||||||
phantom: PhantomData<(S, C, E, I, R)>,
|
phantom: PhantomData<(C, E, I, R)>,
|
||||||
is_broker: bool,
|
is_broker: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<S, C, E, I, R> EventManager<S, C, E, I, R> for LLMPEventManager<S, C, E, I, R>
|
impl<C, E, I, R> EventManager<C, E, I, R> for LLMPEventManager<C, E, I, R>
|
||||||
where
|
where
|
||||||
S: State<C, E, I, R>,
|
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
//CE: CustomEvent<S, C, E, I, R>,
|
//CE: CustomEvent<C, E, I, R>,
|
||||||
{
|
{
|
||||||
fn enabled(&self) -> bool {
|
fn enabled(&self) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fire(&mut self, _event: Event<S, C, E, I, R>) -> Result<(), AflError> {
|
fn fire(&mut self, _event: Event<C, E, I, R>) -> Result<(), AflError> {
|
||||||
//self.events.push(event);
|
//self.events.push(event);
|
||||||
|
|
||||||
// TODO: Serde serialize, llmp send
|
// TODO: Serde serialize, llmp send
|
||||||
@ -96,7 +94,7 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process(&mut self, _state: &mut S, _corpus: &mut C) -> Result<usize, AflError> {
|
fn process(&mut self, _state: &mut State<I, R>, _corpus: &mut C) -> Result<usize, AflError> {
|
||||||
// TODO: iterators
|
// TODO: iterators
|
||||||
/*
|
/*
|
||||||
let mut handled = vec![];
|
let mut handled = vec![];
|
||||||
@ -127,9 +125,8 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<S, C, E, I, R> LLMPEventManager<S, C, E, I, R>
|
impl<C, E, I, R> LLMPEventManager<C, E, I, R>
|
||||||
where
|
where
|
||||||
S: State<C, E, I, R>,
|
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
I: Input,
|
I: Input,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
|
@ -34,9 +34,9 @@ enum BrokerEventResult {
|
|||||||
/*
|
/*
|
||||||
|
|
||||||
/// A custom event, in case a user wants to extend the features (at compile time)
|
/// A custom event, in case a user wants to extend the features (at compile time)
|
||||||
pub trait CustomEvent<S, C, E, I, R>
|
pub trait CustomEvent<C, E, I, R>
|
||||||
where
|
where
|
||||||
S: State<C, E, I, R>,
|
S: State<I, R>,
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
@ -45,81 +45,79 @@ where
|
|||||||
/// Returns the name of this event
|
/// Returns the name of this event
|
||||||
fn name(&self) -> &str;
|
fn name(&self) -> &str;
|
||||||
/// This method will be called in the broker
|
/// This method will be called in the broker
|
||||||
fn handle_in_broker(&self, broker: &dyn EventManager<S, C, E, I, R, Self>, state: &mut S, corpus: &mut C) -> Result<BrokerEventResult, AflError>;
|
fn handle_in_broker(&self, broker: &dyn EventManager<C, E, I, R, Self>, state: &mut State<I, R>, corpus: &mut C) -> Result<BrokerEventResult, AflError>;
|
||||||
/// This method will be called in the clients after handle_in_broker (unless BrokerEventResult::Handled) was returned in handle_in_broker
|
/// This method will be called in the clients after handle_in_broker (unless BrokerEventResult::Handled) was returned in handle_in_broker
|
||||||
fn handle_in_client(&self, client: &dyn EventManager<S, C, E, I, R, Self>, state: &mut S, corpus: &mut C) -> Result<(), AflError>;
|
fn handle_in_client(&self, client: &dyn EventManager<C, E, I, R, Self>, state: &mut State<I, R>, corpus: &mut C) -> Result<(), AflError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct UnusedCustomEvent {}
|
struct UnusedCustomEvent {}
|
||||||
impl<S, C, E, I, R> CustomEvent<S, C, E, I, R> for UnusedCustomEvent<S, C, E, I, R>
|
impl<C, E, I, R> CustomEvent<C, E, I, R> for UnusedCustomEvent<C, E, I, R>
|
||||||
where
|
where
|
||||||
S: State<C, E, I, R>,
|
S: State<I, R>,
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
fn name(&self) -> &str {"No custom events"}
|
fn name(&self) -> &str {"No custom events"}
|
||||||
fn handle_in_broker(&self, broker: &dyn EventManager<S, C, E, I, R, Self>, state: &mut S, corpus: &mut C) {Ok(BrokerEventResult::Handled)}
|
fn handle_in_broker(&self, broker: &dyn EventManager<C, E, I, R, Self>, state: &mut State<I, R>, corpus: &mut C) {Ok(BrokerEventResult::Handled)}
|
||||||
fn handle_in_client(&self, client: &dyn EventManager<S, C, E, I, R, Self>, state: &mut S, corpus: &mut C) {Ok(())}
|
fn handle_in_client(&self, client: &dyn EventManager<C, E, I, R, Self>, state: &mut State<I, R>, corpus: &mut C) {Ok(())}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/// Events sent around in the library
|
/// Events sent around in the library
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub enum Event<S, C, E, I, R>
|
pub enum Event<C, E, I, R>
|
||||||
where
|
where
|
||||||
S: State<C, E, I, R>,
|
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
// CE: CustomEvent<S, C, E, I, R>,
|
// CE: CustomEvent<C, E, I, R>,
|
||||||
{
|
{
|
||||||
LoadInitial {
|
LoadInitial {
|
||||||
sender_id: u64,
|
sender_id: u64,
|
||||||
phantom: PhantomData<(S, C, E, I, R)>,
|
phantom: PhantomData<(C, E, I, R)>,
|
||||||
},
|
},
|
||||||
NewTestcase {
|
NewTestcase {
|
||||||
sender_id: u64,
|
sender_id: u64,
|
||||||
testcase: Testcase<I>,
|
testcase: Testcase<I>,
|
||||||
phantom: PhantomData<(S, C, E, I, R)>,
|
phantom: PhantomData<(C, E, I, R)>,
|
||||||
},
|
},
|
||||||
UpdateStats {
|
UpdateStats {
|
||||||
sender_id: u64,
|
sender_id: u64,
|
||||||
new_execs: usize,
|
new_execs: usize,
|
||||||
phantom: PhantomData<(S, C, E, I, R)>,
|
phantom: PhantomData<(C, E, I, R)>,
|
||||||
},
|
},
|
||||||
Crash {
|
Crash {
|
||||||
sender_id: u64,
|
sender_id: u64,
|
||||||
input: I,
|
input: I,
|
||||||
phantom: PhantomData<(S, C, E, I, R)>,
|
phantom: PhantomData<(C, E, I, R)>,
|
||||||
},
|
},
|
||||||
Timeout {
|
Timeout {
|
||||||
sender_id: u64,
|
sender_id: u64,
|
||||||
input: I,
|
input: I,
|
||||||
phantom: PhantomData<(S, C, E, I, R)>,
|
phantom: PhantomData<(C, E, I, R)>,
|
||||||
},
|
},
|
||||||
Log {
|
Log {
|
||||||
sender_id: u64,
|
sender_id: u64,
|
||||||
severity_level: u8,
|
severity_level: u8,
|
||||||
message: String,
|
message: String,
|
||||||
phantom: PhantomData<(S, C, E, I, R)>,
|
phantom: PhantomData<(C, E, I, R)>,
|
||||||
},
|
},
|
||||||
None {
|
None {
|
||||||
phantom: PhantomData<(S, C, E, I, R)>,
|
phantom: PhantomData<(C, E, I, R)>,
|
||||||
},
|
},
|
||||||
//Custom {sender_id: u64, custom_event: CE},
|
//Custom {sender_id: u64, custom_event: CE},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S, C, E, I, R> Event<S, C, E, I, R>
|
impl<C, E, I, R> Event<C, E, I, R>
|
||||||
where
|
where
|
||||||
S: State<C, E, I, R>,
|
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
//CE: CustomEvent<S, C, E, I, R>,
|
//CE: CustomEvent<C, E, I, R>,
|
||||||
{
|
{
|
||||||
pub fn name(&self) -> &str {
|
pub fn name(&self) -> &str {
|
||||||
match self {
|
match self {
|
||||||
@ -160,7 +158,7 @@ where
|
|||||||
|
|
||||||
fn handle_in_broker(
|
fn handle_in_broker(
|
||||||
&self,
|
&self,
|
||||||
/*broker: &dyn EventManager<S, C, E, I, R>,*/ _state: &mut S,
|
/*broker: &dyn EventManager<C, E, I, R>,*/ _state: &mut State<I, R>,
|
||||||
_corpus: &mut C,
|
_corpus: &mut C,
|
||||||
) -> Result<BrokerEventResult, AflError> {
|
) -> Result<BrokerEventResult, AflError> {
|
||||||
match self {
|
match self {
|
||||||
@ -215,7 +213,7 @@ where
|
|||||||
|
|
||||||
fn handle_in_client(
|
fn handle_in_client(
|
||||||
self,
|
self,
|
||||||
/*client: &dyn EventManager<S, C, E, I, R>,*/ _state: &mut S,
|
/*client: &dyn EventManager<C, E, I, R>,*/ _state: &mut State<I, R>,
|
||||||
corpus: &mut C,
|
corpus: &mut C,
|
||||||
) -> Result<(), AflError> {
|
) -> Result<(), AflError> {
|
||||||
match self {
|
match self {
|
||||||
@ -236,9 +234,8 @@ where
|
|||||||
// TODO serialize and deserialize, defaults to serde
|
// TODO serialize and deserialize, defaults to serde
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait EventManager<S, C, E, I, R>
|
pub trait EventManager<C, E, I, R>
|
||||||
where
|
where
|
||||||
S: State<C, E, I, R>,
|
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
@ -249,13 +246,13 @@ where
|
|||||||
fn enabled(&self) -> bool;
|
fn enabled(&self) -> bool;
|
||||||
|
|
||||||
/// Fire an Event
|
/// Fire an Event
|
||||||
fn fire(&mut self, event: Event<S, C, E, I, R>) -> Result<(), AflError>;
|
fn fire(&mut self, event: Event<C, E, I, R>) -> Result<(), AflError>;
|
||||||
|
|
||||||
/// Lookup for incoming events and process them.
|
/// Lookup for incoming events and process them.
|
||||||
/// Return the number of processes events or an error
|
/// Return the number of processes events or an error
|
||||||
fn process(&mut self, state: &mut S, corpus: &mut C) -> Result<usize, AflError>;
|
fn process(&mut self, state: &mut State<I, R>, corpus: &mut C) -> Result<usize, AflError>;
|
||||||
|
|
||||||
fn on_recv(&self, _state: &mut S, _corpus: &mut C) -> Result<(), AflError> {
|
fn on_recv(&self, _state: &mut State<I, R>, _corpus: &mut C) -> Result<(), AflError> {
|
||||||
// TODO: Better way to move out of testcase, or get ref
|
// TODO: Better way to move out of testcase, or get ref
|
||||||
//Ok(corpus.add(self.testcase.take().unwrap()))
|
//Ok(corpus.add(self.testcase.take().unwrap()))
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -263,7 +260,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*TODO
|
/*TODO
|
||||||
fn on_recv(&self, state: &mut S, _corpus: &mut C) -> Result<(), AflError> {
|
fn on_recv(&self, state: &mut State<I, R>, _corpus: &mut C) -> Result<(), AflError> {
|
||||||
println!(
|
println!(
|
||||||
"#{}\t exec/s: {}",
|
"#{}\t exec/s: {}",
|
||||||
state.executions(),
|
state.executions(),
|
||||||
@ -275,41 +272,39 @@ where
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub struct LoggerEventManager<S, C, E, I, R, W>
|
pub struct LoggerEventManager<C, E, I, R, W>
|
||||||
where
|
where
|
||||||
S: State<C, E, I, R>,
|
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
I: Input,
|
I: Input,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
W: Write,
|
W: Write,
|
||||||
//CE: CustomEvent<S, C, E, I, R>,
|
//CE: CustomEvent<C, E, I, R>,
|
||||||
{
|
{
|
||||||
events: Vec<Event<S, C, E, I, R>>,
|
events: Vec<Event<C, E, I, R>>,
|
||||||
writer: W,
|
writer: W,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<S, C, E, I, R, W> EventManager<S, C, E, I, R> for LoggerEventManager<S, C, E, I, R, W>
|
impl<C, E, I, R, W> EventManager<C, E, I, R> for LoggerEventManager<C, E, I, R, W>
|
||||||
where
|
where
|
||||||
S: State<C, E, I, R>,
|
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
W: Write,
|
W: Write,
|
||||||
//CE: CustomEvent<S, C, E, I, R>,
|
//CE: CustomEvent<C, E, I, R>,
|
||||||
{
|
{
|
||||||
fn enabled(&self) -> bool {
|
fn enabled(&self) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fire(&mut self, event: Event<S, C, E, I, R>) -> Result<(), AflError> {
|
fn fire(&mut self, event: Event<C, E, I, R>) -> Result<(), AflError> {
|
||||||
self.events.push(event);
|
self.events.push(event);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process(&mut self, state: &mut S, corpus: &mut C) -> Result<usize, AflError> {
|
fn process(&mut self, state: &mut State<I, R>, corpus: &mut C) -> Result<usize, AflError> {
|
||||||
// TODO: iterators
|
// TODO: iterators
|
||||||
let mut handled = vec![];
|
let mut handled = vec![];
|
||||||
for x in self.events.iter() {
|
for x in self.events.iter() {
|
||||||
@ -330,9 +325,8 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<S, C, E, I, R, W> LoggerEventManager<S, C, E, I, R, W>
|
impl<C, E, I, R, W> LoggerEventManager<C, E, I, R, W>
|
||||||
where
|
where
|
||||||
S: State<C, E, I, R>,
|
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
I: Input,
|
I: Input,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
|
@ -2,7 +2,7 @@ pub mod mutational;
|
|||||||
pub use mutational::StdMutationalStage;
|
pub use mutational::StdMutationalStage;
|
||||||
|
|
||||||
use crate::corpus::Corpus;
|
use crate::corpus::Corpus;
|
||||||
use crate::engines::State;
|
use crate::engines::{Engine, State};
|
||||||
use crate::events::EventManager;
|
use crate::events::EventManager;
|
||||||
use crate::executors::Executor;
|
use crate::executors::Executor;
|
||||||
use crate::inputs::Input;
|
use crate::inputs::Input;
|
||||||
@ -21,9 +21,9 @@ where
|
|||||||
fn perform(
|
fn perform(
|
||||||
&mut self,
|
&mut self,
|
||||||
rand: &mut R,
|
rand: &mut R,
|
||||||
state: &mut State<C, E, I, R>,
|
state: &mut State<I, R>,
|
||||||
corpus: &C,
|
corpus: &C,
|
||||||
events: &mut EM,
|
engine: &mut Engine<EM, E, C, I, R>,
|
||||||
input: &I,
|
input: &I,
|
||||||
) -> Result<(), AflError>;
|
) -> Result<(), AflError>;
|
||||||
}
|
}
|
||||||
|
@ -5,18 +5,17 @@ use crate::executors::Executor;
|
|||||||
use crate::inputs::Input;
|
use crate::inputs::Input;
|
||||||
use crate::mutators::Mutator;
|
use crate::mutators::Mutator;
|
||||||
use crate::stages::Corpus;
|
use crate::stages::Corpus;
|
||||||
use crate::stages::Stage;
|
use crate::stages::{Engine, Stage};
|
||||||
use crate::utils::Rand;
|
use crate::utils::Rand;
|
||||||
use crate::AflError;
|
use crate::AflError;
|
||||||
use crate::{engines::State, events::Event};
|
use crate::{engines::State, events::Event};
|
||||||
|
|
||||||
// TODO multi mutators stage
|
// TODO multi mutators stage
|
||||||
|
|
||||||
pub trait MutationalStage<M, S, EM, E, C, I, R>: Stage<S, EM, E, C, I, R>
|
pub trait MutationalStage<M, EM, E, C, I, R>: Stage<EM, E, C, I, R>
|
||||||
where
|
where
|
||||||
M: Mutator<C, I, R>,
|
M: Mutator<C, I, R>,
|
||||||
S: State<C, E, I, R>,
|
EM: EventManager<C, E, I, R>,
|
||||||
EM: EventManager<S, C, E, I, R>,
|
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
I: Input,
|
I: Input,
|
||||||
@ -38,9 +37,9 @@ where
|
|||||||
fn perform_mutational(
|
fn perform_mutational(
|
||||||
&mut self,
|
&mut self,
|
||||||
rand: &mut R,
|
rand: &mut R,
|
||||||
state: &mut S,
|
state: &mut State<I, R>,
|
||||||
corpus: &C,
|
corpus: &C,
|
||||||
events: &mut EM,
|
engine: &mut Engine<EM, E, C, I, R>,
|
||||||
input: &I,
|
input: &I,
|
||||||
) -> Result<(), AflError> {
|
) -> Result<(), AflError> {
|
||||||
let num = self.iterations(rand);
|
let num = self.iterations(rand);
|
||||||
@ -49,7 +48,7 @@ where
|
|||||||
self.mutator_mut()
|
self.mutator_mut()
|
||||||
.mutate(rand, corpus, &mut input_mut, i as i32)?;
|
.mutate(rand, corpus, &mut input_mut, i as i32)?;
|
||||||
|
|
||||||
let fitness = state.evaluate_input(&input_mut)?;
|
let fitness = state.evaluate_input(&input_mut, engine)?;
|
||||||
|
|
||||||
self.mutator_mut()
|
self.mutator_mut()
|
||||||
.post_exec(fitness, &input_mut, i as i32)?;
|
.post_exec(fitness, &input_mut, i as i32)?;
|
||||||
@ -57,7 +56,7 @@ where
|
|||||||
let testcase_maybe = state.testcase_if_interesting(input_mut, fitness)?;
|
let testcase_maybe = state.testcase_if_interesting(input_mut, fitness)?;
|
||||||
if let Some(testcase) = testcase_maybe {
|
if let Some(testcase) = testcase_maybe {
|
||||||
//corpus.entries()[idx]
|
//corpus.entries()[idx]
|
||||||
events.fire(Event::NewTestcase {
|
engine.events_manager_mut().fire(Event::NewTestcase {
|
||||||
sender_id: 0,
|
sender_id: 0,
|
||||||
testcase: testcase,
|
testcase: testcase,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
@ -69,26 +68,24 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The default mutational stage
|
/// The default mutational stage
|
||||||
pub struct StdMutationalStage<M, S, EM, E, C, I, R>
|
pub struct StdMutationalStage<M, EM, E, C, I, R>
|
||||||
where
|
where
|
||||||
M: Mutator<C, I, R>,
|
M: Mutator<C, I, R>,
|
||||||
S: State<C, E, I, R>,
|
EM: EventManager<C, E, I, R>,
|
||||||
EM: EventManager<S, C, E, I, R>,
|
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
mutator: M,
|
mutator: M,
|
||||||
phantom: PhantomData<(S, EM, E, C, I, R)>,
|
phantom: PhantomData<(EM, E, C, I, R)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M, S, EM, E, C, I, R> MutationalStage<M, S, EM, E, C, I, R>
|
impl<M, EM, E, C, I, R> MutationalStage<M, EM, E, C, I, R>
|
||||||
for StdMutationalStage<M, S, EM, E, C, I, R>
|
for StdMutationalStage<M, EM, E, C, I, R>
|
||||||
where
|
where
|
||||||
M: Mutator<C, I, R>,
|
M: Mutator<C, I, R>,
|
||||||
S: State<C, E, I, R>,
|
EM: EventManager<C, E, I, R>,
|
||||||
EM: EventManager<S, C, E, I, R>,
|
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
I: Input,
|
I: Input,
|
||||||
@ -105,11 +102,10 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M, S, EM, E, C, I, R> Stage<S, EM, E, C, I, R> for StdMutationalStage<M, S, EM, E, C, I, R>
|
impl<M, EM, E, C, I, R> Stage<EM, E, C, I, R> for StdMutationalStage<M, EM, E, C, I, R>
|
||||||
where
|
where
|
||||||
M: Mutator<C, I, R>,
|
M: Mutator<C, I, R>,
|
||||||
S: State<C, E, I, R>,
|
EM: EventManager<C, E, I, R>,
|
||||||
EM: EventManager<S, C, E, I, R>,
|
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
I: Input,
|
I: Input,
|
||||||
@ -118,20 +114,19 @@ where
|
|||||||
fn perform(
|
fn perform(
|
||||||
&mut self,
|
&mut self,
|
||||||
rand: &mut R,
|
rand: &mut R,
|
||||||
state: &mut S,
|
state: &mut State<I, R>,
|
||||||
corpus: &C,
|
corpus: &C,
|
||||||
events: &mut EM,
|
engine: &mut Engine<EM, E, C, I, R>,
|
||||||
input: &I,
|
input: &I,
|
||||||
) -> Result<(), AflError> {
|
) -> Result<(), AflError> {
|
||||||
self.perform_mutational(rand, state, corpus, events, input)
|
self.perform_mutational(rand, state, corpus, engine, input)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M, S, EM, E, C, I, R> StdMutationalStage<M, S, EM, E, C, I, R>
|
impl<M, EM, E, C, I, R> StdMutationalStage<M, EM, E, C, I, R>
|
||||||
where
|
where
|
||||||
M: Mutator<C, I, R>,
|
M: Mutator<C, I, R>,
|
||||||
S: State<C, E, I, R>,
|
EM: EventManager<C, E, I, R>,
|
||||||
EM: EventManager<S, C, E, I, R>,
|
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
I: Input,
|
I: Input,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user