diff --git a/Cargo.toml b/Cargo.toml index 270994e82e..e78c01cd43 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,14 +11,15 @@ members = [ "libafl_cc", "libafl_targets", "libafl_frida", - "libafl_tests", + "libafl_tests", ] default-members = [ "libafl", "libafl_derive", "libafl_cc", "libafl_targets", + "libafl_tests", ] exclude = [ - "fuzzers" + "fuzzers", ] diff --git a/fuzzers/frida_libpng/Cargo.toml b/fuzzers/frida_libpng/Cargo.toml index a411002168..cd4a2ee65c 100644 --- a/fuzzers/frida_libpng/Cargo.toml +++ b/fuzzers/frida_libpng/Cargo.toml @@ -24,7 +24,7 @@ which = "4.1" libafl = { path = "../../libafl/", features = [ "std", "llmp_compression", "llmp_bind_public" ] } #, "llmp_small_maps", "llmp_debug"]} capstone = "0.8.0" frida-gum = { version = "0.5.2", features = [ "auto-download", "backtrace", "event-sink", "invocation-listener"] } -libafl_frida = { path = "../../libafl_frida", version = "0.3.2", features = ["cmplog_runtime"] } +libafl_frida = { path = "../../libafl_frida", version = "0.3.2", features = ["cmplog"] } libafl_targets = { path = "../../libafl_targets", version = "0.3.2" , features = ["sancov_cmplog"] } lazy_static = "1.4.0" libc = "0.2" diff --git a/fuzzers/frida_libpng/src/fuzzer.rs b/fuzzers/frida_libpng/src/fuzzer.rs index fbf5857e01..a6f96c02eb 100644 --- a/fuzzers/frida_libpng/src/fuzzer.rs +++ b/fuzzers/frida_libpng/src/fuzzer.rs @@ -33,7 +33,6 @@ use libafl::{ token_mutations::Tokens, }, observers::{HitcountsMapObserver, ObserversTuple, StdMapObserver, TimeObserver}, - //stages::mutational::StdMutationalStage, stages::{StdMutationalStage, TracingStage}, state::{HasCorpus, HasMetadata, StdState}, stats::MultiStats, diff --git a/fuzzers/libfuzzer_stb_image/src/main.rs b/fuzzers/libfuzzer_stb_image/src/main.rs index 4ee16c36c3..c718b1ad2e 100644 --- a/fuzzers/libfuzzer_stb_image/src/main.rs +++ b/fuzzers/libfuzzer_stb_image/src/main.rs @@ -75,9 +75,6 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re let cmplog = unsafe { &mut CMPLOG_MAP }; let cmplog_observer = CmpLogObserver::new("cmplog", cmplog, true); - let cmplog = unsafe { &mut CMPLOG_MAP }; - let cmplog_observer = CmpLogObserver::new("cmplog", cmplog, true); - // The state of the edges feedback. let feedback_state = MapFeedbackState::with_observer(&edges_observer); diff --git a/libafl_frida/Cargo.toml b/libafl_frida/Cargo.toml index 3d4784f6b0..b8871b08de 100644 --- a/libafl_frida/Cargo.toml +++ b/libafl_frida/Cargo.toml @@ -13,7 +13,7 @@ edition = "2018" [features] default = [] -cmplog_runtime = [] +cmplog = [] [build-dependencies] cc = { version = "1.0", features = ["parallel"] } diff --git a/libafl_frida/src/cmplog_rt.rs b/libafl_frida/src/cmplog_rt.rs index 45518f7eb5..95b2193dd0 100644 --- a/libafl_frida/src/cmplog_rt.rs +++ b/libafl_frida/src/cmplog_rt.rs @@ -1,11 +1,5 @@ use dynasmrt::{dynasm, DynasmApi, DynasmLabelApi}; -use libafl_targets::cmplog::{ - libafl_cmplog_map, CmpLogHeader, CmpLogMap, CmpLogOperands, CMPLOG_MAP_W, -}; -use nix::{ - libc::{memmove, memset}, - sys::mman::{mmap, MapFlags, ProtFlags}, -}; +use libafl_targets::cmplog::CMPLOG_MAP_W; use std::ffi::c_void; extern crate libafl_targets; @@ -13,44 +7,7 @@ extern "C" { pub fn libafl_targets_cmplog_wrapper(k: u64, shape: u8, arg1: u64, arg2: u64); } -#[cfg(any(target_os = "macos", target_os = "ios"))] -const ANONYMOUS_FLAG: MapFlags = MapFlags::MAP_ANON; -#[cfg(not(any(target_os = "macos", target_os = "ios")))] -const ANONYMOUS_FLAG: MapFlags = MapFlags::MAP_ANONYMOUS; - -// #[repr(C)] -// #[derive(Debug, Clone, Copy)] -// pub struct CmpLogHeader { -// hits: u16, -// shape: u8, -// kind: u8, -// } - -// #[repr(C)] -// #[derive(Debug, Clone, Copy)] -// pub struct CmpLogOperands(u64, u64); - -// #[repr(C)] -// #[derive(Debug, Clone, Copy)] -// pub struct CmpLogMap { -// headers: [CmpLogHeader; CMPLOG_MAP_W], -// operands: [CmpLogOperands; CMPLOG_MAP_W], -// } - -// #[no_mangle] -// pub static mut libafl_cmplog_map: CmpLogMap = CmpLogMap { -// headers: [CmpLogHeader { -// hits: 0, -// shape: 0, -// kind: 0, -// }; CMPLOG_MAP_W], -// operands: [CmpLogOperands(0, 0); CMPLOG_MAP_W], -// }; - pub struct CmpLogRuntime { - regs: [u64; 3], - // cmp_idx: usize, - // cmplog_map: CmpLogMap, ops_save_register_and_blr_to_populate: Option>, } @@ -58,20 +15,11 @@ impl CmpLogRuntime { #[must_use] pub fn new() -> CmpLogRuntime { Self { - regs: [0; 3], - // cmp_idx: 0, - // cmplog_map: CmpLogMap { - // headers: [CmpLogHeader { - // hits: 0, - // shape: 0, - // kind: 0, - // }; CMPLOG_MAP_W], - // operands: [CmpLogOperands(0, 0); CMPLOG_MAP_W], - // }, ops_save_register_and_blr_to_populate: None, } } + /// Call the external function that populates the cmplog_map with the relevant values extern "C" fn populate_lists(&mut self, op1: u64, op2: u64, retaddr: u64) { // println!( // "entered populate_lists with: {:#02x}, {:#02x}, {:#02x}", @@ -117,10 +65,7 @@ impl CmpLogRuntime { ; b >done ; self_addr: ; .qword self as *mut _ as *mut c_void as i64 - ; self_regs_addr: //for rust based population of the lists.. - ; .qword &mut self.regs as *mut _ as *mut c_void as i64 ; populate_lists: - //; .qword __sanitizer_cov_trace_cmp8 as *mut c_void as i64 ; .qword CmpLogRuntime::populate_lists as *mut c_void as i64 ; done: );}; @@ -138,30 +83,6 @@ impl CmpLogRuntime { ); } pub fn init(&mut self) { - // workaround frida's frida-gum-allocate-near bug: - unsafe { - for _ in 0..64 { - mmap( - std::ptr::null_mut(), - 128 * 1024, - ProtFlags::PROT_NONE, - ANONYMOUS_FLAG | MapFlags::MAP_PRIVATE, - -1, - 0, - ) - .expect("Failed to map dummy regions for frida workaround"); - mmap( - std::ptr::null_mut(), - 4 * 1024 * 1024, - ProtFlags::PROT_NONE, - ANONYMOUS_FLAG | MapFlags::MAP_PRIVATE, - -1, - 0, - ) - .expect("Failed to map dummy regions for frida workaround"); - } - } - self.generate_instrumentation_blobs(); } diff --git a/libafl_frida/src/helper.rs b/libafl_frida/src/helper.rs index f94ba4e79a..adc5b1938b 100644 --- a/libafl_frida/src/helper.rs +++ b/libafl_frida/src/helper.rs @@ -35,10 +35,10 @@ use nix::sys::mman::{mmap, MapFlags, ProtFlags}; use crate::{asan_rt::AsanRuntime, FridaOptions}; -#[cfg(feature = "cmplog_runtime")] +#[cfg(feature = "cmplog")] use crate::cmplog_rt::CmpLogRuntime; -#[cfg(feature = "cmplog_runtime")] +#[cfg(feature = "cmplog")] enum CmplogOperandType { Regid(capstone::RegId), Imm(u64), @@ -89,7 +89,7 @@ pub struct FridaInstrumentationHelper<'a> { #[cfg(target_arch = "aarch64")] capstone: Capstone, asan_runtime: AsanRuntime, - #[cfg(all(feature = "cmplog_runtime"))] + #[cfg(feature = "cmplog")] cmplog_runtime: CmpLogRuntime, ranges: RangeMap, module_map: ModuleMap, @@ -276,7 +276,7 @@ impl<'a> FridaInstrumentationHelper<'a> { .build() .expect("Failed to create Capstone object"), asan_runtime: AsanRuntime::new(options.clone()), - #[cfg(all(feature = "cmplog_runtime"))] + #[cfg(feature = "cmplog")] cmplog_runtime: CmpLogRuntime::new(), ranges: RangeMap::new(), module_map: ModuleMap::new_from_names(modules_to_instrument), @@ -340,7 +340,7 @@ impl<'a> FridaInstrumentationHelper<'a> { todo!("Implement ASAN for non-aarch64 targets"); #[cfg(target_arch = "aarch64")] if let Ok((basereg, indexreg, displacement, width, shift, extender)) = - helper.is_interesting_asan_instruction(address, instr) + helper.asan_is_interesting_instruction(address, instr) { helper.emit_shadow_check( address, @@ -357,12 +357,11 @@ impl<'a> FridaInstrumentationHelper<'a> { if helper.options().cmplog_enabled() { #[cfg(not(target_arch = "aarch64"))] todo!("Implement cmplog for non-aarch64 targets"); - #[cfg(all(feature = "cmplog_runtime", target_arch = "aarch64"))] + #[cfg(all(feature = "cmplog", target_arch = "aarch64"))] // check if this instruction is a compare instruction and if so save the registers values if let Ok((op1, op2)) = - helper.is_interesting_cmplog_instruction(address, instr) + helper.cmplog_is_interesting_instruction(address, instr) { - println!("emmiting at {} => {}", address, instr); //emit code that saves the relevant data in runtime(passes it to x0, x1) helper.emit_comparison_handling(address, &output, op1, op2); } @@ -382,7 +381,7 @@ impl<'a> FridaInstrumentationHelper<'a> { if helper.options().asan_enabled() || helper.options().drcov_enabled() { helper.asan_runtime.init(gum, modules_to_instrument); } - #[cfg(all(feature = "cmplog_runtime"))] + #[cfg(feature = "cmplog")] if helper.options.cmplog_enabled() { helper.cmplog_runtime.init(); } @@ -401,8 +400,9 @@ impl<'a> FridaInstrumentationHelper<'a> { Aarch64Register::from_u32(regint as u32).unwrap() } - #[cfg(all(feature = "cmplog_runtime", target_arch = "aarch64"))] + #[cfg(all(feature = "cmplog", target_arch = "aarch64"))] #[inline] + /// Emit the instrumentation code which is responsible for opernads value extraction and cmplog map population fn emit_comparison_handling( &self, _address: u64, @@ -440,7 +440,7 @@ impl<'a> FridaInstrumentationHelper<'a> { } } } - CmplogOperandType::Mem(basereg, indexreg, displacement, width) => { + CmplogOperandType::Mem(basereg, indexreg, displacement, _width) => { let basereg = self.writer_register(basereg); let indexreg = if indexreg.0 != 0 { Some(self.writer_register(indexreg)) @@ -509,7 +509,7 @@ impl<'a> FridaInstrumentationHelper<'a> { } } } - CmplogOperandType::Mem(basereg, indexreg, displacement, width) => { + CmplogOperandType::Mem(basereg, indexreg, displacement, _width) => { let basereg = self.writer_register(basereg); let indexreg = if indexreg.0 != 0 { Some(self.writer_register(indexreg)) @@ -983,7 +983,7 @@ impl<'a> FridaInstrumentationHelper<'a> { #[cfg(target_arch = "aarch64")] #[inline] - fn is_interesting_asan_instruction( + fn asan_is_interesting_instruction( &self, _address: u64, instr: &Insn, @@ -1033,9 +1033,10 @@ impl<'a> FridaInstrumentationHelper<'a> { Err(()) } - #[cfg(all(feature = "cmplog_runtime", target_arch = "aarch64"))] + #[cfg(all(feature = "cmplog", target_arch = "aarch64"))] #[inline] - fn is_interesting_cmplog_instruction( + /// Check if the current instruction is cmplog relevant one(any opcode which sets the flags) + fn cmplog_is_interesting_instruction( &self, _address: u64, instr: &Insn, diff --git a/libafl_frida/src/lib.rs b/libafl_frida/src/lib.rs index 70668662d9..1b049e19b8 100644 --- a/libafl_frida/src/lib.rs +++ b/libafl_frida/src/lib.rs @@ -10,7 +10,7 @@ pub mod asan_errors; /// The frida address sanitizer runtime pub mod asan_rt; -#[cfg(all(feature = "cmplog_runtime"))] +#[cfg(feature = "cmplog")] /// The frida cmplog runtime pub mod cmplog_rt; @@ -108,6 +108,10 @@ impl FridaOptions { } "cmplog" => { options.enable_cmplog = value.parse().unwrap(); + match cfg!(feature = "cmplog") { + false => panic!("cmplog feature is disabled!"), + _ => (), + } } _ => { panic!("unknown FRIDA option: '{}'", option); diff --git a/libafl_targets/src/cmplog.h b/libafl_targets/src/cmplog.h index 5933f59c8f..b595033602 100644 --- a/libafl_targets/src/cmplog.h +++ b/libafl_targets/src/cmplog.h @@ -33,7 +33,7 @@ extern uint8_t libafl_cmplog_enabled; static void __libafl_targets_cmplog(uintptr_t k, uint8_t shape, uint64_t arg1, uint64_t arg2) { - //if (!libafl_cmplog_enabled) return; + if (!libafl_cmplog_enabled) return; uint16_t hits; if (libafl_cmplog_map.headers[k].kind != CMPLOG_KIND_INS) { diff --git a/libafl_targets/src/cmplog.rs b/libafl_targets/src/cmplog.rs index a02a57a575..8f975c716f 100644 --- a/libafl_targets/src/cmplog.rs +++ b/libafl_targets/src/cmplog.rs @@ -140,7 +140,7 @@ pub use libafl_cmplog_map as CMPLOG_MAP; /// Value indicating if cmplog is enabled. #[no_mangle] -pub static mut libafl_cmplog_enabled: u8 = 1; +pub static mut libafl_cmplog_enabled: u8 = 0; pub use libafl_cmplog_enabled as CMPLOG_ENABLED;