added utils, folder structure
This commit is contained in:
parent
bca91aeafb
commit
d91717a34c
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,2 +1,4 @@
|
|||||||
/target
|
/target
|
||||||
Cargo.lock
|
Cargo.lock
|
||||||
|
|
||||||
|
.vscode
|
@ -7,3 +7,4 @@ edition = "2018"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
xxhrs = { version = "2.0.0", features = [] } #"random_entropy"] }
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
use std::time;
|
use std::time;
|
||||||
|
|
||||||
pub trait RandState {}
|
use crate::utils::Rand;
|
||||||
pub trait Executor {}
|
use crate::feedbacks::Feedback;
|
||||||
pub trait Feedback {}
|
use crate::stages::Stage;
|
||||||
pub trait 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 Rand>,
|
||||||
|
//pub feedback: Vec<Box<dyn Feedback>>,
|
||||||
pub rand: Box<dyn RandState>,
|
|
||||||
pub feedback: Vec<Box<dyn Feedback>>,
|
|
||||||
|
|
||||||
pub stages: Vec<Box<dyn Stage>>,
|
pub stages: Vec<Box<dyn Stage>>,
|
||||||
pub current_stage: Box<dyn Stage>,
|
pub current_stage: Box<dyn Stage>,
|
||||||
@ -26,3 +26,7 @@ pub struct DefaultEngine {
|
|||||||
pub monitors: Vec<Box<dyn Monitor>>,
|
pub monitors: Vec<Box<dyn Monitor>>,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Engine for AflEngine {
|
||||||
|
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
pub mod engine;
|
pub mod aflengine;
|
||||||
|
|
||||||
pub trait Engine {
|
pub trait Engine {
|
||||||
|
|
||||||
|
2
src/executors/mod.rs
Normal file
2
src/executors/mod.rs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
pub trait Executor {}
|
1
src/feedbacks/mod.rs
Normal file
1
src/feedbacks/mod.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
pub trait Feedback {}
|
@ -2,7 +2,7 @@ use crate::inputs::Input;
|
|||||||
|
|
||||||
use std::io::Error;
|
use std::io::Error;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Clone, Debug, Default)]
|
||||||
pub struct BytesInput {
|
pub struct BytesInput {
|
||||||
bytes: Vec<u8>,
|
bytes: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
pub mod engines;
|
pub mod engines;
|
||||||
|
pub mod executors;
|
||||||
|
pub mod feedbacks;
|
||||||
pub mod inputs;
|
pub mod inputs;
|
||||||
|
pub mod monitors;
|
||||||
|
pub mod mutators;
|
||||||
|
pub mod stages;
|
||||||
|
pub mod utils;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
@ -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() {
|
fn main() {
|
||||||
println!("Hello, world!");
|
println!("Hello, world!");
|
||||||
|
1
src/monitors/mod.rs
Normal file
1
src/monitors/mod.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
pub trait Monitor {}
|
24
src/mutators/mod.rs
Normal file
24
src/mutators/mod.rs
Normal 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
12
src/mutators/scheduled.rs
Normal 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
2
src/stages/mod.rs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
//! Stages
|
||||||
|
pub trait Stage {}
|
129
src/utils.rs
Normal file
129
src/utils.rs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user