From c96d103b3737c756310037d95fcd32632b4dad1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rubens=20Brand=C3=A3o?= Date: Thu, 1 Feb 2024 06:55:55 -0300 Subject: [PATCH] HookId trait and types in libafl_qemu (#1796) * libafl_qemu fix remove_hook * libafl_qemu specialize hooks into separated types * libafl_qemu generalize HookState to allow any HookId implementation * fmt: external C qemu hook functions --------- Co-authored-by: Andrea Fioraldi --- libafl_qemu/src/emu.rs | 85 ++++++++++----- libafl_qemu/src/hooks.rs | 224 ++++++++++++++++++++++----------------- 2 files changed, 186 insertions(+), 123 deletions(-) diff --git a/libafl_qemu/src/emu.rs b/libafl_qemu/src/emu.rs index 6c5bd5bed2..551d8a4627 100644 --- a/libafl_qemu/src/emu.rs +++ b/libafl_qemu/src/emu.rs @@ -832,8 +832,45 @@ impl CPU { } } -#[derive(Clone, Copy, PartialEq, Debug)] -pub struct HookId(pub(crate) usize); +pub trait HookId { + fn remove(&self, invalidate_block: bool) -> bool; +} + +macro_rules! create_hook_id { + ($name:ident, $sys:ident, true) => { + paste::paste! { + #[derive(Clone, Copy, PartialEq, Debug)] + pub struct [<$name HookId>](pub(crate) usize); + impl HookId for [<$name HookId>] { + fn remove(&self, invalidate_block: bool) -> bool { + unsafe { libafl_qemu_sys::$sys(self.0, invalidate_block.into()) != 0 } + } + } + } + }; + ($name:ident, $sys:ident, false) => { + paste::paste! { + #[derive(Clone, Copy, PartialEq, Debug)] + pub struct [<$name HookId>](pub(crate) usize); + impl HookId for [<$name HookId>] { + fn remove(&self, _invalidate_block: bool) -> bool { + unsafe { libafl_qemu_sys::$sys(self.0) != 0 } + } + } + } + }; +} + +create_hook_id!(Instruction, libafl_qemu_remove_hook, true); +create_hook_id!(Backdoor, libafl_qemu_remove_backdoor_hook, true); +create_hook_id!(Edge, libafl_qemu_remove_edge_hook, true); +create_hook_id!(Block, libafl_qemu_remove_block_hook, true); +create_hook_id!(Read, libafl_qemu_remove_read_hook, true); +create_hook_id!(Write, libafl_qemu_remove_write_hook, true); +create_hook_id!(Cmp, libafl_qemu_remove_cmp_hook, true); +create_hook_id!(PreSyscall, libafl_qemu_remove_pre_syscall_hook, false); +create_hook_id!(PostSyscall, libafl_qemu_remove_post_syscall_hook, false); +create_hook_id!(NewThread, libafl_qemu_remove_new_thread_hook, false); use std::pin::Pin; @@ -1347,7 +1384,7 @@ impl Emulator { addr: GuestAddr, callback: extern "C" fn(T, GuestAddr), invalidate_block: bool, - ) -> HookId { + ) -> InstructionHookId { unsafe { let data: u64 = data.into().0; let callback: extern "C" fn(u64, GuestAddr) = core::mem::transmute(callback); @@ -1357,13 +1394,13 @@ impl Emulator { data, i32::from(invalidate_block), ); - HookId(num) + InstructionHookId(num) } } #[must_use] - pub fn remove_hook(&self, id: HookId, invalidate_block: bool) -> bool { - unsafe { libafl_qemu_sys::libafl_qemu_remove_hook(id.0, i32::from(invalidate_block)) != 0 } + pub fn remove_hook(&self, id: impl HookId, invalidate_block: bool) -> bool { + id.remove(invalidate_block) } #[must_use] @@ -1378,14 +1415,14 @@ impl Emulator { data: T, gen: Option u64>, exec: Option, - ) -> HookId { + ) -> EdgeHookId { unsafe { let data: u64 = data.into().0; let gen: Option u64> = core::mem::transmute(gen); let exec: Option = core::mem::transmute(exec); let num = libafl_qemu_sys::libafl_add_edge_hook(gen, exec, data); - HookId(num) + EdgeHookId(num) } } @@ -1395,7 +1432,7 @@ impl Emulator { gen: Option u64>, post_gen: Option, exec: Option, - ) -> HookId { + ) -> BlockHookId { unsafe { let data: u64 = data.into().0; let gen: Option u64> = core::mem::transmute(gen); @@ -1403,7 +1440,7 @@ impl Emulator { core::mem::transmute(post_gen); let exec: Option = core::mem::transmute(exec); let num = libafl_qemu_sys::libafl_add_block_hook(gen, post_gen, exec, data); - HookId(num) + BlockHookId(num) } } @@ -1416,7 +1453,7 @@ impl Emulator { exec4: Option, exec8: Option, exec_n: Option, - ) -> HookId { + ) -> ReadHookId { unsafe { let data: u64 = data.into().0; let gen: Option u64> = @@ -1430,7 +1467,7 @@ impl Emulator { let num = libafl_qemu_sys::libafl_add_read_hook( gen, exec1, exec2, exec4, exec8, exec_n, data, ); - HookId(num) + ReadHookId(num) } } @@ -1444,7 +1481,7 @@ impl Emulator { exec4: Option, exec8: Option, exec_n: Option, - ) -> HookId { + ) -> WriteHookId { unsafe { let data: u64 = data.into().0; let gen: Option u64> = @@ -1458,7 +1495,7 @@ impl Emulator { let num = libafl_qemu_sys::libafl_add_write_hook( gen, exec1, exec2, exec4, exec8, exec_n, data, ); - HookId(num) + WriteHookId(num) } } @@ -1470,7 +1507,7 @@ impl Emulator { exec2: Option, exec4: Option, exec8: Option, - ) -> HookId { + ) -> CmpHookId { unsafe { let data: u64 = data.into().0; let gen: Option u64> = @@ -1480,7 +1517,7 @@ impl Emulator { let exec4: Option = core::mem::transmute(exec4); let exec8: Option = core::mem::transmute(exec8); let num = libafl_qemu_sys::libafl_add_cmp_hook(gen, exec1, exec2, exec4, exec8, data); - HookId(num) + CmpHookId(num) } } @@ -1488,12 +1525,12 @@ impl Emulator { &self, data: T, callback: extern "C" fn(T, GuestAddr), - ) -> HookId { + ) -> BackdoorHookId { unsafe { let data: u64 = data.into().0; let callback: extern "C" fn(u64, GuestAddr) = core::mem::transmute(callback); let num = libafl_qemu_sys::libafl_add_backdoor_hook(Some(callback), data); - HookId(num) + BackdoorHookId(num) } } @@ -1514,7 +1551,7 @@ impl Emulator { GuestAddr, GuestAddr, ) -> SyscallHookResult, - ) -> HookId { + ) -> PreSyscallHookId { unsafe { let data: u64 = data.into().0; let callback: extern "C" fn( @@ -1530,7 +1567,7 @@ impl Emulator { GuestAddr, ) -> libafl_qemu_sys::syshook_ret = core::mem::transmute(callback); let num = libafl_qemu_sys::libafl_add_pre_syscall_hook(Some(callback), data); - HookId(num) + PreSyscallHookId(num) } } @@ -1552,7 +1589,7 @@ impl Emulator { GuestAddr, GuestAddr, ) -> GuestAddr, - ) -> HookId { + ) -> PostSyscallHookId { unsafe { let data: u64 = data.into().0; let callback: extern "C" fn( @@ -1569,7 +1606,7 @@ impl Emulator { GuestAddr, ) -> GuestAddr = core::mem::transmute(callback); let num = libafl_qemu_sys::libafl_add_post_syscall_hook(Some(callback), data); - HookId(num) + PostSyscallHookId(num) } } @@ -1578,12 +1615,12 @@ impl Emulator { &self, data: T, callback: extern "C" fn(T, tid: u32) -> bool, - ) -> HookId { + ) -> NewThreadHookId { unsafe { let data: u64 = data.into().0; let callback: extern "C" fn(u64, u32) -> bool = core::mem::transmute(callback); let num = libafl_qemu_sys::libafl_add_new_thread_hook(Some(callback), data); - HookId(num) + NewThreadHookId(num) } } diff --git a/libafl_qemu/src/hooks.rs b/libafl_qemu/src/hooks.rs index 5454431e4d..6393411659 100644 --- a/libafl_qemu/src/hooks.rs +++ b/libafl_qemu/src/hooks.rs @@ -13,9 +13,11 @@ use libafl::{executors::hooks::inprocess::inprocess_get_state, inputs::UsesInput pub use crate::emu::SyscallHookResult; use crate::{ - emu::{Emulator, FatPtr, HookId, MemAccessInfo, SKIP_EXEC_HOOK}, + emu::{Emulator, FatPtr, MemAccessInfo, SKIP_EXEC_HOOK}, helper::QemuHelperTuple, - GuestAddr, GuestUsize, + BackdoorHookId, BlockHookId, CmpHookId, EdgeHookId, GuestAddr, GuestUsize, HookId, + InstructionHookId, NewThreadHookId, PostSyscallHookId, PreSyscallHookId, ReadHookId, + WriteHookId, }; /* @@ -38,8 +40,8 @@ pub(crate) enum HookRepr { Empty, } -pub struct HookState { - id: HookId, +pub struct HookState { + id: H, gen: HookRepr, post_gen: HookRepr, execs: [HookRepr; N], @@ -153,9 +155,9 @@ macro_rules! create_wrapper { } macro_rules! create_gen_wrapper { - ($name:ident, ($($param:ident : $param_type:ty),*), $ret_type:ty, $execs:literal) => { + ($name:ident, ($($param:ident : $param_type:ty),*), $ret_type:ty, $execs:literal, $hook_id:ident) => { paste::paste! { - extern "C" fn [<$name _gen_hook_wrapper>](hook: &mut HookState<{ $execs }>, $($param: $param_type),*) -> $ret_type + extern "C" fn [<$name _gen_hook_wrapper>](hook: &mut HookState<{ $execs }, $hook_id>, $($param: $param_type),*) -> $ret_type where S: UsesInput, QT: QemuHelperTuple, @@ -183,9 +185,9 @@ macro_rules! create_gen_wrapper { } macro_rules! create_post_gen_wrapper { - ($name:ident, ($($param:ident : $param_type:ty),*), $execs:literal) => { + ($name:ident, ($($param:ident : $param_type:ty),*), $execs:literal, $hook_id:ident) => { paste::paste! { - extern "C" fn [<$name _post_gen_hook_wrapper>](hook: &mut HookState<{ $execs }>, $($param: $param_type),*) + extern "C" fn [<$name _post_gen_hook_wrapper>](hook: &mut HookState<{ $execs }, $hook_id>, $($param: $param_type),*) where S: UsesInput, QT: QemuHelperTuple, @@ -213,9 +215,9 @@ macro_rules! create_post_gen_wrapper { } macro_rules! create_exec_wrapper { - ($name:ident, ($($param:ident : $param_type:ty),*), $execidx:literal, $execs:literal) => { + ($name:ident, ($($param:ident : $param_type:ty),*), $execidx:literal, $execs:literal, $hook_id:ident) => { paste::paste! { - extern "C" fn [<$name _ $execidx _exec_hook_wrapper>](hook: &mut HookState<{ $execs }>, $($param: $param_type),*) + extern "C" fn [<$name _ $execidx _exec_hook_wrapper>](hook: &mut HookState<{ $execs }, $hook_id>, $($param: $param_type),*) where S: UsesInput, QT: QemuHelperTuple, @@ -240,13 +242,13 @@ macro_rules! create_exec_wrapper { } } -static mut GENERIC_HOOKS: Vec<(HookId, FatPtr)> = vec![]; +static mut GENERIC_HOOKS: Vec<(InstructionHookId, FatPtr)> = vec![]; create_wrapper!(generic, (pc: GuestAddr)); -static mut BACKDOOR_HOOKS: Vec<(HookId, FatPtr)> = vec![]; +static mut BACKDOOR_HOOKS: Vec<(BackdoorHookId, FatPtr)> = vec![]; create_wrapper!(backdoor, (pc: GuestAddr)); #[cfg(emulation_mode = "usermode")] -static mut PRE_SYSCALL_HOOKS: Vec<(HookId, FatPtr)> = vec![]; +static mut PRE_SYSCALL_HOOKS: Vec<(PreSyscallHookId, FatPtr)> = vec![]; #[cfg(emulation_mode = "usermode")] create_wrapper!(pre_syscall, (sys_num: i32, a0: GuestAddr, @@ -258,7 +260,7 @@ create_wrapper!(pre_syscall, (sys_num: i32, a6: GuestAddr, a7: GuestAddr), SyscallHookResult); #[cfg(emulation_mode = "usermode")] -static mut POST_SYSCALL_HOOKS: Vec<(HookId, FatPtr)> = vec![]; +static mut POST_SYSCALL_HOOKS: Vec<(PostSyscallHookId, FatPtr)> = vec![]; #[cfg(emulation_mode = "usermode")] create_wrapper!(post_syscall, (res: GuestAddr, sys_num: i32, a0: GuestAddr, @@ -270,41 +272,41 @@ create_wrapper!(post_syscall, (res: GuestAddr, sys_num: i32, a6: GuestAddr, a7: GuestAddr), GuestAddr); #[cfg(emulation_mode = "usermode")] -static mut NEW_THREAD_HOOKS: Vec<(HookId, FatPtr)> = vec![]; +static mut NEW_THREAD_HOOKS: Vec<(NewThreadHookId, FatPtr)> = vec![]; #[cfg(emulation_mode = "usermode")] create_wrapper!(new_thread, (tid: u32), bool); -static mut EDGE_HOOKS: Vec> = vec![]; -create_gen_wrapper!(edge, (src: GuestAddr, dest: GuestAddr), u64, 1); -create_exec_wrapper!(edge, (id: u64), 0, 1); +static mut EDGE_HOOKS: Vec> = vec![]; +create_gen_wrapper!(edge, (src: GuestAddr, dest: GuestAddr), u64, 1, EdgeHookId); +create_exec_wrapper!(edge, (id: u64), 0, 1, EdgeHookId); -static mut BLOCK_HOOKS: Vec> = vec![]; -create_gen_wrapper!(block, (addr: GuestAddr), u64, 1); -create_post_gen_wrapper!(block, (addr: GuestAddr, len: GuestUsize), 1); -create_exec_wrapper!(block, (id: u64), 0, 1); +static mut BLOCK_HOOKS: Vec> = vec![]; +create_gen_wrapper!(block, (addr: GuestAddr), u64, 1, BlockHookId); +create_post_gen_wrapper!(block, (addr: GuestAddr, len: GuestUsize), 1, BlockHookId); +create_exec_wrapper!(block, (id: u64), 0, 1, BlockHookId); -static mut READ_HOOKS: Vec> = vec![]; -create_gen_wrapper!(read, (pc: GuestAddr, info: MemAccessInfo), u64, 5); -create_exec_wrapper!(read, (id: u64, addr: GuestAddr), 0, 5); -create_exec_wrapper!(read, (id: u64, addr: GuestAddr), 1, 5); -create_exec_wrapper!(read, (id: u64, addr: GuestAddr), 2, 5); -create_exec_wrapper!(read, (id: u64, addr: GuestAddr), 3, 5); -create_exec_wrapper!(read, (id: u64, addr: GuestAddr, size: usize), 4, 5); +static mut READ_HOOKS: Vec> = vec![]; +create_gen_wrapper!(read, (pc: GuestAddr, info: MemAccessInfo), u64, 5, ReadHookId); +create_exec_wrapper!(read, (id: u64, addr: GuestAddr), 0, 5, ReadHookId); +create_exec_wrapper!(read, (id: u64, addr: GuestAddr), 1, 5, ReadHookId); +create_exec_wrapper!(read, (id: u64, addr: GuestAddr), 2, 5, ReadHookId); +create_exec_wrapper!(read, (id: u64, addr: GuestAddr), 3, 5, ReadHookId); +create_exec_wrapper!(read, (id: u64, addr: GuestAddr, size: usize), 4, 5, ReadHookId); -static mut WRITE_HOOKS: Vec> = vec![]; -create_gen_wrapper!(write, (pc: GuestAddr, info: MemAccessInfo), u64, 5); -create_exec_wrapper!(write, (id: u64, addr: GuestAddr), 0, 5); -create_exec_wrapper!(write, (id: u64, addr: GuestAddr), 1, 5); -create_exec_wrapper!(write, (id: u64, addr: GuestAddr), 2, 5); -create_exec_wrapper!(write, (id: u64, addr: GuestAddr), 3, 5); -create_exec_wrapper!(write, (id: u64, addr: GuestAddr, size: usize), 4, 5); +static mut WRITE_HOOKS: Vec> = vec![]; +create_gen_wrapper!(write, (pc: GuestAddr, info: MemAccessInfo), u64, 5, WriteHookId); +create_exec_wrapper!(write, (id: u64, addr: GuestAddr), 0, 5, WriteHookId); +create_exec_wrapper!(write, (id: u64, addr: GuestAddr), 1, 5, WriteHookId); +create_exec_wrapper!(write, (id: u64, addr: GuestAddr), 2, 5, WriteHookId); +create_exec_wrapper!(write, (id: u64, addr: GuestAddr), 3, 5, WriteHookId); +create_exec_wrapper!(write, (id: u64, addr: GuestAddr, size: usize), 4, 5, WriteHookId); -static mut CMP_HOOKS: Vec> = vec![]; -create_gen_wrapper!(cmp, (pc: GuestAddr, size: usize), u64, 4); -create_exec_wrapper!(cmp, (id: u64, v0: u8, v1: u8), 0, 4); -create_exec_wrapper!(cmp, (id: u64, v0: u16, v1: u16), 1, 4); -create_exec_wrapper!(cmp, (id: u64, v0: u32, v1: u32), 2, 4); -create_exec_wrapper!(cmp, (id: u64, v0: u64, v1: u64), 3, 4); +static mut CMP_HOOKS: Vec> = vec![]; +create_gen_wrapper!(cmp, (pc: GuestAddr, size: usize), u64, 4, CmpHookId); +create_exec_wrapper!(cmp, (id: u64, v0: u8, v1: u8), 0, 4, CmpHookId); +create_exec_wrapper!(cmp, (id: u64, v0: u16, v1: u16), 1, 4, CmpHookId); +create_exec_wrapper!(cmp, (id: u64, v0: u32, v1: u32), 2, 4, CmpHookId); +create_exec_wrapper!(cmp, (id: u64, v0: u64, v1: u64), 3, 4, CmpHookId); #[cfg(emulation_mode = "usermode")] static mut CRASH_HOOKS: Vec = vec![]; @@ -422,7 +424,7 @@ where extern "C" fn(*const (), pc: GuestAddr), >, invalidate_block: bool, - ) -> HookId { + ) -> InstructionHookId { match hook { Hook::Function(f) => self.instruction_function(addr, f, invalidate_block), Hook::Closure(c) => self.instruction_closure(addr, c, invalidate_block), @@ -430,7 +432,7 @@ where let z: *const () = ptr::null::<()>(); self.emulator.set_hook(z, addr, r, invalidate_block) } - Hook::Empty => HookId(0), // TODO error type + Hook::Empty => InstructionHookId(0), // TODO error type } } @@ -439,7 +441,7 @@ where addr: GuestAddr, hook: fn(&mut Self, Option<&mut S>, GuestAddr), invalidate_block: bool, - ) -> HookId { + ) -> InstructionHookId { unsafe { self.emulator.set_hook( transmute(hook), @@ -455,10 +457,10 @@ where addr: GuestAddr, hook: Box FnMut(&'a mut Self, Option<&'a mut S>, GuestAddr)>, invalidate_block: bool, - ) -> HookId { + ) -> InstructionHookId { unsafe { let fat: FatPtr = transmute(hook); - GENERIC_HOOKS.push((HookId(0), fat)); + GENERIC_HOOKS.push((InstructionHookId(0), fat)); let id = self.emulator.set_hook( &mut ((*addr_of_mut!(GENERIC_HOOKS)).last_mut().unwrap().1), addr, @@ -489,20 +491,24 @@ where Box FnMut(&'a mut Self, Option<&'a mut S>, u64)>, extern "C" fn(*const (), id: u64), >, - ) -> HookId { + ) -> EdgeHookId { unsafe { let gen = get_raw_hook!( generation_hook, edge_gen_hook_wrapper::, - extern "C" fn(&mut HookState<1>, src: GuestAddr, dest: GuestAddr) -> u64 + extern "C" fn( + &mut HookState<1, EdgeHookId>, + src: GuestAddr, + dest: GuestAddr, + ) -> u64 ); let exec = get_raw_hook!( execution_hook, edge_0_exec_hook_wrapper::, - extern "C" fn(&mut HookState<1>, id: u64) + extern "C" fn(&mut HookState<1, EdgeHookId>, id: u64) ); EDGE_HOOKS.push(HookState { - id: HookId(0), + id: EdgeHookId(0), gen: hook_to_repr!(generation_hook), post_gen: HookRepr::Empty, execs: [hook_to_repr!(execution_hook)], @@ -532,25 +538,29 @@ where Box FnMut(&'a mut Self, Option<&'a mut S>, u64)>, extern "C" fn(*const (), id: u64), >, - ) -> HookId { + ) -> BlockHookId { unsafe { let gen = get_raw_hook!( generation_hook, block_gen_hook_wrapper::, - extern "C" fn(&mut HookState<1>, pc: GuestAddr) -> u64 + extern "C" fn(&mut HookState<1, BlockHookId>, pc: GuestAddr) -> u64 ); let postgen = get_raw_hook!( post_generation_hook, block_post_gen_hook_wrapper::, - extern "C" fn(&mut HookState<1>, pc: GuestAddr, block_length: GuestUsize) + extern "C" fn( + &mut HookState<1, BlockHookId>, + pc: GuestAddr, + block_length: GuestUsize, + ) ); let exec = get_raw_hook!( execution_hook, block_0_exec_hook_wrapper::, - extern "C" fn(&mut HookState<1>, id: u64) + extern "C" fn(&mut HookState<1, BlockHookId>, id: u64) ); BLOCK_HOOKS.push(HookState { - id: HookId(0), + id: BlockHookId(0), gen: hook_to_repr!(generation_hook), post_gen: hook_to_repr!(post_generation_hook), execs: [hook_to_repr!(execution_hook)], @@ -603,40 +613,44 @@ where Box FnMut(&'a mut Self, Option<&'a mut S>, u64, GuestAddr, usize)>, extern "C" fn(*const (), id: u64, addr: GuestAddr, size: usize), >, - ) -> HookId { + ) -> ReadHookId { unsafe { let gen = get_raw_hook!( generation_hook, read_gen_hook_wrapper::, - extern "C" fn(&mut HookState<5>, pc: GuestAddr, info: MemAccessInfo) -> u64 + extern "C" fn( + &mut HookState<5, ReadHookId>, + pc: GuestAddr, + info: MemAccessInfo, + ) -> u64 ); let exec1 = get_raw_hook!( execution_hook_1, read_0_exec_hook_wrapper::, - extern "C" fn(&mut HookState<5>, id: u64, addr: GuestAddr) + extern "C" fn(&mut HookState<5, ReadHookId>, id: u64, addr: GuestAddr) ); let exec2 = get_raw_hook!( execution_hook_2, read_1_exec_hook_wrapper::, - extern "C" fn(&mut HookState<5>, id: u64, addr: GuestAddr) + extern "C" fn(&mut HookState<5, ReadHookId>, id: u64, addr: GuestAddr) ); let exec4 = get_raw_hook!( execution_hook_4, read_2_exec_hook_wrapper::, - extern "C" fn(&mut HookState<5>, id: u64, addr: GuestAddr) + extern "C" fn(&mut HookState<5, ReadHookId>, id: u64, addr: GuestAddr) ); let exec8 = get_raw_hook!( execution_hook_8, read_3_exec_hook_wrapper::, - extern "C" fn(&mut HookState<5>, id: u64, addr: GuestAddr) + extern "C" fn(&mut HookState<5, ReadHookId>, id: u64, addr: GuestAddr) ); let execn = get_raw_hook!( execution_hook_n, read_4_exec_hook_wrapper::, - extern "C" fn(&mut HookState<5>, id: u64, addr: GuestAddr, size: usize) + extern "C" fn(&mut HookState<5, ReadHookId>, id: u64, addr: GuestAddr, size: usize) ); READ_HOOKS.push(HookState { - id: HookId(0), + id: ReadHookId(0), gen: hook_to_repr!(generation_hook), post_gen: HookRepr::Empty, execs: [ @@ -701,40 +715,49 @@ where Box FnMut(&'a mut Self, Option<&'a mut S>, u64, GuestAddr, usize)>, extern "C" fn(*const (), id: u64, addr: GuestAddr, size: usize), >, - ) -> HookId { + ) -> WriteHookId { unsafe { let gen = get_raw_hook!( generation_hook, write_gen_hook_wrapper::, - extern "C" fn(&mut HookState<5>, pc: GuestAddr, info: MemAccessInfo) -> u64 + extern "C" fn( + &mut HookState<5, WriteHookId>, + pc: GuestAddr, + info: MemAccessInfo, + ) -> u64 ); let exec1 = get_raw_hook!( execution_hook_1, write_0_exec_hook_wrapper::, - extern "C" fn(&mut HookState<5>, id: u64, addr: GuestAddr) + extern "C" fn(&mut HookState<5, WriteHookId>, id: u64, addr: GuestAddr) ); let exec2 = get_raw_hook!( execution_hook_2, write_1_exec_hook_wrapper::, - extern "C" fn(&mut HookState<5>, id: u64, addr: GuestAddr) + extern "C" fn(&mut HookState<5, WriteHookId>, id: u64, addr: GuestAddr) ); let exec4 = get_raw_hook!( execution_hook_4, write_2_exec_hook_wrapper::, - extern "C" fn(&mut HookState<5>, id: u64, addr: GuestAddr) + extern "C" fn(&mut HookState<5, WriteHookId>, id: u64, addr: GuestAddr) ); let exec8 = get_raw_hook!( execution_hook_8, write_3_exec_hook_wrapper::, - extern "C" fn(&mut HookState<5>, id: u64, addr: GuestAddr) + extern "C" fn(&mut HookState<5, WriteHookId>, id: u64, addr: GuestAddr) ); let execn = get_raw_hook!( execution_hook_n, write_4_exec_hook_wrapper::, - extern "C" fn(&mut HookState<5>, id: u64, addr: GuestAddr, size: usize) + extern "C" fn( + &mut HookState<5, WriteHookId>, + id: u64, + addr: GuestAddr, + size: usize, + ) ); WRITE_HOOKS.push(HookState { - id: HookId(0), + id: WriteHookId(0), gen: hook_to_repr!(generation_hook), post_gen: HookRepr::Empty, execs: [ @@ -788,35 +811,35 @@ where Box FnMut(&'a mut Self, Option<&'a mut S>, u64, u64, u64)>, extern "C" fn(*const (), id: u64, v0: u64, v1: u64), >, - ) -> HookId { + ) -> CmpHookId { unsafe { let gen = get_raw_hook!( generation_hook, cmp_gen_hook_wrapper::, - extern "C" fn(&mut HookState<4>, pc: GuestAddr, size: usize) -> u64 + extern "C" fn(&mut HookState<4, CmpHookId>, pc: GuestAddr, size: usize) -> u64 ); let exec1 = get_raw_hook!( execution_hook_1, cmp_0_exec_hook_wrapper::, - extern "C" fn(&mut HookState<4>, id: u64, v0: u8, v1: u8) + extern "C" fn(&mut HookState<4, CmpHookId>, id: u64, v0: u8, v1: u8) ); let exec2 = get_raw_hook!( execution_hook_2, cmp_1_exec_hook_wrapper::, - extern "C" fn(&mut HookState<4>, id: u64, v0: u16, v1: u16) + extern "C" fn(&mut HookState<4, CmpHookId>, id: u64, v0: u16, v1: u16) ); let exec4 = get_raw_hook!( execution_hook_4, cmp_2_exec_hook_wrapper::, - extern "C" fn(&mut HookState<4>, id: u64, v0: u32, v1: u32) + extern "C" fn(&mut HookState<4, CmpHookId>, id: u64, v0: u32, v1: u32) ); let exec8 = get_raw_hook!( execution_hook_8, cmp_3_exec_hook_wrapper::, - extern "C" fn(&mut HookState<4>, id: u64, v0: u64, v1: u64) + extern "C" fn(&mut HookState<4, CmpHookId>, id: u64, v0: u64, v1: u64) ); CMP_HOOKS.push(HookState { - id: HookId(0), + id: CmpHookId(0), gen: hook_to_repr!(generation_hook), post_gen: HookRepr::Empty, execs: [ @@ -846,7 +869,7 @@ where Box FnMut(&'a mut Self, Option<&'a mut S>, GuestAddr)>, extern "C" fn(*const (), pc: GuestAddr), >, - ) -> HookId { + ) -> BackdoorHookId { match hook { Hook::Function(f) => self.backdoor_function(f), Hook::Closure(c) => self.backdoor_closure(c), @@ -854,11 +877,14 @@ where let z: *const () = ptr::null::<()>(); self.emulator.add_backdoor_hook(z, r) } - Hook::Empty => HookId(0), // TODO error type + Hook::Empty => BackdoorHookId(0), // TODO error type } } - pub fn backdoor_function(&self, hook: fn(&mut Self, Option<&mut S>, pc: GuestAddr)) -> HookId { + pub fn backdoor_function( + &self, + hook: fn(&mut Self, Option<&mut S>, pc: GuestAddr), + ) -> BackdoorHookId { unsafe { self.emulator .add_backdoor_hook(transmute(hook), func_backdoor_hook_wrapper::) @@ -868,10 +894,10 @@ where pub fn backdoor_closure( &self, hook: Box FnMut(&'a mut Self, Option<&'a mut S>, GuestAddr)>, - ) -> HookId { + ) -> BackdoorHookId { unsafe { let fat: FatPtr = transmute(hook); - BACKDOOR_HOOKS.push((HookId(0), fat)); + BACKDOOR_HOOKS.push((BackdoorHookId(0), fat)); let id = self.emulator.add_backdoor_hook( &mut ((*addr_of_mut!(BACKDOOR_HOOKS)).last_mut().unwrap().1), closure_backdoor_hook_wrapper::, @@ -927,7 +953,7 @@ where GuestAddr, ) -> SyscallHookResult, >, - ) -> HookId { + ) -> PreSyscallHookId { match hook { Hook::Function(f) => self.syscalls_function(f), Hook::Closure(c) => self.syscalls_closure(c), @@ -935,7 +961,7 @@ where let z: *const () = ptr::null::<()>(); self.emulator.add_pre_syscall_hook(z, r) } - Hook::Empty => HookId(0), // TODO error type + Hook::Empty => PreSyscallHookId(0), // TODO error type } } @@ -956,7 +982,7 @@ where a6: GuestAddr, a7: GuestAddr, ) -> SyscallHookResult, - ) -> HookId { + ) -> PreSyscallHookId { unsafe { self.emulator .add_pre_syscall_hook(transmute(hook), func_pre_syscall_hook_wrapper::) @@ -982,10 +1008,10 @@ where GuestAddr, ) -> SyscallHookResult, >, - ) -> HookId { + ) -> PreSyscallHookId { unsafe { let fat: FatPtr = transmute(hook); - PRE_SYSCALL_HOOKS.push((HookId(0), fat)); + PRE_SYSCALL_HOOKS.push((PreSyscallHookId(0), fat)); let id = self.emulator.add_pre_syscall_hook( &mut ((*addr_of_mut!(PRE_SYSCALL_HOOKS)).last_mut().unwrap().1), closure_pre_syscall_hook_wrapper::, @@ -1044,7 +1070,7 @@ where GuestAddr, ) -> GuestAddr, >, - ) -> HookId { + ) -> PostSyscallHookId { match hook { Hook::Function(f) => self.after_syscalls_function(f), Hook::Closure(c) => self.after_syscalls_closure(c), @@ -1052,7 +1078,7 @@ where let z: *const () = ptr::null::<()>(); self.emulator.add_post_syscall_hook(z, r) } - Hook::Empty => HookId(0), // TODO error type + Hook::Empty => PostSyscallHookId(0), // TODO error type } } @@ -1074,7 +1100,7 @@ where a6: GuestAddr, a7: GuestAddr, ) -> GuestAddr, - ) -> HookId { + ) -> PostSyscallHookId { unsafe { self.emulator .add_post_syscall_hook(transmute(hook), func_post_syscall_hook_wrapper::) @@ -1101,10 +1127,10 @@ where GuestAddr, ) -> GuestAddr, >, - ) -> HookId { + ) -> PostSyscallHookId { unsafe { let fat: FatPtr = transmute(hook); - POST_SYSCALL_HOOKS.push((HookId(0), fat)); + POST_SYSCALL_HOOKS.push((PostSyscallHookId(0), fat)); let id = self.emulator.add_post_syscall_hook( &mut ((*addr_of_mut!(POST_SYSCALL_HOOKS)).last_mut().unwrap().1), closure_post_syscall_hook_wrapper::, @@ -1122,7 +1148,7 @@ where Box FnMut(&'a mut Self, Option<&'a mut S>, u32) -> bool>, extern "C" fn(*const (), tid: u32) -> bool, >, - ) -> HookId { + ) -> NewThreadHookId { match hook { Hook::Function(f) => self.thread_creation_function(f), Hook::Closure(c) => self.thread_creation_closure(c), @@ -1130,7 +1156,7 @@ where let z: *const () = ptr::null::<()>(); self.emulator.add_new_thread_hook(z, r) } - Hook::Empty => HookId(0), // TODO error type + Hook::Empty => NewThreadHookId(0), // TODO error type } } @@ -1138,7 +1164,7 @@ where pub fn thread_creation_function( &self, hook: fn(&mut Self, Option<&mut S>, tid: u32) -> bool, - ) -> HookId { + ) -> NewThreadHookId { unsafe { self.emulator .add_new_thread_hook(transmute(hook), func_new_thread_hook_wrapper::) @@ -1149,10 +1175,10 @@ where pub fn thread_creation_closure( &self, hook: Box FnMut(&'a mut Self, Option<&'a mut S>, u32) -> bool>, - ) -> HookId { + ) -> NewThreadHookId { unsafe { let fat: FatPtr = transmute(hook); - NEW_THREAD_HOOKS.push((HookId(0), fat)); + NEW_THREAD_HOOKS.push((NewThreadHookId(0), fat)); let id = self.emulator.add_new_thread_hook( &mut (*addr_of_mut!(NEW_THREAD_HOOKS)).last_mut().unwrap().1, closure_new_thread_hook_wrapper::,