LibAFL Atheris Compatibility (#1576)

* Made changes to libafl_atheris/src/lib.rs to work with Atheris

* Removed unused imports

* Ran  on libafl_atheris

* Fixed issue with using extra_counters and issue with using println

---------

Co-authored-by: eceo902 <evan.seeyave@gmail.com>
Co-authored-by: Evan <53020947+eceo902@users.noreply.github.com>
This commit is contained in:
Dominik Maier 2024-01-02 22:18:34 +01:00 committed by GitHub
parent 4f93d7e894
commit 925b33889f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 14 additions and 72 deletions

View File

@ -21,7 +21,7 @@ which = "4.4"
[dependencies]
libafl = { path = "../../libafl/" }
libafl_bolts = { path = "../../libafl_bolts/" }
libafl_targets = { path = "../../libafl_targets/", features = ["pointer_maps", "sancov_cmplog", "libfuzzer"] }
libafl_targets = { path = "../../libafl_targets/", features = ["pointer_maps", "sancov_cmplog", "libfuzzer", "sancov_8bit"] }
clap = { version = "4.0", features = ["default"] }
[lib]

View File

@ -25,7 +25,7 @@ use libafl::{
scheduled::{havoc_mutations, tokens_mutations, StdScheduledMutator},
token_mutations::{I2SRandReplace, Tokens},
},
observers::{HitcountsMapObserver, TimeObserver},
observers::{HitcountsMapObserver, StdMapObserver, TimeObserver},
schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler},
stages::{StdMutationalStage, TracingStage},
state::{HasCorpus, HasMetadata, StdState},
@ -39,63 +39,7 @@ use libafl_bolts::{
tuples::{tuple_list, Merge},
AsSlice,
};
use libafl_targets::{
CmpLogObserver, __sanitizer_cov_trace_cmp1, __sanitizer_cov_trace_cmp2,
__sanitizer_cov_trace_cmp4, __sanitizer_cov_trace_cmp8, std_edges_map_observer, EDGES_MAP_PTR,
MAX_EDGES_NUM,
};
/// Set up our coverage map.
#[no_mangle]
pub extern "C" fn __sanitizer_cov_8bit_counters_init(start: *mut u8, stop: *mut u8) {
unsafe {
EDGES_MAP_PTR = start;
MAX_EDGES_NUM = (stop as usize - start as usize) / 8;
}
}
/// `pcs` tables seem to be unused by `Atheris`, so we can ignore this setup function,
/// but the symbol is still being called and, hence, required.
#[no_mangle]
pub extern "C" fn __sanitizer_cov_pcs_init(_pcs_beg: *mut u8, _pcs_end: *mut u8) {
// noop
}
/// Allow the python code to use `cmplog`.
/// This is a PoC implementation and could be improved.
/// For example, it only takes up to 8 bytes into consideration.
#[no_mangle]
pub extern "C" fn __sanitizer_weak_hook_memcmp(
_caller_pc: *const c_void,
s1: *const c_void,
s2: *const c_void,
n: usize,
_result: c_int,
) {
unsafe {
let s1 = slice::from_raw_parts(s1.cast::<u8>(), n);
let s2 = slice::from_raw_parts(s2.cast::<u8>(), n);
match n {
0 => (),
1 => __sanitizer_cov_trace_cmp1(
u8::from_ne_bytes(s1.try_into().unwrap()),
u8::from_ne_bytes(s2.try_into().unwrap()),
),
2..=3 => __sanitizer_cov_trace_cmp2(
u16::from_ne_bytes(s1.try_into().unwrap()),
u16::from_ne_bytes(s2.try_into().unwrap()),
),
4..=7 => __sanitizer_cov_trace_cmp4(
u32::from_ne_bytes(s1.try_into().unwrap()),
u32::from_ne_bytes(s2.try_into().unwrap()),
),
_ => __sanitizer_cov_trace_cmp8(
u64::from_ne_bytes(s1.try_into().unwrap()),
u64::from_ne_bytes(s2.try_into().unwrap()),
),
}
}
}
use libafl_targets::{extra_counters, std_edges_map_observer, CmpLogObserver};
/// It's called by Atheris after the fuzzer has been initialized.
/// The main entrypoint to our fuzzer, which will be called by `Atheris` when fuzzing starts.
@ -115,11 +59,6 @@ pub extern "C" fn LLVMFuzzerRunDriver(
assert!(harness_fn.is_some(), "No harness callback provided");
let harness_fn = harness_fn.unwrap();
assert!(
!unsafe { EDGES_MAP_PTR.is_null() },
"Edges map was never initialized - __sanitizer_cov_8bit_counters_init never got called"
);
println!("Args: {:?}", std::env::args());
let matches = Command::new("libafl_atheris")
@ -156,10 +95,7 @@ pub extern "C" fn LLVMFuzzerRunDriver(
.get_matches();
let workdir = env::current_dir().unwrap();
println!(
"Workdir: {:?}",
env::current_dir().unwrap().to_string_lossy().to_string()
);
println!("{}", env::current_dir().unwrap().to_string_lossy().to_string());
let cores = Cores::from_cmdline(matches.get_one::<String>("cores").unwrap())
.expect("No valid core count given!");
@ -195,7 +131,13 @@ pub extern "C" fn LLVMFuzzerRunDriver(
let mut run_client = |state: Option<_>, mut mgr, _core_id| {
// Create an observation channel using the coverage map
let edges_observer = unsafe { HitcountsMapObserver::new(std_edges_map_observer("edges")) };
let edges = unsafe { extra_counters() };
println!("edges: {:?}", edges);
let edges_observer;
edges_observer = HitcountsMapObserver::new(StdMapObserver::from_mut_slice(
"edges",
edges.into_iter().next().unwrap(),
));
// Create an observation channel to keep track of the execution time
let time_observer = TimeObserver::new("time");
@ -318,7 +260,7 @@ pub extern "C" fn LLVMFuzzerRunDriver(
} else {
println!("Loading from {:?}", &input_dirs);
// Load from disk
// we used _forced since some Atheris testcases don't touch the map at all, hence, wolud not load any data.
// we used _forced since some Atheris testcases don't touch the map at all, hence, would not load any data.
state
.load_initial_inputs_forced(&mut fuzzer, &mut executor, &mut mgr, &input_dirs)
.unwrap_or_else(|_| {
@ -341,7 +283,7 @@ pub extern "C" fn LLVMFuzzerRunDriver(
.cores(&cores)
.broker_port(broker_port)
.remote_broker_addr(remote_broker_addr)
// remove this comment to sience the target.
// remove this comment to silence the target.
// .stdout_file(Some("/dev/null"))
.build()
.launch()