Merge branch 'main' of github.com:AFLplusplus/LibAFL into main
This commit is contained in:
commit
0bd292f2ae
@ -33,7 +33,7 @@ target/$(BUILD_TARGET)/lib$(FUZZER_NAME).a: src/*
|
||||
|
||||
qemu-libafl-bridge:
|
||||
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
|
||||
mkdir -p build
|
||||
|
@ -273,14 +273,16 @@ fn fuzz(
|
||||
let mut harness = |input: &BytesInput| {
|
||||
let target = input.target_bytes();
|
||||
let mut buf = target.as_slice();
|
||||
if buf.len() > 4096 {
|
||||
let mut len = buf.len();
|
||||
if len > 4096 {
|
||||
buf = &buf[0..4096];
|
||||
len = 4096;
|
||||
}
|
||||
|
||||
emu::write_mem(input_addr, buf);
|
||||
|
||||
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::Rsp, stack_ptr).unwrap();
|
||||
|
||||
|
@ -16,7 +16,14 @@ use crate::bolts::current_nanos;
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
|
||||
#[must_use]
|
||||
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.
|
||||
|
@ -79,7 +79,7 @@ where
|
||||
|
||||
let filename = format!("{:016x}.libafl_state", hasher.finish());
|
||||
let tmpfile = temp_dir().join(&filename);
|
||||
File::open(tmpfile)?.write_all(&serialized)?;
|
||||
File::create(tmpfile)?.write_all(&serialized)?;
|
||||
|
||||
// write the filename to shmem
|
||||
let filename_buf = postcard::to_allocvec(&filename)?;
|
||||
|
@ -11,7 +11,7 @@ use num::Num;
|
||||
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
||||
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)]
|
||||
#[repr(i32)]
|
||||
@ -109,16 +109,30 @@ extern "C" {
|
||||
static exec_path: *const u8;
|
||||
static guest_base: usize;
|
||||
|
||||
static mut libafl_exec_edge_hook: unsafe extern "C" fn(u32);
|
||||
static mut libafl_gen_edge_hook: unsafe extern "C" fn(u64, u64) -> u32;
|
||||
static mut libafl_exec_edge_hook: unsafe extern "C" fn(u64);
|
||||
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_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_cmp_hook2: unsafe extern "C" fn(u32, u16, u16);
|
||||
static mut libafl_exec_cmp_hook4: unsafe extern "C" fn(u32, u32, u32);
|
||||
static mut libafl_exec_cmp_hook8: unsafe extern "C" fn(u32, u64, u64);
|
||||
static mut libafl_gen_cmp_hook: unsafe extern "C" fn(u64, u32) -> u32;
|
||||
static mut libafl_exec_read_hook1: unsafe extern "C" fn(u64, u64);
|
||||
static mut libafl_exec_read_hook2: unsafe extern "C" fn(u64, u64);
|
||||
static mut libafl_exec_read_hook4: unsafe extern "C" fn(u64, u64);
|
||||
static mut libafl_exec_read_hook8: unsafe extern "C" fn(u64, u64);
|
||||
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:
|
||||
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 };
|
||||
}
|
||||
|
||||
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 };
|
||||
}
|
||||
|
||||
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 };
|
||||
}
|
||||
|
||||
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 };
|
||||
}
|
||||
|
||||
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 };
|
||||
}
|
||||
|
||||
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 };
|
||||
}
|
||||
|
||||
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 };
|
||||
}
|
||||
|
||||
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 };
|
||||
}
|
||||
|
||||
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 };
|
||||
}
|
||||
|
||||
|
@ -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_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();
|
||||
|
||||
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 {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" fn gen_block_hook_wrapper<S>(addr: u64) -> u32 {
|
||||
extern "C" fn gen_block_hook_wrapper<S>(pc: u64) -> u64 {
|
||||
unsafe {
|
||||
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);
|
||||
(func)(state, addr).map_or(SKIP_EXEC_HOOK, |id| id)
|
||||
let func: fn(&mut S, u64) -> Option<u64> = transmute(GEN_BLOCK_HOOK_PTR);
|
||||
(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 {
|
||||
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);
|
||||
(func)(state, addr, size as usize).map_or(SKIP_EXEC_HOOK, |id| id)
|
||||
let func: fn(&mut S, usize) -> Option<u64> = transmute(GEN_READ_HOOK_PTR);
|
||||
(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)]
|
||||
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 _ };
|
||||
emu::set_gen_edge_hook(gen_edge_hook_wrapper::<S>);
|
||||
}
|
||||
|
||||
#[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);
|
||||
}
|
||||
|
||||
#[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 _ };
|
||||
emu::set_gen_block_hook(gen_block_hook_wrapper::<S>);
|
||||
}
|
||||
|
||||
#[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);
|
||||
}
|
||||
|
||||
#[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 _ };
|
||||
emu::set_gen_cmp_hook(gen_cmp_hook_wrapper::<S>);
|
||||
}
|
||||
|
||||
#[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);
|
||||
}
|
||||
|
||||
#[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);
|
||||
}
|
||||
|
||||
#[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);
|
||||
}
|
||||
|
||||
#[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);
|
||||
}
|
||||
|
||||
#[allow(clippy::unused_self)]
|
||||
pub fn hook_syscalls(
|
||||
&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);
|
||||
}
|
||||
|
@ -10,8 +10,8 @@ pub use libafl_targets::{
|
||||
|
||||
#[derive(Default, Serialize, Deserialize)]
|
||||
pub struct QemuEdgesMapMetadata {
|
||||
pub map: HashMap<(u64, u64), u32>,
|
||||
pub current_id: u32,
|
||||
pub map: HashMap<(u64, u64), u64>,
|
||||
pub current_id: u64,
|
||||
}
|
||||
|
||||
impl QemuEdgesMapMetadata {
|
||||
@ -28,8 +28,8 @@ libafl::impl_serdeany!(QemuEdgesMapMetadata);
|
||||
|
||||
#[derive(Default, Serialize, Deserialize)]
|
||||
pub struct QemuCmpsMapMetadata {
|
||||
pub map: HashMap<u64, u32>,
|
||||
pub current_id: u32,
|
||||
pub map: HashMap<u64, u64>,
|
||||
pub current_id: u64,
|
||||
}
|
||||
|
||||
impl QemuCmpsMapMetadata {
|
||||
@ -44,7 +44,7 @@ impl 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
|
||||
S: HasMetadata,
|
||||
{
|
||||
@ -59,21 +59,21 @@ where
|
||||
if meta.map.contains_key(&(src, dest)) {
|
||||
Some(*meta.map.get(&(src, dest)).unwrap())
|
||||
} 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 };
|
||||
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 };
|
||||
}
|
||||
|
||||
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 };
|
||||
}
|
||||
|
||||
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
|
||||
S: HasMetadata,
|
||||
{
|
||||
@ -85,26 +85,26 @@ where
|
||||
.get_mut::<QemuCmpsMapMetadata>()
|
||||
.unwrap();
|
||||
let id = meta.current_id as usize;
|
||||
if meta.map.contains_key(&addr) {
|
||||
Some(*meta.map.get(&addr).unwrap())
|
||||
if meta.map.contains_key(&pc) {
|
||||
Some(*meta.map.get(&pc).unwrap())
|
||||
} else {
|
||||
meta.current_id = ((id + 1) & (CMPLOG_MAP_W - 1)) as u32;
|
||||
Some(id as u32)
|
||||
meta.current_id = ((id + 1) & (CMPLOG_MAP_W - 1)) as u64;
|
||||
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)) }
|
||||
}
|
||||
|
||||
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)) }
|
||||
}
|
||||
|
||||
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)) }
|
||||
}
|
||||
|
||||
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) }
|
||||
}
|
||||
|
@ -61,16 +61,30 @@ __attribute__((weak)) int target_munmap(abi_ulong start, abi_ulong len) {
|
||||
__attribute__((weak)) char* exec_path = NULL;
|
||||
__attribute__((weak)) size_t guest_base = 0;
|
||||
|
||||
__attribute__((weak)) void (*libafl_exec_edge_hook)(uint32_t);
|
||||
__attribute__((weak)) uint32_t (*libafl_gen_edge_hook)(uint64_t, uint64_t);
|
||||
__attribute__((weak)) void (*libafl_exec_edge_hook)(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)) 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_cmp_hook2)(uint32_t, uint16_t, uint16_t);
|
||||
__attribute__((weak)) void (*libafl_exec_cmp_hook4)(uint32_t, uint32_t, uint32_t);
|
||||
__attribute__((weak)) void (*libafl_exec_cmp_hook8)(uint32_t, uint64_t, uint64_t);
|
||||
__attribute__((weak)) uint32_t (*libafl_gen_cmp_hook)(uint64_t, uint32_t);
|
||||
__attribute__((weak)) void (*libafl_exec_read_hook1)(uint64_t, uint64_t);
|
||||
__attribute__((weak)) void (*libafl_exec_read_hook2)(uint64_t, uint64_t);
|
||||
__attribute__((weak)) void (*libafl_exec_read_hook4)(uint64_t, uint64_t);
|
||||
__attribute__((weak)) void (*libafl_exec_read_hook8)(uint64_t, uint64_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 {
|
||||
uint64_t retval;
|
||||
|
@ -65,6 +65,21 @@ where
|
||||
/// Bytes harness
|
||||
#[builder(setter(strip_option))]
|
||||
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>
|
||||
@ -171,6 +186,11 @@ where
|
||||
executor.hook_edge_generation(hooks::gen_unique_edge_ids);
|
||||
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
|
||||
let mut executor = TimeoutExecutor::new(executor, timeout);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user