121 lines
3.8 KiB
Rust
121 lines
3.8 KiB
Rust
use clap::{Parser, Subcommand};
|
|
use std::path::PathBuf;
|
|
|
|
// Argument parsing ================================================================================
|
|
|
|
#[derive(Parser,Debug)]
|
|
#[command(author, version, about, long_about = None)]
|
|
pub struct Cli {
|
|
/// Kernel Image
|
|
#[arg(short, long, value_name = "FILE")]
|
|
pub kernel: PathBuf,
|
|
|
|
/// Sets a custom config file
|
|
#[arg(short, long, value_name = "FILE")]
|
|
pub config: PathBuf,
|
|
|
|
/// Sets the prefix of dumed files
|
|
#[arg(short='n', long, value_name = "FILENAME")]
|
|
pub dump_name: Option<PathBuf>,
|
|
|
|
/// do time dumps
|
|
#[arg(short='t', long)]
|
|
pub dump_times: bool,
|
|
|
|
/// do worst-case dumps
|
|
#[arg(short='a', long)]
|
|
pub dump_cases: bool,
|
|
|
|
/// do trace dumps (if supported)
|
|
#[arg(short='r', long)]
|
|
pub dump_traces: bool,
|
|
|
|
/// do graph dumps (if supported)
|
|
#[arg(short='g', long)]
|
|
pub dump_graph: bool,
|
|
|
|
/// select a task for measurments
|
|
#[arg(short='s', long)]
|
|
pub select_task: Option<String>,
|
|
|
|
#[command(subcommand)]
|
|
pub command: Commands,
|
|
}
|
|
#[derive(Subcommand,Clone,Debug)]
|
|
pub 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>,
|
|
}
|
|
}
|
|
|
|
pub fn set_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();
|
|
let mut found = false;
|
|
for r in reader.records() {
|
|
let rec = r.expect("CSV entry error");
|
|
if stem == &rec[0] {
|
|
println!("Config from file {:?}", rec);
|
|
found = true;
|
|
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;
|
|
}
|
|
}
|
|
if !found {
|
|
eprintln!("No config found for kernel {:?}", stem);
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn get_interrupt_config(kernel : &PathBuf, path : &PathBuf) -> Vec<(usize,u32)>{
|
|
let is_csv = path.as_path().extension().map_or(false, |x| x=="csv");
|
|
if !is_csv {
|
|
panic!("Interrupt config must be inside a CSV file");
|
|
} 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] {
|
|
let ret = rec[6].split(';').filter(|x| x != &"").map(|x| {
|
|
let pair = x.split_once('#').expect("Interrupt config error");
|
|
(pair.0.parse().expect("Interrupt config error"), pair.1.parse().expect("Interrupt config error"))
|
|
}).collect();
|
|
println!("Interrupt config {:?}", ret);
|
|
return ret;
|
|
}
|
|
}
|
|
}
|
|
return Vec::new();
|
|
} |