new cli
This commit is contained in:
parent
6e0b49bf9b
commit
90cae14958
@ -40,3 +40,5 @@ hashbrown = { version = "0.14.0", features = ["serde"] } # A faster hashmap, no
|
||||
petgraph = { version="0.6.0", features = ["serde-1"] }
|
||||
ron = "0.7" # write serialized data - including hashmaps
|
||||
rand = "0.5"
|
||||
clap = { version = "4.4.11", features = ["derive"] }
|
||||
csv = "1.3.0"
|
||||
|
@ -2,7 +2,7 @@ import csv
|
||||
import os
|
||||
def_flags="--no-default-features --features std,snapshot_restore,singlecore,restarting,run_until_saturation"
|
||||
remote="timedump_253048_1873f6_all/"
|
||||
RUNTIME=10
|
||||
RUNTIME=120
|
||||
TARGET_REPS_A=2
|
||||
TARGET_REPS_B=2
|
||||
NUM_NODES=2
|
||||
@ -157,19 +157,21 @@ rule run_bench:
|
||||
bkp=line['return_function']
|
||||
script="""
|
||||
mkdir -p $(dirname {output[0]})
|
||||
export KERNEL=$(pwd)/{input[0]}
|
||||
export FUZZ_MAIN={fuzz_main}
|
||||
export FUZZ_INPUT={fuzz_input}
|
||||
export FUZZ_INPUT_LEN={fuzz_len}
|
||||
export BREAKPOINT={bkp}
|
||||
export SEED_RANDOM={wildcards.num}
|
||||
# export KERNEL=$(pwd)/{input[0]}
|
||||
# export FUZZ_MAIN={fuzz_main}
|
||||
# export FUZZ_INPUT={fuzz_input}
|
||||
# export FUZZ_INPUT_LEN={fuzz_len}
|
||||
# export BREAKPOINT={bkp}
|
||||
# export SEED_RANDOM={wildcards.num}
|
||||
export TIME_DUMP=$(pwd)/{output[0]}
|
||||
export CASE_DUMP=$(pwd)/{output[0]}.case
|
||||
export TRACE_DUMP=$(pwd)/{output[0]}.trace
|
||||
export FUZZ_ITERS={RUNTIME}
|
||||
# export FUZZ_ITERS={RUNTIME}
|
||||
export FUZZER=$(pwd)/{input[1]}/debug/fret
|
||||
set +e
|
||||
../fuzzer.sh > {output[1]} 2>&1
|
||||
# ../fuzzer.sh > {output[1]} 2>&1
|
||||
echo $(pwd)/{input[1]}/debug/fret -k {input[0]} -c ./target_symbols.csv fuzz -t {RUNTIME} -s {wildcards.num}
|
||||
$(pwd)/{input[1]}/debug/fret -k {input[0]} -c ./target_symbols.csv fuzz -t {RUNTIME} -s {wildcards.num} > {output[1]} 2>&1
|
||||
exit 0
|
||||
"""
|
||||
if wildcards.fuzzer.find('random') >= 0:
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! A fuzzer using qemu in systemmode for binary-only coverage of kernels
|
||||
//!
|
||||
use core::time::Duration;
|
||||
use std::{env, path::PathBuf, process::{self, abort}, io::{Read, Write}, fs::{self, OpenOptions}, cmp::{min, max}, mem::transmute_copy, collections::btree_map::Range, ptr::addr_of_mut};
|
||||
use std::{env, path::PathBuf, process::{self, abort}, io::{Read, Write}, fs::{self, OpenOptions}, cmp::{min, max}, mem::transmute_copy, collections::btree_map::Range, ptr::addr_of_mut, ffi::OsStr};
|
||||
|
||||
use libafl_bolts::{
|
||||
core_affinity::Cores,
|
||||
@ -43,6 +43,8 @@ use crate::{
|
||||
mutational::{MINIMUM_INTER_ARRIVAL_TIME},
|
||||
};
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use clap::{Parser, Subcommand};
|
||||
use csv::Reader;
|
||||
|
||||
pub static mut RNG_SEED: u64 = 1;
|
||||
|
||||
@ -82,7 +84,73 @@ extern "C" {
|
||||
}
|
||||
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
struct Cli {
|
||||
/// Kernel Image
|
||||
#[arg(short, long, value_name = "FILE")]
|
||||
kernel: PathBuf,
|
||||
|
||||
/// Sets a custom config file
|
||||
#[arg(short, long, value_name = "FILE")]
|
||||
config: PathBuf,
|
||||
|
||||
#[command(subcommand)]
|
||||
command: Commands,
|
||||
}
|
||||
#[derive(Subcommand)]
|
||||
enum Commands {
|
||||
/// run a single input
|
||||
Showmap {
|
||||
/// take this input
|
||||
#[arg(short, long)]
|
||||
input: PathBuf,
|
||||
},
|
||||
/// start fuzzing campaign
|
||||
Fuzz {
|
||||
/// disable heuristic
|
||||
#[arg(short, long)]
|
||||
random: bool,
|
||||
/// seed for randomness
|
||||
#[arg(short, long)]
|
||||
seed: Option<u64>,
|
||||
/// runtime in seconds
|
||||
#[arg(short, long)]
|
||||
time: Option<u64>,
|
||||
}
|
||||
}
|
||||
|
||||
fn env_from_config(kernel : &PathBuf, path : &PathBuf) {
|
||||
let is_csv = path.as_path().extension().map_or(false, |x| x=="csv");
|
||||
if !is_csv {
|
||||
let lines = std::fs::read_to_string(path).expect("Config file not found");
|
||||
let lines = lines.lines().filter(
|
||||
|x| x.len()>0
|
||||
);
|
||||
for l in lines {
|
||||
let pair = l.split_once('=').expect("Non VAR=VAL line in config");
|
||||
std::env::set_var(pair.0, pair.1);
|
||||
}
|
||||
} else {
|
||||
let mut reader = csv::Reader::from_path(path).expect("CSV read from config failed");
|
||||
let p = kernel.as_path();
|
||||
let stem = p.file_stem().expect("Kernel filename error").to_str().unwrap();
|
||||
for r in reader.records() {
|
||||
let rec = r.expect("CSV entry error");
|
||||
if stem == &rec[0] {
|
||||
std::env::set_var("FUZZ_MAIN", &rec[1]);
|
||||
std::env::set_var("FUZZ_INPUT", &rec[2]);
|
||||
std::env::set_var("FUZZ_INPUT_LEN", &rec[3]);
|
||||
std::env::set_var("BREAKPOINT", &rec[4]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fuzz() {
|
||||
let cli = Cli::parse();
|
||||
env_from_config(&cli.kernel, &cli.config);
|
||||
unsafe {FUZZ_START_TIMESTAMP = SystemTime::now();}
|
||||
let mut starttime = std::time::Instant::now();
|
||||
if let Ok(s) = env::var("FUZZ_SIZE") {
|
||||
@ -97,7 +165,7 @@ pub fn fuzz() {
|
||||
|
||||
let mut elf_buffer = Vec::new();
|
||||
let elf = EasyElf::from_file(
|
||||
env::var("KERNEL").expect("KERNEL env not set"),
|
||||
&cli.kernel,
|
||||
&mut elf_buffer,
|
||||
)
|
||||
.unwrap();
|
||||
@ -168,7 +236,27 @@ pub fn fuzz() {
|
||||
|
||||
let mut run_client = |state: Option<_>, mut mgr, _core_id| {
|
||||
// Initialize QEMU
|
||||
let args: Vec<String> = env::args().collect();
|
||||
let args: Vec<String> = vec![
|
||||
"target/debug/fret",
|
||||
"-icount",
|
||||
"shift=4,align=off,sleep=off",
|
||||
"-machine",
|
||||
"mps2-an385",
|
||||
"-monitor",
|
||||
"null",
|
||||
"-kernel",
|
||||
&cli.kernel.as_os_str().to_str().expect("kernel path is not a string"),
|
||||
"-serial",
|
||||
"null",
|
||||
"-nographic",
|
||||
"-S",
|
||||
"-semihosting",
|
||||
"--semihosting-config",
|
||||
"enable=on,target=native",
|
||||
"-snapshot",
|
||||
"-drive",
|
||||
"if=none,format=qcow2,file=dummy.qcow2",
|
||||
].into_iter().map(String::from).collect();
|
||||
let env: Vec<(String, String)> = env::vars().collect();
|
||||
let emu = Emulator::new(&args, &env).expect("Emulator creation failed");
|
||||
|
||||
@ -372,8 +460,8 @@ pub fn fuzz() {
|
||||
#[cfg(not(feature = "fuzz_int"))]
|
||||
let mut stages = tuple_list!(StdMutationalStage::new(mutator));
|
||||
|
||||
if env::var("DO_SHOWMAP").is_ok() {
|
||||
let s = &env::var("DO_SHOWMAP").unwrap();
|
||||
if let Commands::Showmap { input } = cli.command {
|
||||
let s = input.as_os_str();
|
||||
let show_input = if s=="-" {
|
||||
let mut buf = Vec::<u8>::new();
|
||||
std::io::stdin().read_to_end(&mut buf).expect("Could not read Stdin");
|
||||
@ -398,10 +486,10 @@ pub fn fuzz() {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if let Ok(_) = env::var("SEED_RANDOM") {
|
||||
} else if let Commands::Fuzz { random, time, seed } = cli.command {
|
||||
if let Some(se) = seed {
|
||||
unsafe {
|
||||
let mut rng = StdRng::seed_from_u64(RNG_SEED);
|
||||
let mut rng = StdRng::seed_from_u64(se);
|
||||
for i in 0..100 {
|
||||
let inp = BytesInput::new(vec![rng.gen::<u8>(); MAX_INPUT_SIZE]);
|
||||
fuzzer.evaluate_input(&mut state, &mut executor, &mut mgr, inp).unwrap();
|
||||
@ -426,15 +514,15 @@ pub fn fuzz() {
|
||||
println!("We imported {} inputs from disk.", state.corpus().count());
|
||||
}
|
||||
|
||||
match env::var("FUZZ_ITERS") {
|
||||
Err(_) => {
|
||||
match time {
|
||||
None => {
|
||||
fuzzer
|
||||
.fuzz_loop(&mut stages, &mut executor, &mut state, &mut mgr)
|
||||
.unwrap();
|
||||
},
|
||||
Ok(t) => {
|
||||
Some(t) => {
|
||||
println!("Iterations {}",t);
|
||||
let num = str::parse::<u64>(&t).expect("FUZZ_ITERS was not a number");
|
||||
let num = t;
|
||||
if let Ok(s) = env::var("FUZZ_RANDOM") { unsafe {
|
||||
if s.contains("watersv2_int") {
|
||||
println!("V2");
|
||||
|
Loading…
x
Reference in New Issue
Block a user