Fix regex fixing generated bindings for QEMU (#2163)

* Fix regex fixing generated bindings

* Do not write 2 times bindings to filesystem

* Update stub bindings

* fmt

* clippy

* fmt

* use `unsafe extern "C"` instead of `extern "C"`.
This commit is contained in:
Romain Malmain 2024-05-13 17:41:56 +02:00 committed by GitHub
parent c621a5e475
commit b0d95676f9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 155 additions and 139 deletions

View File

@ -155,7 +155,7 @@ pub fn generate(
bindings bindings
.allowlist_type("CPUX86State") .allowlist_type("CPUX86State")
.allowlist_type("X86CPU") .allowlist_type("X86CPU")
} else if cpu_target == "arssssm" { } else if cpu_target == "arm" {
bindings bindings
.allowlist_type("ARMCPU") .allowlist_type("ARMCPU")
.allowlist_type("ARMv7MState") .allowlist_type("ARMv7MState")

View File

@ -12,7 +12,6 @@ use std::{
ptr::addr_of_mut, ptr::addr_of_mut,
}; };
use regex::Regex;
use which::which; use which::which;
mod bindings; mod bindings;
@ -77,15 +76,9 @@ pub fn build_with_bindings(
let bind = bindings::generate(&build_result.build_dir, cpu_target, clang_args) let bind = bindings::generate(&build_result.build_dir, cpu_target, clang_args)
.expect("Failed to generate the bindings"); .expect("Failed to generate the bindings");
bind.write_to_file(bindings_file)
.expect("Faield to write to the bindings file");
// """Fix""" the bindings here // Write the final bindings
let contents = fs::write(bindings_file, bind.to_string()).expect("Unable to write file");
fs::read_to_string(bindings_file).expect("Should have been able to read the file");
let re = Regex::new("(Option<\\s*)unsafe( extern \"C\" fn\\(data: u64)").unwrap();
let replaced = re.replace_all(&contents, "$1$2");
fs::write(bindings_file, replaced.as_bytes()).expect("Unable to write file");
cargo_propagate_rpath(); cargo_propagate_rpath();
} }

View File

@ -13622,7 +13622,7 @@ impl Default for libafl_hook {
extern "C" { extern "C" {
pub fn libafl_qemu_set_hook( pub fn libafl_qemu_set_hook(
pc: target_ulong, pc: target_ulong,
callback: ::std::option::Option< extern "C" fn(data: u64, pc: target_ulong)>, callback: ::std::option::Option<unsafe extern "C" fn(data: u64, pc: target_ulong)>,
data: u64, data: u64,
invalidate: ::std::os::raw::c_int, invalidate: ::std::os::raw::c_int,
) -> usize; ) -> usize;
@ -13645,7 +13645,7 @@ extern "C" {
extern "C" { extern "C" {
pub fn libafl_add_backdoor_hook( pub fn libafl_add_backdoor_hook(
exec: ::std::option::Option< exec: ::std::option::Option<
extern "C" fn(data: u64, cpu: *mut CPUArchState, pc: target_ulong), unsafe extern "C" fn(data: u64, cpu: *mut CPUArchState, pc: target_ulong),
>, >,
data: u64, data: u64,
) -> usize; ) -> usize;
@ -13659,9 +13659,9 @@ extern "C" {
extern "C" { extern "C" {
pub fn libafl_add_edge_hook( pub fn libafl_add_edge_hook(
gen: ::std::option::Option< gen: ::std::option::Option<
extern "C" fn(data: u64, src: target_ulong, dst: target_ulong) -> u64, unsafe extern "C" fn(data: u64, src: target_ulong, dst: target_ulong) -> u64,
>, >,
exec: ::std::option::Option< extern "C" fn(data: u64, id: u64)>, exec: ::std::option::Option<unsafe extern "C" fn(data: u64, id: u64)>,
data: u64, data: u64,
) -> usize; ) -> usize;
} }
@ -13679,11 +13679,11 @@ extern "C" {
} }
extern "C" { extern "C" {
pub fn libafl_add_block_hook( pub fn libafl_add_block_hook(
gen: ::std::option::Option< extern "C" fn(data: u64, pc: target_ulong) -> u64>, gen: ::std::option::Option<unsafe extern "C" fn(data: u64, pc: target_ulong) -> u64>,
post_gen: ::std::option::Option< post_gen: ::std::option::Option<
extern "C" fn(data: u64, pc: target_ulong, block_length: target_ulong), unsafe extern "C" fn(data: u64, pc: target_ulong, block_length: target_ulong),
>, >,
exec: ::std::option::Option< extern "C" fn(data: u64, id: u64)>, exec: ::std::option::Option<unsafe extern "C" fn(data: u64, id: u64)>,
data: u64, data: u64,
) -> usize; ) -> usize;
} }
@ -13709,12 +13709,12 @@ extern "C" {
oi: MemOpIdx, oi: MemOpIdx,
) -> u64, ) -> u64,
>, >,
exec1: ::std::option::Option< extern "C" fn(data: u64, id: u64, addr: target_ulong)>, exec1: ::std::option::Option<unsafe extern "C" fn(data: u64, id: u64, addr: target_ulong)>,
exec2: ::std::option::Option< extern "C" fn(data: u64, id: u64, addr: target_ulong)>, exec2: ::std::option::Option<unsafe extern "C" fn(data: u64, id: u64, addr: target_ulong)>,
exec4: ::std::option::Option< extern "C" fn(data: u64, id: u64, addr: target_ulong)>, exec4: ::std::option::Option<unsafe extern "C" fn(data: u64, id: u64, addr: target_ulong)>,
exec8: ::std::option::Option< extern "C" fn(data: u64, id: u64, addr: target_ulong)>, exec8: ::std::option::Option<unsafe extern "C" fn(data: u64, id: u64, addr: target_ulong)>,
execN: ::std::option::Option< execN: ::std::option::Option<
extern "C" fn(data: u64, id: u64, addr: target_ulong, size: usize), unsafe extern "C" fn(data: u64, id: u64, addr: target_ulong, size: usize),
>, >,
data: u64, data: u64,
) -> usize; ) -> usize;
@ -13729,12 +13729,12 @@ extern "C" {
oi: MemOpIdx, oi: MemOpIdx,
) -> u64, ) -> u64,
>, >,
exec1: ::std::option::Option< extern "C" fn(data: u64, id: u64, addr: target_ulong)>, exec1: ::std::option::Option<unsafe extern "C" fn(data: u64, id: u64, addr: target_ulong)>,
exec2: ::std::option::Option< extern "C" fn(data: u64, id: u64, addr: target_ulong)>, exec2: ::std::option::Option<unsafe extern "C" fn(data: u64, id: u64, addr: target_ulong)>,
exec4: ::std::option::Option< extern "C" fn(data: u64, id: u64, addr: target_ulong)>, exec4: ::std::option::Option<unsafe extern "C" fn(data: u64, id: u64, addr: target_ulong)>,
exec8: ::std::option::Option< extern "C" fn(data: u64, id: u64, addr: target_ulong)>, exec8: ::std::option::Option<unsafe extern "C" fn(data: u64, id: u64, addr: target_ulong)>,
execN: ::std::option::Option< execN: ::std::option::Option<
extern "C" fn(data: u64, id: u64, addr: target_ulong, size: usize), unsafe extern "C" fn(data: u64, id: u64, addr: target_ulong, size: usize),
>, >,
data: u64, data: u64,
) -> usize; ) -> usize;
@ -13760,12 +13760,12 @@ extern "C" {
extern "C" { extern "C" {
pub fn libafl_add_cmp_hook( pub fn libafl_add_cmp_hook(
gen: ::std::option::Option< gen: ::std::option::Option<
extern "C" fn(data: u64, pc: target_ulong, size: usize) -> u64, unsafe extern "C" fn(data: u64, pc: target_ulong, size: usize) -> u64,
>, >,
exec1: ::std::option::Option< extern "C" fn(data: u64, id: u64, v0: u8, v1: u8)>, exec1: ::std::option::Option<unsafe extern "C" fn(data: u64, id: u64, v0: u8, v1: u8)>,
exec2: ::std::option::Option< extern "C" fn(data: u64, id: u64, v0: u16, v1: u16)>, exec2: ::std::option::Option<unsafe extern "C" fn(data: u64, id: u64, v0: u16, v1: u16)>,
exec4: ::std::option::Option< extern "C" fn(data: u64, id: u64, v0: u32, v1: u32)>, exec4: ::std::option::Option<unsafe extern "C" fn(data: u64, id: u64, v0: u32, v1: u32)>,
exec8: ::std::option::Option< extern "C" fn(data: u64, id: u64, v0: u64, v1: u64)>, exec8: ::std::option::Option<unsafe extern "C" fn(data: u64, id: u64, v0: u64, v1: u64)>,
data: u64, data: u64,
) -> usize; ) -> usize;
} }
@ -13863,7 +13863,7 @@ extern "C" {
} }
extern "C" { extern "C" {
pub fn libafl_add_new_thread_hook( pub fn libafl_add_new_thread_hook(
callback: ::std::option::Option< extern "C" fn(data: u64, tid: u32) -> bool>, callback: ::std::option::Option<unsafe extern "C" fn(data: u64, tid: u32) -> bool>,
data: u64, data: u64,
) -> usize; ) -> usize;
} }

View File

@ -650,8 +650,8 @@ where
pub fn add_edge_hooks<T: Into<HookData>>( pub fn add_edge_hooks<T: Into<HookData>>(
&self, &self,
data: T, data: T,
gen: Option<extern "C" fn(T, GuestAddr, GuestAddr) -> u64>, gen: Option<unsafe extern "C" fn(T, GuestAddr, GuestAddr) -> u64>,
exec: Option<extern "C" fn(T, u64)>, exec: Option<unsafe extern "C" fn(T, u64)>,
) -> EdgeHookId { ) -> EdgeHookId {
self.qemu.add_edge_hooks(data, gen, exec) self.qemu.add_edge_hooks(data, gen, exec)
} }
@ -662,9 +662,9 @@ where
pub fn add_block_hooks<T: Into<HookData>>( pub fn add_block_hooks<T: Into<HookData>>(
&self, &self,
data: T, data: T,
gen: Option<extern "C" fn(T, GuestAddr) -> u64>, gen: Option<unsafe extern "C" fn(T, GuestAddr) -> u64>,
post_gen: Option<extern "C" fn(T, GuestAddr, GuestUsize)>, post_gen: Option<unsafe extern "C" fn(T, GuestAddr, GuestUsize)>,
exec: Option<extern "C" fn(T, u64)>, exec: Option<unsafe extern "C" fn(T, u64)>,
) -> BlockHookId { ) -> BlockHookId {
self.qemu.add_block_hooks(data, gen, post_gen, exec) self.qemu.add_block_hooks(data, gen, post_gen, exec)
} }
@ -675,12 +675,12 @@ where
pub fn add_read_hooks<T: Into<HookData>>( pub fn add_read_hooks<T: Into<HookData>>(
&self, &self,
data: T, data: T,
gen: Option<extern "C" fn(T, GuestAddr, *mut TCGTemp, MemAccessInfo) -> u64>, gen: Option<unsafe extern "C" fn(T, GuestAddr, *mut TCGTemp, MemAccessInfo) -> u64>,
exec1: Option<extern "C" fn(T, u64, GuestAddr)>, exec1: Option<unsafe extern "C" fn(T, u64, GuestAddr)>,
exec2: Option<extern "C" fn(T, u64, GuestAddr)>, exec2: Option<unsafe extern "C" fn(T, u64, GuestAddr)>,
exec4: Option<extern "C" fn(T, u64, GuestAddr)>, exec4: Option<unsafe extern "C" fn(T, u64, GuestAddr)>,
exec8: Option<extern "C" fn(T, u64, GuestAddr)>, exec8: Option<unsafe extern "C" fn(T, u64, GuestAddr)>,
exec_n: Option<extern "C" fn(T, u64, GuestAddr, usize)>, exec_n: Option<unsafe extern "C" fn(T, u64, GuestAddr, usize)>,
) -> ReadHookId { ) -> ReadHookId {
self.qemu self.qemu
.add_read_hooks(data, gen, exec1, exec2, exec4, exec8, exec_n) .add_read_hooks(data, gen, exec1, exec2, exec4, exec8, exec_n)
@ -693,12 +693,12 @@ where
pub fn add_write_hooks<T: Into<HookData>>( pub fn add_write_hooks<T: Into<HookData>>(
&self, &self,
data: T, data: T,
gen: Option<extern "C" fn(T, GuestAddr, *mut TCGTemp, MemAccessInfo) -> u64>, gen: Option<unsafe extern "C" fn(T, GuestAddr, *mut TCGTemp, MemAccessInfo) -> u64>,
exec1: Option<extern "C" fn(T, u64, GuestAddr)>, exec1: Option<unsafe extern "C" fn(T, u64, GuestAddr)>,
exec2: Option<extern "C" fn(T, u64, GuestAddr)>, exec2: Option<unsafe extern "C" fn(T, u64, GuestAddr)>,
exec4: Option<extern "C" fn(T, u64, GuestAddr)>, exec4: Option<unsafe extern "C" fn(T, u64, GuestAddr)>,
exec8: Option<extern "C" fn(T, u64, GuestAddr)>, exec8: Option<unsafe extern "C" fn(T, u64, GuestAddr)>,
exec_n: Option<extern "C" fn(T, u64, GuestAddr, usize)>, exec_n: Option<unsafe extern "C" fn(T, u64, GuestAddr, usize)>,
) -> WriteHookId { ) -> WriteHookId {
self.qemu self.qemu
.add_write_hooks(data, gen, exec1, exec2, exec4, exec8, exec_n) .add_write_hooks(data, gen, exec1, exec2, exec4, exec8, exec_n)
@ -710,11 +710,11 @@ where
pub fn add_cmp_hooks<T: Into<HookData>>( pub fn add_cmp_hooks<T: Into<HookData>>(
&self, &self,
data: T, data: T,
gen: Option<extern "C" fn(T, GuestAddr, usize) -> u64>, gen: Option<unsafe extern "C" fn(T, GuestAddr, usize) -> u64>,
exec1: Option<extern "C" fn(T, u64, u8, u8)>, exec1: Option<unsafe extern "C" fn(T, u64, u8, u8)>,
exec2: Option<extern "C" fn(T, u64, u16, u16)>, exec2: Option<unsafe extern "C" fn(T, u64, u16, u16)>,
exec4: Option<extern "C" fn(T, u64, u32, u32)>, exec4: Option<unsafe extern "C" fn(T, u64, u32, u32)>,
exec8: Option<extern "C" fn(T, u64, u64, u64)>, exec8: Option<unsafe extern "C" fn(T, u64, u64, u64)>,
) -> CmpHookId { ) -> CmpHookId {
self.qemu self.qemu
.add_cmp_hooks(data, gen, exec1, exec2, exec4, exec8) .add_cmp_hooks(data, gen, exec1, exec2, exec4, exec8)

View File

@ -572,7 +572,7 @@ where
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( unsafe extern "C" fn(
&mut HookState<1, EdgeHookId>, &mut HookState<1, EdgeHookId>,
src: GuestAddr, src: GuestAddr,
dest: GuestAddr, dest: GuestAddr,
@ -581,7 +581,7 @@ where
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, EdgeHookId>, id: u64) unsafe extern "C" fn(&mut HookState<1, EdgeHookId>, id: u64)
); );
EDGE_HOOKS.push(Box::pin(HookState { EDGE_HOOKS.push(Box::pin(HookState {
id: EdgeHookId(0), id: EdgeHookId(0),
@ -609,29 +609,29 @@ where
generation_hook: Hook< generation_hook: Hook<
fn(&mut Self, Option<&mut S>, pc: GuestAddr) -> Option<u64>, fn(&mut Self, Option<&mut S>, pc: GuestAddr) -> Option<u64>,
Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, GuestAddr) -> Option<u64>>, Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, GuestAddr) -> Option<u64>>,
extern "C" fn(*const (), pc: GuestAddr) -> u64, unsafe extern "C" fn(*const (), pc: GuestAddr) -> u64,
>, >,
post_generation_hook: Hook< post_generation_hook: Hook<
fn(&mut Self, Option<&mut S>, pc: GuestAddr, block_length: GuestUsize), fn(&mut Self, Option<&mut S>, pc: GuestAddr, block_length: GuestUsize),
Box<dyn for<'a> FnMut(&'a mut Self, Option<&mut S>, GuestAddr, GuestUsize)>, Box<dyn for<'a> FnMut(&'a mut Self, Option<&mut S>, GuestAddr, GuestUsize)>,
extern "C" fn(*const (), pc: GuestAddr, block_length: GuestUsize), unsafe extern "C" fn(*const (), pc: GuestAddr, block_length: GuestUsize),
>, >,
execution_hook: Hook< execution_hook: Hook<
fn(&mut Self, Option<&mut S>, id: u64), fn(&mut Self, Option<&mut S>, id: u64),
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), unsafe extern "C" fn(*const (), id: u64),
>, >,
) -> BlockHookId { ) -> 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, BlockHookId>, pc: GuestAddr) -> u64 unsafe 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( unsafe extern "C" fn(
&mut HookState<1, BlockHookId>, &mut HookState<1, BlockHookId>,
pc: GuestAddr, pc: GuestAddr,
block_length: GuestUsize, block_length: GuestUsize,
@ -640,7 +640,7 @@ where
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, BlockHookId>, id: u64) unsafe extern "C" fn(&mut HookState<1, BlockHookId>, id: u64)
); );
BLOCK_HOOKS.push(Box::pin(HookState { BLOCK_HOOKS.push(Box::pin(HookState {
id: BlockHookId(0), id: BlockHookId(0),
@ -684,39 +684,44 @@ where
MemAccessInfo, MemAccessInfo,
) -> Option<u64>, ) -> Option<u64>,
>, >,
extern "C" fn(*const (), pc: GuestAddr, addr: *mut TCGTemp, info: MemAccessInfo) -> u64, unsafe extern "C" fn(
*const (),
pc: GuestAddr,
addr: *mut TCGTemp,
info: MemAccessInfo,
) -> u64,
>, >,
execution_hook_1: Hook< execution_hook_1: Hook<
fn(&mut Self, Option<&mut S>, id: u64, addr: GuestAddr), fn(&mut Self, Option<&mut S>, id: u64, addr: GuestAddr),
Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u64, GuestAddr)>, Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u64, GuestAddr)>,
extern "C" fn(*const (), id: u64, addr: GuestAddr), unsafe extern "C" fn(*const (), id: u64, addr: GuestAddr),
>, >,
execution_hook_2: Hook< execution_hook_2: Hook<
fn(&mut Self, Option<&mut S>, id: u64, addr: GuestAddr), fn(&mut Self, Option<&mut S>, id: u64, addr: GuestAddr),
Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u64, GuestAddr)>, Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u64, GuestAddr)>,
extern "C" fn(*const (), id: u64, addr: GuestAddr), unsafe extern "C" fn(*const (), id: u64, addr: GuestAddr),
>, >,
execution_hook_4: Hook< execution_hook_4: Hook<
fn(&mut Self, Option<&mut S>, id: u64, addr: GuestAddr), fn(&mut Self, Option<&mut S>, id: u64, addr: GuestAddr),
Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u64, GuestAddr)>, Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u64, GuestAddr)>,
extern "C" fn(*const (), id: u64, addr: GuestAddr), unsafe extern "C" fn(*const (), id: u64, addr: GuestAddr),
>, >,
execution_hook_8: Hook< execution_hook_8: Hook<
fn(&mut Self, Option<&mut S>, id: u64, addr: GuestAddr), fn(&mut Self, Option<&mut S>, id: u64, addr: GuestAddr),
Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u64, GuestAddr)>, Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u64, GuestAddr)>,
extern "C" fn(*const (), id: u64, addr: GuestAddr), unsafe extern "C" fn(*const (), id: u64, addr: GuestAddr),
>, >,
execution_hook_n: Hook< execution_hook_n: Hook<
fn(&mut Self, Option<&mut S>, id: u64, addr: GuestAddr, size: usize), fn(&mut Self, Option<&mut S>, id: u64, addr: GuestAddr, size: usize),
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), unsafe extern "C" fn(*const (), id: u64, addr: GuestAddr, size: usize),
>, >,
) -> ReadHookId { ) -> 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( unsafe extern "C" fn(
&mut HookState<5, ReadHookId>, &mut HookState<5, ReadHookId>,
pc: GuestAddr, pc: GuestAddr,
addr: *mut TCGTemp, addr: *mut TCGTemp,
@ -726,27 +731,32 @@ where
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, ReadHookId>, id: u64, addr: GuestAddr) unsafe 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, ReadHookId>, id: u64, addr: GuestAddr) unsafe 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, ReadHookId>, id: u64, addr: GuestAddr) unsafe 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, ReadHookId>, id: u64, addr: GuestAddr) unsafe 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, ReadHookId>, id: u64, addr: GuestAddr, size: usize) unsafe extern "C" fn(
&mut HookState<5, ReadHookId>,
id: u64,
addr: GuestAddr,
size: usize,
)
); );
READ_HOOKS.push(Box::pin(HookState { READ_HOOKS.push(Box::pin(HookState {
id: ReadHookId(0), id: ReadHookId(0),
@ -799,39 +809,44 @@ where
MemAccessInfo, MemAccessInfo,
) -> Option<u64>, ) -> Option<u64>,
>, >,
extern "C" fn(*const (), pc: GuestAddr, addr: *mut TCGTemp, info: MemAccessInfo) -> u64, unsafe extern "C" fn(
*const (),
pc: GuestAddr,
addr: *mut TCGTemp,
info: MemAccessInfo,
) -> u64,
>, >,
execution_hook_1: Hook< execution_hook_1: Hook<
fn(&mut Self, Option<&mut S>, id: u64, addr: GuestAddr), fn(&mut Self, Option<&mut S>, id: u64, addr: GuestAddr),
Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u64, GuestAddr)>, Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u64, GuestAddr)>,
extern "C" fn(*const (), id: u64, addr: GuestAddr), unsafe extern "C" fn(*const (), id: u64, addr: GuestAddr),
>, >,
execution_hook_2: Hook< execution_hook_2: Hook<
fn(&mut Self, Option<&mut S>, id: u64, addr: GuestAddr), fn(&mut Self, Option<&mut S>, id: u64, addr: GuestAddr),
Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u64, GuestAddr)>, Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u64, GuestAddr)>,
extern "C" fn(*const (), id: u64, addr: GuestAddr), unsafe extern "C" fn(*const (), id: u64, addr: GuestAddr),
>, >,
execution_hook_4: Hook< execution_hook_4: Hook<
fn(&mut Self, Option<&mut S>, id: u64, addr: GuestAddr), fn(&mut Self, Option<&mut S>, id: u64, addr: GuestAddr),
Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u64, GuestAddr)>, Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u64, GuestAddr)>,
extern "C" fn(*const (), id: u64, addr: GuestAddr), unsafe extern "C" fn(*const (), id: u64, addr: GuestAddr),
>, >,
execution_hook_8: Hook< execution_hook_8: Hook<
fn(&mut Self, Option<&mut S>, id: u64, addr: GuestAddr), fn(&mut Self, Option<&mut S>, id: u64, addr: GuestAddr),
Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u64, GuestAddr)>, Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u64, GuestAddr)>,
extern "C" fn(*const (), id: u64, addr: GuestAddr), unsafe extern "C" fn(*const (), id: u64, addr: GuestAddr),
>, >,
execution_hook_n: Hook< execution_hook_n: Hook<
fn(&mut Self, Option<&mut S>, id: u64, addr: GuestAddr, size: usize), fn(&mut Self, Option<&mut S>, id: u64, addr: GuestAddr, size: usize),
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), unsafe extern "C" fn(*const (), id: u64, addr: GuestAddr, size: usize),
>, >,
) -> WriteHookId { ) -> 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( unsafe extern "C" fn(
&mut HookState<5, WriteHookId>, &mut HookState<5, WriteHookId>,
pc: GuestAddr, pc: GuestAddr,
addr: *mut TCGTemp, addr: *mut TCGTemp,
@ -841,27 +856,27 @@ where
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, WriteHookId>, id: u64, addr: GuestAddr) unsafe 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, WriteHookId>, id: u64, addr: GuestAddr) unsafe 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, WriteHookId>, id: u64, addr: GuestAddr) unsafe 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, WriteHookId>, id: u64, addr: GuestAddr) unsafe 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( unsafe extern "C" fn(
&mut HookState<5, WriteHookId>, &mut HookState<5, WriteHookId>,
id: u64, id: u64,
addr: GuestAddr, addr: GuestAddr,
@ -906,54 +921,58 @@ where
Box< Box<
dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, GuestAddr, usize) -> Option<u64>, dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, GuestAddr, usize) -> Option<u64>,
>, >,
extern "C" fn(*const (), pc: GuestAddr, size: usize) -> u64, unsafe extern "C" fn(*const (), pc: GuestAddr, size: usize) -> u64,
>, >,
execution_hook_1: Hook< execution_hook_1: Hook<
fn(&mut Self, Option<&mut S>, id: u64, v0: u8, v1: u8), fn(&mut Self, Option<&mut S>, id: u64, v0: u8, v1: u8),
Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u64, u8, u8)>, Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u64, u8, u8)>,
extern "C" fn(*const (), id: u64, v0: u8, v1: u8), unsafe extern "C" fn(*const (), id: u64, v0: u8, v1: u8),
>, >,
execution_hook_2: Hook< execution_hook_2: Hook<
fn(&mut Self, Option<&mut S>, id: u64, v0: u16, v1: u16), fn(&mut Self, Option<&mut S>, id: u64, v0: u16, v1: u16),
Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u64, u16, u16)>, Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u64, u16, u16)>,
extern "C" fn(*const (), id: u64, v0: u16, v1: u16), unsafe extern "C" fn(*const (), id: u64, v0: u16, v1: u16),
>, >,
execution_hook_4: Hook< execution_hook_4: Hook<
fn(&mut Self, Option<&mut S>, id: u64, v0: u32, v1: u32), fn(&mut Self, Option<&mut S>, id: u64, v0: u32, v1: u32),
Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u64, u32, u32)>, Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u64, u32, u32)>,
extern "C" fn(*const (), id: u64, v0: u32, v1: u32), unsafe extern "C" fn(*const (), id: u64, v0: u32, v1: u32),
>, >,
execution_hook_8: Hook< execution_hook_8: Hook<
fn(&mut Self, Option<&mut S>, id: u64, v0: u64, v1: u64), fn(&mut Self, Option<&mut S>, id: u64, v0: u64, v1: u64),
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), unsafe extern "C" fn(*const (), id: u64, v0: u64, v1: u64),
>, >,
) -> CmpHookId { ) -> 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, CmpHookId>, pc: GuestAddr, size: usize) -> u64 unsafe 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, CmpHookId>, id: u64, v0: u8, v1: u8) unsafe 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, CmpHookId>, id: u64, v0: u16, v1: u16) unsafe 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, CmpHookId>, id: u64, v0: u32, v1: u32) unsafe 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, CmpHookId>, id: u64, v0: u64, v1: u64) unsafe extern "C" fn(&mut HookState<4, CmpHookId>, id: u64, v0: u64, v1: u64)
); );
CMP_HOOKS.push(Box::pin(HookState { CMP_HOOKS.push(Box::pin(HookState {
id: CmpHookId(0), id: CmpHookId(0),

View File

@ -761,13 +761,14 @@ impl Qemu {
pub fn add_edge_hooks<T: Into<HookData>>( pub fn add_edge_hooks<T: Into<HookData>>(
&self, &self,
data: T, data: T,
gen: Option<extern "C" fn(T, GuestAddr, GuestAddr) -> u64>, gen: Option<unsafe extern "C" fn(T, GuestAddr, GuestAddr) -> u64>,
exec: Option<extern "C" fn(T, u64)>, exec: Option<unsafe extern "C" fn(T, u64)>,
) -> EdgeHookId { ) -> 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> = transmute(gen); let gen: Option<unsafe extern "C" fn(u64, GuestAddr, GuestAddr) -> u64> =
let exec: Option<extern "C" fn(u64, u64)> = transmute(exec); transmute(gen);
let exec: Option<unsafe extern "C" fn(u64, u64)> = 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);
EdgeHookId(num) EdgeHookId(num)
} }
@ -777,15 +778,16 @@ impl Qemu {
pub fn add_block_hooks<T: Into<HookData>>( pub fn add_block_hooks<T: Into<HookData>>(
&self, &self,
data: T, data: T,
gen: Option<extern "C" fn(T, GuestAddr) -> u64>, gen: Option<unsafe extern "C" fn(T, GuestAddr) -> u64>,
post_gen: Option<extern "C" fn(T, GuestAddr, GuestUsize)>, post_gen: Option<unsafe extern "C" fn(T, GuestAddr, GuestUsize)>,
exec: Option<extern "C" fn(T, u64)>, exec: Option<unsafe extern "C" fn(T, u64)>,
) -> BlockHookId { ) -> BlockHookId {
unsafe { unsafe {
let data: u64 = data.into().0; let data: u64 = data.into().0;
let gen: Option<extern "C" fn(u64, GuestAddr) -> u64> = transmute(gen); let gen: Option<unsafe extern "C" fn(u64, GuestAddr) -> u64> = transmute(gen);
let post_gen: Option<extern "C" fn(u64, GuestAddr, GuestUsize)> = transmute(post_gen); let post_gen: Option<unsafe extern "C" fn(u64, GuestAddr, GuestUsize)> =
let exec: Option<extern "C" fn(u64, u64)> = transmute(exec); transmute(post_gen);
let exec: Option<unsafe extern "C" fn(u64, u64)> = 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);
BlockHookId(num) BlockHookId(num)
} }
@ -807,12 +809,12 @@ impl Qemu {
pub fn add_read_hooks<T: Into<HookData>>( pub fn add_read_hooks<T: Into<HookData>>(
&self, &self,
data: T, data: T,
gen: Option<extern "C" fn(T, GuestAddr, *mut TCGTemp, MemAccessInfo) -> u64>, gen: Option<unsafe extern "C" fn(T, GuestAddr, *mut TCGTemp, MemAccessInfo) -> u64>,
exec1: Option<extern "C" fn(T, u64, GuestAddr)>, exec1: Option<unsafe extern "C" fn(T, u64, GuestAddr)>,
exec2: Option<extern "C" fn(T, u64, GuestAddr)>, exec2: Option<unsafe extern "C" fn(T, u64, GuestAddr)>,
exec4: Option<extern "C" fn(T, u64, GuestAddr)>, exec4: Option<unsafe extern "C" fn(T, u64, GuestAddr)>,
exec8: Option<extern "C" fn(T, u64, GuestAddr)>, exec8: Option<unsafe extern "C" fn(T, u64, GuestAddr)>,
exec_n: Option<extern "C" fn(T, u64, GuestAddr, usize)>, exec_n: Option<unsafe extern "C" fn(T, u64, GuestAddr, usize)>,
) -> ReadHookId { ) -> ReadHookId {
unsafe { unsafe {
let data: u64 = data.into().0; let data: u64 = data.into().0;
@ -824,11 +826,12 @@ impl Qemu {
libafl_qemu_sys::MemOpIdx, libafl_qemu_sys::MemOpIdx,
) -> u64, ) -> u64,
> = transmute(gen); > = transmute(gen);
let exec1: Option<extern "C" fn(u64, u64, GuestAddr)> = transmute(exec1); let exec1: Option<unsafe extern "C" fn(u64, u64, GuestAddr)> = transmute(exec1);
let exec2: Option<extern "C" fn(u64, u64, GuestAddr)> = transmute(exec2); let exec2: Option<unsafe extern "C" fn(u64, u64, GuestAddr)> = transmute(exec2);
let exec4: Option<extern "C" fn(u64, u64, GuestAddr)> = transmute(exec4); let exec4: Option<unsafe extern "C" fn(u64, u64, GuestAddr)> = transmute(exec4);
let exec8: Option<extern "C" fn(u64, u64, GuestAddr)> = transmute(exec8); let exec8: Option<unsafe extern "C" fn(u64, u64, GuestAddr)> = transmute(exec8);
let exec_n: Option<extern "C" fn(u64, u64, GuestAddr, usize)> = transmute(exec_n); let exec_n: Option<unsafe extern "C" fn(u64, u64, GuestAddr, usize)> =
transmute(exec_n);
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,
); );
@ -841,12 +844,12 @@ impl Qemu {
pub fn add_write_hooks<T: Into<HookData>>( pub fn add_write_hooks<T: Into<HookData>>(
&self, &self,
data: T, data: T,
gen: Option<extern "C" fn(T, GuestAddr, *mut TCGTemp, MemAccessInfo) -> u64>, gen: Option<unsafe extern "C" fn(T, GuestAddr, *mut TCGTemp, MemAccessInfo) -> u64>,
exec1: Option<extern "C" fn(T, u64, GuestAddr)>, exec1: Option<unsafe extern "C" fn(T, u64, GuestAddr)>,
exec2: Option<extern "C" fn(T, u64, GuestAddr)>, exec2: Option<unsafe extern "C" fn(T, u64, GuestAddr)>,
exec4: Option<extern "C" fn(T, u64, GuestAddr)>, exec4: Option<unsafe extern "C" fn(T, u64, GuestAddr)>,
exec8: Option<extern "C" fn(T, u64, GuestAddr)>, exec8: Option<unsafe extern "C" fn(T, u64, GuestAddr)>,
exec_n: Option<extern "C" fn(T, u64, GuestAddr, usize)>, exec_n: Option<unsafe extern "C" fn(T, u64, GuestAddr, usize)>,
) -> WriteHookId { ) -> WriteHookId {
unsafe { unsafe {
let data: u64 = data.into().0; let data: u64 = data.into().0;
@ -858,11 +861,12 @@ impl Qemu {
libafl_qemu_sys::MemOpIdx, libafl_qemu_sys::MemOpIdx,
) -> u64, ) -> u64,
> = transmute(gen); > = transmute(gen);
let exec1: Option<extern "C" fn(u64, u64, GuestAddr)> = transmute(exec1); let exec1: Option<unsafe extern "C" fn(u64, u64, GuestAddr)> = transmute(exec1);
let exec2: Option<extern "C" fn(u64, u64, GuestAddr)> = transmute(exec2); let exec2: Option<unsafe extern "C" fn(u64, u64, GuestAddr)> = transmute(exec2);
let exec4: Option<extern "C" fn(u64, u64, GuestAddr)> = transmute(exec4); let exec4: Option<unsafe extern "C" fn(u64, u64, GuestAddr)> = transmute(exec4);
let exec8: Option<extern "C" fn(u64, u64, GuestAddr)> = transmute(exec8); let exec8: Option<unsafe extern "C" fn(u64, u64, GuestAddr)> = transmute(exec8);
let exec_n: Option<extern "C" fn(u64, u64, GuestAddr, usize)> = transmute(exec_n); let exec_n: Option<unsafe extern "C" fn(u64, u64, GuestAddr, usize)> =
transmute(exec_n);
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,
); );
@ -874,19 +878,19 @@ impl Qemu {
pub fn add_cmp_hooks<T: Into<HookData>>( pub fn add_cmp_hooks<T: Into<HookData>>(
&self, &self,
data: T, data: T,
gen: Option<extern "C" fn(T, GuestAddr, usize) -> u64>, gen: Option<unsafe extern "C" fn(T, GuestAddr, usize) -> u64>,
exec1: Option<extern "C" fn(T, u64, u8, u8)>, exec1: Option<unsafe extern "C" fn(T, u64, u8, u8)>,
exec2: Option<extern "C" fn(T, u64, u16, u16)>, exec2: Option<unsafe extern "C" fn(T, u64, u16, u16)>,
exec4: Option<extern "C" fn(T, u64, u32, u32)>, exec4: Option<unsafe extern "C" fn(T, u64, u32, u32)>,
exec8: Option<extern "C" fn(T, u64, u64, u64)>, exec8: Option<unsafe extern "C" fn(T, u64, u64, u64)>,
) -> CmpHookId { ) -> 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> = transmute(gen); let gen: Option<unsafe extern "C" fn(u64, GuestAddr, usize) -> u64> = transmute(gen);
let exec1: Option<extern "C" fn(u64, u64, u8, u8)> = transmute(exec1); let exec1: Option<unsafe extern "C" fn(u64, u64, u8, u8)> = transmute(exec1);
let exec2: Option<extern "C" fn(u64, u64, u16, u16)> = transmute(exec2); let exec2: Option<unsafe extern "C" fn(u64, u64, u16, u16)> = transmute(exec2);
let exec4: Option<extern "C" fn(u64, u64, u32, u32)> = transmute(exec4); let exec4: Option<unsafe extern "C" fn(u64, u64, u32, u32)> = transmute(exec4);
let exec8: Option<extern "C" fn(u64, u64, u64, u64)> = transmute(exec8); let exec8: Option<unsafe extern "C" fn(u64, u64, u64, u64)> = 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);
CmpHookId(num) CmpHookId(num)
} }