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 <andreafioraldi@gmail.com>
This commit is contained in:
parent
13dd1cc4ec
commit
c96d103b37
@ -832,8 +832,45 @@ impl CPU {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
pub trait HookId {
|
||||||
pub struct HookId(pub(crate) usize);
|
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;
|
use std::pin::Pin;
|
||||||
|
|
||||||
@ -1347,7 +1384,7 @@ impl Emulator {
|
|||||||
addr: GuestAddr,
|
addr: GuestAddr,
|
||||||
callback: extern "C" fn(T, GuestAddr),
|
callback: extern "C" fn(T, GuestAddr),
|
||||||
invalidate_block: bool,
|
invalidate_block: bool,
|
||||||
) -> HookId {
|
) -> InstructionHookId {
|
||||||
unsafe {
|
unsafe {
|
||||||
let data: u64 = data.into().0;
|
let data: u64 = data.into().0;
|
||||||
let callback: extern "C" fn(u64, GuestAddr) = core::mem::transmute(callback);
|
let callback: extern "C" fn(u64, GuestAddr) = core::mem::transmute(callback);
|
||||||
@ -1357,13 +1394,13 @@ impl Emulator {
|
|||||||
data,
|
data,
|
||||||
i32::from(invalidate_block),
|
i32::from(invalidate_block),
|
||||||
);
|
);
|
||||||
HookId(num)
|
InstructionHookId(num)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn remove_hook(&self, id: HookId, invalidate_block: bool) -> bool {
|
pub fn remove_hook(&self, id: impl HookId, invalidate_block: bool) -> bool {
|
||||||
unsafe { libafl_qemu_sys::libafl_qemu_remove_hook(id.0, i32::from(invalidate_block)) != 0 }
|
id.remove(invalidate_block)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
@ -1378,14 +1415,14 @@ impl Emulator {
|
|||||||
data: T,
|
data: T,
|
||||||
gen: Option<extern "C" fn(T, GuestAddr, GuestAddr) -> u64>,
|
gen: Option<extern "C" fn(T, GuestAddr, GuestAddr) -> u64>,
|
||||||
exec: Option<extern "C" fn(T, u64)>,
|
exec: Option<extern "C" fn(T, u64)>,
|
||||||
) -> HookId {
|
) -> EdgeHookId {
|
||||||
unsafe {
|
unsafe {
|
||||||
let data: u64 = data.into().0;
|
let data: u64 = data.into().0;
|
||||||
let gen: Option<extern "C" fn(u64, GuestAddr, GuestAddr) -> u64> =
|
let gen: Option<extern "C" fn(u64, GuestAddr, GuestAddr) -> u64> =
|
||||||
core::mem::transmute(gen);
|
core::mem::transmute(gen);
|
||||||
let exec: Option<extern "C" fn(u64, u64)> = core::mem::transmute(exec);
|
let exec: Option<extern "C" fn(u64, u64)> = core::mem::transmute(exec);
|
||||||
let num = libafl_qemu_sys::libafl_add_edge_hook(gen, exec, data);
|
let num = libafl_qemu_sys::libafl_add_edge_hook(gen, exec, data);
|
||||||
HookId(num)
|
EdgeHookId(num)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1395,7 +1432,7 @@ impl Emulator {
|
|||||||
gen: Option<extern "C" fn(T, GuestAddr) -> u64>,
|
gen: Option<extern "C" fn(T, GuestAddr) -> u64>,
|
||||||
post_gen: Option<extern "C" fn(T, GuestAddr, GuestUsize)>,
|
post_gen: Option<extern "C" fn(T, GuestAddr, GuestUsize)>,
|
||||||
exec: Option<extern "C" fn(T, u64)>,
|
exec: Option<extern "C" fn(T, u64)>,
|
||||||
) -> HookId {
|
) -> BlockHookId {
|
||||||
unsafe {
|
unsafe {
|
||||||
let data: u64 = data.into().0;
|
let data: u64 = data.into().0;
|
||||||
let gen: Option<extern "C" fn(u64, GuestAddr) -> u64> = core::mem::transmute(gen);
|
let gen: Option<extern "C" fn(u64, GuestAddr) -> u64> = core::mem::transmute(gen);
|
||||||
@ -1403,7 +1440,7 @@ impl Emulator {
|
|||||||
core::mem::transmute(post_gen);
|
core::mem::transmute(post_gen);
|
||||||
let exec: Option<extern "C" fn(u64, u64)> = core::mem::transmute(exec);
|
let exec: Option<extern "C" fn(u64, u64)> = core::mem::transmute(exec);
|
||||||
let num = libafl_qemu_sys::libafl_add_block_hook(gen, post_gen, exec, data);
|
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<extern "C" fn(T, u64, GuestAddr)>,
|
exec4: Option<extern "C" fn(T, u64, GuestAddr)>,
|
||||||
exec8: Option<extern "C" fn(T, u64, GuestAddr)>,
|
exec8: Option<extern "C" fn(T, u64, GuestAddr)>,
|
||||||
exec_n: Option<extern "C" fn(T, u64, GuestAddr, usize)>,
|
exec_n: Option<extern "C" fn(T, u64, GuestAddr, usize)>,
|
||||||
) -> HookId {
|
) -> ReadHookId {
|
||||||
unsafe {
|
unsafe {
|
||||||
let data: u64 = data.into().0;
|
let data: u64 = data.into().0;
|
||||||
let gen: Option<extern "C" fn(u64, GuestAddr, libafl_qemu_sys::MemOpIdx) -> u64> =
|
let gen: Option<extern "C" fn(u64, GuestAddr, libafl_qemu_sys::MemOpIdx) -> u64> =
|
||||||
@ -1430,7 +1467,7 @@ impl Emulator {
|
|||||||
let num = libafl_qemu_sys::libafl_add_read_hook(
|
let num = libafl_qemu_sys::libafl_add_read_hook(
|
||||||
gen, exec1, exec2, exec4, exec8, exec_n, data,
|
gen, exec1, exec2, exec4, exec8, exec_n, data,
|
||||||
);
|
);
|
||||||
HookId(num)
|
ReadHookId(num)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1444,7 +1481,7 @@ impl Emulator {
|
|||||||
exec4: Option<extern "C" fn(T, u64, GuestAddr)>,
|
exec4: Option<extern "C" fn(T, u64, GuestAddr)>,
|
||||||
exec8: Option<extern "C" fn(T, u64, GuestAddr)>,
|
exec8: Option<extern "C" fn(T, u64, GuestAddr)>,
|
||||||
exec_n: Option<extern "C" fn(T, u64, GuestAddr, usize)>,
|
exec_n: Option<extern "C" fn(T, u64, GuestAddr, usize)>,
|
||||||
) -> HookId {
|
) -> WriteHookId {
|
||||||
unsafe {
|
unsafe {
|
||||||
let data: u64 = data.into().0;
|
let data: u64 = data.into().0;
|
||||||
let gen: Option<extern "C" fn(u64, GuestAddr, libafl_qemu_sys::MemOpIdx) -> u64> =
|
let gen: Option<extern "C" fn(u64, GuestAddr, libafl_qemu_sys::MemOpIdx) -> u64> =
|
||||||
@ -1458,7 +1495,7 @@ impl Emulator {
|
|||||||
let num = libafl_qemu_sys::libafl_add_write_hook(
|
let num = libafl_qemu_sys::libafl_add_write_hook(
|
||||||
gen, exec1, exec2, exec4, exec8, exec_n, data,
|
gen, exec1, exec2, exec4, exec8, exec_n, data,
|
||||||
);
|
);
|
||||||
HookId(num)
|
WriteHookId(num)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1470,7 +1507,7 @@ impl Emulator {
|
|||||||
exec2: Option<extern "C" fn(T, u64, u16, u16)>,
|
exec2: Option<extern "C" fn(T, u64, u16, u16)>,
|
||||||
exec4: Option<extern "C" fn(T, u64, u32, u32)>,
|
exec4: Option<extern "C" fn(T, u64, u32, u32)>,
|
||||||
exec8: Option<extern "C" fn(T, u64, u64, u64)>,
|
exec8: Option<extern "C" fn(T, u64, u64, u64)>,
|
||||||
) -> HookId {
|
) -> CmpHookId {
|
||||||
unsafe {
|
unsafe {
|
||||||
let data: u64 = data.into().0;
|
let data: u64 = data.into().0;
|
||||||
let gen: Option<extern "C" fn(u64, GuestAddr, usize) -> u64> =
|
let gen: Option<extern "C" fn(u64, GuestAddr, usize) -> u64> =
|
||||||
@ -1480,7 +1517,7 @@ impl Emulator {
|
|||||||
let exec4: Option<extern "C" fn(u64, u64, u32, u32)> = core::mem::transmute(exec4);
|
let exec4: Option<extern "C" fn(u64, u64, u32, u32)> = core::mem::transmute(exec4);
|
||||||
let exec8: Option<extern "C" fn(u64, u64, u64, u64)> = core::mem::transmute(exec8);
|
let exec8: Option<extern "C" fn(u64, u64, u64, u64)> = core::mem::transmute(exec8);
|
||||||
let num = libafl_qemu_sys::libafl_add_cmp_hook(gen, exec1, exec2, exec4, exec8, data);
|
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,
|
&self,
|
||||||
data: T,
|
data: T,
|
||||||
callback: extern "C" fn(T, GuestAddr),
|
callback: extern "C" fn(T, GuestAddr),
|
||||||
) -> HookId {
|
) -> BackdoorHookId {
|
||||||
unsafe {
|
unsafe {
|
||||||
let data: u64 = data.into().0;
|
let data: u64 = data.into().0;
|
||||||
let callback: extern "C" fn(u64, GuestAddr) = core::mem::transmute(callback);
|
let callback: extern "C" fn(u64, GuestAddr) = core::mem::transmute(callback);
|
||||||
let num = libafl_qemu_sys::libafl_add_backdoor_hook(Some(callback), data);
|
let num = libafl_qemu_sys::libafl_add_backdoor_hook(Some(callback), data);
|
||||||
HookId(num)
|
BackdoorHookId(num)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1514,7 +1551,7 @@ impl Emulator {
|
|||||||
GuestAddr,
|
GuestAddr,
|
||||||
GuestAddr,
|
GuestAddr,
|
||||||
) -> SyscallHookResult,
|
) -> SyscallHookResult,
|
||||||
) -> HookId {
|
) -> PreSyscallHookId {
|
||||||
unsafe {
|
unsafe {
|
||||||
let data: u64 = data.into().0;
|
let data: u64 = data.into().0;
|
||||||
let callback: extern "C" fn(
|
let callback: extern "C" fn(
|
||||||
@ -1530,7 +1567,7 @@ impl Emulator {
|
|||||||
GuestAddr,
|
GuestAddr,
|
||||||
) -> libafl_qemu_sys::syshook_ret = core::mem::transmute(callback);
|
) -> libafl_qemu_sys::syshook_ret = core::mem::transmute(callback);
|
||||||
let num = libafl_qemu_sys::libafl_add_pre_syscall_hook(Some(callback), data);
|
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,
|
GuestAddr,
|
||||||
) -> GuestAddr,
|
) -> GuestAddr,
|
||||||
) -> HookId {
|
) -> PostSyscallHookId {
|
||||||
unsafe {
|
unsafe {
|
||||||
let data: u64 = data.into().0;
|
let data: u64 = data.into().0;
|
||||||
let callback: extern "C" fn(
|
let callback: extern "C" fn(
|
||||||
@ -1569,7 +1606,7 @@ impl Emulator {
|
|||||||
GuestAddr,
|
GuestAddr,
|
||||||
) -> GuestAddr = core::mem::transmute(callback);
|
) -> GuestAddr = core::mem::transmute(callback);
|
||||||
let num = libafl_qemu_sys::libafl_add_post_syscall_hook(Some(callback), data);
|
let num = libafl_qemu_sys::libafl_add_post_syscall_hook(Some(callback), data);
|
||||||
HookId(num)
|
PostSyscallHookId(num)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1578,12 +1615,12 @@ impl Emulator {
|
|||||||
&self,
|
&self,
|
||||||
data: T,
|
data: T,
|
||||||
callback: extern "C" fn(T, tid: u32) -> bool,
|
callback: extern "C" fn(T, tid: u32) -> bool,
|
||||||
) -> HookId {
|
) -> NewThreadHookId {
|
||||||
unsafe {
|
unsafe {
|
||||||
let data: u64 = data.into().0;
|
let data: u64 = data.into().0;
|
||||||
let callback: extern "C" fn(u64, u32) -> bool = core::mem::transmute(callback);
|
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);
|
let num = libafl_qemu_sys::libafl_add_new_thread_hook(Some(callback), data);
|
||||||
HookId(num)
|
NewThreadHookId(num)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,9 +13,11 @@ use libafl::{executors::hooks::inprocess::inprocess_get_state, inputs::UsesInput
|
|||||||
|
|
||||||
pub use crate::emu::SyscallHookResult;
|
pub use crate::emu::SyscallHookResult;
|
||||||
use crate::{
|
use crate::{
|
||||||
emu::{Emulator, FatPtr, HookId, MemAccessInfo, SKIP_EXEC_HOOK},
|
emu::{Emulator, FatPtr, MemAccessInfo, SKIP_EXEC_HOOK},
|
||||||
helper::QemuHelperTuple,
|
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,
|
Empty,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct HookState<const N: usize> {
|
pub struct HookState<const N: usize, H: HookId> {
|
||||||
id: HookId,
|
id: H,
|
||||||
gen: HookRepr,
|
gen: HookRepr,
|
||||||
post_gen: HookRepr,
|
post_gen: HookRepr,
|
||||||
execs: [HookRepr; N],
|
execs: [HookRepr; N],
|
||||||
@ -153,9 +155,9 @@ macro_rules! create_wrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! create_gen_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! {
|
paste::paste! {
|
||||||
extern "C" fn [<$name _gen_hook_wrapper>]<QT, S>(hook: &mut HookState<{ $execs }>, $($param: $param_type),*) -> $ret_type
|
extern "C" fn [<$name _gen_hook_wrapper>]<QT, S>(hook: &mut HookState<{ $execs }, $hook_id>, $($param: $param_type),*) -> $ret_type
|
||||||
where
|
where
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
QT: QemuHelperTuple<S>,
|
QT: QemuHelperTuple<S>,
|
||||||
@ -183,9 +185,9 @@ macro_rules! create_gen_wrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! create_post_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! {
|
paste::paste! {
|
||||||
extern "C" fn [<$name _post_gen_hook_wrapper>]<QT, S>(hook: &mut HookState<{ $execs }>, $($param: $param_type),*)
|
extern "C" fn [<$name _post_gen_hook_wrapper>]<QT, S>(hook: &mut HookState<{ $execs }, $hook_id>, $($param: $param_type),*)
|
||||||
where
|
where
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
QT: QemuHelperTuple<S>,
|
QT: QemuHelperTuple<S>,
|
||||||
@ -213,9 +215,9 @@ macro_rules! create_post_gen_wrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! create_exec_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! {
|
paste::paste! {
|
||||||
extern "C" fn [<$name _ $execidx _exec_hook_wrapper>]<QT, S>(hook: &mut HookState<{ $execs }>, $($param: $param_type),*)
|
extern "C" fn [<$name _ $execidx _exec_hook_wrapper>]<QT, S>(hook: &mut HookState<{ $execs }, $hook_id>, $($param: $param_type),*)
|
||||||
where
|
where
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
QT: QemuHelperTuple<S>,
|
QT: QemuHelperTuple<S>,
|
||||||
@ -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));
|
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));
|
create_wrapper!(backdoor, (pc: GuestAddr));
|
||||||
|
|
||||||
#[cfg(emulation_mode = "usermode")]
|
#[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")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
create_wrapper!(pre_syscall, (sys_num: i32,
|
create_wrapper!(pre_syscall, (sys_num: i32,
|
||||||
a0: GuestAddr,
|
a0: GuestAddr,
|
||||||
@ -258,7 +260,7 @@ create_wrapper!(pre_syscall, (sys_num: i32,
|
|||||||
a6: GuestAddr,
|
a6: GuestAddr,
|
||||||
a7: GuestAddr), SyscallHookResult);
|
a7: GuestAddr), SyscallHookResult);
|
||||||
#[cfg(emulation_mode = "usermode")]
|
#[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")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
create_wrapper!(post_syscall, (res: GuestAddr, sys_num: i32,
|
create_wrapper!(post_syscall, (res: GuestAddr, sys_num: i32,
|
||||||
a0: GuestAddr,
|
a0: GuestAddr,
|
||||||
@ -270,41 +272,41 @@ create_wrapper!(post_syscall, (res: GuestAddr, sys_num: i32,
|
|||||||
a6: GuestAddr,
|
a6: GuestAddr,
|
||||||
a7: GuestAddr), GuestAddr);
|
a7: GuestAddr), GuestAddr);
|
||||||
#[cfg(emulation_mode = "usermode")]
|
#[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")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
create_wrapper!(new_thread, (tid: u32), bool);
|
create_wrapper!(new_thread, (tid: u32), bool);
|
||||||
|
|
||||||
static mut EDGE_HOOKS: Vec<HookState<1>> = vec![];
|
static mut EDGE_HOOKS: Vec<HookState<1, EdgeHookId>> = vec![];
|
||||||
create_gen_wrapper!(edge, (src: GuestAddr, dest: GuestAddr), u64, 1);
|
create_gen_wrapper!(edge, (src: GuestAddr, dest: GuestAddr), u64, 1, EdgeHookId);
|
||||||
create_exec_wrapper!(edge, (id: u64), 0, 1);
|
create_exec_wrapper!(edge, (id: u64), 0, 1, EdgeHookId);
|
||||||
|
|
||||||
static mut BLOCK_HOOKS: Vec<HookState<1>> = vec![];
|
static mut BLOCK_HOOKS: Vec<HookState<1, BlockHookId>> = vec![];
|
||||||
create_gen_wrapper!(block, (addr: GuestAddr), u64, 1);
|
create_gen_wrapper!(block, (addr: GuestAddr), u64, 1, BlockHookId);
|
||||||
create_post_gen_wrapper!(block, (addr: GuestAddr, len: GuestUsize), 1);
|
create_post_gen_wrapper!(block, (addr: GuestAddr, len: GuestUsize), 1, BlockHookId);
|
||||||
create_exec_wrapper!(block, (id: u64), 0, 1);
|
create_exec_wrapper!(block, (id: u64), 0, 1, BlockHookId);
|
||||||
|
|
||||||
static mut READ_HOOKS: Vec<HookState<5>> = vec![];
|
static mut READ_HOOKS: Vec<HookState<5, ReadHookId>> = vec![];
|
||||||
create_gen_wrapper!(read, (pc: GuestAddr, info: MemAccessInfo), u64, 5);
|
create_gen_wrapper!(read, (pc: GuestAddr, info: MemAccessInfo), u64, 5, ReadHookId);
|
||||||
create_exec_wrapper!(read, (id: u64, addr: GuestAddr), 0, 5);
|
create_exec_wrapper!(read, (id: u64, addr: GuestAddr), 0, 5, ReadHookId);
|
||||||
create_exec_wrapper!(read, (id: u64, addr: GuestAddr), 1, 5);
|
create_exec_wrapper!(read, (id: u64, addr: GuestAddr), 1, 5, ReadHookId);
|
||||||
create_exec_wrapper!(read, (id: u64, addr: GuestAddr), 2, 5);
|
create_exec_wrapper!(read, (id: u64, addr: GuestAddr), 2, 5, ReadHookId);
|
||||||
create_exec_wrapper!(read, (id: u64, addr: GuestAddr), 3, 5);
|
create_exec_wrapper!(read, (id: u64, addr: GuestAddr), 3, 5, ReadHookId);
|
||||||
create_exec_wrapper!(read, (id: u64, addr: GuestAddr, size: usize), 4, 5);
|
create_exec_wrapper!(read, (id: u64, addr: GuestAddr, size: usize), 4, 5, ReadHookId);
|
||||||
|
|
||||||
static mut WRITE_HOOKS: Vec<HookState<5>> = vec![];
|
static mut WRITE_HOOKS: Vec<HookState<5, WriteHookId>> = vec![];
|
||||||
create_gen_wrapper!(write, (pc: GuestAddr, info: MemAccessInfo), u64, 5);
|
create_gen_wrapper!(write, (pc: GuestAddr, info: MemAccessInfo), u64, 5, WriteHookId);
|
||||||
create_exec_wrapper!(write, (id: u64, addr: GuestAddr), 0, 5);
|
create_exec_wrapper!(write, (id: u64, addr: GuestAddr), 0, 5, WriteHookId);
|
||||||
create_exec_wrapper!(write, (id: u64, addr: GuestAddr), 1, 5);
|
create_exec_wrapper!(write, (id: u64, addr: GuestAddr), 1, 5, WriteHookId);
|
||||||
create_exec_wrapper!(write, (id: u64, addr: GuestAddr), 2, 5);
|
create_exec_wrapper!(write, (id: u64, addr: GuestAddr), 2, 5, WriteHookId);
|
||||||
create_exec_wrapper!(write, (id: u64, addr: GuestAddr), 3, 5);
|
create_exec_wrapper!(write, (id: u64, addr: GuestAddr), 3, 5, WriteHookId);
|
||||||
create_exec_wrapper!(write, (id: u64, addr: GuestAddr, size: usize), 4, 5);
|
create_exec_wrapper!(write, (id: u64, addr: GuestAddr, size: usize), 4, 5, WriteHookId);
|
||||||
|
|
||||||
static mut CMP_HOOKS: Vec<HookState<4>> = vec![];
|
static mut CMP_HOOKS: Vec<HookState<4, CmpHookId>> = vec![];
|
||||||
create_gen_wrapper!(cmp, (pc: GuestAddr, size: usize), u64, 4);
|
create_gen_wrapper!(cmp, (pc: GuestAddr, size: usize), u64, 4, CmpHookId);
|
||||||
create_exec_wrapper!(cmp, (id: u64, v0: u8, v1: u8), 0, 4);
|
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);
|
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);
|
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);
|
create_exec_wrapper!(cmp, (id: u64, v0: u64, v1: u64), 3, 4, CmpHookId);
|
||||||
|
|
||||||
#[cfg(emulation_mode = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
static mut CRASH_HOOKS: Vec<HookRepr> = vec![];
|
static mut CRASH_HOOKS: Vec<HookRepr> = vec![];
|
||||||
@ -422,7 +424,7 @@ where
|
|||||||
extern "C" fn(*const (), pc: GuestAddr),
|
extern "C" fn(*const (), pc: GuestAddr),
|
||||||
>,
|
>,
|
||||||
invalidate_block: bool,
|
invalidate_block: bool,
|
||||||
) -> HookId {
|
) -> InstructionHookId {
|
||||||
match hook {
|
match hook {
|
||||||
Hook::Function(f) => self.instruction_function(addr, f, invalidate_block),
|
Hook::Function(f) => self.instruction_function(addr, f, invalidate_block),
|
||||||
Hook::Closure(c) => self.instruction_closure(addr, c, invalidate_block),
|
Hook::Closure(c) => self.instruction_closure(addr, c, invalidate_block),
|
||||||
@ -430,7 +432,7 @@ where
|
|||||||
let z: *const () = ptr::null::<()>();
|
let z: *const () = ptr::null::<()>();
|
||||||
self.emulator.set_hook(z, addr, r, invalidate_block)
|
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,
|
addr: GuestAddr,
|
||||||
hook: fn(&mut Self, Option<&mut S>, GuestAddr),
|
hook: fn(&mut Self, Option<&mut S>, GuestAddr),
|
||||||
invalidate_block: bool,
|
invalidate_block: bool,
|
||||||
) -> HookId {
|
) -> InstructionHookId {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.emulator.set_hook(
|
self.emulator.set_hook(
|
||||||
transmute(hook),
|
transmute(hook),
|
||||||
@ -455,10 +457,10 @@ where
|
|||||||
addr: GuestAddr,
|
addr: GuestAddr,
|
||||||
hook: Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, GuestAddr)>,
|
hook: Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, GuestAddr)>,
|
||||||
invalidate_block: bool,
|
invalidate_block: bool,
|
||||||
) -> HookId {
|
) -> InstructionHookId {
|
||||||
unsafe {
|
unsafe {
|
||||||
let fat: FatPtr = transmute(hook);
|
let fat: FatPtr = transmute(hook);
|
||||||
GENERIC_HOOKS.push((HookId(0), fat));
|
GENERIC_HOOKS.push((InstructionHookId(0), fat));
|
||||||
let id = self.emulator.set_hook(
|
let id = self.emulator.set_hook(
|
||||||
&mut ((*addr_of_mut!(GENERIC_HOOKS)).last_mut().unwrap().1),
|
&mut ((*addr_of_mut!(GENERIC_HOOKS)).last_mut().unwrap().1),
|
||||||
addr,
|
addr,
|
||||||
@ -489,20 +491,24 @@ where
|
|||||||
Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u64)>,
|
Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u64)>,
|
||||||
extern "C" fn(*const (), id: u64),
|
extern "C" fn(*const (), id: u64),
|
||||||
>,
|
>,
|
||||||
) -> HookId {
|
) -> EdgeHookId {
|
||||||
unsafe {
|
unsafe {
|
||||||
let gen = get_raw_hook!(
|
let gen = get_raw_hook!(
|
||||||
generation_hook,
|
generation_hook,
|
||||||
edge_gen_hook_wrapper::<QT, S>,
|
edge_gen_hook_wrapper::<QT, S>,
|
||||||
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!(
|
let exec = get_raw_hook!(
|
||||||
execution_hook,
|
execution_hook,
|
||||||
edge_0_exec_hook_wrapper::<QT, S>,
|
edge_0_exec_hook_wrapper::<QT, S>,
|
||||||
extern "C" fn(&mut HookState<1>, id: u64)
|
extern "C" fn(&mut HookState<1, EdgeHookId>, id: u64)
|
||||||
);
|
);
|
||||||
EDGE_HOOKS.push(HookState {
|
EDGE_HOOKS.push(HookState {
|
||||||
id: HookId(0),
|
id: EdgeHookId(0),
|
||||||
gen: hook_to_repr!(generation_hook),
|
gen: hook_to_repr!(generation_hook),
|
||||||
post_gen: HookRepr::Empty,
|
post_gen: HookRepr::Empty,
|
||||||
execs: [hook_to_repr!(execution_hook)],
|
execs: [hook_to_repr!(execution_hook)],
|
||||||
@ -532,25 +538,29 @@ where
|
|||||||
Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u64)>,
|
Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u64)>,
|
||||||
extern "C" fn(*const (), id: u64),
|
extern "C" fn(*const (), id: u64),
|
||||||
>,
|
>,
|
||||||
) -> HookId {
|
) -> BlockHookId {
|
||||||
unsafe {
|
unsafe {
|
||||||
let gen = get_raw_hook!(
|
let gen = get_raw_hook!(
|
||||||
generation_hook,
|
generation_hook,
|
||||||
block_gen_hook_wrapper::<QT, S>,
|
block_gen_hook_wrapper::<QT, S>,
|
||||||
extern "C" fn(&mut HookState<1>, pc: GuestAddr) -> u64
|
extern "C" fn(&mut HookState<1, BlockHookId>, pc: GuestAddr) -> u64
|
||||||
);
|
);
|
||||||
let postgen = get_raw_hook!(
|
let postgen = get_raw_hook!(
|
||||||
post_generation_hook,
|
post_generation_hook,
|
||||||
block_post_gen_hook_wrapper::<QT, S>,
|
block_post_gen_hook_wrapper::<QT, S>,
|
||||||
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!(
|
let exec = get_raw_hook!(
|
||||||
execution_hook,
|
execution_hook,
|
||||||
block_0_exec_hook_wrapper::<QT, S>,
|
block_0_exec_hook_wrapper::<QT, S>,
|
||||||
extern "C" fn(&mut HookState<1>, id: u64)
|
extern "C" fn(&mut HookState<1, BlockHookId>, id: u64)
|
||||||
);
|
);
|
||||||
BLOCK_HOOKS.push(HookState {
|
BLOCK_HOOKS.push(HookState {
|
||||||
id: HookId(0),
|
id: BlockHookId(0),
|
||||||
gen: hook_to_repr!(generation_hook),
|
gen: hook_to_repr!(generation_hook),
|
||||||
post_gen: hook_to_repr!(post_generation_hook),
|
post_gen: hook_to_repr!(post_generation_hook),
|
||||||
execs: [hook_to_repr!(execution_hook)],
|
execs: [hook_to_repr!(execution_hook)],
|
||||||
@ -603,40 +613,44 @@ where
|
|||||||
Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u64, GuestAddr, usize)>,
|
Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u64, GuestAddr, usize)>,
|
||||||
extern "C" fn(*const (), id: u64, addr: GuestAddr, size: usize),
|
extern "C" fn(*const (), id: u64, addr: GuestAddr, size: usize),
|
||||||
>,
|
>,
|
||||||
) -> HookId {
|
) -> ReadHookId {
|
||||||
unsafe {
|
unsafe {
|
||||||
let gen = get_raw_hook!(
|
let gen = get_raw_hook!(
|
||||||
generation_hook,
|
generation_hook,
|
||||||
read_gen_hook_wrapper::<QT, S>,
|
read_gen_hook_wrapper::<QT, S>,
|
||||||
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!(
|
let exec1 = get_raw_hook!(
|
||||||
execution_hook_1,
|
execution_hook_1,
|
||||||
read_0_exec_hook_wrapper::<QT, S>,
|
read_0_exec_hook_wrapper::<QT, S>,
|
||||||
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!(
|
let exec2 = get_raw_hook!(
|
||||||
execution_hook_2,
|
execution_hook_2,
|
||||||
read_1_exec_hook_wrapper::<QT, S>,
|
read_1_exec_hook_wrapper::<QT, S>,
|
||||||
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!(
|
let exec4 = get_raw_hook!(
|
||||||
execution_hook_4,
|
execution_hook_4,
|
||||||
read_2_exec_hook_wrapper::<QT, S>,
|
read_2_exec_hook_wrapper::<QT, S>,
|
||||||
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!(
|
let exec8 = get_raw_hook!(
|
||||||
execution_hook_8,
|
execution_hook_8,
|
||||||
read_3_exec_hook_wrapper::<QT, S>,
|
read_3_exec_hook_wrapper::<QT, S>,
|
||||||
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!(
|
let execn = get_raw_hook!(
|
||||||
execution_hook_n,
|
execution_hook_n,
|
||||||
read_4_exec_hook_wrapper::<QT, S>,
|
read_4_exec_hook_wrapper::<QT, S>,
|
||||||
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 {
|
READ_HOOKS.push(HookState {
|
||||||
id: HookId(0),
|
id: ReadHookId(0),
|
||||||
gen: hook_to_repr!(generation_hook),
|
gen: hook_to_repr!(generation_hook),
|
||||||
post_gen: HookRepr::Empty,
|
post_gen: HookRepr::Empty,
|
||||||
execs: [
|
execs: [
|
||||||
@ -701,40 +715,49 @@ where
|
|||||||
Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u64, GuestAddr, usize)>,
|
Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u64, GuestAddr, usize)>,
|
||||||
extern "C" fn(*const (), id: u64, addr: GuestAddr, size: usize),
|
extern "C" fn(*const (), id: u64, addr: GuestAddr, size: usize),
|
||||||
>,
|
>,
|
||||||
) -> HookId {
|
) -> WriteHookId {
|
||||||
unsafe {
|
unsafe {
|
||||||
let gen = get_raw_hook!(
|
let gen = get_raw_hook!(
|
||||||
generation_hook,
|
generation_hook,
|
||||||
write_gen_hook_wrapper::<QT, S>,
|
write_gen_hook_wrapper::<QT, S>,
|
||||||
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!(
|
let exec1 = get_raw_hook!(
|
||||||
execution_hook_1,
|
execution_hook_1,
|
||||||
write_0_exec_hook_wrapper::<QT, S>,
|
write_0_exec_hook_wrapper::<QT, S>,
|
||||||
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!(
|
let exec2 = get_raw_hook!(
|
||||||
execution_hook_2,
|
execution_hook_2,
|
||||||
write_1_exec_hook_wrapper::<QT, S>,
|
write_1_exec_hook_wrapper::<QT, S>,
|
||||||
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!(
|
let exec4 = get_raw_hook!(
|
||||||
execution_hook_4,
|
execution_hook_4,
|
||||||
write_2_exec_hook_wrapper::<QT, S>,
|
write_2_exec_hook_wrapper::<QT, S>,
|
||||||
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!(
|
let exec8 = get_raw_hook!(
|
||||||
execution_hook_8,
|
execution_hook_8,
|
||||||
write_3_exec_hook_wrapper::<QT, S>,
|
write_3_exec_hook_wrapper::<QT, S>,
|
||||||
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!(
|
let execn = get_raw_hook!(
|
||||||
execution_hook_n,
|
execution_hook_n,
|
||||||
write_4_exec_hook_wrapper::<QT, S>,
|
write_4_exec_hook_wrapper::<QT, S>,
|
||||||
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 {
|
WRITE_HOOKS.push(HookState {
|
||||||
id: HookId(0),
|
id: WriteHookId(0),
|
||||||
gen: hook_to_repr!(generation_hook),
|
gen: hook_to_repr!(generation_hook),
|
||||||
post_gen: HookRepr::Empty,
|
post_gen: HookRepr::Empty,
|
||||||
execs: [
|
execs: [
|
||||||
@ -788,35 +811,35 @@ where
|
|||||||
Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u64, u64, u64)>,
|
Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u64, u64, u64)>,
|
||||||
extern "C" fn(*const (), id: u64, v0: u64, v1: u64),
|
extern "C" fn(*const (), id: u64, v0: u64, v1: u64),
|
||||||
>,
|
>,
|
||||||
) -> HookId {
|
) -> CmpHookId {
|
||||||
unsafe {
|
unsafe {
|
||||||
let gen = get_raw_hook!(
|
let gen = get_raw_hook!(
|
||||||
generation_hook,
|
generation_hook,
|
||||||
cmp_gen_hook_wrapper::<QT, S>,
|
cmp_gen_hook_wrapper::<QT, S>,
|
||||||
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!(
|
let exec1 = get_raw_hook!(
|
||||||
execution_hook_1,
|
execution_hook_1,
|
||||||
cmp_0_exec_hook_wrapper::<QT, S>,
|
cmp_0_exec_hook_wrapper::<QT, S>,
|
||||||
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!(
|
let exec2 = get_raw_hook!(
|
||||||
execution_hook_2,
|
execution_hook_2,
|
||||||
cmp_1_exec_hook_wrapper::<QT, S>,
|
cmp_1_exec_hook_wrapper::<QT, S>,
|
||||||
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!(
|
let exec4 = get_raw_hook!(
|
||||||
execution_hook_4,
|
execution_hook_4,
|
||||||
cmp_2_exec_hook_wrapper::<QT, S>,
|
cmp_2_exec_hook_wrapper::<QT, S>,
|
||||||
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!(
|
let exec8 = get_raw_hook!(
|
||||||
execution_hook_8,
|
execution_hook_8,
|
||||||
cmp_3_exec_hook_wrapper::<QT, S>,
|
cmp_3_exec_hook_wrapper::<QT, S>,
|
||||||
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 {
|
CMP_HOOKS.push(HookState {
|
||||||
id: HookId(0),
|
id: CmpHookId(0),
|
||||||
gen: hook_to_repr!(generation_hook),
|
gen: hook_to_repr!(generation_hook),
|
||||||
post_gen: HookRepr::Empty,
|
post_gen: HookRepr::Empty,
|
||||||
execs: [
|
execs: [
|
||||||
@ -846,7 +869,7 @@ where
|
|||||||
Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, GuestAddr)>,
|
Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, GuestAddr)>,
|
||||||
extern "C" fn(*const (), pc: GuestAddr),
|
extern "C" fn(*const (), pc: GuestAddr),
|
||||||
>,
|
>,
|
||||||
) -> HookId {
|
) -> BackdoorHookId {
|
||||||
match hook {
|
match hook {
|
||||||
Hook::Function(f) => self.backdoor_function(f),
|
Hook::Function(f) => self.backdoor_function(f),
|
||||||
Hook::Closure(c) => self.backdoor_closure(c),
|
Hook::Closure(c) => self.backdoor_closure(c),
|
||||||
@ -854,11 +877,14 @@ where
|
|||||||
let z: *const () = ptr::null::<()>();
|
let z: *const () = ptr::null::<()>();
|
||||||
self.emulator.add_backdoor_hook(z, r)
|
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 {
|
unsafe {
|
||||||
self.emulator
|
self.emulator
|
||||||
.add_backdoor_hook(transmute(hook), func_backdoor_hook_wrapper::<QT, S>)
|
.add_backdoor_hook(transmute(hook), func_backdoor_hook_wrapper::<QT, S>)
|
||||||
@ -868,10 +894,10 @@ where
|
|||||||
pub fn backdoor_closure(
|
pub fn backdoor_closure(
|
||||||
&self,
|
&self,
|
||||||
hook: Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, GuestAddr)>,
|
hook: Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, GuestAddr)>,
|
||||||
) -> HookId {
|
) -> BackdoorHookId {
|
||||||
unsafe {
|
unsafe {
|
||||||
let fat: FatPtr = transmute(hook);
|
let fat: FatPtr = transmute(hook);
|
||||||
BACKDOOR_HOOKS.push((HookId(0), fat));
|
BACKDOOR_HOOKS.push((BackdoorHookId(0), fat));
|
||||||
let id = self.emulator.add_backdoor_hook(
|
let id = self.emulator.add_backdoor_hook(
|
||||||
&mut ((*addr_of_mut!(BACKDOOR_HOOKS)).last_mut().unwrap().1),
|
&mut ((*addr_of_mut!(BACKDOOR_HOOKS)).last_mut().unwrap().1),
|
||||||
closure_backdoor_hook_wrapper::<QT, S>,
|
closure_backdoor_hook_wrapper::<QT, S>,
|
||||||
@ -927,7 +953,7 @@ where
|
|||||||
GuestAddr,
|
GuestAddr,
|
||||||
) -> SyscallHookResult,
|
) -> SyscallHookResult,
|
||||||
>,
|
>,
|
||||||
) -> HookId {
|
) -> PreSyscallHookId {
|
||||||
match hook {
|
match hook {
|
||||||
Hook::Function(f) => self.syscalls_function(f),
|
Hook::Function(f) => self.syscalls_function(f),
|
||||||
Hook::Closure(c) => self.syscalls_closure(c),
|
Hook::Closure(c) => self.syscalls_closure(c),
|
||||||
@ -935,7 +961,7 @@ where
|
|||||||
let z: *const () = ptr::null::<()>();
|
let z: *const () = ptr::null::<()>();
|
||||||
self.emulator.add_pre_syscall_hook(z, r)
|
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,
|
a6: GuestAddr,
|
||||||
a7: GuestAddr,
|
a7: GuestAddr,
|
||||||
) -> SyscallHookResult,
|
) -> SyscallHookResult,
|
||||||
) -> HookId {
|
) -> PreSyscallHookId {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.emulator
|
self.emulator
|
||||||
.add_pre_syscall_hook(transmute(hook), func_pre_syscall_hook_wrapper::<QT, S>)
|
.add_pre_syscall_hook(transmute(hook), func_pre_syscall_hook_wrapper::<QT, S>)
|
||||||
@ -982,10 +1008,10 @@ where
|
|||||||
GuestAddr,
|
GuestAddr,
|
||||||
) -> SyscallHookResult,
|
) -> SyscallHookResult,
|
||||||
>,
|
>,
|
||||||
) -> HookId {
|
) -> PreSyscallHookId {
|
||||||
unsafe {
|
unsafe {
|
||||||
let fat: FatPtr = transmute(hook);
|
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(
|
let id = self.emulator.add_pre_syscall_hook(
|
||||||
&mut ((*addr_of_mut!(PRE_SYSCALL_HOOKS)).last_mut().unwrap().1),
|
&mut ((*addr_of_mut!(PRE_SYSCALL_HOOKS)).last_mut().unwrap().1),
|
||||||
closure_pre_syscall_hook_wrapper::<QT, S>,
|
closure_pre_syscall_hook_wrapper::<QT, S>,
|
||||||
@ -1044,7 +1070,7 @@ where
|
|||||||
GuestAddr,
|
GuestAddr,
|
||||||
) -> GuestAddr,
|
) -> GuestAddr,
|
||||||
>,
|
>,
|
||||||
) -> HookId {
|
) -> PostSyscallHookId {
|
||||||
match hook {
|
match hook {
|
||||||
Hook::Function(f) => self.after_syscalls_function(f),
|
Hook::Function(f) => self.after_syscalls_function(f),
|
||||||
Hook::Closure(c) => self.after_syscalls_closure(c),
|
Hook::Closure(c) => self.after_syscalls_closure(c),
|
||||||
@ -1052,7 +1078,7 @@ where
|
|||||||
let z: *const () = ptr::null::<()>();
|
let z: *const () = ptr::null::<()>();
|
||||||
self.emulator.add_post_syscall_hook(z, r)
|
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,
|
a6: GuestAddr,
|
||||||
a7: GuestAddr,
|
a7: GuestAddr,
|
||||||
) -> GuestAddr,
|
) -> GuestAddr,
|
||||||
) -> HookId {
|
) -> PostSyscallHookId {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.emulator
|
self.emulator
|
||||||
.add_post_syscall_hook(transmute(hook), func_post_syscall_hook_wrapper::<QT, S>)
|
.add_post_syscall_hook(transmute(hook), func_post_syscall_hook_wrapper::<QT, S>)
|
||||||
@ -1101,10 +1127,10 @@ where
|
|||||||
GuestAddr,
|
GuestAddr,
|
||||||
) -> GuestAddr,
|
) -> GuestAddr,
|
||||||
>,
|
>,
|
||||||
) -> HookId {
|
) -> PostSyscallHookId {
|
||||||
unsafe {
|
unsafe {
|
||||||
let fat: FatPtr = transmute(hook);
|
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(
|
let id = self.emulator.add_post_syscall_hook(
|
||||||
&mut ((*addr_of_mut!(POST_SYSCALL_HOOKS)).last_mut().unwrap().1),
|
&mut ((*addr_of_mut!(POST_SYSCALL_HOOKS)).last_mut().unwrap().1),
|
||||||
closure_post_syscall_hook_wrapper::<QT, S>,
|
closure_post_syscall_hook_wrapper::<QT, S>,
|
||||||
@ -1122,7 +1148,7 @@ where
|
|||||||
Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u32) -> bool>,
|
Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u32) -> bool>,
|
||||||
extern "C" fn(*const (), tid: u32) -> bool,
|
extern "C" fn(*const (), tid: u32) -> bool,
|
||||||
>,
|
>,
|
||||||
) -> HookId {
|
) -> NewThreadHookId {
|
||||||
match hook {
|
match hook {
|
||||||
Hook::Function(f) => self.thread_creation_function(f),
|
Hook::Function(f) => self.thread_creation_function(f),
|
||||||
Hook::Closure(c) => self.thread_creation_closure(c),
|
Hook::Closure(c) => self.thread_creation_closure(c),
|
||||||
@ -1130,7 +1156,7 @@ where
|
|||||||
let z: *const () = ptr::null::<()>();
|
let z: *const () = ptr::null::<()>();
|
||||||
self.emulator.add_new_thread_hook(z, r)
|
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(
|
pub fn thread_creation_function(
|
||||||
&self,
|
&self,
|
||||||
hook: fn(&mut Self, Option<&mut S>, tid: u32) -> bool,
|
hook: fn(&mut Self, Option<&mut S>, tid: u32) -> bool,
|
||||||
) -> HookId {
|
) -> NewThreadHookId {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.emulator
|
self.emulator
|
||||||
.add_new_thread_hook(transmute(hook), func_new_thread_hook_wrapper::<QT, S>)
|
.add_new_thread_hook(transmute(hook), func_new_thread_hook_wrapper::<QT, S>)
|
||||||
@ -1149,10 +1175,10 @@ where
|
|||||||
pub fn thread_creation_closure(
|
pub fn thread_creation_closure(
|
||||||
&self,
|
&self,
|
||||||
hook: Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u32) -> bool>,
|
hook: Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u32) -> bool>,
|
||||||
) -> HookId {
|
) -> NewThreadHookId {
|
||||||
unsafe {
|
unsafe {
|
||||||
let fat: FatPtr = transmute(hook);
|
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(
|
let id = self.emulator.add_new_thread_hook(
|
||||||
&mut (*addr_of_mut!(NEW_THREAD_HOOKS)).last_mut().unwrap().1,
|
&mut (*addr_of_mut!(NEW_THREAD_HOOKS)).last_mut().unwrap().1,
|
||||||
closure_new_thread_hook_wrapper::<QT, S>,
|
closure_new_thread_hook_wrapper::<QT, S>,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user