get rid of irrelevant changes and unused code, add comments, change

feature name to "cmplog"
This commit is contained in:
Omree 2021-06-09 13:01:22 +03:00
parent 1fc9796bdb
commit 0e2a280eae
10 changed files with 30 additions and 107 deletions

View File

@ -11,14 +11,15 @@ members = [
"libafl_cc", "libafl_cc",
"libafl_targets", "libafl_targets",
"libafl_frida", "libafl_frida",
"libafl_tests", "libafl_tests",
] ]
default-members = [ default-members = [
"libafl", "libafl",
"libafl_derive", "libafl_derive",
"libafl_cc", "libafl_cc",
"libafl_targets", "libafl_targets",
"libafl_tests",
] ]
exclude = [ exclude = [
"fuzzers" "fuzzers",
] ]

View File

@ -24,7 +24,7 @@ which = "4.1"
libafl = { path = "../../libafl/", features = [ "std", "llmp_compression", "llmp_bind_public" ] } #, "llmp_small_maps", "llmp_debug"]} libafl = { path = "../../libafl/", features = [ "std", "llmp_compression", "llmp_bind_public" ] } #, "llmp_small_maps", "llmp_debug"]}
capstone = "0.8.0" capstone = "0.8.0"
frida-gum = { version = "0.5.2", features = [ "auto-download", "backtrace", "event-sink", "invocation-listener"] } 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"] } libafl_targets = { path = "../../libafl_targets", version = "0.3.2" , features = ["sancov_cmplog"] }
lazy_static = "1.4.0" lazy_static = "1.4.0"
libc = "0.2" libc = "0.2"

View File

@ -33,7 +33,6 @@ use libafl::{
token_mutations::Tokens, token_mutations::Tokens,
}, },
observers::{HitcountsMapObserver, ObserversTuple, StdMapObserver, TimeObserver}, observers::{HitcountsMapObserver, ObserversTuple, StdMapObserver, TimeObserver},
//stages::mutational::StdMutationalStage,
stages::{StdMutationalStage, TracingStage}, stages::{StdMutationalStage, TracingStage},
state::{HasCorpus, HasMetadata, StdState}, state::{HasCorpus, HasMetadata, StdState},
stats::MultiStats, stats::MultiStats,

View File

@ -75,9 +75,6 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
let cmplog = unsafe { &mut CMPLOG_MAP }; let cmplog = unsafe { &mut CMPLOG_MAP };
let cmplog_observer = CmpLogObserver::new("cmplog", cmplog, true); 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. // The state of the edges feedback.
let feedback_state = MapFeedbackState::with_observer(&edges_observer); let feedback_state = MapFeedbackState::with_observer(&edges_observer);

View File

@ -13,7 +13,7 @@ edition = "2018"
[features] [features]
default = [] default = []
cmplog_runtime = [] cmplog = []
[build-dependencies] [build-dependencies]
cc = { version = "1.0", features = ["parallel"] } cc = { version = "1.0", features = ["parallel"] }

View File

@ -1,11 +1,5 @@
use dynasmrt::{dynasm, DynasmApi, DynasmLabelApi}; use dynasmrt::{dynasm, DynasmApi, DynasmLabelApi};
use libafl_targets::cmplog::{ use libafl_targets::cmplog::CMPLOG_MAP_W;
libafl_cmplog_map, CmpLogHeader, CmpLogMap, CmpLogOperands, CMPLOG_MAP_W,
};
use nix::{
libc::{memmove, memset},
sys::mman::{mmap, MapFlags, ProtFlags},
};
use std::ffi::c_void; use std::ffi::c_void;
extern crate libafl_targets; extern crate libafl_targets;
@ -13,44 +7,7 @@ extern "C" {
pub fn libafl_targets_cmplog_wrapper(k: u64, shape: u8, arg1: u64, arg2: u64); 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 { pub struct CmpLogRuntime {
regs: [u64; 3],
// cmp_idx: usize,
// cmplog_map: CmpLogMap,
ops_save_register_and_blr_to_populate: Option<Box<[u8]>>, ops_save_register_and_blr_to_populate: Option<Box<[u8]>>,
} }
@ -58,20 +15,11 @@ impl CmpLogRuntime {
#[must_use] #[must_use]
pub fn new() -> CmpLogRuntime { pub fn new() -> CmpLogRuntime {
Self { 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, 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) { extern "C" fn populate_lists(&mut self, op1: u64, op2: u64, retaddr: u64) {
// println!( // println!(
// "entered populate_lists with: {:#02x}, {:#02x}, {:#02x}", // "entered populate_lists with: {:#02x}, {:#02x}, {:#02x}",
@ -117,10 +65,7 @@ impl CmpLogRuntime {
; b >done ; b >done
; self_addr: ; self_addr:
; .qword self as *mut _ as *mut c_void as i64 ; .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: ; populate_lists:
//; .qword __sanitizer_cov_trace_cmp8 as *mut c_void as i64
; .qword CmpLogRuntime::populate_lists as *mut c_void as i64 ; .qword CmpLogRuntime::populate_lists as *mut c_void as i64
; done: ; done:
);}; );};
@ -138,30 +83,6 @@ impl CmpLogRuntime {
); );
} }
pub fn init(&mut self) { 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(); self.generate_instrumentation_blobs();
} }

View File

@ -35,10 +35,10 @@ use nix::sys::mman::{mmap, MapFlags, ProtFlags};
use crate::{asan_rt::AsanRuntime, FridaOptions}; use crate::{asan_rt::AsanRuntime, FridaOptions};
#[cfg(feature = "cmplog_runtime")] #[cfg(feature = "cmplog")]
use crate::cmplog_rt::CmpLogRuntime; use crate::cmplog_rt::CmpLogRuntime;
#[cfg(feature = "cmplog_runtime")] #[cfg(feature = "cmplog")]
enum CmplogOperandType { enum CmplogOperandType {
Regid(capstone::RegId), Regid(capstone::RegId),
Imm(u64), Imm(u64),
@ -89,7 +89,7 @@ pub struct FridaInstrumentationHelper<'a> {
#[cfg(target_arch = "aarch64")] #[cfg(target_arch = "aarch64")]
capstone: Capstone, capstone: Capstone,
asan_runtime: AsanRuntime, asan_runtime: AsanRuntime,
#[cfg(all(feature = "cmplog_runtime"))] #[cfg(feature = "cmplog")]
cmplog_runtime: CmpLogRuntime, cmplog_runtime: CmpLogRuntime,
ranges: RangeMap<usize, (u16, String)>, ranges: RangeMap<usize, (u16, String)>,
module_map: ModuleMap, module_map: ModuleMap,
@ -276,7 +276,7 @@ impl<'a> FridaInstrumentationHelper<'a> {
.build() .build()
.expect("Failed to create Capstone object"), .expect("Failed to create Capstone object"),
asan_runtime: AsanRuntime::new(options.clone()), asan_runtime: AsanRuntime::new(options.clone()),
#[cfg(all(feature = "cmplog_runtime"))] #[cfg(feature = "cmplog")]
cmplog_runtime: CmpLogRuntime::new(), cmplog_runtime: CmpLogRuntime::new(),
ranges: RangeMap::new(), ranges: RangeMap::new(),
module_map: ModuleMap::new_from_names(modules_to_instrument), module_map: ModuleMap::new_from_names(modules_to_instrument),
@ -340,7 +340,7 @@ impl<'a> FridaInstrumentationHelper<'a> {
todo!("Implement ASAN for non-aarch64 targets"); todo!("Implement ASAN for non-aarch64 targets");
#[cfg(target_arch = "aarch64")] #[cfg(target_arch = "aarch64")]
if let Ok((basereg, indexreg, displacement, width, shift, extender)) = 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( helper.emit_shadow_check(
address, address,
@ -357,12 +357,11 @@ impl<'a> FridaInstrumentationHelper<'a> {
if helper.options().cmplog_enabled() { if helper.options().cmplog_enabled() {
#[cfg(not(target_arch = "aarch64"))] #[cfg(not(target_arch = "aarch64"))]
todo!("Implement cmplog for non-aarch64 targets"); 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 // check if this instruction is a compare instruction and if so save the registers values
if let Ok((op1, op2)) = 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) //emit code that saves the relevant data in runtime(passes it to x0, x1)
helper.emit_comparison_handling(address, &output, op1, op2); 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() { if helper.options().asan_enabled() || helper.options().drcov_enabled() {
helper.asan_runtime.init(gum, modules_to_instrument); helper.asan_runtime.init(gum, modules_to_instrument);
} }
#[cfg(all(feature = "cmplog_runtime"))] #[cfg(feature = "cmplog")]
if helper.options.cmplog_enabled() { if helper.options.cmplog_enabled() {
helper.cmplog_runtime.init(); helper.cmplog_runtime.init();
} }
@ -401,8 +400,9 @@ impl<'a> FridaInstrumentationHelper<'a> {
Aarch64Register::from_u32(regint as u32).unwrap() Aarch64Register::from_u32(regint as u32).unwrap()
} }
#[cfg(all(feature = "cmplog_runtime", target_arch = "aarch64"))] #[cfg(all(feature = "cmplog", target_arch = "aarch64"))]
#[inline] #[inline]
/// Emit the instrumentation code which is responsible for opernads value extraction and cmplog map population
fn emit_comparison_handling( fn emit_comparison_handling(
&self, &self,
_address: u64, _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 basereg = self.writer_register(basereg);
let indexreg = if indexreg.0 != 0 { let indexreg = if indexreg.0 != 0 {
Some(self.writer_register(indexreg)) 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 basereg = self.writer_register(basereg);
let indexreg = if indexreg.0 != 0 { let indexreg = if indexreg.0 != 0 {
Some(self.writer_register(indexreg)) Some(self.writer_register(indexreg))
@ -983,7 +983,7 @@ impl<'a> FridaInstrumentationHelper<'a> {
#[cfg(target_arch = "aarch64")] #[cfg(target_arch = "aarch64")]
#[inline] #[inline]
fn is_interesting_asan_instruction( fn asan_is_interesting_instruction(
&self, &self,
_address: u64, _address: u64,
instr: &Insn, instr: &Insn,
@ -1033,9 +1033,10 @@ impl<'a> FridaInstrumentationHelper<'a> {
Err(()) Err(())
} }
#[cfg(all(feature = "cmplog_runtime", target_arch = "aarch64"))] #[cfg(all(feature = "cmplog", target_arch = "aarch64"))]
#[inline] #[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, &self,
_address: u64, _address: u64,
instr: &Insn, instr: &Insn,

View File

@ -10,7 +10,7 @@ pub mod asan_errors;
/// The frida address sanitizer runtime /// The frida address sanitizer runtime
pub mod asan_rt; pub mod asan_rt;
#[cfg(all(feature = "cmplog_runtime"))] #[cfg(feature = "cmplog")]
/// The frida cmplog runtime /// The frida cmplog runtime
pub mod cmplog_rt; pub mod cmplog_rt;
@ -108,6 +108,10 @@ impl FridaOptions {
} }
"cmplog" => { "cmplog" => {
options.enable_cmplog = value.parse().unwrap(); options.enable_cmplog = value.parse().unwrap();
match cfg!(feature = "cmplog") {
false => panic!("cmplog feature is disabled!"),
_ => (),
}
} }
_ => { _ => {
panic!("unknown FRIDA option: '{}'", option); panic!("unknown FRIDA option: '{}'", option);

View File

@ -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) { 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; uint16_t hits;
if (libafl_cmplog_map.headers[k].kind != CMPLOG_KIND_INS) { if (libafl_cmplog_map.headers[k].kind != CMPLOG_KIND_INS) {

View File

@ -140,7 +140,7 @@ pub use libafl_cmplog_map as CMPLOG_MAP;
/// Value indicating if cmplog is enabled. /// Value indicating if cmplog is enabled.
#[no_mangle] #[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; pub use libafl_cmplog_enabled as CMPLOG_ENABLED;