From 00806b177d93fd3495f74e2dc4adacf47e379e21 Mon Sep 17 00:00:00 2001 From: Romain Malmain Date: Tue, 13 Aug 2024 18:40:51 +0200 Subject: [PATCH] Qemu native hooks refactoring (#2480) * qemu native hooks refactoring (companion patch of qemu-libafl-bridge#82) * update stubs --- libafl_qemu/libafl_qemu_build/src/bindings.rs | 16 +- libafl_qemu/libafl_qemu_build/src/build.rs | 2 +- .../src/x86_64_stub_bindings.rs | 1200 +++++++++++++++-- .../runtime/libafl_qemu_stub_bindings.rs | 15 +- libafl_qemu/src/emu/hooks.rs | 148 +- libafl_qemu/src/qemu/hooks.rs | 157 ++- 6 files changed, 1340 insertions(+), 198 deletions(-) diff --git a/libafl_qemu/libafl_qemu_build/src/bindings.rs b/libafl_qemu/libafl_qemu_build/src/bindings.rs index 6469981e9b..6929d5fc64 100644 --- a/libafl_qemu/libafl_qemu_build/src/bindings.rs +++ b/libafl_qemu/libafl_qemu_build/src/bindings.rs @@ -82,10 +82,24 @@ const WRAPPER_HEADER: &str = r#" #include "qemu/plugin-memory.h" #include "libafl/exit.h" -#include "libafl/hook.h" #include "libafl/jit.h" #include "libafl/utils.h" +#include "libafl/hook.h" + +#include "libafl/hooks/tcg/backdoor.h" +#include "libafl/hooks/tcg/block.h" +#include "libafl/hooks/tcg/cmp.h" +#include "libafl/hooks/tcg/edge.h" +#include "libafl/hooks/tcg/instruction.h" +#include "libafl/hooks/tcg/read_write.h" +#include "libafl/hooks/cpu_run.h" + +#ifdef CONFIG_USER_ONLY +#include "libafl/hooks/thread.h" +#include "libafl/hooks/syscall.h" +#endif + "#; pub fn generate( diff --git a/libafl_qemu/libafl_qemu_build/src/build.rs b/libafl_qemu/libafl_qemu_build/src/build.rs index 55a28e28bf..8fcaf8bf1f 100644 --- a/libafl_qemu/libafl_qemu_build/src/build.rs +++ b/libafl_qemu/libafl_qemu_build/src/build.rs @@ -11,7 +11,7 @@ use crate::cargo_add_rpath; pub const QEMU_URL: &str = "https://github.com/AFLplusplus/qemu-libafl-bridge"; pub const QEMU_DIRNAME: &str = "qemu-libafl-bridge"; -pub const QEMU_REVISION: &str = "24abc2a717226bedc047167f639aef0edc9ce92d"; +pub const QEMU_REVISION: &str = "86d38fbfa7e632b3a4a14def14a11b9b9ba1642d"; #[allow(clippy::module_name_repetitions)] pub struct BuildResult { diff --git a/libafl_qemu/libafl_qemu_sys/src/x86_64_stub_bindings.rs b/libafl_qemu/libafl_qemu_sys/src/x86_64_stub_bindings.rs index 807316d98d..647c70f3b3 100644 --- a/libafl_qemu/libafl_qemu_sys/src/x86_64_stub_bindings.rs +++ b/libafl_qemu/libafl_qemu_sys/src/x86_64_stub_bindings.rs @@ -1,5 +1,5 @@ -/* 1.81.0-nightly */ -/* qemu git hash: 712661c8200804c0bb0750f237048c6c3da2d863 */ +/* 1.82.0-nightly */ +/* qemu git hash: 8f61fadbec181bfcbd305ba92a86a41376a476f7 */ /* automatically generated by rust-bindgen 0.69.4 */ #[repr(C)] @@ -112,8 +112,12 @@ impl ::std::fmt::Debug for __IncompleteArrayField { fmt.write_str("__IncompleteArrayField") } } +pub type __uint32_t = ::std::os::raw::c_uint; +pub type __uid_t = ::std::os::raw::c_uint; pub type __off_t = ::std::os::raw::c_long; pub type __off64_t = ::std::os::raw::c_long; +pub type __pid_t = ::std::os::raw::c_int; +pub type __clock_t = ::std::os::raw::c_long; pub type off_t = __off64_t; #[repr(C)] #[derive(Debug, Default, Copy, Clone)] @@ -703,7 +707,7 @@ pub struct _IO_FILE { pub _wide_data: *mut _IO_wide_data, pub _freeres_list: *mut _IO_FILE, pub _freeres_buf: *mut ::std::os::raw::c_void, - pub __pad5: usize, + pub _prevchain: *mut *mut _IO_FILE, pub _mode: ::std::os::raw::c_int, pub _unused2: [::std::os::raw::c_char; 20usize], } @@ -982,13 +986,13 @@ fn bindgen_test_layout__IO_FILE() { ) ); assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).__pad5) as usize - ptr as usize }, + unsafe { ::std::ptr::addr_of!((*ptr)._prevchain) as usize - ptr as usize }, 184usize, concat!( "Offset of field: ", stringify!(_IO_FILE), "::", - stringify!(__pad5) + stringify!(_prevchain) ) ); assert_eq!( @@ -1075,6 +1079,859 @@ fn bindgen_test_layout___jmp_buf_tag() { ); } pub type sigjmp_buf = [__jmp_buf_tag; 1usize]; +#[repr(C)] +#[derive(Copy, Clone)] +pub union sigval { + pub sival_int: ::std::os::raw::c_int, + pub sival_ptr: *mut ::std::os::raw::c_void, +} +#[test] +fn bindgen_test_layout_sigval() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 8usize, + concat!("Size of: ", stringify!(sigval)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(sigval)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).sival_int) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(sigval), + "::", + stringify!(sival_int) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).sival_ptr) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(sigval), + "::", + stringify!(sival_ptr) + ) + ); +} +impl Default for sigval { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +impl ::std::fmt::Debug for sigval { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + write!(f, "sigval {{ union }}") + } +} +pub type __sigval_t = sigval; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct siginfo_t { + pub si_signo: ::std::os::raw::c_int, + pub si_errno: ::std::os::raw::c_int, + pub si_code: ::std::os::raw::c_int, + pub __pad0: ::std::os::raw::c_int, + pub _sifields: siginfo_t__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union siginfo_t__bindgen_ty_1 { + pub _pad: [::std::os::raw::c_int; 28usize], + pub _kill: siginfo_t__bindgen_ty_1__bindgen_ty_1, + pub _timer: siginfo_t__bindgen_ty_1__bindgen_ty_2, + pub _rt: siginfo_t__bindgen_ty_1__bindgen_ty_3, + pub _sigchld: siginfo_t__bindgen_ty_1__bindgen_ty_4, + pub _sigfault: siginfo_t__bindgen_ty_1__bindgen_ty_5, + pub _sigpoll: siginfo_t__bindgen_ty_1__bindgen_ty_6, + pub _sigsys: siginfo_t__bindgen_ty_1__bindgen_ty_7, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct siginfo_t__bindgen_ty_1__bindgen_ty_1 { + pub si_pid: __pid_t, + pub si_uid: __uid_t, +} +#[test] +fn bindgen_test_layout_siginfo_t__bindgen_ty_1__bindgen_ty_1() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 8usize, + concat!( + "Size of: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_1) + ) + ); + assert_eq!( + ::std::mem::align_of::(), + 4usize, + concat!( + "Alignment of ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_1) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).si_pid) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_1), + "::", + stringify!(si_pid) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).si_uid) as usize - ptr as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_1), + "::", + stringify!(si_uid) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct siginfo_t__bindgen_ty_1__bindgen_ty_2 { + pub si_tid: ::std::os::raw::c_int, + pub si_overrun: ::std::os::raw::c_int, + pub si_sigval: __sigval_t, +} +#[test] +fn bindgen_test_layout_siginfo_t__bindgen_ty_1__bindgen_ty_2() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!( + "Size of: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_2) + ) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!( + "Alignment of ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_2) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).si_tid) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_2), + "::", + stringify!(si_tid) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).si_overrun) as usize - ptr as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_2), + "::", + stringify!(si_overrun) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).si_sigval) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_2), + "::", + stringify!(si_sigval) + ) + ); +} +impl Default for siginfo_t__bindgen_ty_1__bindgen_ty_2 { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +impl ::std::fmt::Debug for siginfo_t__bindgen_ty_1__bindgen_ty_2 { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + write ! (f , "siginfo_t__bindgen_ty_1__bindgen_ty_2 {{ si_tid: {:?}, si_overrun: {:?}, si_sigval: {:?} }}" , self . si_tid , self . si_overrun , self . si_sigval) + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct siginfo_t__bindgen_ty_1__bindgen_ty_3 { + pub si_pid: __pid_t, + pub si_uid: __uid_t, + pub si_sigval: __sigval_t, +} +#[test] +fn bindgen_test_layout_siginfo_t__bindgen_ty_1__bindgen_ty_3() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!( + "Size of: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_3) + ) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!( + "Alignment of ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_3) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).si_pid) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_3), + "::", + stringify!(si_pid) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).si_uid) as usize - ptr as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_3), + "::", + stringify!(si_uid) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).si_sigval) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_3), + "::", + stringify!(si_sigval) + ) + ); +} +impl Default for siginfo_t__bindgen_ty_1__bindgen_ty_3 { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +impl ::std::fmt::Debug for siginfo_t__bindgen_ty_1__bindgen_ty_3 { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + write ! (f , "siginfo_t__bindgen_ty_1__bindgen_ty_3 {{ si_pid: {:?}, si_uid: {:?}, si_sigval: {:?} }}" , self . si_pid , self . si_uid , self . si_sigval) + } +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct siginfo_t__bindgen_ty_1__bindgen_ty_4 { + pub si_pid: __pid_t, + pub si_uid: __uid_t, + pub si_status: ::std::os::raw::c_int, + pub si_utime: __clock_t, + pub si_stime: __clock_t, +} +#[test] +fn bindgen_test_layout_siginfo_t__bindgen_ty_1__bindgen_ty_4() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 32usize, + concat!( + "Size of: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_4) + ) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!( + "Alignment of ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_4) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).si_pid) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_4), + "::", + stringify!(si_pid) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).si_uid) as usize - ptr as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_4), + "::", + stringify!(si_uid) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).si_status) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_4), + "::", + stringify!(si_status) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).si_utime) as usize - ptr as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_4), + "::", + stringify!(si_utime) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).si_stime) as usize - ptr as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_4), + "::", + stringify!(si_stime) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct siginfo_t__bindgen_ty_1__bindgen_ty_5 { + pub si_addr: *mut ::std::os::raw::c_void, + pub si_addr_lsb: ::std::os::raw::c_short, + pub _bounds: siginfo_t__bindgen_ty_1__bindgen_ty_5__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union siginfo_t__bindgen_ty_1__bindgen_ty_5__bindgen_ty_1 { + pub _addr_bnd: siginfo_t__bindgen_ty_1__bindgen_ty_5__bindgen_ty_1__bindgen_ty_1, + pub _pkey: __uint32_t, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct siginfo_t__bindgen_ty_1__bindgen_ty_5__bindgen_ty_1__bindgen_ty_1 { + pub _lower: *mut ::std::os::raw::c_void, + pub _upper: *mut ::std::os::raw::c_void, +} +#[test] +fn bindgen_test_layout_siginfo_t__bindgen_ty_1__bindgen_ty_5__bindgen_ty_1__bindgen_ty_1() { + const UNINIT: ::std::mem::MaybeUninit< + siginfo_t__bindgen_ty_1__bindgen_ty_5__bindgen_ty_1__bindgen_ty_1, + > = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!( + "Size of: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_5__bindgen_ty_1__bindgen_ty_1) + ) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!( + "Alignment of ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_5__bindgen_ty_1__bindgen_ty_1) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._lower) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_5__bindgen_ty_1__bindgen_ty_1), + "::", + stringify!(_lower) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._upper) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_5__bindgen_ty_1__bindgen_ty_1), + "::", + stringify!(_upper) + ) + ); +} +impl Default for siginfo_t__bindgen_ty_1__bindgen_ty_5__bindgen_ty_1__bindgen_ty_1 { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[test] +fn bindgen_test_layout_siginfo_t__bindgen_ty_1__bindgen_ty_5__bindgen_ty_1() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!( + "Size of: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_5__bindgen_ty_1) + ) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!( + "Alignment of ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_5__bindgen_ty_1) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._addr_bnd) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_5__bindgen_ty_1), + "::", + stringify!(_addr_bnd) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._pkey) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_5__bindgen_ty_1), + "::", + stringify!(_pkey) + ) + ); +} +impl Default for siginfo_t__bindgen_ty_1__bindgen_ty_5__bindgen_ty_1 { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +impl ::std::fmt::Debug for siginfo_t__bindgen_ty_1__bindgen_ty_5__bindgen_ty_1 { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + write!( + f, + "siginfo_t__bindgen_ty_1__bindgen_ty_5__bindgen_ty_1 {{ union }}" + ) + } +} +#[test] +fn bindgen_test_layout_siginfo_t__bindgen_ty_1__bindgen_ty_5() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 32usize, + concat!( + "Size of: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_5) + ) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!( + "Alignment of ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_5) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).si_addr) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_5), + "::", + stringify!(si_addr) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).si_addr_lsb) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_5), + "::", + stringify!(si_addr_lsb) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._bounds) as usize - ptr as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_5), + "::", + stringify!(_bounds) + ) + ); +} +impl Default for siginfo_t__bindgen_ty_1__bindgen_ty_5 { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +impl ::std::fmt::Debug for siginfo_t__bindgen_ty_1__bindgen_ty_5 { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + write ! (f , "siginfo_t__bindgen_ty_1__bindgen_ty_5 {{ si_addr: {:?}, si_addr_lsb: {:?}, _bounds: {:?} }}" , self . si_addr , self . si_addr_lsb , self . _bounds) + } +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct siginfo_t__bindgen_ty_1__bindgen_ty_6 { + pub si_band: ::std::os::raw::c_long, + pub si_fd: ::std::os::raw::c_int, +} +#[test] +fn bindgen_test_layout_siginfo_t__bindgen_ty_1__bindgen_ty_6() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!( + "Size of: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_6) + ) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!( + "Alignment of ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_6) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).si_band) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_6), + "::", + stringify!(si_band) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).si_fd) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_6), + "::", + stringify!(si_fd) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct siginfo_t__bindgen_ty_1__bindgen_ty_7 { + pub _call_addr: *mut ::std::os::raw::c_void, + pub _syscall: ::std::os::raw::c_int, + pub _arch: ::std::os::raw::c_uint, +} +#[test] +fn bindgen_test_layout_siginfo_t__bindgen_ty_1__bindgen_ty_7() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!( + "Size of: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_7) + ) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!( + "Alignment of ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_7) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._call_addr) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_7), + "::", + stringify!(_call_addr) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._syscall) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_7), + "::", + stringify!(_syscall) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._arch) as usize - ptr as usize }, + 12usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_7), + "::", + stringify!(_arch) + ) + ); +} +impl Default for siginfo_t__bindgen_ty_1__bindgen_ty_7 { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[test] +fn bindgen_test_layout_siginfo_t__bindgen_ty_1() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 112usize, + concat!("Size of: ", stringify!(siginfo_t__bindgen_ty_1)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(siginfo_t__bindgen_ty_1)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._pad) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1), + "::", + stringify!(_pad) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._kill) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1), + "::", + stringify!(_kill) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._timer) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1), + "::", + stringify!(_timer) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._rt) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1), + "::", + stringify!(_rt) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._sigchld) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1), + "::", + stringify!(_sigchld) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._sigfault) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1), + "::", + stringify!(_sigfault) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._sigpoll) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1), + "::", + stringify!(_sigpoll) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._sigsys) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1), + "::", + stringify!(_sigsys) + ) + ); +} +impl Default for siginfo_t__bindgen_ty_1 { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +impl ::std::fmt::Debug for siginfo_t__bindgen_ty_1 { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + write!(f, "siginfo_t__bindgen_ty_1 {{ union }}") + } +} +#[test] +fn bindgen_test_layout_siginfo_t() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 128usize, + concat!("Size of: ", stringify!(siginfo_t)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(siginfo_t)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).si_signo) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t), + "::", + stringify!(si_signo) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).si_errno) as usize - ptr as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t), + "::", + stringify!(si_errno) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).si_code) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t), + "::", + stringify!(si_code) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__pad0) as usize - ptr as usize }, + 12usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t), + "::", + stringify!(__pad0) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._sifields) as usize - ptr as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t), + "::", + stringify!(_sifields) + ) + ); +} +impl Default for siginfo_t { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +impl ::std::fmt::Debug for siginfo_t { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + write ! (f , "siginfo_t {{ si_signo: {:?}, si_errno: {:?}, si_code: {:?}, __pad0: {:?}, _sifields: {:?} }}" , self . si_signo , self . si_errno , self . si_code , self . __pad0 , self . _sifields) + } +} pub type guint8 = ::std::os::raw::c_uchar; pub type gchar = ::std::os::raw::c_char; pub type guint = ::std::os::raw::c_uint; @@ -2342,6 +3199,7 @@ pub type DeviceReset = ::std::option::Option *mut IntervalTreeNode; } @@ -13521,6 +14389,93 @@ extern "C" { data: *mut qemu_plugin_hwaddr, ) -> bool; } +extern "C" { + pub fn libafl_jit_trace_edge_hitcount(data: u64, id: u64) -> usize; +} +extern "C" { + pub fn libafl_jit_trace_edge_single(data: u64, id: u64) -> usize; +} +extern "C" { + pub fn libafl_jit_trace_block_hitcount(data: u64, id: u64) -> usize; +} +extern "C" { + pub fn libafl_jit_trace_block_single(data: u64, id: u64) -> usize; +} +extern "C" { + pub fn libafl_qemu_host_page_size() -> usize; +} +extern "C" { + pub fn libafl_tcg_gen_asan(addr: *mut TCGTemp, size: usize); +} +extern "C" { + pub fn libafl_gen_backdoor(pc: target_ulong); +} +extern "C" { + pub fn libafl_add_backdoor_hook( + exec: ::std::option::Option< + unsafe extern "C" fn(data: u64, cpu: *mut CPUArchState, pc: target_ulong), + >, + data: u64, + ) -> usize; +} +extern "C" { + pub fn libafl_qemu_remove_backdoor_hook( + num: usize, + invalidate: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libafl_qemu_hook_backdoor_run(pc_next: vaddr); +} +extern "C" { + pub fn libafl_qemu_hook_block_post_gen(tb: *mut TranslationBlock, pc: vaddr); +} +extern "C" { + pub fn libafl_qemu_hook_block_run(pc: target_ulong); +} +extern "C" { + pub fn libafl_qemu_block_hook_set_jit( + num: usize, + jit: ::std::option::Option usize>, + ) -> bool; +} +extern "C" { + pub fn libafl_qemu_remove_block_hook( + num: usize, + invalidate: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libafl_add_block_hook( + gen: ::std::option::Option u64>, + post_gen: ::std::option::Option< + unsafe extern "C" fn(data: u64, pc: target_ulong, block_length: target_ulong), + >, + exec: ::std::option::Option, + data: u64, + ) -> usize; +} +extern "C" { + pub fn libafl_gen_cmp(pc: target_ulong, op0: TCGv, op1: TCGv, ot: MemOp); +} +extern "C" { + pub fn libafl_add_cmp_hook( + gen: ::std::option::Option< + unsafe extern "C" fn(data: u64, pc: target_ulong, size: usize) -> u64, + >, + exec1: ::std::option::Option, + exec2: ::std::option::Option, + exec4: ::std::option::Option, + exec8: ::std::option::Option, + data: u64, + ) -> usize; +} +extern "C" { + pub fn libafl_qemu_remove_cmp_hook( + num: usize, + invalidate: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} extern "C" { pub fn libafl_gen_edge( cpu: *mut CPUState, @@ -13533,62 +14488,84 @@ extern "C" { ) -> *mut TranslationBlock; } extern "C" { - pub fn libafl_gen_cmp(pc: target_ulong, op0: TCGv, op1: TCGv, ot: MemOp); + pub fn libafl_add_edge_hook( + gen: ::std::option::Option< + unsafe extern "C" fn(data: u64, src: target_ulong, dst: target_ulong) -> u64, + >, + exec: ::std::option::Option, + data: u64, + ) -> usize; } extern "C" { - pub fn libafl_gen_backdoor(pc: target_ulong); + pub fn libafl_qemu_edge_hook_set_jit( + num: usize, + jit: ::std::option::Option usize>, + ) -> bool; +} +extern "C" { + pub fn libafl_qemu_remove_edge_hook( + num: usize, + invalidate: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libafl_qemu_hook_edge_gen(src_block: target_ulong, dst_block: target_ulong) -> bool; +} +extern "C" { + pub fn libafl_qemu_hook_edge_run(); } #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct libafl_hook { - pub addr: target_ulong, +pub struct libafl_instruction_hook { pub data: u64, pub num: usize, + pub addr: target_ulong, pub helper_info: TCGHelperInfo, - pub next: *mut libafl_hook, + pub next: *mut libafl_instruction_hook, } #[test] -fn bindgen_test_layout_libafl_hook() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); +fn bindgen_test_layout_libafl_instruction_hook() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); let ptr = UNINIT.as_ptr(); assert_eq!( - ::std::mem::size_of::(), + ::std::mem::size_of::(), 120usize, - concat!("Size of: ", stringify!(libafl_hook)) + concat!("Size of: ", stringify!(libafl_instruction_hook)) ); assert_eq!( - ::std::mem::align_of::(), + ::std::mem::align_of::(), 8usize, - concat!("Alignment of ", stringify!(libafl_hook)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(libafl_hook), - "::", - stringify!(addr) - ) + concat!("Alignment of ", stringify!(libafl_instruction_hook)) ); assert_eq!( unsafe { ::std::ptr::addr_of!((*ptr).data) as usize - ptr as usize }, - 8usize, + 0usize, concat!( "Offset of field: ", - stringify!(libafl_hook), + stringify!(libafl_instruction_hook), "::", stringify!(data) ) ); assert_eq!( unsafe { ::std::ptr::addr_of!((*ptr).num) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(libafl_instruction_hook), + "::", + stringify!(num) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize }, 16usize, concat!( "Offset of field: ", - stringify!(libafl_hook), + stringify!(libafl_instruction_hook), "::", - stringify!(num) + stringify!(addr) ) ); assert_eq!( @@ -13596,7 +14573,7 @@ fn bindgen_test_layout_libafl_hook() { 24usize, concat!( "Offset of field: ", - stringify!(libafl_hook), + stringify!(libafl_instruction_hook), "::", stringify!(helper_info) ) @@ -13606,13 +14583,13 @@ fn bindgen_test_layout_libafl_hook() { 112usize, concat!( "Offset of field: ", - stringify!(libafl_hook), + stringify!(libafl_instruction_hook), "::", stringify!(next) ) ); } -impl Default for libafl_hook { +impl Default for libafl_instruction_hook { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); unsafe { @@ -13629,12 +14606,6 @@ extern "C" { invalidate: ::std::os::raw::c_int, ) -> usize; } -extern "C" { - pub fn libafl_qemu_remove_instruction_hooks_at( - addr: target_ulong, - invalidate: ::std::os::raw::c_int, - ) -> usize; -} extern "C" { pub fn libafl_qemu_remove_instruction_hook( num: usize, @@ -13642,64 +14613,22 @@ extern "C" { ) -> ::std::os::raw::c_int; } extern "C" { - pub fn libafl_search_instruction_hook(addr: target_ulong) -> *mut libafl_hook; -} -extern "C" { - pub fn libafl_add_backdoor_hook( - exec: ::std::option::Option< - unsafe extern "C" fn(data: u64, cpu: *mut CPUArchState, pc: target_ulong), - >, - data: u64, + pub fn libafl_qemu_remove_instruction_hooks_at( + addr: target_ulong, + invalidate: ::std::os::raw::c_int, ) -> usize; } extern "C" { - pub fn libafl_qemu_remove_backdoor_hook( - num: usize, - invalidate: ::std::os::raw::c_int, - ) -> ::std::os::raw::c_int; + pub fn libafl_search_instruction_hook(addr: target_ulong) -> *mut libafl_instruction_hook; } extern "C" { - pub fn libafl_add_edge_hook( - gen: ::std::option::Option< - unsafe extern "C" fn(data: u64, src: target_ulong, dst: target_ulong) -> u64, - >, - exec: ::std::option::Option, - data: u64, - ) -> usize; + pub fn libafl_qemu_hook_instruction_run(pc_next: vaddr); } extern "C" { - pub fn libafl_qemu_remove_edge_hook( - num: usize, - invalidate: ::std::os::raw::c_int, - ) -> ::std::os::raw::c_int; + pub fn libafl_gen_read(addr: *mut TCGTemp, oi: MemOpIdx); } extern "C" { - pub fn libafl_qemu_edge_hook_set_jit( - num: usize, - jit: ::std::option::Option usize>, - ) -> bool; -} -extern "C" { - pub fn libafl_add_block_hook( - gen: ::std::option::Option u64>, - post_gen: ::std::option::Option< - unsafe extern "C" fn(data: u64, pc: target_ulong, block_length: target_ulong), - >, - exec: ::std::option::Option, - data: u64, - ) -> usize; -} -extern "C" { - pub fn libafl_qemu_remove_block_hook( - num: usize, - invalidate: ::std::os::raw::c_int, - ) -> ::std::os::raw::c_int; -} -extern "C" { - pub fn libafl_qemu_block_hook_set_jit( - num: usize, - jit: ::std::option::Option usize>, - ) -> bool; + pub fn libafl_gen_write(addr: *mut TCGTemp, oi: MemOpIdx); } extern "C" { pub fn libafl_add_read_hook( @@ -13753,29 +14682,40 @@ extern "C" { invalidate: ::std::os::raw::c_int, ) -> ::std::os::raw::c_int; } +pub type libafl_cpu_run_fn = + ::std::option::Option; extern "C" { - pub fn libafl_gen_read(addr: *mut TCGTemp, oi: MemOpIdx); -} -extern "C" { - pub fn libafl_gen_write(addr: *mut TCGTemp, oi: MemOpIdx); -} -extern "C" { - pub fn libafl_add_cmp_hook( - gen: ::std::option::Option< - unsafe extern "C" fn(data: u64, pc: target_ulong, size: usize) -> u64, - >, - exec1: ::std::option::Option, - exec2: ::std::option::Option, - exec4: ::std::option::Option, - exec8: ::std::option::Option, + pub fn libafl_hook_cpu_run_add( + pre_cpu_run: libafl_cpu_run_fn, + post_cpu_run: libafl_cpu_run_fn, data: u64, ) -> usize; } extern "C" { - pub fn libafl_qemu_remove_cmp_hook( - num: usize, - invalidate: ::std::os::raw::c_int, - ) -> ::std::os::raw::c_int; + pub fn libafl_hook_cpu_run_remove(num: usize) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libafl_qemu_remove_cpu_run_hook(num: usize) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libafl_hook_cpu_run_pre_exec(cpu: *mut CPUState); +} +extern "C" { + pub fn libafl_hook_cpu_run_post_exec(cpu: *mut CPUState); +} +extern "C" { + pub fn libafl_add_new_thread_hook( + callback: ::std::option::Option< + unsafe extern "C" fn(data: u64, env: *mut CPUArchState, tid: u32) -> bool, + >, + data: u64, + ) -> usize; +} +extern "C" { + pub fn libafl_qemu_remove_new_thread_hook(num: usize) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libafl_hook_new_thread_run(env: *mut CPUArchState) -> bool; } #[repr(C)] #[derive(Debug, Default, Copy, Clone)] @@ -13864,31 +14804,33 @@ extern "C" { pub fn libafl_qemu_remove_post_syscall_hook(num: usize) -> ::std::os::raw::c_int; } extern "C" { - pub fn libafl_add_new_thread_hook( - callback: ::std::option::Option bool>, - data: u64, - ) -> usize; + pub fn libafl_hook_syscall_pre_run( + env: *mut CPUArchState, + num: ::std::os::raw::c_int, + arg1: abi_long, + arg2: abi_long, + arg3: abi_long, + arg4: abi_long, + arg5: abi_long, + arg6: abi_long, + arg7: abi_long, + arg8: abi_long, + ret: *mut abi_long, + ) -> bool; } extern "C" { - pub fn libafl_qemu_remove_new_thread_hook(num: usize) -> ::std::os::raw::c_int; -} -extern "C" { - pub fn libafl_tcg_gen_asan(addr: *mut TCGTemp, size: usize); -} -extern "C" { - pub fn libafl_jit_trace_edge_hitcount(data: u64, id: u64) -> usize; -} -extern "C" { - pub fn libafl_jit_trace_edge_single(data: u64, id: u64) -> usize; -} -extern "C" { - pub fn libafl_jit_trace_block_hitcount(data: u64, id: u64) -> usize; -} -extern "C" { - pub fn libafl_jit_trace_block_single(data: u64, id: u64) -> usize; -} -extern "C" { - pub fn libafl_qemu_host_page_size() -> usize; + pub fn libafl_hook_syscall_post_run( + num: ::std::os::raw::c_int, + arg1: abi_long, + arg2: abi_long, + arg3: abi_long, + arg4: abi_long, + arg5: abi_long, + arg6: abi_long, + arg7: abi_long, + arg8: abi_long, + ret: *mut abi_long, + ); } #[repr(C)] #[derive(Debug, Default, Copy, Clone)] diff --git a/libafl_qemu/runtime/libafl_qemu_stub_bindings.rs b/libafl_qemu/runtime/libafl_qemu_stub_bindings.rs index 0918ab0b2b..7b9ad5e84e 100644 --- a/libafl_qemu/runtime/libafl_qemu_stub_bindings.rs +++ b/libafl_qemu/runtime/libafl_qemu_stub_bindings.rs @@ -1,11 +1,11 @@ -/* 1.81.0-nightly */ -/* qemu git hash: 712661c8200804c0bb0750f237048c6c3da2d863 */ +/* 1.82.0-nightly */ +/* qemu git hash: 8f61fadbec181bfcbd305ba92a86a41376a476f7 */ /* automatically generated by rust-bindgen 0.69.4 */ pub const _STDINT_H: u32 = 1; pub const _FEATURES_H: u32 = 1; pub const _DEFAULT_SOURCE: u32 = 1; -pub const __GLIBC_USE_ISOC2X: u32 = 0; +pub const __GLIBC_USE_ISOC23: u32 = 0; pub const __USE_ISOC11: u32 = 1; pub const __USE_ISOC99: u32 = 1; pub const __USE_ISOC95: u32 = 1; @@ -23,12 +23,13 @@ pub const __WORDSIZE: u32 = 64; pub const __WORDSIZE_TIME64_COMPAT32: u32 = 1; pub const __SYSCALL_WORDSIZE: u32 = 64; pub const __TIMESIZE: u32 = 64; +pub const __USE_TIME_BITS64: u32 = 1; pub const __USE_MISC: u32 = 1; pub const __USE_ATFILE: u32 = 1; pub const __USE_FORTIFY_LEVEL: u32 = 0; pub const __GLIBC_USE_DEPRECATED_GETS: u32 = 0; pub const __GLIBC_USE_DEPRECATED_SCANF: u32 = 0; -pub const __GLIBC_USE_C2X_STRTOL: u32 = 0; +pub const __GLIBC_USE_C23_STRTOL: u32 = 0; pub const _STDC_PREDEF_H: u32 = 1; pub const __STDC_IEC_559__: u32 = 1; pub const __STDC_IEC_60559_BFP__: u32 = 201404; @@ -37,17 +38,17 @@ pub const __STDC_IEC_60559_COMPLEX__: u32 = 201404; pub const __STDC_ISO_10646__: u32 = 201706; pub const __GNU_LIBRARY__: u32 = 6; pub const __GLIBC__: u32 = 2; -pub const __GLIBC_MINOR__: u32 = 39; +pub const __GLIBC_MINOR__: u32 = 40; pub const _SYS_CDEFS_H: u32 = 1; pub const __glibc_c99_flexarr_available: u32 = 1; pub const __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI: u32 = 0; pub const __HAVE_GENERIC_SELECTION: u32 = 1; pub const __GLIBC_USE_LIB_EXT2: u32 = 0; pub const __GLIBC_USE_IEC_60559_BFP_EXT: u32 = 0; -pub const __GLIBC_USE_IEC_60559_BFP_EXT_C2X: u32 = 0; +pub const __GLIBC_USE_IEC_60559_BFP_EXT_C23: u32 = 0; pub const __GLIBC_USE_IEC_60559_EXT: u32 = 0; pub const __GLIBC_USE_IEC_60559_FUNCS_EXT: u32 = 0; -pub const __GLIBC_USE_IEC_60559_FUNCS_EXT_C2X: u32 = 0; +pub const __GLIBC_USE_IEC_60559_FUNCS_EXT_C23: u32 = 0; pub const __GLIBC_USE_IEC_60559_TYPES_EXT: u32 = 0; pub const _BITS_TYPES_H: u32 = 1; pub const _BITS_TYPESIZES_H: u32 = 1; diff --git a/libafl_qemu/src/emu/hooks.rs b/libafl_qemu/src/emu/hooks.rs index a14a03bc8d..2de17a65ca 100644 --- a/libafl_qemu/src/emu/hooks.rs +++ b/libafl_qemu/src/emu/hooks.rs @@ -5,7 +5,7 @@ use std::ptr::addr_of_mut; use std::{fmt::Debug, marker::PhantomData, mem::transmute, pin::Pin, ptr}; use libafl::{executors::ExitKind, inputs::UsesInput, observers::ObserversTuple}; -use libafl_qemu_sys::{CPUArchStatePtr, FatPtr, GuestAddr, GuestUsize, TCGTemp}; +use libafl_qemu_sys::{CPUArchStatePtr, CPUStatePtr, FatPtr, GuestAddr, GuestUsize, TCGTemp}; #[cfg(emulation_mode = "usermode")] use crate::qemu::{ @@ -20,6 +20,7 @@ use crate::qemu::{ PreSyscallHookClosure, PreSyscallHookFn, }; use crate::{ + cpu_run_post_exec_hook_wrapper, cpu_run_pre_exec_hook_wrapper, modules::{EmulatorModule, EmulatorModuleTuple}, qemu::{ block_0_exec_hook_wrapper, block_gen_hook_wrapper, block_post_gen_hook_wrapper, @@ -33,11 +34,11 @@ use crate::{ write_4_exec_hook_wrapper, write_gen_hook_wrapper, BackdoorHook, BackdoorHookClosure, BackdoorHookFn, BackdoorHookId, BlockExecHook, BlockGenHook, BlockHookId, BlockPostGenHook, CmpExecHook, CmpGenHook, CmpHookId, EdgeExecHook, EdgeGenHook, EdgeHookId, Hook, HookRepr, - HookState, InstructionHook, InstructionHookClosure, InstructionHookFn, InstructionHookId, - QemuHooks, ReadExecHook, ReadExecNHook, ReadGenHook, ReadHookId, WriteExecHook, + InstructionHook, InstructionHookClosure, InstructionHookFn, InstructionHookId, QemuHooks, + ReadExecHook, ReadExecNHook, ReadGenHook, ReadHookId, TcgHookState, WriteExecHook, WriteExecNHook, WriteGenHook, WriteHookId, }, - MemAccessInfo, Qemu, + CpuPostRunHook, CpuPreRunHook, CpuRunHookId, HookState, MemAccessInfo, Qemu, }; macro_rules! get_raw_hook { @@ -119,11 +120,13 @@ where instruction_hooks: Vec>>, backdoor_hooks: Vec>>, - edge_hooks: Vec>>>, - block_hooks: Vec>>>, - read_hooks: Vec>>>, - write_hooks: Vec>>>, - cmp_hooks: Vec>>>, + edge_hooks: Vec>>>, + block_hooks: Vec>>>, + read_hooks: Vec>>>, + write_hooks: Vec>>>, + cmp_hooks: Vec>>>, + + cpu_run_hooks: Vec>>>, #[cfg(emulation_mode = "usermode")] pre_syscall_hooks: Vec>>, @@ -156,6 +159,8 @@ where write_hooks: Vec::new(), cmp_hooks: Vec::new(), + cpu_run_hooks: Vec::new(), + #[cfg(emulation_mode = "usermode")] pre_syscall_hooks: Vec::new(), @@ -252,7 +257,7 @@ where generation_hook, edge_gen_hook_wrapper::, unsafe extern "C" fn( - &mut HookState<1, EdgeHookId>, + &mut TcgHookState<1, EdgeHookId>, src: GuestAddr, dest: GuestAddr, ) -> u64 @@ -261,17 +266,17 @@ where let exec = get_raw_hook!( execution_hook, edge_0_exec_hook_wrapper::, - unsafe extern "C" fn(&mut HookState<1, EdgeHookId>, id: u64) + unsafe extern "C" fn(&mut TcgHookState<1, EdgeHookId>, id: u64) ); - self.edge_hooks.push(Box::pin(HookState::new( + self.edge_hooks.push(Box::pin(TcgHookState::new( EdgeHookId::invalid(), hook_to_repr!(generation_hook), HookRepr::Empty, [hook_to_repr!(execution_hook)], ))); - let hook_state = &mut *ptr::from_mut::>( + let hook_state = &mut *ptr::from_mut::>( self.edge_hooks .last_mut() .unwrap() @@ -302,14 +307,14 @@ where let gen = get_raw_hook!( generation_hook, block_gen_hook_wrapper::, - unsafe extern "C" fn(&mut HookState<1, BlockHookId>, pc: GuestAddr) -> u64 + unsafe extern "C" fn(&mut TcgHookState<1, BlockHookId>, pc: GuestAddr) -> u64 ); let postgen = get_raw_hook!( post_generation_hook, block_post_gen_hook_wrapper::, unsafe extern "C" fn( - &mut HookState<1, BlockHookId>, + &mut TcgHookState<1, BlockHookId>, pc: GuestAddr, block_length: GuestUsize, ) @@ -318,17 +323,17 @@ where let exec = get_raw_hook!( execution_hook, block_0_exec_hook_wrapper::, - unsafe extern "C" fn(&mut HookState<1, BlockHookId>, id: u64) + unsafe extern "C" fn(&mut TcgHookState<1, BlockHookId>, id: u64) ); - self.block_hooks.push(Box::pin(HookState::new( + self.block_hooks.push(Box::pin(TcgHookState::new( BlockHookId::invalid(), hook_to_repr!(generation_hook), hook_to_repr!(post_generation_hook), [hook_to_repr!(execution_hook)], ))); - let hook_state = &mut *ptr::from_mut::>( + let hook_state = &mut *ptr::from_mut::>( self.block_hooks .last_mut() .unwrap() @@ -351,6 +356,53 @@ where } } + pub fn cpu_runs( + &mut self, + pre_exec_hook: CpuPreRunHook, + post_exec_hook: CpuPostRunHook, + ) -> CpuRunHookId { + unsafe { + let pre_run = get_raw_hook!( + pre_exec_hook, + cpu_run_pre_exec_hook_wrapper::, + unsafe extern "C" fn(&mut HookState, cpu: CPUStatePtr) + ); + + let post_run = get_raw_hook!( + post_exec_hook, + cpu_run_post_exec_hook_wrapper::, + unsafe extern "C" fn(&mut HookState, cpu: CPUStatePtr) + ); + + self.cpu_run_hooks.push(Box::pin(HookState::new( + CpuRunHookId::invalid(), + hook_to_repr!(pre_exec_hook), + hook_to_repr!(post_exec_hook), + ))); + + let hook_state = &mut *ptr::from_mut::>( + self.cpu_run_hooks + .last_mut() + .unwrap() + .as_mut() + .get_unchecked_mut(), + ); + + let id = self + .qemu_hooks + .add_cpu_run_hooks(hook_state, pre_run, post_run); + + self.cpu_run_hooks + .last_mut() + .unwrap() + .as_mut() + .get_unchecked_mut() + .set_id(id); + + id + } + } + #[allow(clippy::similar_names)] pub fn reads( &mut self, @@ -366,7 +418,7 @@ where generation_hook, read_gen_hook_wrapper::, unsafe extern "C" fn( - &mut HookState<5, ReadHookId>, + &mut TcgHookState<5, ReadHookId>, pc: GuestAddr, addr: *mut TCGTemp, info: MemAccessInfo, @@ -375,35 +427,35 @@ where let exec1 = get_raw_hook!( execution_hook_1, read_0_exec_hook_wrapper::, - unsafe extern "C" fn(&mut HookState<5, ReadHookId>, id: u64, addr: GuestAddr) + unsafe extern "C" fn(&mut TcgHookState<5, ReadHookId>, id: u64, addr: GuestAddr) ); let exec2 = get_raw_hook!( execution_hook_2, read_1_exec_hook_wrapper::, - unsafe extern "C" fn(&mut HookState<5, ReadHookId>, id: u64, addr: GuestAddr) + unsafe extern "C" fn(&mut TcgHookState<5, ReadHookId>, id: u64, addr: GuestAddr) ); let exec4 = get_raw_hook!( execution_hook_4, read_2_exec_hook_wrapper::, - unsafe extern "C" fn(&mut HookState<5, ReadHookId>, id: u64, addr: GuestAddr) + unsafe extern "C" fn(&mut TcgHookState<5, ReadHookId>, id: u64, addr: GuestAddr) ); let exec8 = get_raw_hook!( execution_hook_8, read_3_exec_hook_wrapper::, - unsafe extern "C" fn(&mut HookState<5, ReadHookId>, id: u64, addr: GuestAddr) + unsafe extern "C" fn(&mut TcgHookState<5, ReadHookId>, id: u64, addr: GuestAddr) ); let execn = get_raw_hook!( execution_hook_n, read_4_exec_hook_wrapper::, unsafe extern "C" fn( - &mut HookState<5, ReadHookId>, + &mut TcgHookState<5, ReadHookId>, id: u64, addr: GuestAddr, size: usize, ) ); - self.read_hooks.push(Box::pin(HookState::new( + self.read_hooks.push(Box::pin(TcgHookState::new( ReadHookId::invalid(), hook_to_repr!(generation_hook), HookRepr::Empty, @@ -416,7 +468,7 @@ where ], ))); - let hook_state = &mut *ptr::from_mut::>( + let hook_state = &mut *ptr::from_mut::>( self.read_hooks .last_mut() .unwrap() @@ -454,7 +506,7 @@ where generation_hook, write_gen_hook_wrapper::, unsafe extern "C" fn( - &mut HookState<5, WriteHookId>, + &mut TcgHookState<5, WriteHookId>, pc: GuestAddr, addr: *mut TCGTemp, info: MemAccessInfo, @@ -463,35 +515,35 @@ where let exec1 = get_raw_hook!( execution_hook_1, write_0_exec_hook_wrapper::, - unsafe extern "C" fn(&mut HookState<5, WriteHookId>, id: u64, addr: GuestAddr) + unsafe extern "C" fn(&mut TcgHookState<5, WriteHookId>, id: u64, addr: GuestAddr) ); let exec2 = get_raw_hook!( execution_hook_2, write_1_exec_hook_wrapper::, - unsafe extern "C" fn(&mut HookState<5, WriteHookId>, id: u64, addr: GuestAddr) + unsafe extern "C" fn(&mut TcgHookState<5, WriteHookId>, id: u64, addr: GuestAddr) ); let exec4 = get_raw_hook!( execution_hook_4, write_2_exec_hook_wrapper::, - unsafe extern "C" fn(&mut HookState<5, WriteHookId>, id: u64, addr: GuestAddr) + unsafe extern "C" fn(&mut TcgHookState<5, WriteHookId>, id: u64, addr: GuestAddr) ); let exec8 = get_raw_hook!( execution_hook_8, write_3_exec_hook_wrapper::, - unsafe extern "C" fn(&mut HookState<5, WriteHookId>, id: u64, addr: GuestAddr) + unsafe extern "C" fn(&mut TcgHookState<5, WriteHookId>, id: u64, addr: GuestAddr) ); let execn = get_raw_hook!( execution_hook_n, write_4_exec_hook_wrapper::, unsafe extern "C" fn( - &mut HookState<5, WriteHookId>, + &mut TcgHookState<5, WriteHookId>, id: u64, addr: GuestAddr, size: usize, ) ); - self.write_hooks.push(Box::pin(HookState::new( + self.write_hooks.push(Box::pin(TcgHookState::new( WriteHookId::invalid(), hook_to_repr!(generation_hook), HookRepr::Empty, @@ -504,7 +556,7 @@ where ], ))); - let hook_state = &mut *ptr::from_mut::>( + let hook_state = &mut *ptr::from_mut::>( self.write_hooks .last_mut() .unwrap() @@ -540,7 +592,7 @@ where generation_hook, cmp_gen_hook_wrapper::, unsafe extern "C" fn( - &mut HookState<4, CmpHookId>, + &mut TcgHookState<4, CmpHookId>, pc: GuestAddr, size: usize, ) -> u64 @@ -548,25 +600,25 @@ where let exec1 = get_raw_hook!( execution_hook_1, cmp_0_exec_hook_wrapper::, - unsafe extern "C" fn(&mut HookState<4, CmpHookId>, id: u64, v0: u8, v1: u8) + unsafe extern "C" fn(&mut TcgHookState<4, CmpHookId>, id: u64, v0: u8, v1: u8) ); let exec2 = get_raw_hook!( execution_hook_2, cmp_1_exec_hook_wrapper::, - unsafe extern "C" fn(&mut HookState<4, CmpHookId>, id: u64, v0: u16, v1: u16) + unsafe extern "C" fn(&mut TcgHookState<4, CmpHookId>, id: u64, v0: u16, v1: u16) ); let exec4 = get_raw_hook!( execution_hook_4, cmp_2_exec_hook_wrapper::, - unsafe extern "C" fn(&mut HookState<4, CmpHookId>, id: u64, v0: u32, v1: u32) + unsafe extern "C" fn(&mut TcgHookState<4, CmpHookId>, id: u64, v0: u32, v1: u32) ); let exec8 = get_raw_hook!( execution_hook_8, cmp_3_exec_hook_wrapper::, - unsafe extern "C" fn(&mut HookState<4, CmpHookId>, id: u64, v0: u64, v1: u64) + unsafe extern "C" fn(&mut TcgHookState<4, CmpHookId>, id: u64, v0: u64, v1: u64) ); - self.cmp_hooks.push(Box::pin(HookState::new( + self.cmp_hooks.push(Box::pin(TcgHookState::new( CmpHookId::invalid(), hook_to_repr!(generation_hook), HookRepr::Empty, @@ -578,7 +630,7 @@ where ], ))); - let hook_state = &mut *ptr::from_mut::>( + let hook_state = &mut *ptr::from_mut::>( self.cmp_hooks .last_mut() .unwrap() @@ -776,7 +828,12 @@ where pub fn thread_creation_function( &mut self, - hook: fn(&mut EmulatorModules, Option<&mut S>, tid: u32) -> bool, + hook: fn( + &mut EmulatorModules, + Option<&mut S>, + env: CPUArchStatePtr, + tid: u32, + ) -> bool, ) -> NewThreadHookId { unsafe { self.qemu_hooks @@ -1206,7 +1263,12 @@ where pub fn thread_creation_function( &mut self, - hook: fn(&mut EmulatorModules, Option<&mut S>, tid: u32) -> bool, + hook: fn( + &mut EmulatorModules, + Option<&mut S>, + env: CPUArchStatePtr, + tid: u32, + ) -> bool, ) -> NewThreadHookId { self.hooks.thread_creation_function(hook) } diff --git a/libafl_qemu/src/qemu/hooks.rs b/libafl_qemu/src/qemu/hooks.rs index e4f7cb31e2..9e40461c79 100644 --- a/libafl_qemu/src/qemu/hooks.rs +++ b/libafl_qemu/src/qemu/hooks.rs @@ -6,7 +6,7 @@ use core::{ffi::c_void, fmt::Debug, mem::transmute, ptr}; use libafl::{executors::hooks::inprocess::inprocess_get_state, inputs::UsesInput}; #[cfg(emulation_mode = "usermode")] use libafl_qemu_sys::libafl_dump_core_hook; -use libafl_qemu_sys::{CPUArchStatePtr, FatPtr, GuestAddr, GuestUsize}; +use libafl_qemu_sys::{CPUArchStatePtr, CPUStatePtr, FatPtr, GuestAddr, GuestUsize}; #[cfg(feature = "python")] use pyo3::{pyclass, pymethods, FromPyObject}; @@ -29,14 +29,21 @@ pub enum HookRepr { } #[derive(Debug)] -pub struct HookState { +pub struct TcgHookState { id: H, gen: HookRepr, post_gen: HookRepr, execs: [HookRepr; N], } -impl HookState { +#[derive(Debug)] +pub struct HookState { + id: H, + pre_run: HookRepr, + post_run: HookRepr, +} + +impl TcgHookState { pub fn new(id: H, gen: HookRepr, post_gen: HookRepr, execs: [HookRepr; N]) -> Self { Self { id, @@ -51,6 +58,20 @@ impl HookState { } } +impl HookState { + pub fn new(id: H, pre_run: HookRepr, post_run: HookRepr) -> Self { + Self { + id, + pre_run, + post_run, + } + } + + pub unsafe fn set_id(&mut self, id: H) { + self.id = id; + } +} + pub enum Hook { Function(F), Closure(C), @@ -129,10 +150,72 @@ macro_rules! create_wrapper { }; } +macro_rules! create_pre_exec_wrapper { + ($name:ident, ($($param:ident : $param_type:ty),*), $hook_id:ident) => { + paste::paste! { + pub extern "C" fn [<$name _pre_exec_hook_wrapper>](hook: &mut HookState<$hook_id>, $($param: $param_type),*) + where + ET: EmulatorModuleTuple, + S: Unpin + UsesInput, + { + unsafe { + let modules = EmulatorModules::::emulator_modules_mut_unchecked(); + + match &mut hook.pre_run { + HookRepr::Function(ptr) => { + let func: fn(&mut EmulatorModules, Option<&mut S>, $($param_type),*) = + transmute(*ptr); + func(modules, inprocess_get_state::(), $($param),*) + } + HookRepr::Closure(ptr) => { + let func: &mut Box< + dyn FnMut(&mut EmulatorModules, Option<&mut S>, $($param_type),*), + > = transmute(ptr); + func(modules, inprocess_get_state::(), $($param),*) + } + _ => (), + } + } + } + } + } +} + +macro_rules! create_post_exec_wrapper { + ($name:ident, ($($param:ident : $param_type:ty),*), $hook_id:ident) => { + paste::paste! { + pub extern "C" fn [<$name _post_exec_hook_wrapper>](hook: &mut HookState<$hook_id>, $($param: $param_type),*) + where + ET: EmulatorModuleTuple, + S: Unpin + UsesInput, + { + unsafe { + let modules = EmulatorModules::::emulator_modules_mut_unchecked(); + + match &mut hook.post_run { + HookRepr::Function(ptr) => { + let func: fn(&mut EmulatorModules, Option<&mut S>, $($param_type),*) = + transmute(*ptr); + func(modules, inprocess_get_state::(), $($param),*); + } + HookRepr::Closure(ptr) => { + let func: &mut Box< + dyn FnMut(&mut EmulatorModules, Option<&mut S>, $($param_type),*), + > = transmute(ptr); + func(modules, inprocess_get_state::(), $($param),*); + } + _ => (), + } + } + } + } + } +} + macro_rules! create_gen_wrapper { ($name:ident, ($($param:ident : $param_type:ty),*), $ret_type:ty, $execs:literal, $hook_id:ident) => { paste::paste! { - pub extern "C" fn [<$name _gen_hook_wrapper>](hook: &mut HookState<{ $execs }, $hook_id>, $($param: $param_type),*) -> $ret_type + pub extern "C" fn [<$name _gen_hook_wrapper>](hook: &mut TcgHookState<{ $execs }, $hook_id>, $($param: $param_type),*) -> $ret_type where ET: EmulatorModuleTuple, S: Unpin + UsesInput, @@ -163,7 +246,7 @@ macro_rules! create_gen_wrapper { macro_rules! create_post_gen_wrapper { ($name:ident, ($($param:ident : $param_type:ty),*), $execs:literal, $hook_id:ident) => { paste::paste! { - pub extern "C" fn [<$name _post_gen_hook_wrapper>](hook: &mut HookState<{ $execs }, $hook_id>, $($param: $param_type),*) + pub extern "C" fn [<$name _post_gen_hook_wrapper>](hook: &mut TcgHookState<{ $execs }, $hook_id>, $($param: $param_type),*) where ET: EmulatorModuleTuple, S: Unpin + UsesInput, @@ -193,7 +276,7 @@ macro_rules! create_post_gen_wrapper { macro_rules! create_exec_wrapper { ($name:ident, ($($param:ident : $param_type:ty),*), $execidx:literal, $execs:literal, $hook_id:ident) => { paste::paste! { - pub extern "C" fn [<$name _ $execidx _exec_hook_wrapper>](hook: &mut HookState<{ $execs }, $hook_id>, $($param: $param_type),*) + pub extern "C" fn [<$name _ $execidx _exec_hook_wrapper>](hook: &mut TcgHookState<{ $execs }, $hook_id>, $($param: $param_type),*) where ET: EmulatorModuleTuple, S: Unpin + UsesInput, @@ -271,11 +354,6 @@ macro_rules! create_hook_types { }; } -#[cfg(emulation_mode = "usermode")] -create_hook_id!(PostSyscall, libafl_qemu_remove_post_syscall_hook, false); -#[cfg(emulation_mode = "usermode")] -create_hook_id!(NewThread, libafl_qemu_remove_new_thread_hook, false); - // Instruction hook wrappers create_hook_types!( Instruction, @@ -409,6 +487,8 @@ create_hook_types!( ) -> GuestAddr ); #[cfg(emulation_mode = "usermode")] +create_hook_id!(PostSyscall, libafl_qemu_remove_post_syscall_hook, false); +#[cfg(emulation_mode = "usermode")] create_wrapper!( post_syscall, ( @@ -430,12 +510,39 @@ create_wrapper!( #[cfg(emulation_mode = "usermode")] create_hook_types!( NewThread, - fn(&mut EmulatorModules, Option<&mut S>, tid: u32) -> bool, - Box FnMut(&'a mut EmulatorModules, Option<&'a mut S>, u32) -> bool>, - extern "C" fn(*const (), tid: u32) -> bool + fn(&mut EmulatorModules, Option<&mut S>, env: CPUArchStatePtr, tid: u32) -> bool, + Box< + dyn for<'a> FnMut( + &'a mut EmulatorModules, + Option<&'a mut S>, + CPUArchStatePtr, + u32, + ) -> bool, + >, + extern "C" fn(*const (), env: CPUArchStatePtr, tid: u32) -> bool ); #[cfg(emulation_mode = "usermode")] -create_wrapper!(new_thread, (tid: u32), bool); +create_hook_id!(NewThread, libafl_qemu_remove_new_thread_hook, false); +#[cfg(emulation_mode = "usermode")] +create_wrapper!(new_thread, (env: CPUArchStatePtr, tid: u32), bool); + +// CPU Run hook wrappers +create_hook_types!( + CpuPreRun, + fn(&mut EmulatorModules, Option<&mut S>, cpu: CPUStatePtr), + Box FnMut(&'a mut EmulatorModules, Option<&'a mut S>, CPUStatePtr)>, + extern "C" fn(*const (), cpu: CPUStatePtr) +); +create_hook_types!( + CpuPostRun, + fn(&mut EmulatorModules, Option<&mut S>, cpu: CPUStatePtr), + Box FnMut(&'a mut EmulatorModules, Option<&'a mut S>, CPUStatePtr)>, + extern "C" fn(*const (), cpu: CPUStatePtr) +); +create_hook_id!(CpuRun, libafl_qemu_remove_cpu_run_hook, false); +create_pre_exec_wrapper!(cpu_run, (cpu: CPUStatePtr), CpuRunHookId); +create_post_exec_wrapper!(cpu_run, (addr: CPUStatePtr), CpuRunHookId); +create_wrapper!(cpu_run, (cpu: CPUStatePtr)); // Edge hook wrappers create_hook_types!( @@ -714,6 +821,22 @@ impl QemuHooks { } } + #[allow(clippy::missing_transmute_annotations)] + pub fn add_cpu_run_hooks>( + &self, + data: T, + pre_exec: Option, + post_exec: Option, + ) -> CpuRunHookId { + unsafe { + let data: u64 = data.into().0; + let pre_exec: Option = transmute(pre_exec); + let post_gen: Option = transmute(post_exec); + let num = libafl_qemu_sys::libafl_hook_cpu_run_add(pre_exec, post_gen, data); + CpuRunHookId(num) + } + } + /// `data` can be used to pass data that can be accessed as the first argument in the `gen` and the `exec` functions /// /// `gen` gets passed the current programm counter, mutable access to a `TCGTemp` and information about the memory @@ -873,11 +996,11 @@ impl QemuHooks { pub fn add_new_thread_hook>( &self, data: T, - callback: extern "C" fn(T, tid: u32) -> bool, + callback: extern "C" fn(T, env: CPUArchStatePtr, tid: u32) -> bool, ) -> NewThreadHookId { unsafe { let data: u64 = data.into().0; - let callback: extern "C" fn(u64, u32) -> bool = transmute(callback); + let callback: extern "C" fn(u64, CPUArchStatePtr, u32) -> bool = transmute(callback); let num = libafl_qemu_sys::libafl_add_new_thread_hook(Some(callback), data); NewThreadHookId(num) }