broken engine
This commit is contained in:
parent
34d51ee5e0
commit
5e51f8f143
@ -56,14 +56,14 @@ where
|
||||
}
|
||||
|
||||
/// Gets a random entry
|
||||
fn random_entry(&mut self) -> Result<&Rc<RefCell<Testcase<I>>>, AflError> {
|
||||
fn random_entry(&mut self) -> Result<Rc<RefCell<Testcase<I>>>, AflError> {
|
||||
let len = { self.entries().len() };
|
||||
let id = self.rand_mut().below(len as u64) as usize;
|
||||
Ok(self.entries_mut().get_mut(id).unwrap())
|
||||
Ok(self.entries()[id].clone())
|
||||
}
|
||||
|
||||
/// Gets the next entry (random by default)
|
||||
fn get(&mut self) -> Result<&Rc<RefCell<Testcase<I>>>, AflError> {
|
||||
fn get(&mut self) -> Result<Rc<RefCell<Testcase<I>>>, AflError> {
|
||||
self.random_entry()
|
||||
}
|
||||
}
|
||||
@ -257,12 +257,12 @@ where
|
||||
}
|
||||
|
||||
/// Gets a random entry
|
||||
fn random_entry(&mut self) -> Result<&Rc<RefCell<Testcase<I>>>, AflError> {
|
||||
fn random_entry(&mut self) -> Result<Rc<RefCell<Testcase<I>>>, AflError> {
|
||||
self.corpus.random_entry()
|
||||
}
|
||||
|
||||
/// Gets the next entry
|
||||
fn get(&mut self) -> Result<&Rc<RefCell<Testcase<I>>>, AflError> {
|
||||
fn get(&mut self) -> Result<Rc<RefCell<Testcase<I>>>, AflError> {
|
||||
if self.corpus.count() == 0 {
|
||||
return Err(AflError::Empty("Testcases".to_string()));
|
||||
}
|
||||
@ -271,7 +271,7 @@ where
|
||||
self.cycles = self.cycles + 1;
|
||||
self.pos = 0;
|
||||
}
|
||||
Ok(self.corpus.entries_mut().get_mut(self.pos).unwrap())
|
||||
Ok(self.corpus.entries()[self.pos].clone())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,6 +82,11 @@ where
|
||||
&mut self.metadatas
|
||||
}
|
||||
|
||||
/// Add a metadata
|
||||
pub fn add_metadata(&mut self, name: String, meta: Box<dyn TestcaseMetadata>) {
|
||||
self.metadatas.insert(name, meta);
|
||||
}
|
||||
|
||||
/// Create a new DefaultTestcase instace given an input
|
||||
pub fn new(input: I) -> Self {
|
||||
Testcase {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::time;
|
||||
|
||||
use crate::engines::Engine;
|
||||
use crate::engines::Evaluator;
|
||||
use crate::executors::Executor;
|
||||
use crate::feedbacks::Feedback;
|
||||
use crate::inputs::Input;
|
||||
|
@ -1,16 +1,160 @@
|
||||
pub mod aflengine;
|
||||
|
||||
use crate::corpus::testcase::Testcase;
|
||||
use crate::corpus::Corpus;
|
||||
use crate::executors::Executor;
|
||||
use crate::feedbacks::Feedback;
|
||||
use crate::inputs::Input;
|
||||
use crate::stages::Stage;
|
||||
use crate::AflError;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub trait Engine<'a, I>
|
||||
pub trait Evaluator<I>
|
||||
where
|
||||
I: Input,
|
||||
{
|
||||
fn execute(&mut self, input: &mut I, entry: Rc<RefCell<Testcase<I>>>)
|
||||
-> Result<bool, AflError>;
|
||||
fn evaluate_input(
|
||||
&mut self,
|
||||
input: &mut I,
|
||||
entry: Rc<RefCell<Testcase<I>>>,
|
||||
) -> Result<bool, AflError>;
|
||||
}
|
||||
|
||||
pub trait Engine<'a, I, C, E>: Evaluator<I>
|
||||
where
|
||||
I: Input,
|
||||
C: Corpus<I>,
|
||||
E: Executor<I>,
|
||||
{
|
||||
fn feedbacks(&self) -> &Vec<Box<dyn Feedback<I>>>;
|
||||
|
||||
fn feedbacks_mut(&mut self) -> &mut Vec<Box<dyn Feedback<I>>>;
|
||||
|
||||
fn add_feedback(&mut self, feedback: Box<dyn Feedback<I>>) {
|
||||
self.feedbacks_mut().push(feedback);
|
||||
}
|
||||
|
||||
fn stages(&self) -> &Vec<Box<dyn Stage<'a, I, E = Self>>>;
|
||||
|
||||
fn stages_mut(&mut self) -> &mut Vec<Box<dyn Stage<'a, I, E = Self>>>;
|
||||
|
||||
fn add_stage(&mut self, stage: Box<dyn Stage<'a, I, E = Self>>) {
|
||||
self.stages_mut().push(stage);
|
||||
}
|
||||
|
||||
fn corpus(&self) -> &C;
|
||||
|
||||
fn corpus_mut(&mut self) -> &mut C;
|
||||
|
||||
fn executor(&self) -> &E;
|
||||
|
||||
fn executor_mut(&mut self) -> &mut E;
|
||||
|
||||
fn fuzz_one(&mut self) -> Result<(), AflError> {
|
||||
let entry = self.corpus_mut().get()?;
|
||||
for stage in self.stages_mut() {
|
||||
stage.perform(entry.clone())?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn evaluate_input_engine(
|
||||
&mut self,
|
||||
input: &mut I,
|
||||
entry: Rc<RefCell<Testcase<I>>>,
|
||||
) -> Result<bool, AflError> {
|
||||
{
|
||||
self.executor_mut().reset_observers()?;
|
||||
// self.executor_mut().place_input(Box::new(input))?;
|
||||
|
||||
self.executor_mut().run_target()?;
|
||||
|
||||
self.executor_mut().post_exec_observers()?;
|
||||
}
|
||||
|
||||
// TODO new method for this shit
|
||||
let mut new_entry: Option<Rc<RefCell<Testcase<I>>>> = None; // lazy init
|
||||
let mut rate_acc = 0;
|
||||
for feedback in self.feedbacks_mut() {
|
||||
let (rate, meta) = feedback.is_interesting(self.executor_mut());
|
||||
rate_acc += rate;
|
||||
if let Some(m) = meta {
|
||||
//if new_entry.is_none() {
|
||||
new_entry = Some(Rc::new(RefCell::new(Testcase::<I>::new(input.clone()))));
|
||||
//}
|
||||
new_entry
|
||||
.unwrap()
|
||||
.borrow_mut()
|
||||
.add_metadata("test".to_string(), m);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(true)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DefaultEngine<'a, I, C, E>
|
||||
where
|
||||
I: Input,
|
||||
C: Corpus<I>,
|
||||
E: Executor<I>,
|
||||
{
|
||||
feedbacks: Vec<Box<dyn Feedback<I>>>,
|
||||
stages: Vec<Box<dyn Stage<'a, I, E = Self>>>,
|
||||
executor: &'a mut E,
|
||||
corpus: &'a mut C,
|
||||
}
|
||||
|
||||
impl<'a, I, C, E> Evaluator<I> for DefaultEngine<'a, I, C, E>
|
||||
where
|
||||
I: Input,
|
||||
C: Corpus<I>,
|
||||
E: Executor<I>,
|
||||
{
|
||||
fn evaluate_input(
|
||||
&mut self,
|
||||
input: &mut I,
|
||||
entry: Rc<RefCell<Testcase<I>>>,
|
||||
) -> Result<bool, AflError> {
|
||||
self.evaluate_input_engine(input, entry)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, I, C, E> Engine<'a, I, C, E> for DefaultEngine<'a, I, C, E>
|
||||
where
|
||||
I: Input,
|
||||
C: Corpus<I>,
|
||||
E: Executor<I>,
|
||||
{
|
||||
fn feedbacks(&self) -> &Vec<Box<dyn Feedback<I>>> {
|
||||
&self.feedbacks
|
||||
}
|
||||
|
||||
fn feedbacks_mut(&mut self) -> &mut Vec<Box<dyn Feedback<I>>> {
|
||||
&mut self.feedbacks
|
||||
}
|
||||
|
||||
fn stages(&self) -> &Vec<Box<dyn Stage<'a, I, E = Self>>> {
|
||||
&self.stages
|
||||
}
|
||||
|
||||
fn stages_mut(&mut self) -> &mut Vec<Box<dyn Stage<'a, I, E = Self>>> {
|
||||
&mut self.stages
|
||||
}
|
||||
|
||||
fn corpus(&self) -> &C {
|
||||
self.corpus
|
||||
}
|
||||
|
||||
fn corpus_mut(&mut self) -> &mut C {
|
||||
self.corpus
|
||||
}
|
||||
|
||||
fn executor(&self) -> &E {
|
||||
self.executor
|
||||
}
|
||||
|
||||
fn executor_mut(&mut self) -> &mut E {
|
||||
self.executor
|
||||
}
|
||||
}
|
||||
|
@ -193,7 +193,6 @@ mod tests {
|
||||
use crate::inputs::Input;
|
||||
use crate::observers::Observer;
|
||||
use crate::AflError;
|
||||
use std::any::Any;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct NopInput {}
|
||||
|
@ -1,6 +1,6 @@
|
||||
extern crate num;
|
||||
|
||||
use crate::corpus::Testcase;
|
||||
use crate::corpus::{Testcase, TestcaseMetadata};
|
||||
use crate::executors::Executor;
|
||||
use crate::inputs::Input;
|
||||
use crate::observers::MapObserver;
|
||||
@ -14,9 +14,13 @@ where
|
||||
I: Input,
|
||||
{
|
||||
/// is_interesting should return the "Interestingness" from 0 to 255 (percent times 2.55)
|
||||
fn is_interesting(&mut self, executor: &dyn Executor<I>, entry: &Testcase<I>) -> u8;
|
||||
fn is_interesting(
|
||||
&mut self,
|
||||
executor: &dyn Executor<I>,
|
||||
) -> (u32, Option<Box<dyn TestcaseMetadata>>);
|
||||
}
|
||||
|
||||
/// A Reducer function is used to aggregate values for the novelty search
|
||||
pub trait Reducer<T>
|
||||
where
|
||||
T: Integer + Copy + 'static,
|
||||
@ -86,7 +90,10 @@ where
|
||||
O: MapObserver<T>,
|
||||
I: Input,
|
||||
{
|
||||
fn is_interesting(&mut self, _executor: &dyn Executor<I>, _entry: &Testcase<I>) -> u8 {
|
||||
fn is_interesting(
|
||||
&mut self,
|
||||
_executor: &dyn Executor<I>,
|
||||
) -> (u32, Option<Box<dyn TestcaseMetadata>>) {
|
||||
let mut interesting = 0;
|
||||
|
||||
// TODO: impl. correctly, optimize
|
||||
@ -101,11 +108,11 @@ where
|
||||
*history = reduced;
|
||||
interesting += 25;
|
||||
if interesting >= 250 {
|
||||
return 255;
|
||||
return (255, None);
|
||||
}
|
||||
}
|
||||
}
|
||||
interesting
|
||||
(interesting, None)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,25 +1,25 @@
|
||||
pub mod mutational;
|
||||
|
||||
use crate::corpus::Testcase;
|
||||
use crate::engines::Engine;
|
||||
use crate::engines::Evaluator;
|
||||
use crate::inputs::Input;
|
||||
use crate::AflError;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub trait HasEngine<'a, I>
|
||||
pub trait HasEvaluator<I>
|
||||
where
|
||||
I: Input,
|
||||
{
|
||||
type E: Engine<'a, I>;
|
||||
type E: Evaluator<I>;
|
||||
|
||||
fn engine(&self) -> &Self::E;
|
||||
fn eval(&self) -> &Self::E;
|
||||
|
||||
fn engine_mut(&mut self) -> &mut Self::E;
|
||||
fn eval_mut(&mut self) -> &mut Self::E;
|
||||
}
|
||||
|
||||
pub trait Stage<'a, I>: HasEngine<'a, I>
|
||||
pub trait Stage<'a, I>: HasEvaluator<I>
|
||||
where
|
||||
I: Input,
|
||||
{
|
||||
|
@ -1,8 +1,8 @@
|
||||
use crate::corpus::testcase::Testcase;
|
||||
use crate::engines::Engine;
|
||||
use crate::engines::Evaluator;
|
||||
use crate::inputs::Input;
|
||||
use crate::mutators::Mutator;
|
||||
use crate::stages::{HasEngine, Stage};
|
||||
use crate::stages::{HasEvaluator, Stage};
|
||||
use crate::utils::{HasRand, Rand};
|
||||
use crate::AflError;
|
||||
|
||||
@ -36,7 +36,7 @@ where
|
||||
m.mutate(&mut input, i as i32)?;
|
||||
}
|
||||
|
||||
let interesting = self.engine_mut().execute(&mut input, entry.clone())?;
|
||||
let interesting = self.eval_mut().evaluate_input(&mut input, entry.clone())?;
|
||||
|
||||
for m in self.mutators_mut() {
|
||||
m.post_exec(interesting, i as i32)?;
|
||||
@ -52,10 +52,10 @@ pub struct DefaultMutationalStage<'a, I, R, E>
|
||||
where
|
||||
I: Input,
|
||||
R: Rand,
|
||||
E: Engine<'a, I>,
|
||||
E: Evaluator<I>,
|
||||
{
|
||||
rand: &'a mut R,
|
||||
engine: &'a mut E,
|
||||
eval: &'a mut E,
|
||||
mutators: Vec<Box<dyn Mutator<I, R = R>>>,
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ impl<'a, I, R, E> HasRand for DefaultMutationalStage<'a, I, R, E>
|
||||
where
|
||||
I: Input,
|
||||
R: Rand,
|
||||
E: Engine<'a, I>,
|
||||
E: Evaluator<I>,
|
||||
{
|
||||
type R = R;
|
||||
|
||||
@ -75,20 +75,20 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, I, R, E> HasEngine<'a, I> for DefaultMutationalStage<'a, I, R, E>
|
||||
impl<'a, I, R, E> HasEvaluator<I> for DefaultMutationalStage<'a, I, R, E>
|
||||
where
|
||||
I: Input,
|
||||
R: Rand,
|
||||
E: Engine<'a, I>,
|
||||
E: Evaluator<I>,
|
||||
{
|
||||
type E = E;
|
||||
|
||||
fn engine(&self) -> &Self::E {
|
||||
self.engine
|
||||
fn eval(&self) -> &Self::E {
|
||||
self.eval
|
||||
}
|
||||
|
||||
fn engine_mut(&mut self) -> &mut Self::E {
|
||||
self.engine
|
||||
fn eval_mut(&mut self) -> &mut Self::E {
|
||||
self.eval
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,7 +96,7 @@ impl<'a, I, R, E> MutationalStage<'a, I> for DefaultMutationalStage<'a, I, R, E>
|
||||
where
|
||||
I: Input,
|
||||
R: Rand,
|
||||
E: Engine<'a, I>,
|
||||
E: Evaluator<I>,
|
||||
{
|
||||
fn mutators(&self) -> &Vec<Box<dyn Mutator<I, R = Self::R>>> {
|
||||
&self.mutators
|
||||
@ -111,7 +111,7 @@ impl<'a, I, R, E> Stage<'a, I> for DefaultMutationalStage<'a, I, R, E>
|
||||
where
|
||||
I: Input,
|
||||
R: Rand,
|
||||
E: Engine<'a, I>,
|
||||
E: Evaluator<I>,
|
||||
{
|
||||
fn perform(&mut self, entry: Rc<RefCell<Testcase<I>>>) -> Result<(), AflError> {
|
||||
self.perform_mutational(entry)
|
||||
@ -122,12 +122,12 @@ impl<'a, I, R, E> DefaultMutationalStage<'a, I, R, E>
|
||||
where
|
||||
I: Input,
|
||||
R: Rand,
|
||||
E: Engine<'a, I>,
|
||||
E: Evaluator<I>,
|
||||
{
|
||||
pub fn new(rand: &'a mut R, engine: &'a mut E) -> Self {
|
||||
pub fn new(rand: &'a mut R, eval: &'a mut E) -> Self {
|
||||
DefaultMutationalStage {
|
||||
rand: rand,
|
||||
engine: engine,
|
||||
eval: eval,
|
||||
mutators: vec![],
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user