Update dependencies, removed unused deps, CI fixes (#839)

* update clap, remove unused deps

* update grammartek

* update pyo3

* update pyo3

* undid clap update

* not changing nyx

* updated deps

* Update more deps, fixes

* not needed clippy

* fix windows

* try to enable deprecated pyproto for pyo3

* unused

* moving some things to clap4 after all

* initial move to clap 4

* fix clap

* more clap4, removed accidental file

* fixes, fmt

* fix

* all fix no play

* fix
This commit is contained in:
Dominik Maier 2022-10-18 20:36:43 +02:00 committed by GitHub
parent d6d4fa506b
commit e8b3d33bf4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
49 changed files with 204 additions and 250 deletions

3
.gitignore vendored
View File

@ -1,4 +1,5 @@
target target
target-bin
out out
Cargo.lock Cargo.lock
vendor vendor
@ -48,4 +49,4 @@ __pycache__
*atomic_file_testfile* *atomic_file_testfile*
**/libxml2 **/libxml2
**/corpus_discovered **/corpus_discovered
**/libxml2-*.tar.gz **/libxml2-*.tar.gz

View File

@ -4,13 +4,13 @@ version = "0.8.2"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
pyo3 = { version = "0.15", features = ["extension-module"] } pyo3 = { version = "0.17", features = ["extension-module"] }
libafl_qemu = { path = "../../libafl_qemu", version = "0.8.2", features = ["python"] } libafl_qemu = { path = "../../libafl_qemu", version = "0.8.2", features = ["python"] }
libafl_sugar = { path = "../../libafl_sugar", version = "0.8.2", features = ["python"] } libafl_sugar = { path = "../../libafl_sugar", version = "0.8.2", features = ["python"] }
libafl = { path = "../../libafl", version = "0.8.2", features = ["python"] } libafl = { path = "../../libafl", version = "0.8.2", features = ["python"] }
[build-dependencies] [build-dependencies]
pyo3-build-config = { version = "0.15" } pyo3-build-config = { version = "0.17" }
[lib] [lib]
name = "pylibafl" name = "pylibafl"

View File

@ -1,10 +1,10 @@
# How to use python bindings # How to use python bindings
## First time setup ## First time setup
``` ```bash
# Create environment variable
python -m venv .env
# Install maturin # Install maturin
pip install maturin pip install maturin
# Create virtual environment
python3 -m venv .env
``` ```
## Build bindings ## Build bindings
``` ```
@ -13,7 +13,7 @@ source .env/bin/activate
# Build python module # Build python module
maturin develop maturin develop
``` ```
This is going to install `pylibafl` python module. This is going to install `pylibafl` python module into this venv.
## Use bindings ## Use bindings
### Example: Running baby_fuzzer in fuzzers/baby_fuzzer/baby_fuzzer.py ### Example: Running baby_fuzzer in fuzzers/baby_fuzzer/baby_fuzzer.py
@ -28,4 +28,4 @@ Then simply run
``` ```
python PATH_TO_BABY_FUZZER/baby_fuzzer.py python PATH_TO_BABY_FUZZER/baby_fuzzer.py
``` ```
The crashes' directory will be created in the directory from which you ran the command. The crashes directory will be created in the directory from which you ran the command.

View File

@ -18,4 +18,4 @@ opt-level = 3
[dependencies] [dependencies]
libafl = { path = "../../libafl/" } libafl = { path = "../../libafl/" }
clap = { version = "3.2", features = ["default"] } clap = { version = "3.2", features = ["default"] }
nix = "0.24" nix = "0.25"

View File

@ -74,7 +74,9 @@ pub fn main() {
) )
.get_matches(); .get_matches();
let corpus_dirs = vec![PathBuf::from(res.value_of("in").unwrap().to_string())]; let corpus_dirs = vec![PathBuf::from(
res.get_one::<String>("in").unwrap().to_string(),
)];
const MAP_SIZE: usize = 65536; const MAP_SIZE: usize = 65536;
@ -159,7 +161,7 @@ pub fn main() {
let mut tokens = Tokens::new(); let mut tokens = Tokens::new();
let forkserver = ForkserverExecutor::builder() let forkserver = ForkserverExecutor::builder()
.program(res.value_of("executable").unwrap()) .program(res.get_one::<String>("executable").unwrap())
.debug_child(debug_child) .debug_child(debug_child)
.shmem_provider(&mut shmem_provider) .shmem_provider(&mut shmem_provider)
.autotokens(&mut tokens) .autotokens(&mut tokens)
@ -170,13 +172,16 @@ pub fn main() {
let mut executor = TimeoutForkserverExecutor::with_signal( let mut executor = TimeoutForkserverExecutor::with_signal(
forkserver, forkserver,
Duration::from_millis( Duration::from_millis(
res.value_of("timeout") res.get_one::<String>("timeout")
.unwrap() .unwrap()
.to_string() .to_string()
.parse() .parse()
.expect("Could not parse timeout in milliseconds"), .expect("Could not parse timeout in milliseconds"),
), ),
res.value_of("signal").unwrap().parse::<Signal>().unwrap(), res.get_one::<String>("signal")
.unwrap()
.parse::<Signal>()
.unwrap(),
) )
.expect("Failed to create the executor."); .expect("Failed to create the executor.");

View File

@ -33,7 +33,7 @@ libc = "0.2"
libloading = "0.7" libloading = "0.7"
num-traits = "0.2" num-traits = "0.2"
rangemap = "0.1" rangemap = "0.1"
clap = { version = "3.2", features = ["derive"] } clap = { version = "4.0", features = ["derive"] }
serde = "1.0" serde = "1.0"
mimalloc = { version = "*", default-features = false } mimalloc = { version = "*", default-features = false }

View File

@ -36,7 +36,7 @@ libc = "0.2"
libloading = "0.7" libloading = "0.7"
num-traits = "0.2" num-traits = "0.2"
rangemap = "0.1" rangemap = "0.1"
clap = { version = "3.2", features = ["derive"] } clap = { version = "4.0", features = ["derive"] }
serde = "1.0" serde = "1.0"
mimalloc = { version = "*", default-features = false } mimalloc = { version = "*", default-features = false }

View File

@ -23,8 +23,8 @@ libafl = { path = "../../libafl/" }
libafl_targets = { path = "../../libafl_targets/", features = ["sancov_pcguard_hitcounts", "sancov_cmplog", "libfuzzer"] } libafl_targets = { path = "../../libafl_targets/", features = ["sancov_pcguard_hitcounts", "sancov_cmplog", "libfuzzer"] }
# TODO Include it only when building cc # TODO Include it only when building cc
libafl_cc = { path = "../../libafl_cc/" } libafl_cc = { path = "../../libafl_cc/" }
clap = { version = "3.2", features = ["default"] } clap = { version = "4.0", features = ["default"] }
nix = "0.24" nix = "0.25"
mimalloc = { version = "*", default-features = false } mimalloc = { version = "*", default-features = false }
[lib] [lib]

BIN
fuzzers/fuzzbench/server Executable file

Binary file not shown.

View File

@ -71,22 +71,19 @@ pub fn libafl_main() {
Arg::new("out") Arg::new("out")
.short('o') .short('o')
.long("output") .long("output")
.help("The directory to place finds in ('corpus')") .help("The directory to place finds in ('corpus')"),
.takes_value(true),
) )
.arg( .arg(
Arg::new("in") Arg::new("in")
.short('i') .short('i')
.long("input") .long("input")
.help("The directory to read initial inputs from ('seeds')") .help("The directory to read initial inputs from ('seeds')"),
.takes_value(true),
) )
.arg( .arg(
Arg::new("tokens") Arg::new("tokens")
.short('x') .short('x')
.long("tokens") .long("tokens")
.help("A file to read tokens from, to be used during fuzzing") .help("A file to read tokens from, to be used during fuzzing"),
.takes_value(true),
) )
.arg( .arg(
Arg::new("logfile") Arg::new("logfile")
@ -102,7 +99,7 @@ pub fn libafl_main() {
.help("Timeout for each individual execution, in milliseconds") .help("Timeout for each individual execution, in milliseconds")
.default_value("1200"), .default_value("1200"),
) )
.arg(Arg::new("remaining").multiple_values(true)) .arg(Arg::new("remaining"))
.try_get_matches() .try_get_matches()
{ {
Ok(res) => res, Ok(res) => res,
@ -123,8 +120,8 @@ pub fn libafl_main() {
env::current_dir().unwrap().to_string_lossy().to_string() env::current_dir().unwrap().to_string_lossy().to_string()
); );
if let Some(filenames) = res.values_of("remaining") { if let Some(filenames) = res.get_many::<String>("remaining") {
let filenames: Vec<&str> = filenames.collect(); let filenames: Vec<&str> = filenames.map(|v| v.as_str()).collect();
if !filenames.is_empty() { if !filenames.is_empty() {
run_testcases(&filenames); run_testcases(&filenames);
return; return;
@ -133,7 +130,7 @@ pub fn libafl_main() {
// For fuzzbench, crashes and finds are inside the same `corpus` directory, in the "queue" and "crashes" subdir. // For fuzzbench, crashes and finds are inside the same `corpus` directory, in the "queue" and "crashes" subdir.
let mut out_dir = PathBuf::from( let mut out_dir = PathBuf::from(
res.value_of("out") res.get_one::<String>("out")
.expect("The --output parameter is missing") .expect("The --output parameter is missing")
.to_string(), .to_string(),
); );
@ -149,7 +146,7 @@ pub fn libafl_main() {
out_dir.push("queue"); out_dir.push("queue");
let in_dir = PathBuf::from( let in_dir = PathBuf::from(
res.value_of("in") res.get_one::<String>("in")
.expect("The --input parameter is missing") .expect("The --input parameter is missing")
.to_string(), .to_string(),
); );
@ -158,14 +155,13 @@ pub fn libafl_main() {
return; return;
} }
let tokens = res.value_of("tokens").map(PathBuf::from); let tokens = res.get_one::<String>("tokens").map(PathBuf::from);
let logfile = PathBuf::from(res.value_of("logfile").unwrap().to_string()); let logfile = PathBuf::from(res.get_one::<String>("logfile").unwrap());
let timeout = Duration::from_millis( let timeout = Duration::from_millis(
res.value_of("timeout") res.get_one::<String>("timeout")
.unwrap() .unwrap()
.to_string()
.parse() .parse()
.expect("Could not parse timeout in milliseconds"), .expect("Could not parse timeout in milliseconds"),
); );

View File

@ -15,4 +15,4 @@ debug = true
libafl = { path = "../../libafl/" } libafl = { path = "../../libafl/" }
libafl_qemu = { path = "../../libafl_qemu/", features = ["x86_64"] } libafl_qemu = { path = "../../libafl_qemu/", features = ["x86_64"] }
clap = { version = "3.2", features = ["default"] } clap = { version = "3.2", features = ["default"] }
nix = "0.24" nix = "0.25"

View File

@ -113,7 +113,7 @@ pub fn main() {
); );
// For fuzzbench, crashes and finds are inside the same `corpus` directory, in the "queue" and "crashes" subdir. // For fuzzbench, crashes and finds are inside the same `corpus` directory, in the "queue" and "crashes" subdir.
let mut out_dir = PathBuf::from(res.value_of("out").unwrap().to_string()); let mut out_dir = PathBuf::from(res.get_one::<String>("out").unwrap().to_string());
if fs::create_dir(&out_dir).is_err() { if fs::create_dir(&out_dir).is_err() {
println!("Out dir at {:?} already exists.", &out_dir); println!("Out dir at {:?} already exists.", &out_dir);
if !out_dir.is_dir() { if !out_dir.is_dir() {
@ -125,15 +125,15 @@ pub fn main() {
crashes.push("crashes"); crashes.push("crashes");
out_dir.push("queue"); out_dir.push("queue");
let in_dir = PathBuf::from(res.value_of("in").unwrap().to_string()); let in_dir = PathBuf::from(res.get_one::<String>("in").unwrap().to_string());
if !in_dir.is_dir() { if !in_dir.is_dir() {
println!("In dir at {:?} is not a valid directory!", &in_dir); println!("In dir at {:?} is not a valid directory!", &in_dir);
return; return;
} }
let tokens = res.value_of("tokens").map(PathBuf::from); let tokens = res.get_one::<String>("tokens").map(PathBuf::from);
let logfile = PathBuf::from(res.value_of("logfile").unwrap().to_string()); let logfile = PathBuf::from(res.get_one::<String>("logfile").unwrap().to_string());
fuzz(out_dir, crashes, in_dir, tokens, logfile).expect("An error occurred while fuzzing"); fuzz(out_dir, crashes, in_dir, tokens, logfile).expect("An error occurred while fuzzing");
} }

View File

@ -15,4 +15,4 @@ debug = true
libafl = { path = "../../libafl/" } libafl = { path = "../../libafl/" }
libafl_qemu = { path = "../../libafl_qemu/", features = ["x86_64"] } libafl_qemu = { path = "../../libafl_qemu/", features = ["x86_64"] }
clap = { version = "3.2", features = ["default"] } clap = { version = "3.2", features = ["default"] }
nix = "0.24" nix = "0.25"

View File

@ -125,7 +125,7 @@ pub fn main() {
); );
// For fuzzbench, crashes and finds are inside the same `corpus` directory, in the "queue" and "crashes" subdir. // For fuzzbench, crashes and finds are inside the same `corpus` directory, in the "queue" and "crashes" subdir.
let mut out_dir = PathBuf::from(res.value_of("out").unwrap().to_string()); let mut out_dir = PathBuf::from(res.get_one::<String>("out").unwrap().to_string());
if fs::create_dir(&out_dir).is_err() { if fs::create_dir(&out_dir).is_err() {
println!("Out dir at {:?} already exists.", &out_dir); println!("Out dir at {:?} already exists.", &out_dir);
if !out_dir.is_dir() { if !out_dir.is_dir() {
@ -137,18 +137,18 @@ pub fn main() {
crashes.push("crashes"); crashes.push("crashes");
out_dir.push("queue"); out_dir.push("queue");
let in_dir = PathBuf::from(res.value_of("in").unwrap().to_string()); let in_dir = PathBuf::from(res.get_one::<String>("in").unwrap().to_string());
if !in_dir.is_dir() { if !in_dir.is_dir() {
println!("In dir at {:?} is not a valid directory!", &in_dir); println!("In dir at {:?} is not a valid directory!", &in_dir);
return; return;
} }
let tokens = res.value_of("tokens").map(PathBuf::from); let tokens = res.get_one::<String>("tokens").map(PathBuf::from);
let logfile = PathBuf::from(res.value_of("logfile").unwrap().to_string()); let logfile = PathBuf::from(res.get_one::<String>("logfile").unwrap().to_string());
let timeout = Duration::from_millis( let timeout = Duration::from_millis(
res.value_of("timeout") res.get_one::<String>("timeout")
.unwrap() .unwrap()
.to_string() .to_string()
.parse() .parse()

View File

@ -24,7 +24,7 @@ libafl_targets = { path = "../../libafl_targets/", features = ["sancov_pcguard_h
# TODO Include it only when building cc # TODO Include it only when building cc
libafl_cc = { path = "../../libafl_cc/" } libafl_cc = { path = "../../libafl_cc/" }
clap = { version = "3.2", features = ["default"] } clap = { version = "3.2", features = ["default"] }
nix = "0.24" nix = "0.25"
mimalloc = { version = "*", default-features = false } mimalloc = { version = "*", default-features = false }
content_inspector = "0.2.4" content_inspector = "0.2.4"

View File

@ -139,7 +139,7 @@ pub fn libafl_main() {
// For fuzzbench, crashes and finds are inside the same `corpus` directory, in the "queue" and "crashes" subdir. // For fuzzbench, crashes and finds are inside the same `corpus` directory, in the "queue" and "crashes" subdir.
let mut out_dir = PathBuf::from( let mut out_dir = PathBuf::from(
res.value_of("out") res.get_one::<String>("out")
.expect("The --output parameter is missing") .expect("The --output parameter is missing")
.to_string(), .to_string(),
); );
@ -155,7 +155,7 @@ pub fn libafl_main() {
out_dir.push("queue"); out_dir.push("queue");
let in_dir = PathBuf::from( let in_dir = PathBuf::from(
res.value_of("in") res.get_one::<String>("in")
.expect("The --input parameter is missing") .expect("The --input parameter is missing")
.to_string(), .to_string(),
); );
@ -164,12 +164,12 @@ pub fn libafl_main() {
return; return;
} }
let tokens = res.value_of("tokens").map(PathBuf::from); let tokens = res.get_one::<String>("tokens").map(PathBuf::from);
let logfile = PathBuf::from(res.value_of("logfile").unwrap().to_string()); let logfile = PathBuf::from(res.get_one::<String>("logfile").unwrap().to_string());
let timeout = Duration::from_millis( let timeout = Duration::from_millis(
res.value_of("timeout") res.get_one::<String>("timeout")
.unwrap() .unwrap()
.to_string() .to_string()
.parse() .parse()

View File

@ -24,7 +24,7 @@ libafl_targets = { path = "../../libafl_targets/", features = ["sancov_pcguard_h
# TODO Include it only when building cc # TODO Include it only when building cc
libafl_cc = { path = "../../libafl_cc/" } libafl_cc = { path = "../../libafl_cc/" }
clap = { version = "3.2", features = ["default"] } clap = { version = "3.2", features = ["default"] }
nix = "0.24" nix = "0.25"
mimalloc = { version = "*", default-features = false } mimalloc = { version = "*", default-features = false }
[lib] [lib]

View File

@ -133,7 +133,7 @@ pub fn libafl_main() {
// For fuzzbench, crashes and finds are inside the same `corpus` directory, in the "queue" and "crashes" subdir. // For fuzzbench, crashes and finds are inside the same `corpus` directory, in the "queue" and "crashes" subdir.
let mut out_dir = PathBuf::from( let mut out_dir = PathBuf::from(
res.value_of("out") res.get_one::<String>("out")
.expect("The --output parameter is missing") .expect("The --output parameter is missing")
.to_string(), .to_string(),
); );
@ -149,7 +149,7 @@ pub fn libafl_main() {
out_dir.push("queue"); out_dir.push("queue");
let in_dir = PathBuf::from( let in_dir = PathBuf::from(
res.value_of("in") res.get_one::<String>("in")
.expect("The --input parameter is missing") .expect("The --input parameter is missing")
.to_string(), .to_string(),
); );
@ -158,12 +158,12 @@ pub fn libafl_main() {
return; return;
} }
let tokens = res.value_of("tokens").map(PathBuf::from); let tokens = res.get_one::<String>("tokens").map(PathBuf::from);
let logfile = PathBuf::from(res.value_of("logfile").unwrap().to_string()); let logfile = PathBuf::from(res.get_one::<String>("logfile").unwrap().to_string());
let timeout = Duration::from_millis( let timeout = Duration::from_millis(
res.value_of("timeout") res.get_one::<String>("timeout")
.unwrap() .unwrap()
.to_string() .to_string()
.parse() .parse()

View File

@ -180,21 +180,21 @@ pub fn LLVMFuzzerRunDriver(
env::current_dir().unwrap().to_string_lossy().to_string() env::current_dir().unwrap().to_string_lossy().to_string()
); );
let cores = Cores::from_cmdline(matches.value_of("cores").unwrap()) let cores = Cores::from_cmdline(matches.get_one::<String>("cores").unwrap())
.expect("No valid core count given!"); .expect("No valid core count given!");
let broker_port = matches let broker_port = matches
.value_of("broker_port") .get_one::<String>("broker_port")
.map(|s| s.parse().expect("Invalid broker port")) .map(|s| s.parse().expect("Invalid broker port"))
.unwrap_or(1337); .unwrap_or(1337);
let remote_broker_addr = matches let remote_broker_addr = matches
.value_of("remote_broker_addr") .get_one::<String>("remote_broker_addr")
.map(|s| s.parse().expect("Invalid broker address")); .map(|s| s.parse().expect("Invalid broker address"));
let input_dirs: Vec<PathBuf> = matches let input_dirs: Vec<PathBuf> = matches
.values_of("input") .values_of("input")
.map(|v| v.map(PathBuf::from).collect()) .map(|v| v.map(PathBuf::from).collect())
.unwrap_or_default(); .unwrap_or_default();
let output_dir = matches let output_dir = matches
.value_of("output") .get_one::<String>("output")
.map(PathBuf::from) .map(PathBuf::from)
.unwrap_or_else(|| workdir.clone()); .unwrap_or_else(|| workdir.clone());
let token_files: Vec<&str> = matches let token_files: Vec<&str> = matches
@ -202,7 +202,7 @@ pub fn LLVMFuzzerRunDriver(
.map(|v| v.collect()) .map(|v| v.collect())
.unwrap_or_default(); .unwrap_or_default();
let timeout_ms = matches let timeout_ms = matches
.value_of("timeout") .get_one::<String>("timeout")
.map(|s| s.parse().expect("Invalid timeout")) .map(|s| s.parse().expect("Invalid timeout"))
.unwrap_or(10000); .unwrap_or(10000);
// let cmplog_enabled = matches.is_present("cmplog"); // let cmplog_enabled = matches.is_present("cmplog");

View File

@ -23,7 +23,7 @@ libafl = { path = "../../libafl/", features = ["std", "derive", "llmp_compressio
libafl_targets = { path = "../../libafl_targets/", features = ["sancov_pcguard_hitcounts", "libfuzzer"] } libafl_targets = { path = "../../libafl_targets/", features = ["sancov_pcguard_hitcounts", "libfuzzer"] }
# TODO Include it only when building cc # TODO Include it only when building cc
libafl_cc = { path = "../../libafl_cc/" } libafl_cc = { path = "../../libafl_cc/" }
clap = { version = "3.2", features = ["derive"] } clap = { version = "4.0", features = ["derive"] }
mimalloc = { version = "*", default-features = false } mimalloc = { version = "*", default-features = false }
[lib] [lib]

View File

@ -9,7 +9,7 @@ static GLOBAL: MiMalloc = MiMalloc;
use core::time::Duration; use core::time::Duration;
use std::{env, net::SocketAddr, path::PathBuf}; use std::{env, net::SocketAddr, path::PathBuf};
use clap::{self, StructOpt}; use clap::Parser;
use libafl::{ use libafl::{
bolts::{ bolts::{
core_affinity::Cores, core_affinity::Cores,
@ -48,23 +48,23 @@ fn timeout_from_millis_str(time: &str) -> Result<Duration, Error> {
} }
/// The commandline args this fuzzer accepts /// The commandline args this fuzzer accepts
#[derive(Debug, StructOpt)] #[derive(Debug, Parser)]
#[clap( #[command(
name = "libfuzzer_libpng_launcher", name = "libfuzzer_libpng_launcher",
about = "A libfuzzer-like fuzzer for libpng with llmp-multithreading support and a launcher", about = "A libfuzzer-like fuzzer for libpng with llmp-multithreading support and a launcher",
author = "Andrea Fioraldi <andreafioraldi@gmail.com>, Dominik Maier <domenukk@gmail.com>" author = "Andrea Fioraldi <andreafioraldi@gmail.com>, Dominik Maier <domenukk@gmail.com>"
)] )]
struct Opt { struct Opt {
#[clap( #[arg(
short, short,
long, long,
parse(try_from_str = Cores::from_cmdline), value_parser = Cores::from_cmdline,
help = "Spawn a client in each of the provided cores. Broker runs in the 0th core. 'all' to select all available cores. 'none' to run a client without binding to any core. eg: '1,2-4,6' selects the cores 1,2,3,4,6.", help = "Spawn a client in each of the provided cores. Broker runs in the 0th core. 'all' to select all available cores. 'none' to run a client without binding to any core. eg: '1,2-4,6' selects the cores 1,2,3,4,6.",
name = "CORES" name = "CORES"
)] )]
cores: Cores, cores: Cores,
#[clap( #[arg(
short = 'p', short = 'p',
long, long,
help = "Choose the broker TCP port, default is 1337", help = "Choose the broker TCP port, default is 1337",
@ -73,47 +73,34 @@ struct Opt {
)] )]
broker_port: u16, broker_port: u16,
#[clap( #[arg(short = 'a', long, help = "Specify a remote broker", name = "REMOTE")]
parse(try_from_str),
short = 'a',
long,
help = "Specify a remote broker",
name = "REMOTE"
)]
remote_broker_addr: Option<SocketAddr>, remote_broker_addr: Option<SocketAddr>,
#[clap( #[arg(short, long, help = "Set an initial corpus directory", name = "INPUT")]
parse(try_from_str),
short,
long,
help = "Set an initial corpus directory",
name = "INPUT"
)]
input: Vec<PathBuf>, input: Vec<PathBuf>,
#[clap( #[arg(
short, short,
long, long,
parse(try_from_str),
help = "Set the output directory, default is ./out", help = "Set the output directory, default is ./out",
name = "OUTPUT", name = "OUTPUT",
default_value = "./out" default_value = "./out"
)] )]
output: PathBuf, output: PathBuf,
#[clap( #[arg(
parse(try_from_str = timeout_from_millis_str), value_parser = timeout_from_millis_str,
short, short,
long, long,
help = "Set the exeucution timeout in milliseconds, default is 10000", help = "Set the execution timeout in milliseconds, default is 10000",
name = "TIMEOUT", name = "TIMEOUT",
default_value = "10000" default_value = "10000"
)] )]
timeout: Duration, timeout: Duration,
/* /*
/// This fuzzer has hard-coded tokens /// This fuzzer has hard-coded tokens
#[clap( #[arg(
parse(from_os_str),
short = "x", short = "x",
long, long,
help = "Feed the fuzzer with an user-specified list of tokens (often called \"dictionary\"", help = "Feed the fuzzer with an user-specified list of tokens (often called \"dictionary\"",

View File

@ -23,7 +23,7 @@ libafl = { path = "../../libafl/", features = ["std", "derive", "llmp_compressio
libafl_targets = { path = "../../libafl_targets/", features = ["libfuzzer"] } libafl_targets = { path = "../../libafl_targets/", features = ["libfuzzer"] }
# TODO Include it only when building cc # TODO Include it only when building cc
libafl_cc = { path = "../../libafl_cc/" } libafl_cc = { path = "../../libafl_cc/" }
clap = { version = "3.2", features = ["derive"] } clap = { version = "4.0", features = ["derive"] }
mimalloc = { version = "*", default-features = false } mimalloc = { version = "*", default-features = false }
[lib] [lib]

View File

@ -9,7 +9,7 @@ static GLOBAL: MiMalloc = MiMalloc;
use core::time::Duration; use core::time::Duration;
use std::{env, net::SocketAddr, path::PathBuf}; use std::{env, net::SocketAddr, path::PathBuf};
use clap::{self, StructOpt}; use clap::{self, Parser};
use libafl::{ use libafl::{
bolts::{ bolts::{
core_affinity::Cores, core_affinity::Cores,
@ -44,23 +44,23 @@ fn timeout_from_millis_str(time: &str) -> Result<Duration, Error> {
Ok(Duration::from_millis(time.parse()?)) Ok(Duration::from_millis(time.parse()?))
} }
#[derive(Debug, StructOpt)] #[derive(Debug, Parser)]
#[clap( #[command(
name = "libfuzzer_libpng_ctx", name = "libfuzzer_libpng_ctx",
about = "A clone of libfuzzer using LibAFL for a libpng harness", about = "A clone of libfuzzer using LibAFL for a libpng harness",
author = "Andrea Fioraldi <andreafioraldi@gmail.com>, Dominik Maier <domenukk@gmail.com>" author = "Andrea Fioraldi <andreafioraldi@gmail.com>, Dominik Maier <domenukk@gmail.com>"
)] )]
struct Opt { struct Opt {
#[clap( #[arg(
short, short,
long, long,
parse(try_from_str = Cores::from_cmdline), value_parser = Cores::from_cmdline,
help = "Spawn a client in each of the provided cores. Broker runs in the 0th core. 'all' to select all available cores. 'none' to run a client without binding to any core. eg: '1,2-4,6' selects the cores 1,2,3,4,6.", help = "Spawn a client in each of the provided cores. Broker runs in the 0th core. 'all' to select all available cores. 'none' to run a client without binding to any core. eg: '1,2-4,6' selects the cores 1,2,3,4,6.",
name = "CORES" name = "CORES"
)] )]
cores: Cores, cores: Cores,
#[clap( #[arg(
short = 'p', short = 'p',
long, long,
help = "Choose the broker TCP port, default is 1337", help = "Choose the broker TCP port, default is 1337",
@ -69,38 +69,25 @@ struct Opt {
)] )]
broker_port: u16, broker_port: u16,
#[clap( #[arg(short = 'a', long, help = "Specify a remote broker", name = "REMOTE")]
parse(try_from_str),
short = 'a',
long,
help = "Specify a remote broker",
name = "REMOTE"
)]
remote_broker_addr: Option<SocketAddr>, remote_broker_addr: Option<SocketAddr>,
#[clap( #[arg(short, long, help = "Set an initial corpus directory", name = "INPUT")]
parse(try_from_str),
short,
long,
help = "Set an initial corpus directory",
name = "INPUT"
)]
input: Vec<PathBuf>, input: Vec<PathBuf>,
#[clap( #[arg(
short, short,
long, long,
parse(try_from_str),
help = "Set the output directory, default is ./out", help = "Set the output directory, default is ./out",
name = "OUTPUT", name = "OUTPUT",
default_value = "./out" default_value = "./out"
)] )]
output: PathBuf, output: PathBuf,
#[clap( #[arg(
short, short,
long, long,
parse(try_from_str = timeout_from_millis_str), value_parser = timeout_from_millis_str,
help = "Set the exeucution timeout in milliseconds, default is 10000", help = "Set the exeucution timeout in milliseconds, default is 10000",
name = "TIMEOUT", name = "TIMEOUT",
default_value = "10000", default_value = "10000",
@ -108,8 +95,8 @@ struct Opt {
timeout: Duration, timeout: Duration,
/* /*
// The tokens are hardcoded in this example. // The tokens are hardcoded in this example.
#[clap( #[arg(
parse(from_os_str),
short = "x", short = "x",
long, long,
help = "Feed the fuzzer with an user-specified list of tokens (often called \"dictionary\"", help = "Feed the fuzzer with an user-specified list of tokens (often called \"dictionary\"",

View File

@ -23,7 +23,7 @@ libafl = { path = "../../libafl/", features = ["std", "derive", "llmp_compressio
libafl_targets = { path = "../../libafl_targets/", features = ["sancov_pcguard_hitcounts", "libfuzzer"] } libafl_targets = { path = "../../libafl_targets/", features = ["sancov_pcguard_hitcounts", "libfuzzer"] }
# TODO Include it only when building cc # TODO Include it only when building cc
libafl_cc = { path = "../../libafl_cc/" } libafl_cc = { path = "../../libafl_cc/" }
clap = { version = "3.2", features = ["derive"] } clap = { version = "4.0", features = ["derive"] }
mimalloc = { version = "*", default-features = false } mimalloc = { version = "*", default-features = false }
[lib] [lib]

View File

@ -9,7 +9,7 @@ static GLOBAL: MiMalloc = MiMalloc;
use core::time::Duration; use core::time::Duration;
use std::{env, net::SocketAddr, path::PathBuf}; use std::{env, net::SocketAddr, path::PathBuf};
use clap::{self, StructOpt}; use clap::{self, Parser};
use libafl::{ use libafl::{
bolts::{ bolts::{
core_affinity::Cores, core_affinity::Cores,
@ -46,23 +46,23 @@ fn timeout_from_millis_str(time: &str) -> Result<Duration, Error> {
} }
/// The commandline args this fuzzer accepts /// The commandline args this fuzzer accepts
#[derive(Debug, StructOpt)] #[derive(Debug, Parser)]
#[clap( #[command(
name = "libfuzzer_libpng_launcher", name = "libfuzzer_libpng_launcher",
about = "A libfuzzer-like fuzzer for libpng with llmp-multithreading support and a launcher", about = "A libfuzzer-like fuzzer for libpng with llmp-multithreading support and a launcher",
author = "Andrea Fioraldi <andreafioraldi@gmail.com>, Dominik Maier <domenukk@gmail.com>" author = "Andrea Fioraldi <andreafioraldi@gmail.com>, Dominik Maier <domenukk@gmail.com>"
)] )]
struct Opt { struct Opt {
#[clap( #[arg(
short, short,
long, long,
parse(try_from_str = Cores::from_cmdline), value_parser = Cores::from_cmdline,
help = "Spawn a client in each of the provided cores. Broker runs in the 0th core. 'all' to select all available cores. 'none' to run a client without binding to any core. eg: '1,2-4,6' selects the cores 1,2,3,4,6.", help = "Spawn a client in each of the provided cores. Broker runs in the 0th core. 'all' to select all available cores. 'none' to run a client without binding to any core. eg: '1,2-4,6' selects the cores 1,2,3,4,6.",
name = "CORES" name = "CORES"
)] )]
cores: Cores, cores: Cores,
#[clap( #[arg(
short = 'p', short = 'p',
long, long,
help = "Choose the broker TCP port, default is 1337", help = "Choose the broker TCP port, default is 1337",
@ -71,36 +71,23 @@ struct Opt {
)] )]
broker_port: u16, broker_port: u16,
#[clap( #[arg(short = 'a', long, help = "Specify a remote broker", name = "REMOTE")]
parse(try_from_str),
short = 'a',
long,
help = "Specify a remote broker",
name = "REMOTE"
)]
remote_broker_addr: Option<SocketAddr>, remote_broker_addr: Option<SocketAddr>,
#[clap( #[arg(short, long, help = "Set an initial corpus directory", name = "INPUT")]
parse(try_from_str),
short,
long,
help = "Set an initial corpus directory",
name = "INPUT"
)]
input: Vec<PathBuf>, input: Vec<PathBuf>,
#[clap( #[arg(
short, short,
long, long,
parse(try_from_str),
help = "Set the output directory, default is ./out", help = "Set the output directory, default is ./out",
name = "OUTPUT", name = "OUTPUT",
default_value = "./out" default_value = "./out"
)] )]
output: PathBuf, output: PathBuf,
#[clap( #[arg(
parse(try_from_str = timeout_from_millis_str), value_parser = timeout_from_millis_str,
short, short,
long, long,
help = "Set the exeucution timeout in milliseconds, default is 10000", help = "Set the exeucution timeout in milliseconds, default is 10000",
@ -110,8 +97,8 @@ struct Opt {
timeout: Duration, timeout: Duration,
/* /*
/// This fuzzer has hard-coded tokens /// This fuzzer has hard-coded tokens
#[clap( #[arg(
parse(from_os_str),
short = "x", short = "x",
long, long,
help = "Feed the fuzzer with an user-specified list of tokens (often called \"dictionary\"", help = "Feed the fuzzer with an user-specified list of tokens (often called \"dictionary\"",

View File

@ -18,7 +18,7 @@ debug = true
[dependencies] [dependencies]
libafl = { path = "../../../libafl/", features = ["concolic_mutation"] } libafl = { path = "../../../libafl/", features = ["concolic_mutation"] }
libafl_targets = { path = "../../../libafl_targets/", features = ["sancov_pcguard_edges", "sancov_cmplog", "libfuzzer"] } libafl_targets = { path = "../../../libafl_targets/", features = ["sancov_pcguard_edges", "sancov_cmplog", "libfuzzer"] }
clap = { version = "3.2", features = ["derive"]} clap = { version = "4.0", features = ["derive"]}
mimalloc = { version = "*", default-features = false } mimalloc = { version = "*", default-features = false }
[build-dependencies] [build-dependencies]

View File

@ -4,7 +4,7 @@ use mimalloc::MiMalloc;
#[global_allocator] #[global_allocator]
static GLOBAL: MiMalloc = MiMalloc; static GLOBAL: MiMalloc = MiMalloc;
use clap::{self, StructOpt}; use clap::{self, Parser};
use std::{ use std::{
env, env,
path::PathBuf, path::PathBuf,
@ -54,10 +54,10 @@ use libafl_targets::{
MAX_EDGES_NUM, MAX_EDGES_NUM,
}; };
#[derive(Debug, StructOpt)] #[derive(Debug, Parser)]
struct Opt { struct Opt {
/// This node should do concolic tracing + solving instead of traditional fuzzing /// This node should do concolic tracing + solving instead of traditional fuzzing
#[clap(short, long)] #[arg(short, long)]
concolic: bool, concolic: bool,
} }

View File

@ -19,7 +19,7 @@ fork = [] # uses the fork() syscall to spawn children, instead of launching a ne
rand_trait = ["rand_core"] # If set, libafl's rand implementations will implement `rand::Rng` rand_trait = ["rand_core"] # If set, libafl's rand implementations will implement `rand::Rng`
introspection = [] # Include performance statistics of the fuzzing pipeline introspection = [] # Include performance statistics of the fuzzing pipeline
concolic_mutation = ["z3"] # include a simple concolic mutator based on z3 concolic_mutation = ["z3"] # include a simple concolic mutator based on z3
python = ["pyo3"] python = ["pyo3", "concat-idents"]
prelude = [] # Expose libafl::prelude for access without additional using directives prelude = [] # Expose libafl::prelude for access without additional using directives
tui_monitor = ["tui", "crossterm"] # enable TuiMonitor with crossterm tui_monitor = ["tui", "crossterm"] # enable TuiMonitor with crossterm
cli = ["clap"] # expose bolts::cli cli = ["clap"] # expose bolts::cli
@ -45,7 +45,7 @@ rustversion = "1.0"
[dev-dependencies] [dev-dependencies]
serde_json = { version = "1.0", default-features = false, features = ["alloc"] } serde_json = { version = "1.0", default-features = false, features = ["alloc"] }
serial_test = "0.8" serial_test = "0.9"
[dependencies] [dependencies]
libafl_derive = { version = "0.8.2", optional = true, path = "../libafl_derive" } libafl_derive = { version = "0.8.2", optional = true, path = "../libafl_derive" }
@ -62,47 +62,46 @@ bincode = {version = "1.3", optional = true }
static_assertions = "1.1.0" static_assertions = "1.1.0"
num_enum = { version = "0.5.7", default-features = false } num_enum = { version = "0.5.7", default-features = false }
typed-builder = "0.10.0" # Implement the builder pattern at compiletime typed-builder = "0.10.0" # Implement the builder pattern at compiletime
ahash = { version = "0.7", default-features=false, features=["compile-time-rng"] } # The hash function already used in hashbrown ahash = { version = "0.7", default-features=false } # The hash function already used in hashbrown
intervaltree = { version = "0.2.7", default-features = false, features = ["serde"] } intervaltree = { version = "0.2.7", default-features = false, features = ["serde"] }
backtrace = {version = "0.3", optional = true} # Used to get the stacktrace in StacktraceObserver backtrace = {version = "0.3", optional = true} # Used to get the stacktrace in StacktraceObserver
ctor = { optional = true, version = "0.1" } ctor = { optional = true, version = "0.1" }
serde_json = { version = "1.0", optional = true, default-features = false, features = ["alloc"] } serde_json = { version = "1.0", optional = true, default-features = false, features = ["alloc"] }
miniz_oxide = { version = "0.5.3", optional = true} miniz_oxide = { version = "0.6.2", optional = true}
hostname = { version = "^0.3", optional = true } # Is there really no gethostname in the stdlib? hostname = { version = "^0.3", optional = true } # Is there really no gethostname in the stdlib?
rand_core = { version = "0.6", optional = true } rand_core = { version = "0.6", optional = true }
nix = { version = "0.24", optional = true } nix = { version = "0.25", optional = true }
regex = { version = "1", optional = true } regex = { version = "1", optional = true }
uuid = { version = "1.1.2", optional = true, features = ["serde", "v4"] } uuid = { version = "1.1.2", optional = true, features = ["serde", "v4"] }
byteorder = { version = "1.4", optional = true } byteorder = { version = "1.4", optional = true }
once_cell = { version = "1.13", optional = true } once_cell = { version = "1.13", optional = true }
libm = "0.2.2" libm = "0.2.2"
tui = { version = "0.18", default-features = false, features = ['crossterm'], optional = true } tui = { version = "0.19", default-features = false, features = ['crossterm'], optional = true }
crossterm = { version = "0.24", optional = true } crossterm = { version = "0.25", optional = true }
clap = {version = "3.2", features = ["derive", "wrap_help"], optional = true} clap = {version = "4.0", features = ["derive", "wrap_help"], optional = true}
wait-timeout = { version = "0.2", optional = true } # used by CommandExecutor to wait for child process wait-timeout = { version = "0.2", optional = true } # used by CommandExecutor to wait for child process
z3 = { version = "0.11", features = ["static-link-z3"], optional = true } # for concolic mutation z3 = { version = "0.11", features = ["static-link-z3"], optional = true } # for concolic mutation
pyo3 = { version = "0.15", optional = true, features = ["serde", "macros"] } pyo3 = { version = "0.17", optional = true, features = ["serde", "macros"] }
concat-idents = "1.1.3" concat-idents = { version = "1.1.3", optional = true }
# AGPL # AGPL
# !!! this create requires nightly # !!! this create requires nightly
grammartec = { version = "0.1", optional = true } grammartec = { version = "0.2", optional = true }
[target.'cfg(unix)'.dependencies] [target.'cfg(unix)'.dependencies]
libc = "0.2" # For (*nix) libc libc = "0.2" # For (*nix) libc
uds = "0.2.6" uds = "0.2.6"
lock_api = "0.4.7" lock_api = "0.4.7"
regex = "1"
[target.'cfg(windows)'.dependencies] [target.'cfg(windows)'.dependencies]
windows = { version = "0.39.0", features = ["Win32_Foundation", "Win32_System_Threading", "Win32_System_Diagnostics_Debug", "Win32_System_Kernel", "Win32_System_Memory", "Win32_Security", "Win32_System_SystemInformation"] } windows = { version = "0.42.0", features = ["Win32_Foundation", "Win32_System_Threading", "Win32_System_Diagnostics_Debug", "Win32_System_Kernel", "Win32_System_Memory", "Win32_Security", "Win32_System_SystemInformation"] }
[target.'cfg(windows)'.build-dependencies] [target.'cfg(windows)'.build-dependencies]
windows = "0.39.0" windows = "0.42.0"
#[profile.release] #[profile.release]
#lto = true #lto = true

View File

@ -106,7 +106,7 @@ fn parse_instrumentation_location(
/// Top-level container for cli options/arguments/subcommands /// Top-level container for cli options/arguments/subcommands
#[derive(Parser, Clone, Debug, Serialize, Deserialize)] #[derive(Parser, Clone, Debug, Serialize, Deserialize)]
#[clap( #[command(
arg_required_else_help(true), arg_required_else_help(true),
subcommand_precedence_over_arg(true), subcommand_precedence_over_arg(true),
args_conflicts_with_subcommands(true) args_conflicts_with_subcommands(true)
@ -114,48 +114,48 @@ fn parse_instrumentation_location(
#[allow(clippy::struct_excessive_bools)] #[allow(clippy::struct_excessive_bools)]
pub struct FuzzerOptions { pub struct FuzzerOptions {
/// timeout for each target execution (milliseconds) /// timeout for each target execution (milliseconds)
#[clap(short, long, default_value = "1000", parse(try_from_str = parse_timeout), help_heading = "Fuzz Options")] #[arg(short, long, default_value = "1000", value_parser = parse_timeout, help_heading = "Fuzz Options")]
pub timeout: Duration, pub timeout: Duration,
/// whether or not to print debug info /// whether or not to print debug info
#[clap(short, long)] #[arg(short, long)]
pub verbose: bool, pub verbose: bool,
/// file to which all client output should be written /// file to which all client output should be written
#[clap(short, long, default_value = "/dev/null")] #[arg(short, long, default_value = "/dev/null")]
pub stdout: String, pub stdout: String,
/// the name of the configuration to use /// the name of the configuration to use
#[clap(long, default_value = "default configuration")] #[arg(long, default_value = "default configuration")]
pub configuration: String, pub configuration: String,
/// enable Address Sanitizer (ASAN) /// enable Address Sanitizer (ASAN)
#[clap(short = 'A', long, help_heading = "Fuzz Options")] #[arg(short = 'A', long, help_heading = "Fuzz Options")]
pub asan: bool, pub asan: bool,
/// Enable ASAN on each of the provided cores. Use 'all' to select all available /// Enable ASAN on each of the provided cores. Use 'all' to select all available
/// cores. 'none' to run a client without binding to any core. /// cores. 'none' to run a client without binding to any core.
/// ex: '1,2-4,6' selects the cores 1, 2, 3, 4, and 6. /// ex: '1,2-4,6' selects the cores 1, 2, 3, 4, and 6.
#[cfg(feature = "frida_cli")] #[cfg(feature = "frida_cli")]
#[clap(long, default_value = "0", parse(try_from_str = Cores::from_cmdline), help_heading = "ASAN Options")] #[arg(long, default_value = "0", value_parser = Cores::from_cmdline, help_heading = "ASAN Options")]
pub asan_cores: Cores, pub asan_cores: Cores,
/// number of fuzz iterations to perform /// number of fuzz iterations to perform
#[clap(short = 'I', long, help_heading = "Fuzz Options", default_value = "0")] #[arg(short = 'I', long, help_heading = "Fuzz Options", default_value = "0")]
pub iterations: usize, pub iterations: usize,
/// path to the harness /// path to the harness
#[clap(short = 'H', long, parse(from_os_str), help_heading = "Fuzz Options")] #[arg(short = 'H', long, help_heading = "Fuzz Options")]
pub harness: Option<PathBuf>, pub harness: Option<PathBuf>,
/// trailing arguments (after "--"); can be passed directly to the harness /// trailing arguments (after "--"); can be passed directly to the harness
#[cfg(not(feature = "qemu_cli"))] #[cfg(not(feature = "qemu_cli"))]
#[clap(last = true, name = "HARNESS_ARGS")] #[arg(last = true, value_name = "HARNESS_ARGS")]
pub harness_args: Vec<String>, pub harness_args: Vec<String>,
/// harness function to call /// harness function to call
#[cfg(feature = "frida_cli")] #[cfg(feature = "frida_cli")]
#[clap( #[arg(
short = 'F', short = 'F',
long, long,
default_value = "LLVMFuzzerTestOneInput", default_value = "LLVMFuzzerTestOneInput",
@ -165,17 +165,17 @@ pub struct FuzzerOptions {
/// additional libraries to instrument /// additional libraries to instrument
#[cfg(feature = "frida_cli")] #[cfg(feature = "frida_cli")]
#[clap(short, long, help_heading = "Frida Options")] #[arg(short, long, help_heading = "Frida Options")]
pub libs_to_instrument: Vec<String>, pub libs_to_instrument: Vec<String>,
/// enable CmpLog instrumentation /// enable CmpLog instrumentation
#[cfg_attr( #[cfg_attr(
feature = "frida_cli", feature = "frida_cli",
clap(short = 'C', long, help_heading = "Frida Options") arg(short = 'C', long, help_heading = "Frida Options")
)] )]
#[cfg_attr( #[cfg_attr(
not(feature = "frida_cli"), not(feature = "frida_cli"),
clap(short = 'C', long, help_heading = "Fuzz Options") arg(short = 'C', long, help_heading = "Fuzz Options")
)] )]
pub cmplog: bool, pub cmplog: bool,
@ -183,27 +183,27 @@ pub struct FuzzerOptions {
/// cores. 'none' to run a client without binding to any core. /// cores. 'none' to run a client without binding to any core.
/// ex: '1,2-4,6' selects the cores 1, 2, 3, 4, and 6. /// ex: '1,2-4,6' selects the cores 1, 2, 3, 4, and 6.
#[cfg(feature = "frida_cli")] #[cfg(feature = "frida_cli")]
#[clap(long, default_value = "0", parse(try_from_str = Cores::from_cmdline), help_heading = "Frida Options")] #[arg(long, default_value = "0", value_parser = Cores::from_cmdline, help_heading = "Frida Options")]
pub cmplog_cores: Cores, pub cmplog_cores: Cores,
/// enable ASAN leak detection /// enable ASAN leak detection
#[cfg(feature = "frida_cli")] #[cfg(feature = "frida_cli")]
#[clap(short, long, help_heading = "ASAN Options")] #[arg(short, long, help_heading = "ASAN Options")]
pub detect_leaks: bool, pub detect_leaks: bool,
/// instruct ASAN to continue after a memory error is detected /// instruct ASAN to continue after a memory error is detected
#[cfg(feature = "frida_cli")] #[cfg(feature = "frida_cli")]
#[clap(long, help_heading = "ASAN Options")] #[arg(long, help_heading = "ASAN Options")]
pub continue_on_error: bool, pub continue_on_error: bool,
/// instruct ASAN to gather (and report) allocation-/free-site backtraces /// instruct ASAN to gather (and report) allocation-/free-site backtraces
#[cfg(feature = "frida_cli")] #[cfg(feature = "frida_cli")]
#[clap(long, help_heading = "ASAN Options")] #[arg(long, help_heading = "ASAN Options")]
pub allocation_backtraces: bool, pub allocation_backtraces: bool,
/// the maximum size that the ASAN allocator should allocate /// the maximum size that the ASAN allocator should allocate
#[cfg(feature = "frida_cli")] #[cfg(feature = "frida_cli")]
#[clap( #[arg(
short, short,
long, long,
default_value = "1073741824", // 1_usize << 30 default_value = "1073741824", // 1_usize << 30
@ -213,7 +213,7 @@ pub struct FuzzerOptions {
/// the maximum total allocation size that the ASAN allocator should allocate /// the maximum total allocation size that the ASAN allocator should allocate
#[cfg(feature = "frida_cli")] #[cfg(feature = "frida_cli")]
#[clap( #[arg(
short = 'M', short = 'M',
long, long,
default_value = "4294967296", // 1_usize << 32 default_value = "4294967296", // 1_usize << 32
@ -223,56 +223,47 @@ pub struct FuzzerOptions {
/// instruct ASAN to panic if the max ASAN allocation size is exceeded /// instruct ASAN to panic if the max ASAN allocation size is exceeded
#[cfg(feature = "frida_cli")] #[cfg(feature = "frida_cli")]
#[clap(long, help_heading = "ASAN Options")] #[arg(long, help_heading = "ASAN Options")]
pub max_allocation_panics: bool, pub max_allocation_panics: bool,
/// disable coverage /// disable coverage
#[cfg(feature = "frida_cli")] #[cfg(feature = "frida_cli")]
#[clap(long, help_heading = "Frida Options")] #[arg(long, help_heading = "Frida Options")]
pub disable_coverage: bool, pub disable_coverage: bool,
/// enable DrCov (aarch64 only) /// enable DrCov (aarch64 only)
#[cfg(feature = "frida_cli")] #[cfg(feature = "frida_cli")]
#[clap(long, help_heading = "Frida Options")] #[arg(long, help_heading = "Frida Options")]
pub drcov: bool, pub drcov: bool,
/// locations which will not be instrumented for ASAN or coverage purposes (ex: mod_name@0x12345) /// locations which will not be instrumented for ASAN or coverage purposes (ex: mod_name@0x12345)
#[cfg(feature = "frida_cli")] #[cfg(feature = "frida_cli")]
#[clap(short = 'D', long, help_heading = "Frida Options", parse(try_from_str = parse_instrumentation_location), multiple_occurrences = true)] #[arg(short = 'D', long, help_heading = "Frida Options", value_parser = parse_instrumentation_location)]
pub dont_instrument: Vec<(String, usize)>, pub dont_instrument: Vec<(String, usize)>,
/// trailing arguments (after "--"); can be passed directly to QEMU /// trailing arguments (after "--"); can be passed directly to QEMU
#[cfg(feature = "qemu_cli")] #[cfg(feature = "qemu_cli")]
#[clap(last = true)] #[arg(last = true)]
pub qemu_args: Vec<String>, pub qemu_args: Vec<String>,
/// paths to fuzzer token files (aka 'dictionaries') /// paths to fuzzer token files (aka 'dictionaries')
#[clap( #[arg(short = 'x', long, help_heading = "Fuzz Options")]
short = 'x',
long,
multiple_values = true,
parse(from_os_str),
help_heading = "Fuzz Options"
)]
pub tokens: Vec<PathBuf>, pub tokens: Vec<PathBuf>,
/// input corpus directories /// input corpus directories
#[clap( #[arg(
short, short,
long, long,
default_values = &["corpus/"], default_values = &["corpus/"],
multiple_values = true,
parse(from_os_str),
help_heading = "Corpus Options" help_heading = "Corpus Options"
)] )]
pub input: Vec<PathBuf>, pub input: Vec<PathBuf>,
/// output solutions directory /// output solutions directory
#[clap( #[arg(
short, short,
long, long,
default_value = "solutions/", default_value = "solutions/",
parse(from_os_str),
help_heading = "Corpus Options" help_heading = "Corpus Options"
)] )]
pub output: PathBuf, pub output: PathBuf,
@ -280,27 +271,26 @@ pub struct FuzzerOptions {
/// Spawn a client in each of the provided cores. Use 'all' to select all available /// Spawn a client in each of the provided cores. Use 'all' to select all available
/// cores. 'none' to run a client without binding to any core. /// cores. 'none' to run a client without binding to any core.
/// ex: '1,2-4,6' selects the cores 1, 2, 3, 4, and 6. /// ex: '1,2-4,6' selects the cores 1, 2, 3, 4, and 6.
#[clap(short = 'c', long, default_value = "0", parse(try_from_str = Cores::from_cmdline))] #[arg(short = 'c', long, default_value = "0", value_parser = Cores::from_cmdline)]
pub cores: Cores, pub cores: Cores,
/// port on which the broker should listen /// port on which the broker should listen
#[clap(short = 'p', long, default_value = "1337", name = "PORT")] #[arg(short = 'p', long, default_value = "1337", value_name = "PORT")]
pub broker_port: u16, pub broker_port: u16,
/// ip:port where a remote broker is already listening /// ip:port where a remote broker is already listening
#[clap(short = 'a', long, parse(try_from_str), name = "REMOTE")] #[arg(short = 'a', long, value_name = "REMOTE")]
pub remote_broker_addr: Option<SocketAddr>, pub remote_broker_addr: Option<SocketAddr>,
/// path to file that should be sent to the harness for crash reproduction /// path to file that should be sent to the harness for crash reproduction
#[clap(short, long, parse(from_os_str), help_heading = "Replay Options")] #[arg(short, long, help_heading = "Replay Options")]
pub replay: Option<PathBuf>, pub replay: Option<PathBuf>,
/// Run the same replay input multiple times /// Run the same replay input multiple times
#[clap( #[arg(
short = 'R', short = 'R',
long, long,
default_missing_value = "1", default_missing_value = "1",
min_values = 0,
help_heading = "Replay Options", help_heading = "Replay Options",
requires = "replay" requires = "replay"
)] )]
@ -319,10 +309,10 @@ impl FuzzerOptions {
/// fn custom_func(_: &str) {} // not relevant; just for illustrative purposes /// fn custom_func(_: &str) {} // not relevant; just for illustrative purposes
/// ///
/// #[derive(Parser, Debug)] /// #[derive(Parser, Debug)]
/// #[clap(name = "custom")] // the name of the new subcommand /// #[arg(name = "custom")] // the name of the new subcommand
/// struct CustomFooParser { /// struct CustomFooParser {
/// /// a very cromulent option /// /// a very cromulent option
/// #[clap(short, long)] /// #[arg(short, long)]
/// bar: String, /// bar: String,
/// } /// }
/// ///
@ -342,7 +332,7 @@ impl FuzzerOptions {
/// ///
/// // process the results /// // process the results
/// if let Some(("custom", sub_matches)) = matches.subcommand() { /// if let Some(("custom", sub_matches)) = matches.subcommand() {
/// custom_func(sub_matches.value_of("bar").unwrap()) /// custom_func(sub_matches.get_one::<String>("bar").unwrap())
/// } /// }
/// ///
/// println!("{:?}", matches); /// println!("{:?}", matches);

View File

@ -384,7 +384,7 @@ mod windows {
let mut outga = GROUP_AFFINITY::default(); let mut outga = GROUP_AFFINITY::default();
let result = SetThreadGroupAffinity(GetCurrentThread(), &ga, &mut outga); let result = SetThreadGroupAffinity(GetCurrentThread(), &ga, Some(&mut outga));
if result.0 == 0 { if result.0 == 0 {
Err(Error::unknown("Failed to set_for_current")) Err(Error::unknown("Failed to set_for_current"))
} else { } else {

View File

@ -443,6 +443,7 @@ pub mod pybind {
use crate::bolts::{current_nanos, rands::StdRand}; use crate::bolts::{current_nanos, rands::StdRand};
#[pyclass(unsendable, name = "StdRand")] #[pyclass(unsendable, name = "StdRand")]
#[allow(clippy::unsafe_derive_deserialize)]
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
/// Python class for StdRand /// Python class for StdRand
pub struct PythonStdRand { pub struct PythonStdRand {
@ -478,6 +479,7 @@ pub mod pybind {
/// Rand Trait binding /// Rand Trait binding
#[pyclass(unsendable, name = "Rand")] #[pyclass(unsendable, name = "Rand")]
#[allow(clippy::unsafe_derive_deserialize)]
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
pub struct PythonRand { pub struct PythonRand {
wrapper: PythonRandWrapper, wrapper: PythonRandWrapper,

View File

@ -1159,7 +1159,7 @@ pub mod win32_shmem {
use core::{ use core::{
ffi::c_void, ffi::c_void,
fmt::{self, Debug, Formatter}, fmt::{self, Debug, Formatter},
ptr, slice, slice,
}; };
use uuid::Uuid; use uuid::Uuid;
@ -1214,7 +1214,7 @@ pub mod win32_shmem {
map_str_bytes[19] = 0; // Trucate to size 20 map_str_bytes[19] = 0; // Trucate to size 20
let handle = CreateFileMappingA( let handle = CreateFileMappingA(
HANDLE(INVALID_HANDLE_VALUE), HANDLE(INVALID_HANDLE_VALUE),
ptr::null_mut(), None,
PAGE_READWRITE, PAGE_READWRITE,
0, 0,
map_size as u32, map_size as u32,

View File

@ -150,6 +150,7 @@ pub mod pybind {
}; };
#[pyclass(unsendable, name = "CachedOnDiskCorpus")] #[pyclass(unsendable, name = "CachedOnDiskCorpus")]
#[allow(clippy::unsafe_derive_deserialize)]
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
/// Python class for CachedOnDiskCorpus /// Python class for CachedOnDiskCorpus
pub struct PythonCachedOnDiskCorpus { pub struct PythonCachedOnDiskCorpus {

View File

@ -104,6 +104,7 @@ pub mod pybind {
}; };
#[pyclass(unsendable, name = "InMemoryCorpus")] #[pyclass(unsendable, name = "InMemoryCorpus")]
#[allow(clippy::unsafe_derive_deserialize)]
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
/// Python class for InMemoryCorpus /// Python class for InMemoryCorpus
pub struct PythonInMemoryCorpus { pub struct PythonInMemoryCorpus {

View File

@ -247,6 +247,7 @@ pub mod pybind {
}; };
#[pyclass(unsendable, name = "OnDiskCorpus")] #[pyclass(unsendable, name = "OnDiskCorpus")]
#[allow(clippy::unsafe_derive_deserialize)]
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
/// Python class for OnDiskCorpus /// Python class for OnDiskCorpus
pub struct PythonOnDiskCorpus { pub struct PythonOnDiskCorpus {

View File

@ -205,6 +205,7 @@ pub mod pybind {
}; };
#[pyclass(unsendable, name = "ExitKind")] #[pyclass(unsendable, name = "ExitKind")]
#[allow(clippy::unsafe_derive_deserialize)]
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct PythonExitKind { pub struct PythonExitKind {
pub inner: ExitKind, pub inner: ExitKind,

View File

@ -232,8 +232,8 @@ impl<E: HasInProcessHandlers> TimeoutExecutor<E> {
let tp_timer = unsafe { let tp_timer = unsafe {
CreateThreadpoolTimer( CreateThreadpoolTimer(
Some(timeout_handler), Some(timeout_handler),
addr_of_mut!(GLOBAL_STATE) as *mut c_void, Some(addr_of_mut!(GLOBAL_STATE) as *mut c_void),
&TP_CALLBACK_ENVIRON_V3::default(), Some(&TP_CALLBACK_ENVIRON_V3::default()),
) )
}; };
let mut critical = RTL_CRITICAL_SECTION::default(); let mut critical = RTL_CRITICAL_SECTION::default();
@ -301,7 +301,7 @@ where
LeaveCriticalSection(&mut self.critical); LeaveCriticalSection(&mut self.critical);
compiler_fence(Ordering::SeqCst); compiler_fence(Ordering::SeqCst);
SetThreadpoolTimer(self.tp_timer, &ft, 0, 0); SetThreadpoolTimer(self.tp_timer, Some(&ft), 0, 0);
let ret = self.executor.run_target(fuzzer, state, mgr, input); let ret = self.executor.run_target(fuzzer, state, mgr, input);
@ -326,7 +326,7 @@ where
/// Will dereference the given `tp_timer` pointer, unchecked. /// Will dereference the given `tp_timer` pointer, unchecked.
fn post_run_reset(&mut self) { fn post_run_reset(&mut self) {
unsafe { unsafe {
SetThreadpoolTimer(self.tp_timer, core::ptr::null(), 0, 0); SetThreadpoolTimer(self.tp_timer, None, 0, 0);
} }
self.executor.post_run_reset(); self.executor.post_run_reset();
} }

View File

@ -2009,6 +2009,7 @@ pub mod pybind {
} }
#[pyclass(unsendable, name = $py_name2)] #[pyclass(unsendable, name = $py_name2)]
#[allow(clippy::unsafe_derive_deserialize)]
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
/// Python class for OwnedMapObserver (i.e. StdMapObserver with owned map) /// Python class for OwnedMapObserver (i.e. StdMapObserver with owned map)
pub struct $struct_name2 { pub struct $struct_name2 {
@ -2079,6 +2080,7 @@ pub mod pybind {
// Should not be exposed to user // Should not be exposed to user
#[pyclass(unsendable, name = $py_name_trait)] #[pyclass(unsendable, name = $py_name_trait)]
#[allow(clippy::unsafe_derive_deserialize)]
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
/// MapObserver + Observer Trait binding /// MapObserver + Observer Trait binding
pub struct $struct_name_trait { pub struct $struct_name_trait {

View File

@ -458,6 +458,7 @@ pub mod pybind {
} }
#[pyclass(unsendable, name = "Observer")] #[pyclass(unsendable, name = "Observer")]
#[allow(clippy::unsafe_derive_deserialize)]
#[derive(Serialize, Deserialize, Clone, Debug)] #[derive(Serialize, Deserialize, Clone, Debug)]
/// Observer Trait binding /// Observer Trait binding
pub struct PythonObserver { pub struct PythonObserver {
@ -797,6 +798,7 @@ pub mod pybind {
} }
#[derive(Serialize, Deserialize, Clone, Debug)] #[derive(Serialize, Deserialize, Clone, Debug)]
#[allow(clippy::unsafe_derive_deserialize)]
#[pyclass(unsendable, name = "ObserversTuple")] #[pyclass(unsendable, name = "ObserversTuple")]
pub struct PythonObserversTuple { pub struct PythonObserversTuple {
list: Vec<PythonObserver>, list: Vec<PythonObserver>,

View File

@ -26,7 +26,7 @@ libafl = {path = "../../libafl", version="0.8", default-features=false, features
[build-dependencies] [build-dependencies]
cmake = "0.1" cmake = "0.1"
bindgen = "0.60" bindgen = "0.61"
regex = "1" regex = "1"
lazy_static = "1.4" lazy_static = "1.4"
which = "4.2" which = "4.2"

View File

@ -15,4 +15,4 @@ categories = ["development-tools::testing", "emulators", "embedded", "os", "no-s
[dependencies] [dependencies]
libafl = {path = "../../../libafl"} libafl = {path = "../../../libafl"}
clap = { version = "3.2", features = ["derive"] } clap = { version = "4.0", features = ["derive"] }

View File

@ -11,7 +11,7 @@ use std::{
string::ToString, string::ToString,
}; };
use clap::{self, StructOpt}; use clap::{self, Parser};
use libafl::{ use libafl::{
bolts::{ bolts::{
shmem::{ShMem, ShMemProvider, StdShMemProvider}, shmem::{ShMem, ShMemProvider, StdShMemProvider},
@ -23,38 +23,38 @@ use libafl::{
}, },
}; };
#[derive(Debug, StructOpt)] #[derive(Debug, Parser)]
#[clap( #[command(
name = "dump_constraints", name = "dump_constraints",
about = "Dump tool for concolic constraints." about = "Dump tool for concolic constraints."
)] )]
struct Opt { struct Opt {
/// Outputs plain text instead of binary /// Outputs plain text instead of binary
#[clap(short, long)] #[arg(short, long)]
plain_text: bool, plain_text: bool,
/// Outputs coverage information to the given file /// Outputs coverage information to the given file
#[clap(short, long)] #[arg(short, long)]
coverage_file: Option<PathBuf>, coverage_file: Option<PathBuf>,
/// Symbolizes only the given input file offsets. /// Symbolizes only the given input file offsets.
#[clap(short, long)] #[arg(short, long)]
symbolize_offsets: Option<Vec<usize>>, symbolize_offsets: Option<Vec<usize>>,
/// Concretize all floating point operations. /// Concretize all floating point operations.
#[clap(long)] #[arg(long)]
no_float: bool, no_float: bool,
/// Prune expressions from high-frequency code locations. /// Prune expressions from high-frequency code locations.
#[clap(long)] #[arg(long)]
prune: bool, prune: bool,
/// Trace file path, "trace" by default. /// Trace file path, "trace" by default.
#[clap(parse(from_os_str), short, long)] #[arg(short, long)]
output: Option<PathBuf>, output: Option<PathBuf>,
/// Target program and arguments /// Target program and arguments
#[clap(last = true)] #[arg(last = true)]
program: Vec<OsString>, program: Vec<OsString>,
} }

View File

@ -22,7 +22,7 @@ cc = { version = "1.0", features = ["parallel"] }
libafl = { path = "../libafl", version = "0.8.2", features = ["std", "libafl_derive", "frida_cli"] } libafl = { path = "../libafl", version = "0.8.2", features = ["std", "libafl_derive", "frida_cli"] }
libafl_targets = { path = "../libafl_targets", version = "0.8.2", features = ["std", "sancov_cmplog"] } libafl_targets = { path = "../libafl_targets", version = "0.8.2", features = ["std", "sancov_cmplog"] }
nix = "0.24" nix = "0.25"
libc = "0.2" libc = "0.2"
hashbrown = "0.12" hashbrown = "0.12"
libloading = "0.7" libloading = "0.7"

View File

@ -15,5 +15,5 @@ categories = ["development-tools::testing", "emulators", "embedded", "os", "no-s
[target.'cfg(target_os = "linux")'.dependencies] [target.'cfg(target_os = "linux")'.dependencies]
libnyx = {git = "https://github.com/nyx-fuzz/libnyx.git",rev = "acaf7f6"} libnyx = {git = "https://github.com/nyx-fuzz/libnyx.git",rev = "acaf7f6"}
libafl = { path = "../libafl", version = "0.8.0", features = ["std", "libafl_derive", "frida_cli" ]} libafl = { path = "../libafl", version = "0.8.2", features = ["std", "libafl_derive", "frida_cli" ]}
libafl_targets = { path = "../libafl_targets", version = "0.8.0", features = ["std", "sancov_cmplog"] } libafl_targets = { path = "../libafl_targets", version = "0.8.2", features = ["std", "sancov_cmplog"] }

View File

@ -44,12 +44,12 @@ bio = "0.41"
thread_local = "1.1.4" thread_local = "1.1.4"
capstone = "0.11.0" capstone = "0.11.0"
#pyo3 = { version = "0.15", features = ["extension-module"], optional = true } #pyo3 = { version = "0.15", features = ["extension-module"], optional = true }
pyo3 = { version = "0.15", optional = true } pyo3 = { version = "0.17", features = ["pyproto"], optional = true }
[build-dependencies] [build-dependencies]
cc = { version = "1.0" } cc = { version = "1.0" }
which = "4.2" which = "4.2"
pyo3-build-config = { version = "0.16", optional = true } pyo3-build-config = { version = "0.15", optional = true }
[lib] [lib]
name = "libafl_qemu" name = "libafl_qemu"

View File

@ -24,7 +24,7 @@ arm = ["libafl_qemu/arm"] # build qemu for arm
aarch64 = ["libafl_qemu/aarch64"] # build qemu for aarch64 aarch64 = ["libafl_qemu/aarch64"] # build qemu for aarch64
[build-dependencies] [build-dependencies]
pyo3-build-config = { version = "0.16", optional = true } pyo3-build-config = { version = "0.15", optional = true }
[dependencies] [dependencies]
libafl = { path = "../libafl", version = "0.8.2" } libafl = { path = "../libafl", version = "0.8.2" }
@ -32,8 +32,8 @@ libafl_targets = { path = "../libafl_targets", version = "0.8.2" }
libafl_qemu = { path = "../libafl_qemu", version = "0.8.2" } libafl_qemu = { path = "../libafl_qemu", version = "0.8.2" }
typed-builder = "0.10.0" # Implement the builder pattern at compiletime typed-builder = "0.10.0" # Implement the builder pattern at compiletime
#pyo3 = { version = "0.15", features = ["extension-module"], optional = true } #pyo3 = { version = "0.17", features = ["extension-module"], optional = true }
pyo3 = { version = "0.15", optional = true } pyo3 = { version = "0.17", optional = true }
[lib] [lib]
name = "libafl_sugar" name = "libafl_sugar"

View File

@ -20,4 +20,4 @@ regex = "1"
postcard = "1.0" postcard = "1.0"
lazy_static = "1.4.0" lazy_static = "1.4.0"
libafl = { path = "../../../libafl" } libafl = { path = "../../../libafl" }
clap = { version = "3.2", features = ["derive"] } clap = { version = "4.0", features = ["derive"] }

View File

@ -6,21 +6,20 @@ use std::{
rc::Rc, rc::Rc,
}; };
use clap::{self, StructOpt}; use clap::{self, Parser};
use lazy_static::lazy_static; use lazy_static::lazy_static;
use libafl::generators::gramatron::{Automaton, Trigger}; use libafl::generators::gramatron::{Automaton, Trigger};
use regex::Regex; use regex::Regex;
use serde_json::Value; use serde_json::Value;
#[derive(Debug, StructOpt)] #[derive(Debug, Parser)]
#[clap( #[command(
name = "construct_automata", name = "construct_automata",
about = "Generate a serialized Automaton using a json GNF grammar", about = "Generate a serialized Automaton using a json GNF grammar",
author = "Andrea Fioraldi <andreafioraldi@gmail.com>" author = "Andrea Fioraldi <andreafioraldi@gmail.com>"
)] )]
struct Opt { struct Opt {
#[clap( #[arg(
parse(try_from_str),
short, short,
long = "grammar-file", long = "grammar-file",
name = "GRAMMAR", name = "GRAMMAR",
@ -28,8 +27,7 @@ struct Opt {
)] )]
grammar: PathBuf, grammar: PathBuf,
#[clap( #[arg(
parse(try_from_str),
short, short,
long, long,
name = "LIMIT", name = "LIMIT",
@ -38,13 +36,7 @@ struct Opt {
)] )]
limit: usize, limit: usize,
#[clap( #[arg(short, long, help = "Set the output file", name = "OUTPUT")]
parse(try_from_str),
short,
long,
help = "Set the output file",
name = "OUTPUT"
)]
output: PathBuf, output: PathBuf,
} }

View File

@ -1,7 +1,7 @@
[package] [package]
authors = ["Andrea Fioraldi <andreafioraldi@gmail.com>", "Dominik Maier <domenukk@gmail.com>"] authors = ["Andrea Fioraldi <andreafioraldi@gmail.com>", "Dominik Maier <domenukk@gmail.com>"]
name = "libafl_benches" name = "libafl_benches"
version = "0.8.2" version.workspace = true
edition = "2021" edition = "2021"
description = "LibAFL Benchmarks" description = "LibAFL Benchmarks"
documentation = "https://docs.rs/libafl" documentation = "https://docs.rs/libafl"
@ -13,7 +13,7 @@ categories = ["development-tools::testing", "emulators", "embedded", "os", "no-s
[dev-dependencies] [dev-dependencies]
criterion = "0.3" # Benchmarking criterion = "0.3" # Benchmarking
ahash = { version = "0.7", default-features=false, features=["compile-time-rng"] } # The hash function already used in hashbrown ahash = { version = "0.7", default-features=false } # The hash function already used in hashbrown
rustc-hash = { version = "1.1", default-features=false } # yet another hash rustc-hash = { version = "1.1", default-features=false } # yet another hash
xxhash-rust = { version = "0.8.5", features = ["xxh3"] } # xxh3 hashing for rust xxhash-rust = { version = "0.8.5", features = ["xxh3"] } # xxh3 hashing for rust
libafl = { path = "../../libafl", default-features=false } # libafl libafl = { path = "../../libafl", default-features=false } # libafl