code format, infos in cargo toml
This commit is contained in:
parent
6e949fa469
commit
ca1be853e1
13
Cargo.toml
13
Cargo.toml
@ -6,6 +6,15 @@ 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
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
criterion = "0.3" # Benchmarking
|
||||||
|
|
||||||
|
[[bench]]
|
||||||
|
name = "rng_hash_benchmark"
|
||||||
|
harness = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
xxhash-rust = { version = "0.8.0-beta.4", features = ["xxh3"] }
|
xxhash-rust = { version = "0.8.0-beta.4", features = ["xxh3"] } # xxh3 hashing for rust
|
||||||
thiserror = "1.0"
|
ahash = "0.5.6" # Fast hashing algorithm
|
||||||
|
thiserror = "1.0" # A nicer way to write Errors
|
||||||
|
hashbrown = "0.9" # A faster hashmap, nostd compatible
|
@ -1,25 +1,20 @@
|
|||||||
use std::fmt::Debug;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use crate::Error;
|
|
||||||
use crate::utils::Rand;
|
|
||||||
use crate::inputs::Input;
|
use crate::inputs::Input;
|
||||||
|
use crate::utils::Rand;
|
||||||
|
use crate::Error;
|
||||||
|
use hashbrown::HashMap;
|
||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
pub trait TestcaseMetadata: Debug {
|
pub trait TestcaseMetadata: Debug {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Testcase: Debug {
|
pub trait Testcase: Debug {
|
||||||
|
|
||||||
fn load_input(&mut self) -> Result<&Box<dyn Input>, Error>;
|
fn load_input(&mut self) -> Result<&Box<dyn Input>, Error>;
|
||||||
fn is_on_disk(&self) -> bool;
|
fn is_on_disk(&self) -> bool;
|
||||||
fn get_filename(&self) -> &str;
|
fn get_filename(&self) -> &str;
|
||||||
fn get_metadatas(&mut self) -> &mut HashMap<String, Box<dyn TestcaseMetadata>>;
|
fn get_metadatas(&mut self) -> &mut HashMap<String, Box<dyn TestcaseMetadata>>;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Corpus with all current testcases
|
/// Corpus with all current testcases
|
||||||
pub trait Corpus: Debug {
|
pub trait Corpus: Debug {
|
||||||
|
|
||||||
/// Returns the number of elements
|
/// Returns the number of elements
|
||||||
fn count(&self) -> usize;
|
fn count(&self) -> usize;
|
||||||
|
|
||||||
@ -33,16 +28,13 @@ pub trait Corpus: Debug {
|
|||||||
|
|
||||||
/// Gets the next entry
|
/// Gets the next entry
|
||||||
fn get(&mut self) -> Result<&Box<dyn Testcase>, Error>;
|
fn get(&mut self) -> Result<&Box<dyn Testcase>, Error>;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A queue-like corpus
|
/// A queue-like corpus
|
||||||
pub trait Queue: Corpus {
|
pub trait Queue: Corpus {
|
||||||
|
|
||||||
fn get_cycles(&self) -> u64;
|
fn get_cycles(&self) -> u64;
|
||||||
|
|
||||||
fn get_pos(&self) -> usize;
|
fn get_pos(&self) -> usize;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -51,12 +43,10 @@ pub struct DefaultQueue<'a> {
|
|||||||
pos: usize,
|
pos: usize,
|
||||||
cycles: u64,
|
cycles: u64,
|
||||||
entries: Vec<Box<dyn Testcase>>,
|
entries: Vec<Box<dyn Testcase>>,
|
||||||
dir_path: String
|
dir_path: String,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Corpus for DefaultQueue<'_> {
|
impl Corpus for DefaultQueue<'_> {
|
||||||
|
|
||||||
/// Returns the number of elements
|
/// Returns the number of elements
|
||||||
fn count(&self) -> usize {
|
fn count(&self) -> usize {
|
||||||
self.entries.len()
|
self.entries.len()
|
||||||
@ -92,7 +82,7 @@ impl Corpus for DefaultQueue<'_> {
|
|||||||
/// Gets the next entry
|
/// Gets the next entry
|
||||||
fn get(&mut self) -> Result<&Box<dyn Testcase>, Error> {
|
fn get(&mut self) -> Result<&Box<dyn Testcase>, Error> {
|
||||||
if self.entries.len() == 0 {
|
if self.entries.len() == 0 {
|
||||||
return Err(Error::Unknown)
|
return Err(Error::Unknown);
|
||||||
}
|
}
|
||||||
self.pos = self.pos + 1;
|
self.pos = self.pos + 1;
|
||||||
if self.pos >= self.entries.len() {
|
if self.pos >= self.entries.len() {
|
||||||
@ -104,7 +94,6 @@ impl Corpus for DefaultQueue<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Queue for DefaultQueue<'_> {
|
impl Queue for DefaultQueue<'_> {
|
||||||
|
|
||||||
fn get_cycles(&self) -> u64 {
|
fn get_cycles(&self) -> u64 {
|
||||||
self.cycles
|
self.cycles
|
||||||
}
|
}
|
||||||
@ -112,11 +101,9 @@ impl Queue for DefaultQueue<'_> {
|
|||||||
fn get_pos(&self) -> usize {
|
fn get_pos(&self) -> usize {
|
||||||
self.pos
|
self.pos
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DefaultQueue<'_> {
|
impl DefaultQueue<'_> {
|
||||||
|
|
||||||
pub fn new<'a>(rand: &'a mut dyn Rand, dir_path: &str) -> DefaultQueue<'a> {
|
pub fn new<'a>(rand: &'a mut dyn Rand, dir_path: &str) -> DefaultQueue<'a> {
|
||||||
DefaultQueue {
|
DefaultQueue {
|
||||||
cycles: 0,
|
cycles: 0,
|
||||||
@ -126,20 +113,16 @@ impl DefaultQueue<'_> {
|
|||||||
rand: rand,
|
rand: rand,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
struct SimpleTestcase {
|
struct SimpleTestcase {
|
||||||
|
|
||||||
is_on_disk: bool,
|
is_on_disk: bool,
|
||||||
filename: String,
|
filename: String,
|
||||||
metadatas: HashMap<String, Box<dyn TestcaseMetadata>>,
|
metadatas: HashMap<String, Box<dyn TestcaseMetadata>>,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Testcase for SimpleTestcase {
|
impl Testcase for SimpleTestcase {
|
||||||
|
|
||||||
fn load_input(&mut self) -> Result<&Box<dyn Input>, Error> {
|
fn load_input(&mut self) -> Result<&Box<dyn Input>, Error> {
|
||||||
// TODO: Implement
|
// TODO: Implement
|
||||||
Err(Error::Unknown)
|
Err(Error::Unknown)
|
||||||
@ -156,7 +139,6 @@ impl Testcase for SimpleTestcase {
|
|||||||
fn get_metadatas(&mut self) -> &mut HashMap<String, Box<dyn TestcaseMetadata>> {
|
fn get_metadatas(&mut self) -> &mut HashMap<String, Box<dyn TestcaseMetadata>> {
|
||||||
&mut self.metadatas
|
&mut self.metadatas
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SimpleTestcase {
|
impl SimpleTestcase {
|
||||||
@ -164,7 +146,7 @@ impl SimpleTestcase {
|
|||||||
SimpleTestcase {
|
SimpleTestcase {
|
||||||
filename: filename.to_owned(),
|
filename: filename.to_owned(),
|
||||||
is_on_disk: false,
|
is_on_disk: false,
|
||||||
metadatas: HashMap::default()
|
metadatas: HashMap::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -184,6 +166,5 @@ mod tests {
|
|||||||
let filename = q.get().unwrap().get_filename().to_owned();
|
let filename = q.get().unwrap().get_filename().to_owned();
|
||||||
assert_eq!(filename, q.get().unwrap().get_filename());
|
assert_eq!(filename, q.get().unwrap().get_filename());
|
||||||
assert_eq!(filename, "fancyfile");
|
assert_eq!(filename, "fancyfile");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,14 +1,13 @@
|
|||||||
use std::time;
|
use std::time;
|
||||||
|
|
||||||
use crate::utils::Rand;
|
|
||||||
use crate::feedbacks::Feedback;
|
|
||||||
use crate::stages::Stage;
|
|
||||||
use crate::executors::Executor;
|
|
||||||
use crate::engines::Engine;
|
use crate::engines::Engine;
|
||||||
|
use crate::executors::Executor;
|
||||||
|
use crate::feedbacks::Feedback;
|
||||||
use crate::monitors::Monitor;
|
use crate::monitors::Monitor;
|
||||||
|
use crate::stages::Stage;
|
||||||
|
use crate::utils::Rand;
|
||||||
|
|
||||||
pub struct AflEngine<'a> {
|
pub struct AflEngine<'a> {
|
||||||
|
|
||||||
pub rand: &'a mut dyn Rand,
|
pub rand: &'a mut dyn Rand,
|
||||||
pub feedbacks: Vec<Box<dyn Feedback>>,
|
pub feedbacks: Vec<Box<dyn Feedback>>,
|
||||||
|
|
||||||
@ -24,9 +23,6 @@ pub struct AflEngine<'a> {
|
|||||||
|
|
||||||
// TODO: Map
|
// TODO: Map
|
||||||
pub monitors: Vec<Box<dyn Monitor>>,
|
pub monitors: Vec<Box<dyn Monitor>>,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Engine<'_> for AflEngine<'_> {
|
impl Engine<'_> for AflEngine<'_> {}
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
pub mod aflengine;
|
pub mod aflengine;
|
||||||
|
|
||||||
pub trait Engine<'a> {
|
pub trait Engine<'a> {}
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -1,2 +1 @@
|
|||||||
|
|
||||||
pub trait Executor {}
|
pub trait Executor {}
|
@ -1,5 +1,5 @@
|
|||||||
use crate::Error;
|
|
||||||
use crate::inputs::Input;
|
use crate::inputs::Input;
|
||||||
|
use crate::Error;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
pub struct BytesInput {
|
pub struct BytesInput {
|
||||||
@ -7,7 +7,6 @@ pub struct BytesInput {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Input for BytesInput {
|
impl Input for BytesInput {
|
||||||
|
|
||||||
fn serialize(&self) -> Result<&[u8], Error> {
|
fn serialize(&self) -> Result<&[u8], Error> {
|
||||||
Ok(&self.bytes)
|
Ok(&self.bytes)
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
pub mod bytes;
|
pub mod bytes;
|
||||||
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Write;
|
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
use crate::Error;
|
use crate::Error;
|
||||||
|
|
||||||
pub trait Input {
|
pub trait Input {
|
||||||
|
|
||||||
fn to_file(&self, path: &str) -> Result<(), Error> {
|
fn to_file(&self, path: &str) -> Result<(), Error> {
|
||||||
let mut file = File::create(path)?;
|
let mut file = File::create(path)?;
|
||||||
file.write_all(self.serialize()?)?;
|
file.write_all(self.serialize()?)?;
|
||||||
@ -25,5 +24,4 @@ pub trait Input {
|
|||||||
fn serialize(&self) -> Result<&[u8], Error>;
|
fn serialize(&self) -> Result<&[u8], Error>;
|
||||||
|
|
||||||
fn deserialize(&mut self, buf: &[u8]) -> Result<(), Error>;
|
fn deserialize(&mut self, buf: &[u8]) -> Result<(), Error>;
|
||||||
|
|
||||||
}
|
}
|
@ -23,7 +23,6 @@ pub enum Error {
|
|||||||
Unknown,
|
Unknown,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
use std::io::Error;
|
|
||||||
use crate::inputs::Input;
|
use crate::inputs::Input;
|
||||||
|
use std::io::Error;
|
||||||
|
|
||||||
pub mod scheduled;
|
pub mod scheduled;
|
||||||
|
|
||||||
pub trait Mutator {
|
pub trait Mutator {
|
||||||
|
|
||||||
//fn rand(&self) -> &Box<dyn Rand>;
|
//fn rand(&self) -> &Box<dyn Rand>;
|
||||||
//fn rand_mut(&self) -> &mut Box<dyn Rand>;
|
//fn rand_mut(&self) -> &mut Box<dyn Rand>;
|
||||||
|
|
||||||
@ -19,5 +18,4 @@ pub trait Mutator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn post_exec_at(&mut self, stage_idx: i32, is_interesting: bool) -> Result<(), Error>;
|
fn post_exec_at(&mut self, stage_idx: i32, is_interesting: bool) -> Result<(), Error>;
|
||||||
|
|
||||||
}
|
}
|
@ -1,12 +1,8 @@
|
|||||||
use crate::mutators::Mutator;
|
use crate::mutators::Mutator;
|
||||||
|
|
||||||
pub trait ScheduledMutator: Mutator {
|
pub trait ScheduledMutator: Mutator {
|
||||||
|
|
||||||
fn iterations(&self) -> u64 {
|
fn iterations(&self) -> u64 {
|
||||||
|
|
||||||
//1 << (1 + self.rand_mut().below(7))
|
//1 << (1 + self.rand_mut().below(7))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
26
src/utils.rs
26
src/utils.rs
@ -1,12 +1,11 @@
|
|||||||
//! Utility functions for AFL
|
//! Utility functions for AFL
|
||||||
|
|
||||||
use std::fmt::Debug;
|
|
||||||
use std::debug_assert;
|
use std::debug_assert;
|
||||||
|
use std::fmt::Debug;
|
||||||
use xxhash_rust::xxh3::xxh3_64_with_seed;
|
use xxhash_rust::xxh3::xxh3_64_with_seed;
|
||||||
|
|
||||||
/// Ways to get random around here
|
/// Ways to get random around here
|
||||||
pub trait Rand: Debug {
|
pub trait Rand: Debug {
|
||||||
|
|
||||||
// Sets the seed of this Rand
|
// Sets the seed of this Rand
|
||||||
fn set_seed(&mut self, seed: u64);
|
fn set_seed(&mut self, seed: u64);
|
||||||
// Gets the next 64 bit value
|
// Gets the next 64 bit value
|
||||||
@ -31,7 +30,6 @@ pub trait Rand: Debug {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unbiased_rnd % upper_bound_excl
|
unbiased_rnd % upper_bound_excl
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets a value between the given lower bound (inclusive) and upper bound (inclusive)
|
// Gets a value between the given lower bound (inclusive) and upper bound (inclusive)
|
||||||
@ -39,7 +37,6 @@ pub trait Rand: Debug {
|
|||||||
debug_assert!(lower_bound_incl <= upper_bound_incl);
|
debug_assert!(lower_bound_incl <= upper_bound_incl);
|
||||||
lower_bound_incl + self.below(upper_bound_incl - lower_bound_incl + 1)
|
lower_bound_incl + self.below(upper_bound_incl - lower_bound_incl + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const HASH_CONST: u64 = 0xa5b35705;
|
const HASH_CONST: u64 = 0xa5b35705;
|
||||||
@ -48,17 +45,11 @@ const HASH_CONST: u64 = 0xa5b35705;
|
|||||||
///
|
///
|
||||||
#[derive(Copy, Clone, Debug, Default)]
|
#[derive(Copy, Clone, Debug, Default)]
|
||||||
pub struct Xoshiro256StarRand {
|
pub struct Xoshiro256StarRand {
|
||||||
|
|
||||||
|
|
||||||
rand_seed: [u64; 4],
|
rand_seed: [u64; 4],
|
||||||
seeded: bool,
|
seeded: bool,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Rand for Xoshiro256StarRand {
|
impl Rand for Xoshiro256StarRand {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fn set_seed(&mut self, seed: u64) {
|
fn set_seed(&mut self, seed: u64) {
|
||||||
self.rand_seed[0] = xxh3_64_with_seed(&HASH_CONST.to_le_bytes(), seed);
|
self.rand_seed[0] = xxh3_64_with_seed(&HASH_CONST.to_le_bytes(), seed);
|
||||||
self.rand_seed[1] = self.rand_seed[0] ^ 0x1234567890abcdef;
|
self.rand_seed[1] = self.rand_seed[0] ^ 0x1234567890abcdef;
|
||||||
@ -69,8 +60,10 @@ impl Rand for Xoshiro256StarRand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn next(&mut self) -> u64 {
|
fn next(&mut self) -> u64 {
|
||||||
|
let ret: u64 = self.rand_seed[0]
|
||||||
let ret: u64 = self.rand_seed[0].wrapping_add(self.rand_seed[3]).rotate_left(23).wrapping_add(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;
|
let t: u64 = self.rand_seed[1] << 17;
|
||||||
|
|
||||||
self.rand_seed[2] ^= self.rand_seed[0];
|
self.rand_seed[2] ^= self.rand_seed[0];
|
||||||
@ -83,20 +76,15 @@ impl Rand for Xoshiro256StarRand {
|
|||||||
self.rand_seed[3] = self.rand_seed[3].rotate_left(45);
|
self.rand_seed[3] = self.rand_seed[3].rotate_left(45);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Xoshiro256StarRand {
|
impl Xoshiro256StarRand {
|
||||||
|
|
||||||
pub fn new() -> Xoshiro256StarRand {
|
pub fn new() -> Xoshiro256StarRand {
|
||||||
|
|
||||||
let mut ret: Xoshiro256StarRand = Default::default();
|
let mut ret: Xoshiro256StarRand = Default::default();
|
||||||
ret.set_seed(0); // TODO: Proper random seed?
|
ret.set_seed(0); // TODO: Proper random seed?
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the next higher power of two
|
/// Get the next higher power of two
|
||||||
@ -105,7 +93,7 @@ fn next_pow2(val: u64) -> u64 {
|
|||||||
if val <= 2 {
|
if val <= 2 {
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
let mut out: u64 = val - 1;
|
let mut out: u64 = val.wrapping_sub(1);
|
||||||
out |= out >> 1;
|
out |= out >> 1;
|
||||||
out |= out >> 2;
|
out |= out >> 2;
|
||||||
out |= out >> 4;
|
out |= out >> 4;
|
||||||
@ -116,7 +104,7 @@ fn next_pow2(val: u64) -> u64 {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::utils::{Rand, Xoshiro256StarRand, next_pow2};
|
use crate::utils::{next_pow2, Rand, Xoshiro256StarRand};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_rand() {
|
fn test_rand() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user