fix build
This commit is contained in:
parent
fc331fc6d8
commit
2ac7874895
@ -25,7 +25,8 @@ use libafl_qemu::{
|
||||
helper::{QemuHelper, QemuHelperTuple, QemuInstrumentationFilter},
|
||||
};
|
||||
use libafl::events::EventFirer;
|
||||
use libafl::state::HasClientPerfMonitor;
|
||||
use libafl::state::MaybeHasClientPerfMonitor;
|
||||
use libafl::prelude::State;
|
||||
use libafl::inputs::Input;
|
||||
use libafl::feedbacks::Feedback;
|
||||
use libafl::SerdeAny;
|
||||
@ -203,7 +204,7 @@ pub struct ClockTimeFeedback {
|
||||
|
||||
impl<S> Feedback<S> for ClockTimeFeedback
|
||||
where
|
||||
S: UsesInput + HasClientPerfMonitor + HasMetadata,
|
||||
S: State + UsesInput + MaybeHasClientPerfMonitor + HasMetadata,
|
||||
{
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
fn is_interesting<EM, OT>(
|
||||
@ -280,7 +281,7 @@ pub struct QemuClockIncreaseFeedback {
|
||||
|
||||
impl<S> Feedback<S> for QemuClockIncreaseFeedback
|
||||
where
|
||||
S: UsesInput + HasNamedMetadata + HasClientPerfMonitor + Debug,
|
||||
S: State + UsesInput + HasNamedMetadata + MaybeHasClientPerfMonitor + Debug,
|
||||
{
|
||||
fn is_interesting<EM, OT>(
|
||||
&mut self,
|
||||
|
@ -469,7 +469,7 @@ pub fn fuzz() {
|
||||
QemuStateRestoreHelper::new(),
|
||||
QemuSystemStateHelper::new(svh,curr_tcb_pointer,task_queue_addr,task_delay_addr,task_delay_overflow_addr,input_counter_ptr,app_range.clone())
|
||||
);
|
||||
let mut hooks = QemuHooks::new(&emu,qhelpers);
|
||||
let mut hooks = QemuHooks::new(emu.clone(),qhelpers);
|
||||
|
||||
#[cfg(not(feature = "systemstate"))]
|
||||
let observer_list = tuple_list!(edges_observer, clock_time_observer);
|
||||
|
@ -1,4 +1,3 @@
|
||||
#![feature(is_sorted)]
|
||||
#[cfg(target_os = "linux")]
|
||||
mod fuzzer;
|
||||
#[cfg(target_os = "linux")]
|
||||
|
@ -1,4 +1,3 @@
|
||||
#![feature(is_sorted)]
|
||||
//! A libfuzzer-like fuzzer using qemu for binary-only coverage
|
||||
#[cfg(target_os = "linux")]
|
||||
mod fuzzer;
|
||||
|
@ -14,9 +14,10 @@ use libafl::{
|
||||
mark_feature_time,
|
||||
stages::{Stage},
|
||||
start_timer,
|
||||
state::{HasClientPerfMonitor, HasCorpus, HasRand, UsesState, HasMetadata},
|
||||
state::{MaybeHasClientPerfMonitor, HasCorpus, HasRand, UsesState, HasMetadata},
|
||||
Error, prelude::{HasBytesVec, UsesInput, new_hash_feedback, MutationResult, Mutator, CorpusId},
|
||||
};
|
||||
use libafl::prelude::State;
|
||||
use crate::{systemstate::{FreeRTOSSystemStateMetadata, RefinedFreeRTOSSystemState}, fuzzer::DO_NUM_INTERRUPT, clock::IcHist};
|
||||
|
||||
pub const MINIMUM_INTER_ARRIVAL_TIME : u32 = 700 * 1000 * (1 << 4);
|
||||
@ -35,7 +36,7 @@ where
|
||||
E: UsesState<State = Z::State>,
|
||||
EM: UsesState<State = Z::State>,
|
||||
Z: Evaluator<E, EM>,
|
||||
Z::State: HasClientPerfMonitor + HasCorpus + HasRand,
|
||||
Z::State: MaybeHasClientPerfMonitor + HasCorpus + HasRand,
|
||||
{
|
||||
pub fn new() -> Self {
|
||||
Self { phantom: PhantomData }
|
||||
@ -47,7 +48,7 @@ where
|
||||
E: UsesState<State = Z::State>,
|
||||
EM: UsesState<State = Z::State>,
|
||||
Z: Evaluator<E, EM>,
|
||||
Z::State: HasClientPerfMonitor + HasCorpus + HasRand + HasMetadata,
|
||||
Z::State: MaybeHasClientPerfMonitor + HasCorpus + HasRand + HasMetadata,
|
||||
<Z::State as UsesInput>::Input: HasBytesVec
|
||||
{
|
||||
fn perform(
|
||||
@ -237,7 +238,7 @@ where
|
||||
E: UsesState<State = Z::State>,
|
||||
EM: UsesState<State = Z::State>,
|
||||
Z: Evaluator<E, EM>,
|
||||
Z::State: HasClientPerfMonitor + HasCorpus + HasRand,
|
||||
Z::State: MaybeHasClientPerfMonitor + HasCorpus + HasRand,
|
||||
{
|
||||
type State = Z::State;
|
||||
}
|
@ -44,13 +44,13 @@ where
|
||||
{
|
||||
const HOOKS_DO_SIDE_EFFECTS: bool = true;
|
||||
|
||||
fn init_hooks<QT>(&self, _hooks: &QemuHooks<'_, QT, S>)
|
||||
fn init_hooks<QT>(&self, _hooks: &QemuHooks<QT, S>)
|
||||
where
|
||||
QT: QemuHelperTuple<S>,
|
||||
{
|
||||
}
|
||||
|
||||
fn first_exec<QT>(&self, _hooks: &QemuHooks<'_, QT, S>)
|
||||
fn first_exec<QT>(&self, _hooks: &QemuHooks<QT, S>)
|
||||
where
|
||||
QT: QemuHelperTuple<S>,
|
||||
{
|
||||
|
@ -11,7 +11,8 @@ use std::collections::hash_map::DefaultHasher;
|
||||
use std::hash::Hasher;
|
||||
use std::hash::Hash;
|
||||
use libafl::events::EventFirer;
|
||||
use libafl::state::HasClientPerfMonitor;
|
||||
use libafl::state::MaybeHasClientPerfMonitor;
|
||||
use libafl::prelude::State;
|
||||
use libafl::feedbacks::Feedback;
|
||||
use libafl_bolts::Named;
|
||||
use libafl::Error;
|
||||
@ -62,7 +63,7 @@ pub struct NovelSystemStateFeedback
|
||||
|
||||
impl<S> Feedback<S> for NovelSystemStateFeedback
|
||||
where
|
||||
S: UsesInput + HasClientPerfMonitor + HasNamedMetadata,
|
||||
S: State + UsesInput + MaybeHasClientPerfMonitor + HasNamedMetadata,
|
||||
{
|
||||
fn is_interesting<EM, OT>(
|
||||
&mut self,
|
||||
@ -176,7 +177,7 @@ pub struct HitSystemStateFeedback
|
||||
|
||||
impl<S> Feedback<S> for HitSystemStateFeedback
|
||||
where
|
||||
S: UsesInput + HasClientPerfMonitor,
|
||||
S: State + UsesInput + MaybeHasClientPerfMonitor,
|
||||
{
|
||||
fn is_interesting<EM, OT>(
|
||||
&mut self,
|
||||
@ -228,7 +229,7 @@ pub struct DumpSystraceFeedback
|
||||
|
||||
impl<S> Feedback<S> for DumpSystraceFeedback
|
||||
where
|
||||
S: UsesInput + HasClientPerfMonitor,
|
||||
S: State + UsesInput + MaybeHasClientPerfMonitor,
|
||||
{
|
||||
fn is_interesting<EM, OT>(
|
||||
&mut self,
|
||||
|
@ -10,6 +10,7 @@ use libafl::prelude::HasTargetBytes;
|
||||
use libafl::prelude::UsesInput;
|
||||
use libafl::state::HasNamedMetadata;
|
||||
use libafl::state::UsesState;
|
||||
use libafl::prelude::State;
|
||||
use core::marker::PhantomData;
|
||||
use libafl::state::HasCorpus;
|
||||
use libafl::state::HasSolutions;
|
||||
@ -29,7 +30,7 @@ use std::collections::hash_map::DefaultHasher;
|
||||
use std::hash::Hasher;
|
||||
use std::hash::Hash;
|
||||
use libafl::events::EventFirer;
|
||||
use libafl::state::HasClientPerfMonitor;
|
||||
use libafl::state::MaybeHasClientPerfMonitor;
|
||||
use libafl::feedbacks::Feedback;
|
||||
use libafl_bolts::Named;
|
||||
use libafl::Error;
|
||||
@ -284,7 +285,7 @@ impl SysMapFeedback {
|
||||
|
||||
impl<S> Feedback<S> for SysMapFeedback
|
||||
where
|
||||
S: UsesInput + HasClientPerfMonitor + HasNamedMetadata,
|
||||
S: State + UsesInput + MaybeHasClientPerfMonitor + HasNamedMetadata,
|
||||
S::Input: HasTargetBytes,
|
||||
{
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
|
@ -10,6 +10,7 @@ use libafl_qemu::QemuHooks;
|
||||
use libafl_qemu::edges::QemuEdgesMapMetadata;
|
||||
use libafl_qemu::emu;
|
||||
use libafl_qemu::hooks;
|
||||
use libafl_qemu::Hook;
|
||||
use crate::systemstate::RawFreeRTOSSystemState;
|
||||
use crate::systemstate::CURRENT_SYSTEMSTATE_VEC;
|
||||
use crate::systemstate::NUM_PRIOS;
|
||||
@ -72,13 +73,13 @@ impl<S> QemuHelper<S> for QemuSystemStateHelper
|
||||
where
|
||||
S: UsesInput,
|
||||
{
|
||||
fn first_exec<QT>(&self, _hooks: &QemuHooks<'_, QT, S>)
|
||||
fn first_exec<QT>(&self, _hooks: &QemuHooks<QT, S>)
|
||||
where
|
||||
QT: QemuHelperTuple<S>,
|
||||
{
|
||||
_hooks.instruction(self.kerneladdr, exec_syscall_hook::<QT, S>, false);
|
||||
_hooks.instruction(self.kerneladdr, Hook::Function(exec_syscall_hook::<QT, S>), false);
|
||||
#[cfg(feature = "trace_abbs")]
|
||||
_hooks.jmps(Some(gen_jmp_is_syscall::<QT, S>), Some(trace_api_call::<QT, S>));
|
||||
_hooks.jmps(Hook::Function(gen_jmp_is_syscall::<QT, S>), Hook::Function(trace_api_call::<QT, S>));
|
||||
}
|
||||
|
||||
// TODO: refactor duplicate code
|
||||
@ -133,10 +134,10 @@ fn trigger_collection(emulator: &Emulator, h: &QemuSystemStateHelper) {
|
||||
unsafe {
|
||||
// TODO: investigate why can_do_io is not set sometimes, as this is just a workaround
|
||||
let c = emulator.cpu_from_index(0);
|
||||
let can_do_io = (*c.raw_ptr()).can_do_io;
|
||||
(*c.raw_ptr()).can_do_io = 1;
|
||||
let can_do_io = (*c.raw_ptr()).neg.can_do_io;
|
||||
(*c.raw_ptr()).neg.can_do_io = true;
|
||||
systemstate.qemu_tick = emu::icount_get_raw();
|
||||
(*c.raw_ptr()).can_do_io = can_do_io;
|
||||
(*c.raw_ptr()).neg.can_do_io = can_do_io;
|
||||
}
|
||||
let mut buf : [u8; 4] = [0,0,0,0];
|
||||
match h.input_counter {
|
||||
@ -183,7 +184,7 @@ fn trigger_collection(emulator: &Emulator, h: &QemuSystemStateHelper) {
|
||||
}
|
||||
|
||||
pub fn exec_syscall_hook<QT, S>(
|
||||
hooks: &mut QemuHooks<'_, QT, S>,
|
||||
hooks: &mut QemuHooks<QT, S>,
|
||||
_state: Option<&mut S>,
|
||||
_pc: GuestAddr,
|
||||
)
|
||||
@ -199,7 +200,7 @@ where
|
||||
thread_local!(static LAST_API_CALL : UnsafeCell<Option<(GuestAddr,GuestAddr)>> = UnsafeCell::new(None));
|
||||
|
||||
pub fn gen_jmp_is_syscall<QT, S>(
|
||||
hooks: &mut QemuHooks<'_, QT, S>,
|
||||
hooks: &mut QemuHooks<QT, S>,
|
||||
_state: Option<&mut S>,
|
||||
src: GuestAddr,
|
||||
dest: GuestAddr,
|
||||
@ -218,7 +219,7 @@ where
|
||||
}
|
||||
|
||||
pub fn trace_api_call<QT, S>(
|
||||
_hooks: &mut QemuHooks<'_, QT, S>,
|
||||
_hooks: &mut QemuHooks<QT, S>,
|
||||
_state: Option<&mut S>,
|
||||
src: GuestAddr, dest: GuestAddr, id: u64
|
||||
)
|
||||
|
@ -160,14 +160,14 @@ pub struct GenerationScheduler<S> {
|
||||
|
||||
impl<S> UsesState for GenerationScheduler<S>
|
||||
where
|
||||
S: UsesInput,
|
||||
S: State + UsesInput,
|
||||
{
|
||||
type State = S;
|
||||
}
|
||||
|
||||
impl<S> Scheduler for GenerationScheduler<S>
|
||||
where
|
||||
S: HasCorpus + HasMetadata,
|
||||
S: State + HasCorpus + HasMetadata,
|
||||
S::Input: HasLen,
|
||||
{
|
||||
/// get first element in current gen,
|
||||
|
@ -13,7 +13,8 @@ use hashbrown::{HashMap};
|
||||
use libafl::observers::ObserversTuple;
|
||||
use libafl::executors::ExitKind;
|
||||
use libafl::events::EventFirer;
|
||||
use libafl::state::{HasClientPerfMonitor, HasCorpus, UsesState};
|
||||
use libafl::state::{MaybeHasClientPerfMonitor, HasCorpus, UsesState};
|
||||
use libafl::prelude::State;
|
||||
use libafl::inputs::Input;
|
||||
use libafl::feedbacks::Feedback;
|
||||
use libafl::state::HasMetadata;
|
||||
@ -101,7 +102,7 @@ pub struct SortedFeedback {
|
||||
|
||||
impl<S> Feedback<S> for SortedFeedback
|
||||
where
|
||||
S: UsesInput + HasClientPerfMonitor,
|
||||
S: State + UsesInput + MaybeHasClientPerfMonitor,
|
||||
S::Input: HasTargetBytes,
|
||||
{
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
@ -122,12 +123,24 @@ where
|
||||
if tmp.len()<32 {return Ok(false);}
|
||||
let tmp = Vec::<u8>::from(&tmp[0..32]);
|
||||
// tmp.reverse();
|
||||
if tmp.is_sorted_by(|a,b| match a.partial_cmp(b).unwrap_or(Less) {
|
||||
Less => Some(Greater),
|
||||
Equal => Some(Greater),
|
||||
Greater => Some(Less),
|
||||
}) {return Ok(true)};
|
||||
return Ok(false);
|
||||
// if tmp.is_sorted_by(|a,b| match a.partial_cmp(b).unwrap_or(Less) {
|
||||
// Less => Some(Greater),
|
||||
// Equal => Some(Greater),
|
||||
// Greater => Some(Less),
|
||||
// }) {return Ok(true)};
|
||||
let mut is_sorted = true;
|
||||
if tmp[0]<tmp[1] {
|
||||
for i in 1..tmp.len() {
|
||||
is_sorted &= tmp[i-1]<=tmp[i];
|
||||
if !is_sorted {break;}
|
||||
}
|
||||
} else {
|
||||
for i in 1..tmp.len() {
|
||||
is_sorted &= tmp[i-1]>=tmp[i];
|
||||
if !is_sorted {break;}
|
||||
}
|
||||
}
|
||||
return Ok(is_sorted);
|
||||
}
|
||||
}
|
||||
|
||||
@ -162,7 +175,7 @@ pub struct ExecTimeReachedFeedback
|
||||
|
||||
impl<S> Feedback<S> for ExecTimeReachedFeedback
|
||||
where
|
||||
S: UsesInput + HasClientPerfMonitor,
|
||||
S: State + UsesInput + MaybeHasClientPerfMonitor,
|
||||
{
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
fn is_interesting<EM, OT>(
|
||||
@ -211,7 +224,7 @@ pub struct ExecTimeCollectorFeedback
|
||||
|
||||
impl<S> Feedback<S> for ExecTimeCollectorFeedback
|
||||
where
|
||||
S: UsesInput + HasClientPerfMonitor,
|
||||
S: State + UsesInput + MaybeHasClientPerfMonitor,
|
||||
{
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
fn is_interesting<EM, OT>(
|
||||
@ -276,7 +289,7 @@ pub struct ExecTimeIncFeedback
|
||||
|
||||
impl<S> Feedback<S> for ExecTimeIncFeedback
|
||||
where
|
||||
S: UsesInput + HasClientPerfMonitor,
|
||||
S: State + UsesInput + MaybeHasClientPerfMonitor,
|
||||
{
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
fn is_interesting<EM, OT>(
|
||||
@ -344,7 +357,7 @@ pub struct AlwaysTrueFeedback
|
||||
|
||||
impl<S> Feedback<S> for AlwaysTrueFeedback
|
||||
where
|
||||
S: UsesInput + HasClientPerfMonitor,
|
||||
S: State + UsesInput + MaybeHasClientPerfMonitor,
|
||||
{
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
fn is_interesting<EM, OT>(
|
||||
|
@ -404,10 +404,10 @@ extern "C" {
|
||||
// void (*exec)(target_ulong src, target_ulong dst, uint64_t id, uint64_t data),
|
||||
// uint64_t data);
|
||||
fn libafl_add_jmp_hook(
|
||||
gen: Option<extern "C" fn(GuestAddr, GuestAddr, u64) -> u64>,
|
||||
exec: Option<extern "C" fn(GuestAddr, GuestAddr, u64, u64)>,
|
||||
gen: Option<extern "C" fn(u64, GuestAddr, GuestAddr) -> u64>, // data,src,dest
|
||||
exec: Option<extern "C" fn(u64, GuestAddr, GuestAddr, u64)>, // data,src,dest,id
|
||||
data: u64,
|
||||
);
|
||||
) -> usize;
|
||||
}
|
||||
|
||||
#[cfg(emulation_mode = "usermode")]
|
||||
@ -1520,13 +1520,28 @@ impl Emulator {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_jmp_hooks(
|
||||
// pub fn add_jmp_hooks(
|
||||
// &self,
|
||||
// gen: Option<extern "C" fn(GuestAddr, GuestAddr, u64) -> u64>,
|
||||
// exec: Option<extern "C" fn(GuestAddr, GuestAddr, u64, u64)>,
|
||||
// data: u64,
|
||||
// ) {
|
||||
// unsafe { libafl_add_jmp_hook(gen, exec, data) }
|
||||
// }
|
||||
pub fn add_jmp_hooks<T: Into<HookData>>(
|
||||
&self,
|
||||
gen: Option<extern "C" fn(GuestAddr, GuestAddr, u64) -> u64>,
|
||||
exec: Option<extern "C" fn(GuestAddr, GuestAddr, u64, u64)>,
|
||||
data: u64,
|
||||
) {
|
||||
unsafe { libafl_add_jmp_hook(gen, exec, data) }
|
||||
data: T,
|
||||
gen: Option<extern "C" fn(T, GuestAddr, GuestAddr) -> u64>,
|
||||
exec: Option<extern "C" fn(T, GuestAddr, GuestAddr, u64)>,
|
||||
) -> HookId {
|
||||
unsafe {
|
||||
let data: u64 = data.into().0;
|
||||
let gen: Option<extern "C" fn(u64, GuestAddr, GuestAddr) -> u64> =
|
||||
core::mem::transmute(gen);
|
||||
let exec: Option<extern "C" fn(u64, GuestAddr, GuestAddr, u64)> = core::mem::transmute(exec);
|
||||
let num = libafl_add_jmp_hook(gen, exec, data);
|
||||
HookId(num)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(emulation_mode = "systemmode")]
|
||||
|
@ -535,77 +535,11 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
static mut JMP_HOOKS: Vec<(Hook, Hook)> = vec![];
|
||||
static mut JMP_HOOKS: Vec<HookState<1>> = vec![];
|
||||
create_gen_wrapper!(jmp, (src: GuestAddr, dest: GuestAddr), u64, 1);
|
||||
create_exec_wrapper!(jmp, (src: GuestAddr, dst: GuestAddr, id: u64), 0, 1);
|
||||
|
||||
extern "C" fn gen_jmp_hook_wrapper<QT, S>(src: GuestAddr, dst: GuestAddr, index: u64) -> u64
|
||||
where
|
||||
S: UsesInput,
|
||||
QT: QemuHelperTuple<S>,
|
||||
{
|
||||
unsafe {
|
||||
let hooks = get_qemu_hooks::<QT, S>();
|
||||
let (gen, _) = &mut JMP_HOOKS[index as usize];
|
||||
match gen {
|
||||
Hook::Function(ptr) => {
|
||||
let func: fn(
|
||||
&mut QemuHooks<'_, QT, S>,
|
||||
Option<&mut S>,
|
||||
GuestAddr,
|
||||
GuestAddr,
|
||||
) -> Option<u64> = transmute(*ptr);
|
||||
(func)(hooks, inprocess_get_state::<S>(), src, dst).map_or(SKIP_EXEC_HOOK, |id| id)
|
||||
}
|
||||
Hook::Closure(ptr) => {
|
||||
let func: &mut Box<
|
||||
dyn FnMut(
|
||||
&mut QemuHooks<'_, QT, S>,
|
||||
Option<&mut S>,
|
||||
GuestAddr,
|
||||
GuestAddr,
|
||||
) -> Option<u64>,
|
||||
> = transmute(ptr);
|
||||
(func)(hooks, inprocess_get_state::<S>(), src, dst).map_or(SKIP_EXEC_HOOK, |id| id)
|
||||
}
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" fn exec_jmp_hook_wrapper<QT, S>(src: GuestAddr, dst: GuestAddr, id: u64, index: u64)
|
||||
where
|
||||
S: UsesInput,
|
||||
QT: QemuHelperTuple<S>,
|
||||
{
|
||||
unsafe {
|
||||
let hooks = get_qemu_hooks::<QT, S>();
|
||||
let (_, exec) = &mut JMP_HOOKS[index as usize];
|
||||
match exec {
|
||||
Hook::Function(ptr) => {
|
||||
let func: fn(
|
||||
&mut QemuHooks<'_, QT, S>,
|
||||
Option<&mut S>,
|
||||
GuestAddr,
|
||||
GuestAddr,
|
||||
u64,
|
||||
) = transmute(*ptr);
|
||||
(func)(hooks, inprocess_get_state::<S>(), src, dst, id);
|
||||
}
|
||||
Hook::Closure(ptr) => {
|
||||
let func: &mut Box<
|
||||
dyn FnMut(
|
||||
&mut QemuHooks<'_, QT, S>,
|
||||
Option<&mut S>,
|
||||
GuestAddr,
|
||||
GuestAddr,
|
||||
u64,
|
||||
),
|
||||
> = transmute(ptr);
|
||||
(func)(hooks, inprocess_get_state::<S>(), src, dst, id);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static mut HOOKS_IS_INITIALIZED: bool = false;
|
||||
static mut FIRST_EXEC: bool = true;
|
||||
@ -1483,34 +1417,46 @@ where
|
||||
|
||||
pub fn jmps(
|
||||
&self,
|
||||
generation_hook: Option<
|
||||
generation_hook: Hook<
|
||||
fn(&mut Self, Option<&mut S>, src: GuestAddr, dest: GuestAddr) -> Option<u64>,
|
||||
Box<
|
||||
dyn for<'a> FnMut(
|
||||
&'a mut Self,
|
||||
Option<&'a mut S>,
|
||||
GuestAddr,
|
||||
GuestAddr,
|
||||
) -> Option<u64>,
|
||||
>,
|
||||
execution_hook: Option<fn(&mut Self, Option<&mut S>, src: GuestAddr, dest: GuestAddr, id: u64)>,
|
||||
) {
|
||||
extern "C" fn(*const (), src: GuestAddr, dest: GuestAddr) -> u64,
|
||||
>,
|
||||
execution_hook: Hook<
|
||||
fn(&mut Self, Option<&mut S>, src: GuestAddr, dest: GuestAddr, id: u64),
|
||||
Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, GuestAddr, GuestAddr, u64)>,
|
||||
extern "C" fn(*const (), src: GuestAddr, dest: GuestAddr, id: u64),
|
||||
>,
|
||||
) -> HookId {
|
||||
unsafe {
|
||||
let index = JMP_HOOKS.len();
|
||||
self.emulator.add_jmp_hooks(
|
||||
if generation_hook.is_none() {
|
||||
None
|
||||
} else {
|
||||
Some(gen_jmp_hook_wrapper::<QT, S>)
|
||||
},
|
||||
if execution_hook.is_none() {
|
||||
None
|
||||
} else {
|
||||
Some(exec_jmp_hook_wrapper::<QT, S>)
|
||||
},
|
||||
index as u64,
|
||||
let gen = get_raw_hook!(
|
||||
generation_hook,
|
||||
jmp_gen_hook_wrapper::<QT, S>,
|
||||
extern "C" fn(&mut HookState<1>, src: GuestAddr, dest: GuestAddr) -> u64
|
||||
);
|
||||
JMP_HOOKS.push((
|
||||
generation_hook.map_or(Hook::Empty, |hook| {
|
||||
Hook::Function(hook as *const libc::c_void)
|
||||
}),
|
||||
execution_hook.map_or(Hook::Empty, |hook| {
|
||||
Hook::Function(hook as *const libc::c_void)
|
||||
}),
|
||||
));
|
||||
let exec = get_raw_hook!(
|
||||
execution_hook,
|
||||
jmp_0_exec_hook_wrapper::<QT, S>,
|
||||
extern "C" fn(&mut HookState<1>, src: GuestAddr, dest: GuestAddr, id: u64)
|
||||
);
|
||||
JMP_HOOKS.push(HookState {
|
||||
id: HookId(0),
|
||||
gen: hook_to_repr!(generation_hook),
|
||||
post_gen: HookRepr::Empty,
|
||||
execs: [hook_to_repr!(execution_hook)],
|
||||
});
|
||||
let id = self
|
||||
.emulator
|
||||
.add_jmp_hooks(JMP_HOOKS.last_mut().unwrap(), gen, exec);
|
||||
JMP_HOOKS.last_mut().unwrap().id = id;
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user