diff --git a/libafl/src/executors/hooks/unix.rs b/libafl/src/executors/hooks/unix.rs index b78a585a9c..ffec12cf13 100644 --- a/libafl/src/executors/hooks/unix.rs +++ b/libafl/src/executors/hooks/unix.rs @@ -127,7 +127,7 @@ pub mod unix_signal_handler { _context: Option<&mut ucontext_t>, data: &mut InProcessExecutorHandlerData, ) where - E: Executor + HasInProcessHooks + HasObservers, + E: HasInProcessHooks + HasObservers, E::Observers: ObserversTuple, EM: EventFirer + EventRestarter, OF: Feedback, diff --git a/libafl/src/executors/inprocess/mod.rs b/libafl/src/executors/inprocess/mod.rs index ef22caf20f..d8450dd27e 100644 --- a/libafl/src/executors/inprocess/mod.rs +++ b/libafl/src/executors/inprocess/mod.rs @@ -379,7 +379,7 @@ pub fn run_observers_and_save_state( event_mgr: &mut EM, exitkind: ExitKind, ) where - E: Executor + HasObservers, + E: HasObservers, E::Observers: ObserversTuple, EM: EventFirer + EventRestarter, OF: Feedback, diff --git a/libafl_qemu/src/executor.rs b/libafl_qemu/src/executor.rs index 9695a1a26d..a1e86f6049 100644 --- a/libafl_qemu/src/executor.rs +++ b/libafl_qemu/src/executor.rs @@ -60,7 +60,7 @@ pub struct QemuExecutor<'a, C, CM, ED, EM, ET, H, I, OT, S, SM, Z> { /// /// This should be used as a crash handler, and nothing else. #[cfg(feature = "usermode")] -unsafe fn inproc_qemu_crash_handler( +pub unsafe fn inproc_qemu_crash_handler( signal: Signal, info: &mut siginfo_t, mut context: Option<&mut ucontext_t>, @@ -161,7 +161,7 @@ pub unsafe fn inproc_qemu_timeout_handler( context: Option<&mut ucontext_t>, data: &mut InProcessExecutorHandlerData, ) where - E: HasObservers + HasInProcessHooks + Executor, + E: HasObservers + HasInProcessHooks, E::Observers: ObserversTuple, EM: EventFirer + EventRestarter, ET: EmulatorModuleTuple, diff --git a/libafl_qemu/src/qemu/hooks.rs b/libafl_qemu/src/qemu/hooks.rs index a64066bcb6..e8c14201d0 100644 --- a/libafl_qemu/src/qemu/hooks.rs +++ b/libafl_qemu/src/qemu/hooks.rs @@ -1,4 +1,5 @@ //! The high-level hooks + #![allow(clippy::type_complexity)] #![allow(clippy::missing_transmute_annotations)] #![allow(clippy::too_many_arguments)] @@ -928,6 +929,38 @@ pub type CrashHookClosure = Box>( &self, @@ -973,6 +1013,9 @@ impl QemuHooks { } } + /// Remove all instruction hooks for the address `addr`. + /// + /// Set `invalidate_block` to invalidate the virtual pages related to the translation block. #[must_use] pub fn remove_instruction_hooks_at(&self, addr: GuestAddr, invalidate_block: bool) -> usize { unsafe { @@ -983,6 +1026,12 @@ impl QemuHooks { } } + /// Add `gen` in the edge generation hooks and `exec` in the edge execution hooks. + /// + /// `gen` gets passed `data` and the source/destination translation blocks addresses + /// when this edge is reached for the first time. + /// + /// `exec` gets passed `data` and the return value of `gen` every time this edge is reached. pub fn add_edge_hooks>( &self, data: T, @@ -999,6 +1048,16 @@ impl QemuHooks { } } + /// Add `gen` in the translation block (pre-)generation hooks, `post_gen` in post-generation hooks and `exec` + /// in the execution hooks. + /// + /// `gen` gets passed `data` and the block start address, when this block is translated + /// for the first time. + /// + /// `post_gen` gets passed `data`, the block start address and the block size in bytes, + /// at the end of the block generation. + /// + /// `exec` gets passed `data` and the return value of `gen`, every time this block is reached. pub fn add_block_hooks>( &self, data: T, @@ -1017,6 +1076,11 @@ impl QemuHooks { } } + /// Add `pre_exec` in the (pre-)execution hooks, `post_exec` in the post-execution hooks. + /// + /// `pre_exec` gets passed a pointer to the cpu state before the code is run. + /// + /// `post_exec` gets passed a pointer to the cpu state after the code is run. pub fn add_cpu_run_hooks>( &self, data: T, @@ -1032,18 +1096,20 @@ impl QemuHooks { } } - /// `data` can be used to pass data that can be accessed as the first argument in the `gen` and the `exec` functions + /// Add hooks for memory read access. /// - /// `gen` gets passed the current programm counter, mutable access to a `TCGTemp` and information about the memory - /// access being performed. - /// The `u64` return value is an id that gets passed to the `exec` functions as their second argument. + /// `data` can be used to pass data that can be accessed as the first argument in the `gen` and the `exec` functions. /// - /// `exec` hooks get invoked on every read performed by the guest + /// `gen` gets passed `data`, the current program counter, mutable access to the address accessed and + /// information about the memory access being performed. /// - /// `exec1`-`exec8` special case accesses of width 1-8 + /// `exec` hooks get invoked on every read performed by the guest with `data`, the return value of `gen`, + /// the current instruction index and the address of the memory accessed. + /// + /// `exec1`-`exec8` are called for special case accesses of width 1-8. /// /// If there is no specialized hook for a given read width, the `exec_n` will be - /// called and its last argument will specify the access width + /// called and its last argument will specify the access width. pub fn add_read_hooks>( &self, data: T, @@ -1081,6 +1147,20 @@ impl QemuHooks { } } + /// Add hooks for memory write access. + /// + /// `data` can be used to pass data that can be accessed as the first argument in the `gen` and the `exec` functions. + /// + /// `gen` gets passed `data`, the current program counter, mutable access to the address written and + /// information about the memory access being performed. + /// + /// `exec` hooks get invoked on every write performed by the guest with `data`, the return value of `gen`, + /// the current instruction index and the address of the memory written. + /// + /// `exec1`-`exec8` are called for special case write of width 1-8. + /// + /// If there is no specialized hook for a given write width, the `exec_n` will be + /// called and its last argument will specify the write width. // TODO add MemOp info pub fn add_write_hooks>( &self,