Post gen (#1282)
* Add post_gen * Adopt post_gen hooks in DrCovHelper * Bump qemu-libafl-bridge revision --------- Co-authored-by: Your Name <you@example.com> Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>
This commit is contained in:
parent
258780370f
commit
53dd6c6be6
@ -8,7 +8,7 @@ use which::which;
|
|||||||
|
|
||||||
const QEMU_URL: &str = "https://github.com/AFLplusplus/qemu-libafl-bridge";
|
const QEMU_URL: &str = "https://github.com/AFLplusplus/qemu-libafl-bridge";
|
||||||
const QEMU_DIRNAME: &str = "qemu-libafl-bridge";
|
const QEMU_DIRNAME: &str = "qemu-libafl-bridge";
|
||||||
const QEMU_REVISION: &str = "0dc52ed6f3915f727aaec8648706760f278f0571";
|
const QEMU_REVISION: &str = "6ae8b5bfb0bc4ac7a0b2ec463cf1000363836c0c";
|
||||||
|
|
||||||
fn build_dep_check(tools: &[&str]) {
|
fn build_dep_check(tools: &[&str]) {
|
||||||
for tool in tools {
|
for tool in tools {
|
||||||
|
@ -1,100 +0,0 @@
|
|||||||
use capstone::prelude::*;
|
|
||||||
|
|
||||||
use crate::{Emulator, GuestAddr};
|
|
||||||
|
|
||||||
pub struct Instruction {
|
|
||||||
pub start_addr: GuestAddr,
|
|
||||||
pub mnemonic: String,
|
|
||||||
pub operands: String,
|
|
||||||
pub insn_len: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Generating the basic block from it's starting address (pc)
|
|
||||||
* Basic block:
|
|
||||||
* - Starting at pc
|
|
||||||
* - Ending at the first branch/jump/interrupt/call instruction
|
|
||||||
* Output:
|
|
||||||
* - Vector of instructions
|
|
||||||
* - Start address
|
|
||||||
* - mnemonic string
|
|
||||||
* - operand string
|
|
||||||
* - instruction length
|
|
||||||
*/
|
|
||||||
pub fn pc2basicblock(
|
|
||||||
pc: GuestAddr,
|
|
||||||
emu: &Emulator,
|
|
||||||
mode: Option<capstone::Mode>,
|
|
||||||
) -> Result<Vec<Instruction>, String> {
|
|
||||||
#[allow(unused_mut)]
|
|
||||||
let mut code = {
|
|
||||||
#[cfg(emulation_mode = "usermode")]
|
|
||||||
unsafe {
|
|
||||||
std::slice::from_raw_parts(emu.g2h(pc), 512)
|
|
||||||
}
|
|
||||||
#[cfg(emulation_mode = "systemmode")]
|
|
||||||
&mut [0; 512]
|
|
||||||
};
|
|
||||||
#[cfg(emulation_mode = "systemmode")]
|
|
||||||
unsafe {
|
|
||||||
emu.read_mem(pc, code)
|
|
||||||
};
|
|
||||||
// TODO better fault handling
|
|
||||||
if code.iter().all(|&x| x == 0) {
|
|
||||||
return Err("Memory region is empty".to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut iaddr = pc;
|
|
||||||
let mut block = Vec::<Instruction>::new();
|
|
||||||
|
|
||||||
let mut cs = crate::capstone().detail(true).build().unwrap();
|
|
||||||
if let Some(m) = mode {
|
|
||||||
cs.set_mode(m).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
'disasm: while let Ok(insns) = cs.disasm_count(code, iaddr.into(), 1) {
|
|
||||||
if insns.is_empty() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
let insn = insns.first().unwrap();
|
|
||||||
let insn_detail: InsnDetail = cs.insn_detail(insn).unwrap();
|
|
||||||
block.push(Instruction {
|
|
||||||
start_addr: insn.address() as GuestAddr,
|
|
||||||
mnemonic: insn.mnemonic().unwrap().to_string(),
|
|
||||||
operands: insn.op_str().unwrap().to_string(),
|
|
||||||
insn_len: insn.len(),
|
|
||||||
});
|
|
||||||
for detail in insn_detail.groups() {
|
|
||||||
match u32::from(detail.0) {
|
|
||||||
capstone::InsnGroupType::CS_GRP_BRANCH_RELATIVE
|
|
||||||
| capstone::InsnGroupType::CS_GRP_CALL
|
|
||||||
| capstone::InsnGroupType::CS_GRP_INT
|
|
||||||
| capstone::InsnGroupType::CS_GRP_INVALID
|
|
||||||
| capstone::InsnGroupType::CS_GRP_IRET
|
|
||||||
| capstone::InsnGroupType::CS_GRP_JUMP
|
|
||||||
| capstone::InsnGroupType::CS_GRP_PRIVILEGE
|
|
||||||
| capstone::InsnGroupType::CS_GRP_RET => {
|
|
||||||
break 'disasm;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
iaddr += insn.bytes().len() as GuestAddr;
|
|
||||||
|
|
||||||
#[cfg(emulation_mode = "usermode")]
|
|
||||||
unsafe {
|
|
||||||
code = std::slice::from_raw_parts(emu.g2h(iaddr), 512);
|
|
||||||
}
|
|
||||||
#[cfg(emulation_mode = "systemmode")]
|
|
||||||
unsafe {
|
|
||||||
emu.read_mem(iaddr, code);
|
|
||||||
}
|
|
||||||
// TODO better fault handling
|
|
||||||
if code.iter().all(|&x| x == 0) {
|
|
||||||
return Err("Memory region is empty".to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(block)
|
|
||||||
}
|
|
@ -414,7 +414,7 @@ where
|
|||||||
where
|
where
|
||||||
QT: QemuHelperTuple<S>,
|
QT: QemuHelperTuple<S>,
|
||||||
{
|
{
|
||||||
hooks.blocks(Some(Self::gen_blocks_calls::<QT, S>), None);
|
hooks.blocks(Some(Self::gen_blocks_calls::<QT, S>), None, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pre_exec(&mut self, emulator: &Emulator, input: &S::Input) {
|
fn pre_exec(&mut self, emulator: &Emulator, input: &S::Input) {
|
||||||
|
@ -9,8 +9,7 @@ use rangemap::RangeMap;
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
blocks::pc2basicblock,
|
emu::{GuestAddr, GuestUsize},
|
||||||
emu::GuestAddr,
|
|
||||||
helper::{QemuHelper, QemuHelperTuple, QemuInstrumentationFilter},
|
helper::{QemuHelper, QemuHelperTuple, QemuInstrumentationFilter},
|
||||||
hooks::QemuHooks,
|
hooks::QemuHooks,
|
||||||
Emulator,
|
Emulator,
|
||||||
@ -18,6 +17,7 @@ use crate::{
|
|||||||
|
|
||||||
static DRCOV_IDS: Mutex<Option<Vec<u64>>> = Mutex::new(None);
|
static DRCOV_IDS: Mutex<Option<Vec<u64>>> = Mutex::new(None);
|
||||||
static DRCOV_MAP: Mutex<Option<HashMap<GuestAddr, u64>>> = Mutex::new(None);
|
static DRCOV_MAP: Mutex<Option<HashMap<GuestAddr, u64>>> = Mutex::new(None);
|
||||||
|
static DRCOV_LENGTHS: Mutex<Option<HashMap<GuestAddr, GuestUsize>>> = Mutex::new(None);
|
||||||
|
|
||||||
#[derive(Debug, Default, Serialize, Deserialize)]
|
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||||
pub struct QemuDrCovMetadata {
|
pub struct QemuDrCovMetadata {
|
||||||
@ -55,6 +55,7 @@ impl QemuDrCovHelper {
|
|||||||
let _ = DRCOV_IDS.lock().unwrap().insert(vec![]);
|
let _ = DRCOV_IDS.lock().unwrap().insert(vec![]);
|
||||||
}
|
}
|
||||||
let _ = DRCOV_MAP.lock().unwrap().insert(HashMap::new());
|
let _ = DRCOV_MAP.lock().unwrap().insert(HashMap::new());
|
||||||
|
let _ = DRCOV_LENGTHS.lock().unwrap().insert(HashMap::new());
|
||||||
Self {
|
Self {
|
||||||
filter,
|
filter,
|
||||||
module_mapping,
|
module_mapping,
|
||||||
@ -80,6 +81,7 @@ where
|
|||||||
{
|
{
|
||||||
hooks.blocks(
|
hooks.blocks(
|
||||||
Some(gen_unique_block_ids::<QT, S>),
|
Some(gen_unique_block_ids::<QT, S>),
|
||||||
|
Some(gen_block_lengths::<QT, S>),
|
||||||
Some(exec_trace_block::<QT, S>),
|
Some(exec_trace_block::<QT, S>),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -88,13 +90,15 @@ where
|
|||||||
|
|
||||||
fn post_exec<OT>(
|
fn post_exec<OT>(
|
||||||
&mut self,
|
&mut self,
|
||||||
emulator: &Emulator,
|
_emulator: &Emulator,
|
||||||
_input: &S::Input,
|
_input: &S::Input,
|
||||||
_observers: &mut OT,
|
_observers: &mut OT,
|
||||||
_exit_kind: &mut ExitKind,
|
_exit_kind: &mut ExitKind,
|
||||||
) where
|
) where
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
{
|
{
|
||||||
|
let lengths_opt = DRCOV_LENGTHS.lock().unwrap();
|
||||||
|
let lengths = lengths_opt.as_ref().unwrap();
|
||||||
if self.full_trace {
|
if self.full_trace {
|
||||||
if DRCOV_IDS.lock().unwrap().as_ref().unwrap().len() > self.drcov_len {
|
if DRCOV_IDS.lock().unwrap().as_ref().unwrap().len() > self.drcov_len {
|
||||||
let mut drcov_vec = Vec::<DrCovBasicBlock>::new();
|
let mut drcov_vec = Vec::<DrCovBasicBlock>::new();
|
||||||
@ -114,27 +118,16 @@ where
|
|||||||
continue 'pcs_full;
|
continue 'pcs_full;
|
||||||
}
|
}
|
||||||
if *idm == *id {
|
if *idm == *id {
|
||||||
#[cfg(cpu_target = "arm")]
|
match lengths.get(pc) {
|
||||||
let mode = if pc & 1 == 1 {
|
Some(block_length) => {
|
||||||
Some(capstone::arch::arm::ArchMode::Thumb.into())
|
|
||||||
} else {
|
|
||||||
Some(capstone::arch::arm::ArchMode::Arm.into())
|
|
||||||
};
|
|
||||||
#[cfg(not(cpu_target = "arm"))]
|
|
||||||
let mode = None;
|
|
||||||
|
|
||||||
match pc2basicblock(*pc, emulator, mode) {
|
|
||||||
Ok(block) => {
|
|
||||||
let mut block_len = 0;
|
|
||||||
for instr in &block {
|
|
||||||
block_len += instr.insn_len;
|
|
||||||
}
|
|
||||||
drcov_vec.push(DrCovBasicBlock::new(
|
drcov_vec.push(DrCovBasicBlock::new(
|
||||||
*pc as usize,
|
*pc as usize,
|
||||||
*pc as usize + block_len,
|
*pc as usize + *block_length as usize,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
Err(r) => log::info!("{r:#?}"),
|
None => {
|
||||||
|
log::info!("Failed to find block length for: {pc:}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -162,26 +155,16 @@ where
|
|||||||
if !module_found {
|
if !module_found {
|
||||||
continue 'pcs;
|
continue 'pcs;
|
||||||
}
|
}
|
||||||
|
match lengths.get(pc) {
|
||||||
#[cfg(cpu_target = "arm")]
|
Some(block_length) => {
|
||||||
let mode = if pc & 1 == 1 {
|
drcov_vec.push(DrCovBasicBlock::new(
|
||||||
Some(capstone::arch::arm::ArchMode::Thumb.into())
|
*pc as usize,
|
||||||
} else {
|
*pc as usize + *block_length as usize,
|
||||||
Some(capstone::arch::arm::ArchMode::Arm.into())
|
));
|
||||||
};
|
}
|
||||||
#[cfg(not(cpu_target = "arm"))]
|
None => {
|
||||||
let mode = None;
|
log::info!("Failed to find block length for: {pc:}");
|
||||||
|
|
||||||
match pc2basicblock(*pc, emulator, mode) {
|
|
||||||
Ok(block) => {
|
|
||||||
let mut block_len = 0;
|
|
||||||
for instr in &block {
|
|
||||||
block_len += instr.insn_len;
|
|
||||||
}
|
|
||||||
drcov_vec
|
|
||||||
.push(DrCovBasicBlock::new(*pc as usize, *pc as usize + block_len));
|
|
||||||
}
|
}
|
||||||
Err(r) => log::info!("{r:#?}"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,6 +232,31 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn gen_block_lengths<QT, S>(
|
||||||
|
hooks: &mut QemuHooks<'_, QT, S>,
|
||||||
|
_state: Option<&mut S>,
|
||||||
|
pc: GuestAddr,
|
||||||
|
block_length: GuestUsize,
|
||||||
|
) where
|
||||||
|
S: HasMetadata,
|
||||||
|
S: UsesInput,
|
||||||
|
QT: QemuHelperTuple<S>,
|
||||||
|
{
|
||||||
|
let drcov_helper = hooks
|
||||||
|
.helpers()
|
||||||
|
.match_first_type::<QemuDrCovHelper>()
|
||||||
|
.unwrap();
|
||||||
|
if !drcov_helper.must_instrument(pc) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DRCOV_LENGTHS
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.insert(pc, block_length);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn exec_trace_block<QT, S>(hooks: &mut QemuHooks<'_, QT, S>, _state: Option<&mut S>, id: u64)
|
pub fn exec_trace_block<QT, S>(hooks: &mut QemuHooks<'_, QT, S>, _state: Option<&mut S>, id: u64)
|
||||||
where
|
where
|
||||||
S: HasMetadata,
|
S: HasMetadata,
|
||||||
|
@ -336,6 +336,7 @@ extern "C" {
|
|||||||
// void libafl_add_block_hook(uint64_t (*gen)(target_ulong pc), void (*exec)(uint64_t id));
|
// void libafl_add_block_hook(uint64_t (*gen)(target_ulong pc), void (*exec)(uint64_t id));
|
||||||
fn libafl_add_block_hook(
|
fn libafl_add_block_hook(
|
||||||
gen: Option<extern "C" fn(GuestAddr, u64) -> u64>,
|
gen: Option<extern "C" fn(GuestAddr, u64) -> u64>,
|
||||||
|
post_gen: Option<extern "C" fn(GuestAddr, GuestUsize, u64)>,
|
||||||
exec: Option<extern "C" fn(u64, u64)>,
|
exec: Option<extern "C" fn(u64, u64)>,
|
||||||
data: u64,
|
data: u64,
|
||||||
);
|
);
|
||||||
@ -1037,10 +1038,11 @@ impl Emulator {
|
|||||||
pub fn add_block_hooks(
|
pub fn add_block_hooks(
|
||||||
&self,
|
&self,
|
||||||
gen: Option<extern "C" fn(GuestAddr, u64) -> u64>,
|
gen: Option<extern "C" fn(GuestAddr, u64) -> u64>,
|
||||||
|
post_gen: Option<extern "C" fn(GuestAddr, GuestUsize, u64)>,
|
||||||
exec: Option<extern "C" fn(u64, u64)>,
|
exec: Option<extern "C" fn(u64, u64)>,
|
||||||
data: u64,
|
data: u64,
|
||||||
) {
|
) {
|
||||||
unsafe { libafl_add_block_hook(gen, exec, data) }
|
unsafe { libafl_add_block_hook(gen, post_gen, exec, data) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_read_hooks(
|
pub fn add_read_hooks(
|
||||||
|
@ -15,7 +15,7 @@ pub use crate::emu::SyscallHookResult;
|
|||||||
use crate::{
|
use crate::{
|
||||||
emu::{Emulator, FatPtr, MemAccessInfo, SKIP_EXEC_HOOK},
|
emu::{Emulator, FatPtr, MemAccessInfo, SKIP_EXEC_HOOK},
|
||||||
helper::QemuHelperTuple,
|
helper::QemuHelperTuple,
|
||||||
GuestAddr,
|
GuestAddr, GuestUsize,
|
||||||
};
|
};
|
||||||
|
|
||||||
// all kinds of hooks
|
// all kinds of hooks
|
||||||
@ -136,7 +136,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static mut BLOCK_HOOKS: Vec<(Hook, Hook)> = vec![];
|
static mut BLOCK_HOOKS: Vec<(Hook, Hook, Hook)> = vec![];
|
||||||
|
|
||||||
extern "C" fn gen_block_hook_wrapper<QT, S>(pc: GuestAddr, index: u64) -> u64
|
extern "C" fn gen_block_hook_wrapper<QT, S>(pc: GuestAddr, index: u64) -> u64
|
||||||
where
|
where
|
||||||
@ -145,7 +145,7 @@ where
|
|||||||
{
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
let hooks = get_qemu_hooks::<QT, S>();
|
let hooks = get_qemu_hooks::<QT, S>();
|
||||||
let (gen, _) = &mut BLOCK_HOOKS[index as usize];
|
let (gen, _, _) = &mut BLOCK_HOOKS[index as usize];
|
||||||
match gen {
|
match gen {
|
||||||
Hook::Function(ptr) => {
|
Hook::Function(ptr) => {
|
||||||
let func: fn(&mut QemuHooks<'_, QT, S>, Option<&mut S>, GuestAddr) -> Option<u64> =
|
let func: fn(&mut QemuHooks<'_, QT, S>, Option<&mut S>, GuestAddr) -> Option<u64> =
|
||||||
@ -163,6 +163,34 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" fn gen_post_block_hook_wrapper<QT, S>(
|
||||||
|
pc: GuestAddr,
|
||||||
|
block_length: GuestUsize,
|
||||||
|
index: u64,
|
||||||
|
) where
|
||||||
|
S: UsesInput,
|
||||||
|
QT: QemuHelperTuple<S>,
|
||||||
|
{
|
||||||
|
unsafe {
|
||||||
|
let hooks = get_qemu_hooks::<QT, S>();
|
||||||
|
let (_, post_gen, _) = &mut BLOCK_HOOKS[index as usize];
|
||||||
|
match post_gen {
|
||||||
|
Hook::Function(ptr) => {
|
||||||
|
let func: fn(&mut QemuHooks<'_, QT, S>, Option<&mut S>, GuestAddr, GuestUsize) =
|
||||||
|
transmute(*ptr);
|
||||||
|
(func)(hooks, inprocess_get_state::<S>(), pc, block_length);
|
||||||
|
}
|
||||||
|
Hook::Closure(ptr) => {
|
||||||
|
let func: &mut Box<
|
||||||
|
dyn FnMut(&mut QemuHooks<'_, QT, S>, Option<&mut S>, GuestAddr, GuestUsize),
|
||||||
|
> = transmute(ptr);
|
||||||
|
(func)(hooks, inprocess_get_state::<S>(), pc, block_length);
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" fn exec_block_hook_wrapper<QT, S>(id: u64, index: u64)
|
extern "C" fn exec_block_hook_wrapper<QT, S>(id: u64, index: u64)
|
||||||
where
|
where
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
@ -170,7 +198,7 @@ where
|
|||||||
{
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
let hooks = get_qemu_hooks::<QT, S>();
|
let hooks = get_qemu_hooks::<QT, S>();
|
||||||
let (_, exec) = &mut BLOCK_HOOKS[index as usize];
|
let (_, _, exec) = &mut BLOCK_HOOKS[index as usize];
|
||||||
match exec {
|
match exec {
|
||||||
Hook::Function(ptr) => {
|
Hook::Function(ptr) => {
|
||||||
let func: fn(&mut QemuHooks<'_, QT, S>, Option<&mut S>, u64) = transmute(*ptr);
|
let func: fn(&mut QemuHooks<'_, QT, S>, Option<&mut S>, u64) = transmute(*ptr);
|
||||||
@ -859,6 +887,9 @@ where
|
|||||||
pub fn blocks(
|
pub fn blocks(
|
||||||
&self,
|
&self,
|
||||||
generation_hook: Option<fn(&mut Self, Option<&mut S>, pc: GuestAddr) -> Option<u64>>,
|
generation_hook: Option<fn(&mut Self, Option<&mut S>, pc: GuestAddr) -> Option<u64>>,
|
||||||
|
post_generation_hook: Option<
|
||||||
|
fn(&mut Self, Option<&mut S>, pc: GuestAddr, block_length: GuestUsize),
|
||||||
|
>,
|
||||||
execution_hook: Option<fn(&mut Self, Option<&mut S>, id: u64)>,
|
execution_hook: Option<fn(&mut Self, Option<&mut S>, id: u64)>,
|
||||||
) {
|
) {
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -869,6 +900,11 @@ where
|
|||||||
} else {
|
} else {
|
||||||
Some(gen_block_hook_wrapper::<QT, S>)
|
Some(gen_block_hook_wrapper::<QT, S>)
|
||||||
},
|
},
|
||||||
|
if post_generation_hook.is_none() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(gen_post_block_hook_wrapper::<QT, S>)
|
||||||
|
},
|
||||||
if execution_hook.is_none() {
|
if execution_hook.is_none() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
@ -880,6 +916,9 @@ where
|
|||||||
generation_hook.map_or(Hook::Empty, |hook| {
|
generation_hook.map_or(Hook::Empty, |hook| {
|
||||||
Hook::Function(hook as *const libc::c_void)
|
Hook::Function(hook as *const libc::c_void)
|
||||||
}),
|
}),
|
||||||
|
post_generation_hook.map_or(Hook::Empty, |hook| {
|
||||||
|
Hook::Function(hook as *const libc::c_void)
|
||||||
|
}),
|
||||||
execution_hook.map_or(Hook::Empty, |hook| {
|
execution_hook.map_or(Hook::Empty, |hook| {
|
||||||
Hook::Function(hook as *const libc::c_void)
|
Hook::Function(hook as *const libc::c_void)
|
||||||
}),
|
}),
|
||||||
@ -892,6 +931,9 @@ where
|
|||||||
generation_hook: Option<
|
generation_hook: Option<
|
||||||
Box<dyn FnMut(&'a mut Self, Option<&'a mut S>, GuestAddr) -> Option<u64>>,
|
Box<dyn FnMut(&'a mut Self, Option<&'a mut S>, GuestAddr) -> Option<u64>>,
|
||||||
>,
|
>,
|
||||||
|
post_generation_hook: Option<
|
||||||
|
Box<dyn FnMut(&'a mut Self, Option<&'a mut S>, GuestAddr, GuestUsize)>,
|
||||||
|
>,
|
||||||
execution_hook: Option<Box<dyn FnMut(&'a mut Self, Option<&'a mut S>, u64)>>,
|
execution_hook: Option<Box<dyn FnMut(&'a mut Self, Option<&'a mut S>, u64)>>,
|
||||||
) {
|
) {
|
||||||
let index = BLOCK_HOOKS.len();
|
let index = BLOCK_HOOKS.len();
|
||||||
@ -901,6 +943,11 @@ where
|
|||||||
} else {
|
} else {
|
||||||
Some(gen_block_hook_wrapper::<QT, S>)
|
Some(gen_block_hook_wrapper::<QT, S>)
|
||||||
},
|
},
|
||||||
|
if post_generation_hook.is_none() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(gen_post_block_hook_wrapper::<QT, S>)
|
||||||
|
},
|
||||||
if execution_hook.is_none() {
|
if execution_hook.is_none() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
@ -910,6 +957,7 @@ where
|
|||||||
);
|
);
|
||||||
BLOCK_HOOKS.push((
|
BLOCK_HOOKS.push((
|
||||||
generation_hook.map_or(Hook::Empty, |hook| Hook::Closure(transmute(hook))),
|
generation_hook.map_or(Hook::Empty, |hook| Hook::Closure(transmute(hook))),
|
||||||
|
post_generation_hook.map_or(Hook::Empty, |hook| Hook::Closure(transmute(hook))),
|
||||||
execution_hook.map_or(Hook::Empty, |hook| Hook::Closure(transmute(hook))),
|
execution_hook.map_or(Hook::Empty, |hook| Hook::Closure(transmute(hook))),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -917,6 +965,9 @@ where
|
|||||||
pub fn blocks_raw(
|
pub fn blocks_raw(
|
||||||
&self,
|
&self,
|
||||||
generation_hook: Option<fn(&mut Self, Option<&mut S>, pc: GuestAddr) -> Option<u64>>,
|
generation_hook: Option<fn(&mut Self, Option<&mut S>, pc: GuestAddr) -> Option<u64>>,
|
||||||
|
post_generation_hook: Option<
|
||||||
|
fn(&mut Self, Option<&mut S>, pc: GuestAddr, block_length: GuestUsize),
|
||||||
|
>,
|
||||||
execution_hook: Option<extern "C" fn(id: u64, data: u64)>,
|
execution_hook: Option<extern "C" fn(id: u64, data: u64)>,
|
||||||
) {
|
) {
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -927,6 +978,11 @@ where
|
|||||||
} else {
|
} else {
|
||||||
Some(gen_block_hook_wrapper::<QT, S>)
|
Some(gen_block_hook_wrapper::<QT, S>)
|
||||||
},
|
},
|
||||||
|
if post_generation_hook.is_none() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(gen_post_block_hook_wrapper::<QT, S>)
|
||||||
|
},
|
||||||
execution_hook,
|
execution_hook,
|
||||||
index as u64,
|
index as u64,
|
||||||
);
|
);
|
||||||
@ -934,6 +990,9 @@ where
|
|||||||
generation_hook.map_or(Hook::Empty, |hook| {
|
generation_hook.map_or(Hook::Empty, |hook| {
|
||||||
Hook::Function(hook as *const libc::c_void)
|
Hook::Function(hook as *const libc::c_void)
|
||||||
}),
|
}),
|
||||||
|
post_generation_hook.map_or(Hook::Empty, |hook| {
|
||||||
|
Hook::Function(hook as *const libc::c_void)
|
||||||
|
}),
|
||||||
Hook::Empty,
|
Hook::Empty,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -74,8 +74,6 @@ pub mod asan;
|
|||||||
#[cfg(emulation_mode = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
pub use asan::{init_with_asan, QemuAsanHelper};
|
pub use asan::{init_with_asan, QemuAsanHelper};
|
||||||
|
|
||||||
pub mod blocks;
|
|
||||||
|
|
||||||
pub mod calls;
|
pub mod calls;
|
||||||
pub mod drcov;
|
pub mod drcov;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user