broken engine
This commit is contained in:
parent
34d51ee5e0
commit
5e51f8f143
@ -56,14 +56,14 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a random entry
|
/// 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 len = { self.entries().len() };
|
||||||
let id = self.rand_mut().below(len as u64) as usize;
|
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)
|
/// 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()
|
self.random_entry()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -257,12 +257,12 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a random entry
|
/// 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()
|
self.corpus.random_entry()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the next 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 {
|
if self.corpus.count() == 0 {
|
||||||
return Err(AflError::Empty("Testcases".to_string()));
|
return Err(AflError::Empty("Testcases".to_string()));
|
||||||
}
|
}
|
||||||
@ -271,7 +271,7 @@ where
|
|||||||
self.cycles = self.cycles + 1;
|
self.cycles = self.cycles + 1;
|
||||||
self.pos = 0;
|
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
|
&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
|
/// Create a new DefaultTestcase instace given an input
|
||||||
pub fn new(input: I) -> Self {
|
pub fn new(input: I) -> Self {
|
||||||
Testcase {
|
Testcase {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::time;
|
use std::time;
|
||||||
|
|
||||||
use crate::engines::Engine;
|
use crate::engines::Evaluator;
|
||||||
use crate::executors::Executor;
|
use crate::executors::Executor;
|
||||||
use crate::feedbacks::Feedback;
|
use crate::feedbacks::Feedback;
|
||||||
use crate::inputs::Input;
|
use crate::inputs::Input;
|
||||||
|
@ -1,16 +1,160 @@
|
|||||||
pub mod aflengine;
|
|
||||||
|
|
||||||
use crate::corpus::testcase::Testcase;
|
use crate::corpus::testcase::Testcase;
|
||||||
|
use crate::corpus::Corpus;
|
||||||
|
use crate::executors::Executor;
|
||||||
|
use crate::feedbacks::Feedback;
|
||||||
use crate::inputs::Input;
|
use crate::inputs::Input;
|
||||||
|
use crate::stages::Stage;
|
||||||
use crate::AflError;
|
use crate::AflError;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub trait Engine<'a, I>
|
pub trait Evaluator<I>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
{
|
{
|
||||||
fn execute(&mut self, input: &mut I, entry: Rc<RefCell<Testcase<I>>>)
|
fn evaluate_input(
|
||||||
-> Result<bool, AflError>;
|
&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::inputs::Input;
|
||||||
use crate::observers::Observer;
|
use crate::observers::Observer;
|
||||||
use crate::AflError;
|
use crate::AflError;
|
||||||
use std::any::Any;
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct NopInput {}
|
struct NopInput {}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
extern crate num;
|
extern crate num;
|
||||||
|
|
||||||
use crate::corpus::Testcase;
|
use crate::corpus::{Testcase, TestcaseMetadata};
|
||||||
use crate::executors::Executor;
|
use crate::executors::Executor;
|
||||||
use crate::inputs::Input;
|
use crate::inputs::Input;
|
||||||
use crate::observers::MapObserver;
|
use crate::observers::MapObserver;
|
||||||
@ -14,9 +14,13 @@ where
|
|||||||
I: Input,
|
I: Input,
|
||||||
{
|
{
|
||||||
/// is_interesting should return the "Interestingness" from 0 to 255 (percent times 2.55)
|
/// 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>
|
pub trait Reducer<T>
|
||||||
where
|
where
|
||||||
T: Integer + Copy + 'static,
|
T: Integer + Copy + 'static,
|
||||||
@ -86,7 +90,10 @@ where
|
|||||||
O: MapObserver<T>,
|
O: MapObserver<T>,
|
||||||
I: Input,
|
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;
|
let mut interesting = 0;
|
||||||
|
|
||||||
// TODO: impl. correctly, optimize
|
// TODO: impl. correctly, optimize
|
||||||
@ -101,11 +108,11 @@ where
|
|||||||
*history = reduced;
|
*history = reduced;
|
||||||
interesting += 25;
|
interesting += 25;
|
||||||
if interesting >= 250 {
|
if interesting >= 250 {
|
||||||
return 255;
|
return (255, None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
interesting
|
(interesting, None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,25 +1,25 @@
|
|||||||
pub mod mutational;
|
pub mod mutational;
|
||||||
|
|
||||||
use crate::corpus::Testcase;
|
use crate::corpus::Testcase;
|
||||||
use crate::engines::Engine;
|
use crate::engines::Evaluator;
|
||||||
use crate::inputs::Input;
|
use crate::inputs::Input;
|
||||||
use crate::AflError;
|
use crate::AflError;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub trait HasEngine<'a, I>
|
pub trait HasEvaluator<I>
|
||||||
where
|
where
|
||||||
I: Input,
|
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
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
{
|
{
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use crate::corpus::testcase::Testcase;
|
use crate::corpus::testcase::Testcase;
|
||||||
use crate::engines::Engine;
|
use crate::engines::Evaluator;
|
||||||
use crate::inputs::Input;
|
use crate::inputs::Input;
|
||||||
use crate::mutators::Mutator;
|
use crate::mutators::Mutator;
|
||||||
use crate::stages::{HasEngine, Stage};
|
use crate::stages::{HasEvaluator, Stage};
|
||||||
use crate::utils::{HasRand, Rand};
|
use crate::utils::{HasRand, Rand};
|
||||||
use crate::AflError;
|
use crate::AflError;
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ where
|
|||||||
m.mutate(&mut input, i as i32)?;
|
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() {
|
for m in self.mutators_mut() {
|
||||||
m.post_exec(interesting, i as i32)?;
|
m.post_exec(interesting, i as i32)?;
|
||||||
@ -52,10 +52,10 @@ pub struct DefaultMutationalStage<'a, I, R, E>
|
|||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
E: Engine<'a, I>,
|
E: Evaluator<I>,
|
||||||
{
|
{
|
||||||
rand: &'a mut R,
|
rand: &'a mut R,
|
||||||
engine: &'a mut E,
|
eval: &'a mut E,
|
||||||
mutators: Vec<Box<dyn Mutator<I, R = R>>>,
|
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
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
E: Engine<'a, I>,
|
E: Evaluator<I>,
|
||||||
{
|
{
|
||||||
type R = R;
|
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
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
E: Engine<'a, I>,
|
E: Evaluator<I>,
|
||||||
{
|
{
|
||||||
type E = E;
|
type E = E;
|
||||||
|
|
||||||
fn engine(&self) -> &Self::E {
|
fn eval(&self) -> &Self::E {
|
||||||
self.engine
|
self.eval
|
||||||
}
|
}
|
||||||
|
|
||||||
fn engine_mut(&mut self) -> &mut Self::E {
|
fn eval_mut(&mut self) -> &mut Self::E {
|
||||||
self.engine
|
self.eval
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +96,7 @@ impl<'a, I, R, E> MutationalStage<'a, I> for DefaultMutationalStage<'a, I, R, E>
|
|||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
E: Engine<'a, I>,
|
E: Evaluator<I>,
|
||||||
{
|
{
|
||||||
fn mutators(&self) -> &Vec<Box<dyn Mutator<I, R = Self::R>>> {
|
fn mutators(&self) -> &Vec<Box<dyn Mutator<I, R = Self::R>>> {
|
||||||
&self.mutators
|
&self.mutators
|
||||||
@ -111,7 +111,7 @@ impl<'a, I, R, E> Stage<'a, I> for DefaultMutationalStage<'a, I, R, E>
|
|||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
E: Engine<'a, I>,
|
E: Evaluator<I>,
|
||||||
{
|
{
|
||||||
fn perform(&mut self, entry: Rc<RefCell<Testcase<I>>>) -> Result<(), AflError> {
|
fn perform(&mut self, entry: Rc<RefCell<Testcase<I>>>) -> Result<(), AflError> {
|
||||||
self.perform_mutational(entry)
|
self.perform_mutational(entry)
|
||||||
@ -122,12 +122,12 @@ impl<'a, I, R, E> DefaultMutationalStage<'a, I, R, E>
|
|||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
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 {
|
DefaultMutationalStage {
|
||||||
rand: rand,
|
rand: rand,
|
||||||
engine: engine,
|
eval: eval,
|
||||||
mutators: vec![],
|
mutators: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user