Merge branch 'main' of github.com:AFLplusplus/LibAFL into main

This commit is contained in:
Andrea Fioraldi 2021-07-22 11:58:32 +02:00
commit 0bd292f2ae
9 changed files with 262 additions and 67 deletions

View File

@ -33,7 +33,7 @@ target/$(BUILD_TARGET)/lib$(FUZZER_NAME).a: src/*
qemu-libafl-bridge: qemu-libafl-bridge:
git clone git@github.com:AFLplusplus/qemu-libafl-bridge.git git clone git@github.com:AFLplusplus/qemu-libafl-bridge.git
cd qemu-libafl-bridge && git checkout 03dfdbd7da90b2d3b9e4df1a52b5a48e8d453a84 cd qemu-libafl-bridge && git checkout ae096f10cec9a0ac489cb6e6c9892bcbfaea159d
build/config.status: qemu-libafl-bridge qemu-libafl-bridge/configure build/config.status: qemu-libafl-bridge qemu-libafl-bridge/configure
mkdir -p build mkdir -p build

View File

@ -273,14 +273,16 @@ fn fuzz(
let mut harness = |input: &BytesInput| { let mut harness = |input: &BytesInput| {
let target = input.target_bytes(); let target = input.target_bytes();
let mut buf = target.as_slice(); let mut buf = target.as_slice();
if buf.len() > 4096 { let mut len = buf.len();
if len > 4096 {
buf = &buf[0..4096]; buf = &buf[0..4096];
len = 4096;
} }
emu::write_mem(input_addr, buf); emu::write_mem(input_addr, buf);
emu::write_reg(Amd64Regs::Rdi, input_addr).unwrap(); emu::write_reg(Amd64Regs::Rdi, input_addr).unwrap();
emu::write_reg(Amd64Regs::Rsi, buf.len()).unwrap(); emu::write_reg(Amd64Regs::Rsi, len).unwrap();
emu::write_reg(Amd64Regs::Rip, test_one_input_ptr).unwrap(); emu::write_reg(Amd64Regs::Rip, test_one_input_ptr).unwrap();
emu::write_reg(Amd64Regs::Rsp, stack_ptr).unwrap(); emu::write_reg(Amd64Regs::Rsp, stack_ptr).unwrap();

View File

@ -16,7 +16,14 @@ use crate::bolts::current_nanos;
#[cfg(any(target_arch = "x86_64", target_arch = "x86"))] #[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
#[must_use] #[must_use]
pub fn read_time_counter() -> u64 { pub fn read_time_counter() -> u64 {
unsafe { core::arch::x86_64::_rdtsc() } #[cfg(target_arch = "x86_64")]
unsafe {
core::arch::x86_64::_rdtsc()
}
#[cfg(target_arch = "x86")]
unsafe {
core::arch::x86::_rdtsc()
}
} }
/// Read a timestamp for measurements. /// Read a timestamp for measurements.

View File

@ -79,7 +79,7 @@ where
let filename = format!("{:016x}.libafl_state", hasher.finish()); let filename = format!("{:016x}.libafl_state", hasher.finish());
let tmpfile = temp_dir().join(&filename); let tmpfile = temp_dir().join(&filename);
File::open(tmpfile)?.write_all(&serialized)?; File::create(tmpfile)?.write_all(&serialized)?;
// write the filename to shmem // write the filename to shmem
let filename_buf = postcard::to_allocvec(&filename)?; let filename_buf = postcard::to_allocvec(&filename)?;

View File

@ -11,7 +11,7 @@ use num::Num;
use num_enum::{IntoPrimitive, TryFromPrimitive}; use num_enum::{IntoPrimitive, TryFromPrimitive};
use std::{slice::from_raw_parts, str::from_utf8_unchecked}; use std::{slice::from_raw_parts, str::from_utf8_unchecked};
pub const SKIP_EXEC_HOOK: u32 = u32::MAX; pub const SKIP_EXEC_HOOK: u64 = u64::MAX;
#[derive(IntoPrimitive, TryFromPrimitive, Clone, Copy)] #[derive(IntoPrimitive, TryFromPrimitive, Clone, Copy)]
#[repr(i32)] #[repr(i32)]
@ -109,16 +109,30 @@ extern "C" {
static exec_path: *const u8; static exec_path: *const u8;
static guest_base: usize; static guest_base: usize;
static mut libafl_exec_edge_hook: unsafe extern "C" fn(u32); static mut libafl_exec_edge_hook: unsafe extern "C" fn(u64);
static mut libafl_gen_edge_hook: unsafe extern "C" fn(u64, u64) -> u32; static mut libafl_gen_edge_hook: unsafe extern "C" fn(u64, u64) -> u64;
static mut libafl_exec_block_hook: unsafe extern "C" fn(u64); static mut libafl_exec_block_hook: unsafe extern "C" fn(u64);
static mut libafl_gen_block_hook: unsafe extern "C" fn(u64) -> u32; static mut libafl_gen_block_hook: unsafe extern "C" fn(u64) -> u64;
static mut libafl_exec_cmp_hook1: unsafe extern "C" fn(u32, u8, u8); static mut libafl_exec_read_hook1: unsafe extern "C" fn(u64, u64);
static mut libafl_exec_cmp_hook2: unsafe extern "C" fn(u32, u16, u16); static mut libafl_exec_read_hook2: unsafe extern "C" fn(u64, u64);
static mut libafl_exec_cmp_hook4: unsafe extern "C" fn(u32, u32, u32); static mut libafl_exec_read_hook4: unsafe extern "C" fn(u64, u64);
static mut libafl_exec_cmp_hook8: unsafe extern "C" fn(u32, u64, u64); static mut libafl_exec_read_hook8: unsafe extern "C" fn(u64, u64);
static mut libafl_gen_cmp_hook: unsafe extern "C" fn(u64, u32) -> u32; static mut libafl_exec_read_hookN: unsafe extern "C" fn(u64, u64, u32);
static mut libafl_gen_read_hook: unsafe extern "C" fn(u32) -> u64;
static mut libafl_exec_write_hook1: unsafe extern "C" fn(u64, u64);
static mut libafl_exec_write_hook2: unsafe extern "C" fn(u64, u64);
static mut libafl_exec_write_hook4: unsafe extern "C" fn(u64, u64);
static mut libafl_exec_write_hook8: unsafe extern "C" fn(u64, u64);
static mut libafl_exec_write_hookN: unsafe extern "C" fn(u64, u64, u32);
static mut libafl_gen_write_hook: unsafe extern "C" fn(u32) -> u64;
static mut libafl_exec_cmp_hook1: unsafe extern "C" fn(u64, u8, u8);
static mut libafl_exec_cmp_hook2: unsafe extern "C" fn(u64, u16, u16);
static mut libafl_exec_cmp_hook4: unsafe extern "C" fn(u64, u32, u32);
static mut libafl_exec_cmp_hook8: unsafe extern "C" fn(u64, u64, u64);
static mut libafl_gen_cmp_hook: unsafe extern "C" fn(u64, u32) -> u64;
static mut libafl_syscall_hook: static mut libafl_syscall_hook:
unsafe extern "C" fn(i32, u64, u64, u64, u64, u64, u64, u64, u64) -> SyscallHookResult; unsafe extern "C" fn(i32, u64, u64, u64, u64, u64, u64, u64, u64) -> SyscallHookResult;
@ -283,39 +297,87 @@ pub fn unmap(addr: u64, size: usize) -> Result<(), String> {
} }
} }
pub fn set_exec_edge_hook(hook: extern "C" fn(id: u32)) { pub fn set_exec_edge_hook(hook: extern "C" fn(id: u64)) {
unsafe { libafl_exec_edge_hook = hook }; unsafe { libafl_exec_edge_hook = hook };
} }
pub fn set_gen_edge_hook(hook: extern "C" fn(src: u64, dest: u64) -> u32) { pub fn set_gen_edge_hook(hook: extern "C" fn(src: u64, dest: u64) -> u64) {
unsafe { libafl_gen_edge_hook = hook }; unsafe { libafl_gen_edge_hook = hook };
} }
pub fn set_exec_block_hook(hook: extern "C" fn(addr: u64)) { pub fn set_exec_block_hook(hook: extern "C" fn(pc: u64)) {
unsafe { libafl_exec_block_hook = hook }; unsafe { libafl_exec_block_hook = hook };
} }
pub fn set_gen_block_hook(hook: extern "C" fn(addr: u64) -> u32) { pub fn set_gen_block_hook(hook: extern "C" fn(pc: u64) -> u64) {
unsafe { libafl_gen_block_hook = hook }; unsafe { libafl_gen_block_hook = hook };
} }
pub fn set_exec_cmp1_hook(hook: extern "C" fn(id: u32, v0: u8, v1: u8)) { pub fn set_exec_read1_hook(hook: extern "C" fn(id: u64, addr: u64)) {
unsafe { libafl_exec_read_hook1 = hook };
}
pub fn set_exec_read2_hook(hook: extern "C" fn(id: u64, addr: u64)) {
unsafe { libafl_exec_read_hook2 = hook };
}
pub fn set_exec_read4_hook(hook: extern "C" fn(id: u64, addr: u64)) {
unsafe { libafl_exec_read_hook4 = hook };
}
pub fn set_exec_read8_hook(hook: extern "C" fn(id: u64, addr: u64)) {
unsafe { libafl_exec_read_hook8 = hook };
}
pub fn set_exec_read_n_hook(hook: extern "C" fn(id: u64, addr: u64, size: u32)) {
unsafe { libafl_exec_read_hookN = hook };
}
pub fn set_gen_read_hook(hook: extern "C" fn(size: u32) -> u64) {
unsafe { libafl_gen_read_hook = hook };
}
pub fn set_exec_write1_hook(hook: extern "C" fn(id: u64, addr: u64)) {
unsafe { libafl_exec_write_hook1 = hook };
}
pub fn set_exec_write2_hook(hook: extern "C" fn(id: u64, addr: u64)) {
unsafe { libafl_exec_write_hook2 = hook };
}
pub fn set_exec_write4_hook(hook: extern "C" fn(id: u64, addr: u64)) {
unsafe { libafl_exec_write_hook4 = hook };
}
pub fn set_exec_write8_hook(hook: extern "C" fn(id: u64, addr: u64)) {
unsafe { libafl_exec_write_hook8 = hook };
}
pub fn set_exec_write_n_hook(hook: extern "C" fn(id: u64, addr: u64, size: u32)) {
unsafe { libafl_exec_write_hookN = hook };
}
pub fn set_gen_write_hook(hook: extern "C" fn(size: u32) -> u64) {
unsafe { libafl_gen_write_hook = hook };
}
pub fn set_exec_cmp1_hook(hook: extern "C" fn(id: u64, v0: u8, v1: u8)) {
unsafe { libafl_exec_cmp_hook1 = hook }; unsafe { libafl_exec_cmp_hook1 = hook };
} }
pub fn set_exec_cmp2_hook(hook: extern "C" fn(id: u32, v0: u16, v1: u16)) { pub fn set_exec_cmp2_hook(hook: extern "C" fn(id: u64, v0: u16, v1: u16)) {
unsafe { libafl_exec_cmp_hook2 = hook }; unsafe { libafl_exec_cmp_hook2 = hook };
} }
pub fn set_exec_cmp4_hook(hook: extern "C" fn(id: u32, v0: u32, v1: u32)) { pub fn set_exec_cmp4_hook(hook: extern "C" fn(id: u64, v0: u32, v1: u32)) {
unsafe { libafl_exec_cmp_hook4 = hook }; unsafe { libafl_exec_cmp_hook4 = hook };
} }
pub fn set_exec_cmp8_hook(hook: extern "C" fn(id: u32, v0: u64, v1: u64)) { pub fn set_exec_cmp8_hook(hook: extern "C" fn(id: u64, v0: u64, v1: u64)) {
unsafe { libafl_exec_cmp_hook8 = hook }; unsafe { libafl_exec_cmp_hook8 = hook };
} }
pub fn set_gen_cmp_hook(hook: extern "C" fn(addr: u64, size: u32) -> u32) { pub fn set_gen_cmp_hook(hook: extern "C" fn(pc: u64, size: u32) -> u64) {
unsafe { libafl_gen_cmp_hook = hook }; unsafe { libafl_gen_cmp_hook = hook };
} }

View File

@ -17,29 +17,47 @@ use crate::{emu, emu::SKIP_EXEC_HOOK};
static mut GEN_EDGE_HOOK_PTR: *const c_void = ptr::null(); static mut GEN_EDGE_HOOK_PTR: *const c_void = ptr::null();
static mut GEN_BLOCK_HOOK_PTR: *const c_void = ptr::null(); static mut GEN_BLOCK_HOOK_PTR: *const c_void = ptr::null();
static mut GEN_READ_HOOK_PTR: *const c_void = ptr::null();
static mut GEN_WRITE_HOOK_PTR: *const c_void = ptr::null();
static mut GEN_CMP_HOOK_PTR: *const c_void = ptr::null(); static mut GEN_CMP_HOOK_PTR: *const c_void = ptr::null();
extern "C" fn gen_edge_hook_wrapper<S>(src: u64, dst: u64) -> u32 { extern "C" fn gen_edge_hook_wrapper<S>(src: u64, dst: u64) -> u64 {
unsafe { unsafe {
let state = (GLOBAL_STATE.state_ptr as *mut S).as_mut().unwrap(); let state = (GLOBAL_STATE.state_ptr as *mut S).as_mut().unwrap();
let func: fn(&mut S, u64, u64) -> Option<u32> = transmute(GEN_EDGE_HOOK_PTR); let func: fn(&mut S, u64, u64) -> Option<u64> = transmute(GEN_EDGE_HOOK_PTR);
(func)(state, src, dst).map_or(SKIP_EXEC_HOOK, |id| id) (func)(state, src, dst).map_or(SKIP_EXEC_HOOK, |id| id)
} }
} }
extern "C" fn gen_block_hook_wrapper<S>(addr: u64) -> u32 { extern "C" fn gen_block_hook_wrapper<S>(pc: u64) -> u64 {
unsafe { unsafe {
let state = (GLOBAL_STATE.state_ptr as *mut S).as_mut().unwrap(); let state = (GLOBAL_STATE.state_ptr as *mut S).as_mut().unwrap();
let func: fn(&mut S, u64) -> Option<u32> = transmute(GEN_BLOCK_HOOK_PTR); let func: fn(&mut S, u64) -> Option<u64> = transmute(GEN_BLOCK_HOOK_PTR);
(func)(state, addr).map_or(SKIP_EXEC_HOOK, |id| id) (func)(state, pc).map_or(SKIP_EXEC_HOOK, |id| id)
} }
} }
extern "C" fn gen_cmp_hook_wrapper<S>(addr: u64, size: u32) -> u32 { extern "C" fn gen_read_hook_wrapper<S>(size: u32) -> u64 {
unsafe { unsafe {
let state = (GLOBAL_STATE.state_ptr as *mut S).as_mut().unwrap(); let state = (GLOBAL_STATE.state_ptr as *mut S).as_mut().unwrap();
let func: fn(&mut S, u64, usize) -> Option<u32> = transmute(GEN_CMP_HOOK_PTR); let func: fn(&mut S, usize) -> Option<u64> = transmute(GEN_READ_HOOK_PTR);
(func)(state, addr, size as usize).map_or(SKIP_EXEC_HOOK, |id| id) (func)(state, size as usize).map_or(SKIP_EXEC_HOOK, |id| id)
}
}
extern "C" fn gen_write_hook_wrapper<S>(size: u32) -> u64 {
unsafe {
let state = (GLOBAL_STATE.state_ptr as *mut S).as_mut().unwrap();
let func: fn(&mut S, usize) -> Option<u64> = transmute(GEN_WRITE_HOOK_PTR);
(func)(state, size as usize).map_or(SKIP_EXEC_HOOK, |id| id)
}
}
extern "C" fn gen_cmp_hook_wrapper<S>(pc: u64, size: u32) -> u64 {
unsafe {
let state = (GLOBAL_STATE.state_ptr as *mut S).as_mut().unwrap();
let func: fn(&mut S, u64, usize) -> Option<u64> = transmute(GEN_CMP_HOOK_PTR);
(func)(state, pc, size as usize).map_or(SKIP_EXEC_HOOK, |id| id)
} }
} }
@ -86,57 +104,129 @@ where
} }
#[allow(clippy::unused_self)] #[allow(clippy::unused_self)]
pub fn hook_edge_generation(&self, hook: fn(&mut S, src: u64, dest: u64) -> Option<u32>) { pub fn hook_edge_generation(&self, hook: fn(&mut S, src: u64, dest: u64) -> Option<u64>) {
unsafe { GEN_EDGE_HOOK_PTR = hook as *const _ }; unsafe { GEN_EDGE_HOOK_PTR = hook as *const _ };
emu::set_gen_edge_hook(gen_edge_hook_wrapper::<S>); emu::set_gen_edge_hook(gen_edge_hook_wrapper::<S>);
} }
#[allow(clippy::unused_self)] #[allow(clippy::unused_self)]
pub fn hook_edge_execution(&self, hook: extern "C" fn(id: u32)) { pub fn hook_edge_execution(&self, hook: extern "C" fn(id: u64)) {
emu::set_exec_edge_hook(hook); emu::set_exec_edge_hook(hook);
} }
#[allow(clippy::unused_self)] #[allow(clippy::unused_self)]
pub fn hook_block_generation(&self, hook: fn(&mut S, addr: u64) -> Option<u32>) { pub fn hook_block_generation(&self, hook: fn(&mut S, pc: u64) -> Option<u64>) {
unsafe { GEN_BLOCK_HOOK_PTR = hook as *const _ }; unsafe { GEN_BLOCK_HOOK_PTR = hook as *const _ };
emu::set_gen_block_hook(gen_block_hook_wrapper::<S>); emu::set_gen_block_hook(gen_block_hook_wrapper::<S>);
} }
#[allow(clippy::unused_self)] #[allow(clippy::unused_self)]
pub fn hook_block_execution(&self, hook: extern "C" fn(addr: u64)) { pub fn hook_block_execution(&self, hook: extern "C" fn(id: u64)) {
emu::set_exec_block_hook(hook); emu::set_exec_block_hook(hook);
} }
#[allow(clippy::unused_self)] #[allow(clippy::unused_self)]
pub fn hook_cmp_generation(&self, hook: fn(&mut S, addr: u64, size: usize) -> Option<u32>) { pub fn hook_read_generation(&self, hook: fn(&mut S, size: usize) -> Option<u64>) {
unsafe { GEN_READ_HOOK_PTR = hook as *const _ };
emu::set_gen_read_hook(gen_read_hook_wrapper::<S>);
}
#[allow(clippy::unused_self)]
pub fn hook_read1_execution(&self, hook: extern "C" fn(id: u64, addr: u64)) {
emu::set_exec_read1_hook(hook);
}
#[allow(clippy::unused_self)]
pub fn hook_read2_execution(&self, hook: extern "C" fn(id: u64, addr: u64)) {
emu::set_exec_read2_hook(hook);
}
#[allow(clippy::unused_self)]
pub fn hook_read4_execution(&self, hook: extern "C" fn(id: u64, addr: u64)) {
emu::set_exec_read4_hook(hook);
}
#[allow(clippy::unused_self)]
pub fn hook_read8_execution(&self, hook: extern "C" fn(id: u64, addr: u64)) {
emu::set_exec_read8_hook(hook);
}
#[allow(clippy::unused_self)]
pub fn hook_read_n_execution(&self, hook: extern "C" fn(id: u64, addr: u64, size: u32)) {
emu::set_exec_read_n_hook(hook);
}
#[allow(clippy::unused_self)]
pub fn hook_write_generation(&self, hook: fn(&mut S, size: usize) -> Option<u64>) {
unsafe { GEN_WRITE_HOOK_PTR = hook as *const _ };
emu::set_gen_write_hook(gen_write_hook_wrapper::<S>);
}
#[allow(clippy::unused_self)]
pub fn hook_write1_execution(&self, hook: extern "C" fn(id: u64, addr: u64)) {
emu::set_exec_write1_hook(hook);
}
#[allow(clippy::unused_self)]
pub fn hook_write2_execution(&self, hook: extern "C" fn(id: u64, addr: u64)) {
emu::set_exec_write2_hook(hook);
}
#[allow(clippy::unused_self)]
pub fn hook_write4_execution(&self, hook: extern "C" fn(id: u64, addr: u64)) {
emu::set_exec_write4_hook(hook);
}
#[allow(clippy::unused_self)]
pub fn hook_write8_execution(&self, hook: extern "C" fn(id: u64, addr: u64)) {
emu::set_exec_write8_hook(hook);
}
#[allow(clippy::unused_self)]
pub fn hook_write_n_execution(&self, hook: extern "C" fn(id: u64, addr: u64, size: u32)) {
emu::set_exec_write_n_hook(hook);
}
#[allow(clippy::unused_self)]
pub fn hook_cmp_generation(&self, hook: fn(&mut S, pc: u64, size: usize) -> Option<u64>) {
unsafe { GEN_CMP_HOOK_PTR = hook as *const _ }; unsafe { GEN_CMP_HOOK_PTR = hook as *const _ };
emu::set_gen_cmp_hook(gen_cmp_hook_wrapper::<S>); emu::set_gen_cmp_hook(gen_cmp_hook_wrapper::<S>);
} }
#[allow(clippy::unused_self)] #[allow(clippy::unused_self)]
pub fn hook_cmp1_execution(&self, hook: extern "C" fn(id: u32, v0: u8, v1: u8)) { pub fn hook_cmp1_execution(&self, hook: extern "C" fn(id: u64, v0: u8, v1: u8)) {
emu::set_exec_cmp1_hook(hook); emu::set_exec_cmp1_hook(hook);
} }
#[allow(clippy::unused_self)] #[allow(clippy::unused_self)]
pub fn hook_cmp2_execution(&self, hook: extern "C" fn(id: u32, v0: u16, v1: u16)) { pub fn hook_cmp2_execution(&self, hook: extern "C" fn(id: u64, v0: u16, v1: u16)) {
emu::set_exec_cmp2_hook(hook); emu::set_exec_cmp2_hook(hook);
} }
#[allow(clippy::unused_self)] #[allow(clippy::unused_self)]
pub fn hook_cmp4_execution(&self, hook: extern "C" fn(id: u32, v0: u32, v1: u32)) { pub fn hook_cmp4_execution(&self, hook: extern "C" fn(id: u64, v0: u32, v1: u32)) {
emu::set_exec_cmp4_hook(hook); emu::set_exec_cmp4_hook(hook);
} }
#[allow(clippy::unused_self)] #[allow(clippy::unused_self)]
pub fn hook_cmp8_execution(&self, hook: extern "C" fn(id: u32, v0: u64, v1: u64)) { pub fn hook_cmp8_execution(&self, hook: extern "C" fn(id: u64, v0: u64, v1: u64)) {
emu::set_exec_cmp8_hook(hook); emu::set_exec_cmp8_hook(hook);
} }
#[allow(clippy::unused_self)] #[allow(clippy::unused_self)]
pub fn hook_syscalls( pub fn hook_syscalls(
&self, &self,
hook: extern "C" fn(i32, u64, u64, u64, u64, u64, u64, u64, u64) -> SyscallHookResult, hook: extern "C" fn(
sys_num: i32,
u64,
u64,
u64,
u64,
u64,
u64,
u64,
u64,
) -> SyscallHookResult,
) { ) {
emu::set_syscall_hook(hook); emu::set_syscall_hook(hook);
} }

View File

@ -10,8 +10,8 @@ pub use libafl_targets::{
#[derive(Default, Serialize, Deserialize)] #[derive(Default, Serialize, Deserialize)]
pub struct QemuEdgesMapMetadata { pub struct QemuEdgesMapMetadata {
pub map: HashMap<(u64, u64), u32>, pub map: HashMap<(u64, u64), u64>,
pub current_id: u32, pub current_id: u64,
} }
impl QemuEdgesMapMetadata { impl QemuEdgesMapMetadata {
@ -28,8 +28,8 @@ libafl::impl_serdeany!(QemuEdgesMapMetadata);
#[derive(Default, Serialize, Deserialize)] #[derive(Default, Serialize, Deserialize)]
pub struct QemuCmpsMapMetadata { pub struct QemuCmpsMapMetadata {
pub map: HashMap<u64, u32>, pub map: HashMap<u64, u64>,
pub current_id: u32, pub current_id: u64,
} }
impl QemuCmpsMapMetadata { impl QemuCmpsMapMetadata {
@ -44,7 +44,7 @@ impl QemuCmpsMapMetadata {
libafl::impl_serdeany!(QemuCmpsMapMetadata); libafl::impl_serdeany!(QemuCmpsMapMetadata);
pub fn gen_unique_edge_ids<S>(state: &mut S, src: u64, dest: u64) -> Option<u32> pub fn gen_unique_edge_ids<S>(state: &mut S, src: u64, dest: u64) -> Option<u64>
where where
S: HasMetadata, S: HasMetadata,
{ {
@ -59,21 +59,21 @@ where
if meta.map.contains_key(&(src, dest)) { if meta.map.contains_key(&(src, dest)) {
Some(*meta.map.get(&(src, dest)).unwrap()) Some(*meta.map.get(&(src, dest)).unwrap())
} else { } else {
meta.current_id = ((id + 1) & (EDGES_MAP_SIZE - 1)) as u32; meta.current_id = ((id + 1) & (EDGES_MAP_SIZE - 1)) as u64;
unsafe { MAX_EDGES_NUM = meta.current_id as usize }; unsafe { MAX_EDGES_NUM = meta.current_id as usize };
Some(id as u32) Some(id as u64)
} }
} }
pub extern "C" fn trace_edge_hitcount(id: u32) { pub extern "C" fn trace_edge_hitcount(id: u64) {
unsafe { EDGES_MAP[id as usize] += 1 }; unsafe { EDGES_MAP[id as usize] += 1 };
} }
pub extern "C" fn trace_edge_single(id: u32) { pub extern "C" fn trace_edge_single(id: u64) {
unsafe { EDGES_MAP[id as usize] = 1 }; unsafe { EDGES_MAP[id as usize] = 1 };
} }
pub fn gen_unique_cmp_ids<S>(state: &mut S, addr: u64, _size: usize) -> Option<u32> pub fn gen_unique_cmp_ids<S>(state: &mut S, pc: u64, _size: usize) -> Option<u64>
where where
S: HasMetadata, S: HasMetadata,
{ {
@ -85,26 +85,26 @@ where
.get_mut::<QemuCmpsMapMetadata>() .get_mut::<QemuCmpsMapMetadata>()
.unwrap(); .unwrap();
let id = meta.current_id as usize; let id = meta.current_id as usize;
if meta.map.contains_key(&addr) { if meta.map.contains_key(&pc) {
Some(*meta.map.get(&addr).unwrap()) Some(*meta.map.get(&pc).unwrap())
} else { } else {
meta.current_id = ((id + 1) & (CMPLOG_MAP_W - 1)) as u32; meta.current_id = ((id + 1) & (CMPLOG_MAP_W - 1)) as u64;
Some(id as u32) Some(id as u64)
} }
} }
pub extern "C" fn trace_cmp1_cmplog(id: u32, v0: u8, v1: u8) { pub extern "C" fn trace_cmp1_cmplog(id: u64, v0: u8, v1: u8) {
unsafe { __libafl_targets_cmplog_instructions(id as usize, 1, u64::from(v0), u64::from(v1)) } unsafe { __libafl_targets_cmplog_instructions(id as usize, 1, u64::from(v0), u64::from(v1)) }
} }
pub extern "C" fn trace_cmp2_cmplog(id: u32, v0: u16, v1: u16) { pub extern "C" fn trace_cmp2_cmplog(id: u64, v0: u16, v1: u16) {
unsafe { __libafl_targets_cmplog_instructions(id as usize, 2, u64::from(v0), u64::from(v1)) } unsafe { __libafl_targets_cmplog_instructions(id as usize, 2, u64::from(v0), u64::from(v1)) }
} }
pub extern "C" fn trace_cmp4_cmplog(id: u32, v0: u32, v1: u32) { pub extern "C" fn trace_cmp4_cmplog(id: u64, v0: u32, v1: u32) {
unsafe { __libafl_targets_cmplog_instructions(id as usize, 4, u64::from(v0), u64::from(v1)) } unsafe { __libafl_targets_cmplog_instructions(id as usize, 4, u64::from(v0), u64::from(v1)) }
} }
pub extern "C" fn trace_cmp8_cmplog(id: u32, v0: u64, v1: u64) { pub extern "C" fn trace_cmp8_cmplog(id: u64, v0: u64, v1: u64) {
unsafe { __libafl_targets_cmplog_instructions(id as usize, 8, v0, v1) } unsafe { __libafl_targets_cmplog_instructions(id as usize, 8, v0, v1) }
} }

View File

@ -61,16 +61,30 @@ __attribute__((weak)) int target_munmap(abi_ulong start, abi_ulong len) {
__attribute__((weak)) char* exec_path = NULL; __attribute__((weak)) char* exec_path = NULL;
__attribute__((weak)) size_t guest_base = 0; __attribute__((weak)) size_t guest_base = 0;
__attribute__((weak)) void (*libafl_exec_edge_hook)(uint32_t); __attribute__((weak)) void (*libafl_exec_edge_hook)(uint64_t);
__attribute__((weak)) uint32_t (*libafl_gen_edge_hook)(uint64_t, uint64_t); __attribute__((weak)) uint64_t (*libafl_gen_edge_hook)(uint64_t, uint64_t);
__attribute__((weak)) void (*libafl_exec_block_hook)(uint64_t); __attribute__((weak)) void (*libafl_exec_block_hook)(uint64_t);
__attribute__((weak)) uint32_t (*libafl_gen_block_hook)(uint64_t); __attribute__((weak)) uint64_t (*libafl_gen_block_hook)(uint64_t);
__attribute__((weak)) void (*libafl_exec_cmp_hook1)(uint32_t, uint8_t, uint8_t); __attribute__((weak)) void (*libafl_exec_read_hook1)(uint64_t, uint64_t);
__attribute__((weak)) void (*libafl_exec_cmp_hook2)(uint32_t, uint16_t, uint16_t); __attribute__((weak)) void (*libafl_exec_read_hook2)(uint64_t, uint64_t);
__attribute__((weak)) void (*libafl_exec_cmp_hook4)(uint32_t, uint32_t, uint32_t); __attribute__((weak)) void (*libafl_exec_read_hook4)(uint64_t, uint64_t);
__attribute__((weak)) void (*libafl_exec_cmp_hook8)(uint32_t, uint64_t, uint64_t); __attribute__((weak)) void (*libafl_exec_read_hook8)(uint64_t, uint64_t);
__attribute__((weak)) uint32_t (*libafl_gen_cmp_hook)(uint64_t, uint32_t); __attribute__((weak)) void (*libafl_exec_read_hookN)(uint64_t, uint64_t, uint32_t);
__attribute__((weak)) uint64_t (*libafl_gen_read_hook)(uint32_t);
__attribute__((weak)) void (*libafl_exec_write_hook1)(uint64_t, uint64_t);
__attribute__((weak)) void (*libafl_exec_write_hook2)(uint64_t, uint64_t);
__attribute__((weak)) void (*libafl_exec_write_hook4)(uint64_t, uint64_t);
__attribute__((weak)) void (*libafl_exec_write_hook8)(uint64_t, uint64_t);
__attribute__((weak)) void (*libafl_exec_write_hookN)(uint64_t, uint64_t, uint32_t);
__attribute__((weak)) uint64_t (*libafl_gen_write_hook)(uint32_t);
__attribute__((weak)) void (*libafl_exec_cmp_hook1)(uint64_t, uint8_t, uint8_t);
__attribute__((weak)) void (*libafl_exec_cmp_hook2)(uint64_t, uint16_t, uint16_t);
__attribute__((weak)) void (*libafl_exec_cmp_hook4)(uint64_t, uint32_t, uint32_t);
__attribute__((weak)) void (*libafl_exec_cmp_hook8)(uint64_t, uint64_t, uint64_t);
__attribute__((weak)) uint64_t (*libafl_gen_cmp_hook)(uint64_t, uint32_t);
struct syshook_ret { struct syshook_ret {
uint64_t retval; uint64_t retval;

View File

@ -65,6 +65,21 @@ where
/// Bytes harness /// Bytes harness
#[builder(setter(strip_option))] #[builder(setter(strip_option))]
harness: Option<H>, harness: Option<H>,
// Syscall hook
#[builder(default = None, setter(strip_option))]
syscall_hook: Option<
extern "C" fn(
sys_num: i32,
u64,
u64,
u64,
u64,
u64,
u64,
u64,
u64,
) -> emu::SyscallHookResult,
>,
} }
impl<'a, H> QemuBytesCoverageSugar<'a, H> impl<'a, H> QemuBytesCoverageSugar<'a, H>
@ -171,6 +186,11 @@ where
executor.hook_edge_generation(hooks::gen_unique_edge_ids); executor.hook_edge_generation(hooks::gen_unique_edge_ids);
executor.hook_edge_execution(hooks::trace_edge_hitcount); executor.hook_edge_execution(hooks::trace_edge_hitcount);
// Hook the syscalls
if let Some(hook) = self.syscall_hook {
executor.hook_syscalls(hook);
}
// Create the executor for an in-process function with one observer for edge coverage and one for the execution time // Create the executor for an in-process function with one observer for edge coverage and one for the execution time
let mut executor = TimeoutExecutor::new(executor, timeout); let mut executor = TimeoutExecutor::new(executor, timeout);