added utils, folder structure

This commit is contained in:
Dominik Maier 2020-10-23 20:05:08 +02:00
parent bca91aeafb
commit d91717a34c
15 changed files with 203 additions and 11 deletions

2
.gitignore vendored
View File

@ -1,2 +1,4 @@
/target
Cargo.lock
.vscode

View File

@ -7,3 +7,4 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
xxhrs = { version = "2.0.0", features = [] } #"random_entropy"] }

View File

@ -1,16 +1,16 @@
use std::time;
pub trait RandState {}
pub trait Executor {}
pub trait Feedback {}
pub trait Stage {}
use crate::utils::Rand;
use crate::feedbacks::Feedback;
use crate::stages::Stage;
use crate::executors::Executor;
use crate::engines::Engine;
use crate::monitors::Monitor;
pub trait Monitor {}
pub struct AflEngine {
pub struct DefaultEngine {
pub rand: Box<dyn RandState>,
pub feedback: Vec<Box<dyn Feedback>>,
//pub rand: Box<dyn Rand>,
//pub feedback: Vec<Box<dyn Feedback>>,
pub stages: Vec<Box<dyn Stage>>,
pub current_stage: Box<dyn Stage>,
@ -25,4 +25,8 @@ pub struct DefaultEngine {
// TODO: Map
pub monitors: Vec<Box<dyn Monitor>>,
}
impl Engine for AflEngine {
}

View File

@ -1,4 +1,4 @@
pub mod engine;
pub mod aflengine;
pub trait Engine {

View File

2
src/executors/mod.rs Normal file
View File

@ -0,0 +1,2 @@
pub trait Executor {}

1
src/feedbacks/mod.rs Normal file
View File

@ -0,0 +1 @@
pub trait Feedback {}

View File

@ -2,7 +2,7 @@ use crate::inputs::Input;
use std::io::Error;
#[derive(Debug)]
#[derive(Clone, Debug, Default)]
pub struct BytesInput {
bytes: Vec<u8>,
}

View File

@ -1,5 +1,11 @@
pub mod engines;
pub mod executors;
pub mod feedbacks;
pub mod inputs;
pub mod monitors;
pub mod mutators;
pub mod stages;
pub mod utils;
#[cfg(test)]
mod tests {

View File

@ -1,3 +1,11 @@
pub mod engines;
pub mod executors;
pub mod feedbacks;
pub mod inputs;
pub mod monitors;
pub mod mutators;
pub mod stages;
pub mod utils;
fn main() {
println!("Hello, world!");

1
src/monitors/mod.rs Normal file
View File

@ -0,0 +1 @@
pub trait Monitor {}

24
src/mutators/mod.rs Normal file
View File

@ -0,0 +1,24 @@
use std::io::Error;
use crate::inputs::Input;
use crate::utils::Rand;
pub mod scheduled;
pub trait Mutator {
//fn rand(&self) -> &Box<dyn Rand>;
//fn rand_mut(&self) -> &mut Box<dyn Rand>;
fn mutate(&mut self, input: &mut dyn Input) -> Result<(), Error> {
self.mutate_at((-1) as i32, input)
}
fn mutate_at(&mut self, stage_idx: i32, input: &mut dyn Input) -> Result<(), Error>;
fn post_exec(&mut self, is_interesting: bool) -> Result<(), Error> {
self.post_exec_at((-1) as i32, is_interesting)
}
fn post_exec_at(&mut self, stage_idx: i32, is_interesting: bool) -> Result<(), Error>;
}

12
src/mutators/scheduled.rs Normal file
View File

@ -0,0 +1,12 @@
use crate::mutators::Mutator;
pub trait ScheduledMutator: Mutator {
fn iterations(&self) -> u64 {
//1 << (1 + self.rand_mut().below(7))
return 0;
}
}

2
src/stages/mod.rs Normal file
View File

@ -0,0 +1,2 @@
//! Stages
pub trait Stage {}

129
src/utils.rs Normal file
View File

@ -0,0 +1,129 @@
//! Utility functions for AFL
use std::debug_assert;
use xxhrs::{XXH3_64};
/// Ways to get random around here
pub trait Rand {
// Returns a new, randomly seeded, rand
fn new() -> Self;
// Sets the seed of this Rand
fn set_seed(&mut self, seed: u64);
// Gets the next 64 bit value
fn next(&mut self) -> u64;
// Gets a value below the given 64 bit val (inclusive)
fn below(&mut self, upper_bound_excl: u64) -> u64 {
if upper_bound_excl <= 1 {
return 0;
}
/*
Modulo is biased - we don't want our fuzzing to be biased so let's do it
right. See
https://stackoverflow.com/questions/10984974/why-do-people-say-there-is-modulo-bias-when-using-a-random-number-generator
*/
let mut unbiased_rnd: u64;
loop {
unbiased_rnd = self.next();
if unbiased_rnd < (u64::MAX - (u64::MAX % upper_bound_excl)) {
break;
}
}
unbiased_rnd % upper_bound_excl
}
// Gets a value between the given lower bound (inclusive) and upper bound (inclusive)
fn between(&mut self, lower_bound_incl: u64, upper_bound_incl: u64) -> u64 {
debug_assert!(lower_bound_incl < upper_bound_incl);
lower_bound_incl + self.below(upper_bound_incl - lower_bound_incl + 1)
}
}
const HASH_CONST: u64 = 0xa5b35705;
/// XXH3 Based, hopefully speedy, rnd implementation
///
#[derive(Copy, Clone, Debug, Default)]
struct AflRand {
rand_seed: [u64; 4],
seeded: bool,
}
impl Rand for AflRand {
fn new() -> AflRand {
let mut ret: AflRand = Default::default();
ret.set_seed(0); // TODO: Proper random seed?
ret
}
fn set_seed(&mut self, seed: u64) {
self.rand_seed[0] = XXH3_64::hash_with_seed(HASH_CONST, &seed.to_le_bytes());
self.rand_seed[1] = self.rand_seed[0] ^ 0x1234567890abcdef;
self.rand_seed[2] = self.rand_seed[0] & 0x0123456789abcdef;
self.rand_seed[3] = self.rand_seed[0] | 0x01abcde43f567908;
self.seeded = true;
}
fn next(&mut self) -> u64 {
let ret: u64 = self.rand_seed[0].wrapping_add(self.rand_seed[3]).rotate_left(23).wrapping_add(self.rand_seed[0]);
let t: u64 = self.rand_seed[1] << 17;
self.rand_seed[2] ^= self.rand_seed[0];
self.rand_seed[3] ^= self.rand_seed[1];
self.rand_seed[1] ^= self.rand_seed[2];
self.rand_seed[0] ^= self.rand_seed[3];
self.rand_seed[2] ^= t;
self.rand_seed[3] = self.rand_seed[3].rotate_left(45);
return ret;
}
}
/// Get the next higher power of two
fn next_pow2(val: u64) -> u64 {
// Early exit so we don't have to do a wrapping subtract;
if val <= 2 {
return val;
}
let mut out: u64 = val - 1;
out |= out >> 1;
out |= out >> 2;
out |= out >> 4;
out |= out >> 8;
out |= out >> 16;
return out + 1;
}
#[cfg(test)]
mod tests {
use crate::utils::{AflRand, next_pow2};
#[test]
fn test_rand() {
//let rand: AflRand = AflRand::new();
}
#[test]
fn test_next_pow2() {
assert_eq!(next_pow2(0), 0);
assert_eq!(next_pow2(1), 1);
assert_eq!(next_pow2(2), 2);
assert_eq!(next_pow2(3), 4);
assert_eq!(next_pow2(1000), 1024);
}
}