parent
c68b30ae2a
commit
184b69be8e
@ -11,7 +11,7 @@ use crate::cargo_add_rpath;
|
|||||||
|
|
||||||
pub const QEMU_URL: &str = "https://github.com/AFLplusplus/qemu-libafl-bridge";
|
pub const QEMU_URL: &str = "https://github.com/AFLplusplus/qemu-libafl-bridge";
|
||||||
pub const QEMU_DIRNAME: &str = "qemu-libafl-bridge";
|
pub const QEMU_DIRNAME: &str = "qemu-libafl-bridge";
|
||||||
pub const QEMU_REVISION: &str = "2a676d9cd8c474b5c0db1d77d2769e56e2ed8524";
|
pub const QEMU_REVISION: &str = "97bef506eed24ee8d0eda4a07c4419c55dae4acb";
|
||||||
|
|
||||||
pub struct BuildResult {
|
pub struct BuildResult {
|
||||||
pub qemu_path: PathBuf,
|
pub qemu_path: PathBuf,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* 1.87.0-nightly */
|
/* 1.87.0-nightly */
|
||||||
/* qemu git hash: 2a676d9cd8c474b5c0db1d77d2769e56e2ed8524 */
|
/* qemu git hash: 97bef506eed24ee8d0eda4a07c4419c55dae4acb */
|
||||||
/* automatically generated by rust-bindgen 0.71.1 */
|
/* automatically generated by rust-bindgen 0.71.1 */
|
||||||
|
|
||||||
use libc::siginfo_t;
|
use libc::siginfo_t;
|
||||||
@ -8687,37 +8687,131 @@ unsafe extern "C" {
|
|||||||
unsafe extern "C" {
|
unsafe extern "C" {
|
||||||
pub fn libafl_hook_new_thread_run(env: *mut CPUArchState, tid: u32) -> bool;
|
pub fn libafl_hook_new_thread_run(env: *mut CPUArchState, tid: u32) -> bool;
|
||||||
}
|
}
|
||||||
|
pub const libafl_syshook_ret_tag_LIBAFL_SYSHOOK_RUN: libafl_syshook_ret_tag =
|
||||||
|
libafl_syshook_ret_tag(0);
|
||||||
|
pub const libafl_syshook_ret_tag_LIBAFL_SYSHOOK_SKIP: libafl_syshook_ret_tag =
|
||||||
|
libafl_syshook_ret_tag(1);
|
||||||
|
impl ::std::ops::BitOr<libafl_syshook_ret_tag> for libafl_syshook_ret_tag {
|
||||||
|
type Output = Self;
|
||||||
|
#[inline]
|
||||||
|
fn bitor(self, other: Self) -> Self {
|
||||||
|
libafl_syshook_ret_tag(self.0 | other.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl ::std::ops::BitOrAssign for libafl_syshook_ret_tag {
|
||||||
|
#[inline]
|
||||||
|
fn bitor_assign(&mut self, rhs: libafl_syshook_ret_tag) {
|
||||||
|
self.0 |= rhs.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl ::std::ops::BitAnd<libafl_syshook_ret_tag> for libafl_syshook_ret_tag {
|
||||||
|
type Output = Self;
|
||||||
|
#[inline]
|
||||||
|
fn bitand(self, other: Self) -> Self {
|
||||||
|
libafl_syshook_ret_tag(self.0 & other.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl ::std::ops::BitAndAssign for libafl_syshook_ret_tag {
|
||||||
|
#[inline]
|
||||||
|
fn bitand_assign(&mut self, rhs: libafl_syshook_ret_tag) {
|
||||||
|
self.0 &= rhs.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[repr(transparent)]
|
||||||
|
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||||
|
pub struct libafl_syshook_ret_tag(pub ::std::os::raw::c_uint);
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Default, Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct syshook_ret {
|
pub struct libafl_syshook_ret {
|
||||||
pub retval: target_ulong,
|
pub tag: libafl_syshook_ret_tag,
|
||||||
pub skip_syscall: bool,
|
pub __bindgen_anon_1: libafl_syshook_ret__bindgen_ty_1,
|
||||||
|
}
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub union libafl_syshook_ret__bindgen_ty_1 {
|
||||||
|
pub syshook_skip_retval: target_ulong,
|
||||||
}
|
}
|
||||||
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
|
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
|
||||||
const _: () = {
|
const _: () = {
|
||||||
["Size of syshook_ret"][::std::mem::size_of::<syshook_ret>() - 16usize];
|
["Size of libafl_syshook_ret__bindgen_ty_1"]
|
||||||
["Alignment of syshook_ret"][::std::mem::align_of::<syshook_ret>() - 8usize];
|
[::std::mem::size_of::<libafl_syshook_ret__bindgen_ty_1>() - 8usize];
|
||||||
["Offset of field: syshook_ret::retval"][::std::mem::offset_of!(syshook_ret, retval) - 0usize];
|
["Alignment of libafl_syshook_ret__bindgen_ty_1"]
|
||||||
["Offset of field: syshook_ret::skip_syscall"]
|
[::std::mem::align_of::<libafl_syshook_ret__bindgen_ty_1>() - 8usize];
|
||||||
[::std::mem::offset_of!(syshook_ret, skip_syscall) - 8usize];
|
["Offset of field: libafl_syshook_ret__bindgen_ty_1::syshook_skip_retval"]
|
||||||
|
[::std::mem::offset_of!(libafl_syshook_ret__bindgen_ty_1, syshook_skip_retval) - 0usize];
|
||||||
};
|
};
|
||||||
|
impl Default for libafl_syshook_ret__bindgen_ty_1 {
|
||||||
|
fn default() -> Self {
|
||||||
|
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
|
||||||
|
unsafe {
|
||||||
|
::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
|
||||||
|
s.assume_init()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl ::std::fmt::Debug for libafl_syshook_ret__bindgen_ty_1 {
|
||||||
|
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
||||||
|
write!(f, "libafl_syshook_ret__bindgen_ty_1 {{ union }}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
|
||||||
|
const _: () = {
|
||||||
|
["Size of libafl_syshook_ret"][::std::mem::size_of::<libafl_syshook_ret>() - 16usize];
|
||||||
|
["Alignment of libafl_syshook_ret"][::std::mem::align_of::<libafl_syshook_ret>() - 8usize];
|
||||||
|
["Offset of field: libafl_syshook_ret::tag"]
|
||||||
|
[::std::mem::offset_of!(libafl_syshook_ret, tag) - 0usize];
|
||||||
|
};
|
||||||
|
impl Default for libafl_syshook_ret {
|
||||||
|
fn default() -> Self {
|
||||||
|
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
|
||||||
|
unsafe {
|
||||||
|
::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
|
||||||
|
s.assume_init()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl ::std::fmt::Debug for libafl_syshook_ret {
|
||||||
|
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"libafl_syshook_ret {{ tag: {:?}, __bindgen_anon_1: {:?} }}",
|
||||||
|
self.tag, self.__bindgen_anon_1
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub type libafl_pre_syscall_cb = ::std::option::Option<
|
||||||
|
unsafe extern "C" fn(
|
||||||
|
data: u64,
|
||||||
|
sys_num: ::std::os::raw::c_int,
|
||||||
|
arg0: target_ulong,
|
||||||
|
arg1: target_ulong,
|
||||||
|
arg2: target_ulong,
|
||||||
|
arg3: target_ulong,
|
||||||
|
arg4: target_ulong,
|
||||||
|
arg5: target_ulong,
|
||||||
|
arg6: target_ulong,
|
||||||
|
arg7: target_ulong,
|
||||||
|
) -> libafl_syshook_ret,
|
||||||
|
>;
|
||||||
|
pub type libafl_post_syscall_cb = ::std::option::Option<
|
||||||
|
unsafe extern "C" fn(
|
||||||
|
data: u64,
|
||||||
|
ret: target_ulong,
|
||||||
|
sys_num: ::std::os::raw::c_int,
|
||||||
|
arg0: target_ulong,
|
||||||
|
arg1: target_ulong,
|
||||||
|
arg2: target_ulong,
|
||||||
|
arg3: target_ulong,
|
||||||
|
arg4: target_ulong,
|
||||||
|
arg5: target_ulong,
|
||||||
|
arg6: target_ulong,
|
||||||
|
arg7: target_ulong,
|
||||||
|
) -> target_ulong,
|
||||||
|
>;
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct libafl_pre_syscall_hook {
|
pub struct libafl_pre_syscall_hook {
|
||||||
pub callback: ::std::option::Option<
|
pub callback: libafl_pre_syscall_cb,
|
||||||
unsafe extern "C" fn(
|
|
||||||
data: u64,
|
|
||||||
sys_num: ::std::os::raw::c_int,
|
|
||||||
arg0: target_ulong,
|
|
||||||
arg1: target_ulong,
|
|
||||||
arg2: target_ulong,
|
|
||||||
arg3: target_ulong,
|
|
||||||
arg4: target_ulong,
|
|
||||||
arg5: target_ulong,
|
|
||||||
arg6: target_ulong,
|
|
||||||
arg7: target_ulong,
|
|
||||||
) -> syshook_ret,
|
|
||||||
>,
|
|
||||||
pub data: u64,
|
pub data: u64,
|
||||||
pub num: usize,
|
pub num: usize,
|
||||||
pub next: *mut libafl_pre_syscall_hook,
|
pub next: *mut libafl_pre_syscall_hook,
|
||||||
@ -8748,21 +8842,7 @@ impl Default for libafl_pre_syscall_hook {
|
|||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct libafl_post_syscall_hook {
|
pub struct libafl_post_syscall_hook {
|
||||||
pub callback: ::std::option::Option<
|
pub callback: libafl_post_syscall_cb,
|
||||||
unsafe extern "C" fn(
|
|
||||||
data: u64,
|
|
||||||
ret: target_ulong,
|
|
||||||
sys_num: ::std::os::raw::c_int,
|
|
||||||
arg0: target_ulong,
|
|
||||||
arg1: target_ulong,
|
|
||||||
arg2: target_ulong,
|
|
||||||
arg3: target_ulong,
|
|
||||||
arg4: target_ulong,
|
|
||||||
arg5: target_ulong,
|
|
||||||
arg6: target_ulong,
|
|
||||||
arg7: target_ulong,
|
|
||||||
) -> target_ulong,
|
|
||||||
>,
|
|
||||||
pub data: u64,
|
pub data: u64,
|
||||||
pub num: usize,
|
pub num: usize,
|
||||||
pub next: *mut libafl_post_syscall_hook,
|
pub next: *mut libafl_post_syscall_hook,
|
||||||
@ -8792,43 +8872,10 @@ impl Default for libafl_post_syscall_hook {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
unsafe extern "C" {
|
unsafe extern "C" {
|
||||||
pub fn libafl_add_pre_syscall_hook(
|
pub fn libafl_add_pre_syscall_hook(callback: libafl_pre_syscall_cb, data: u64) -> usize;
|
||||||
callback: ::std::option::Option<
|
|
||||||
unsafe extern "C" fn(
|
|
||||||
data: u64,
|
|
||||||
sys_num: ::std::os::raw::c_int,
|
|
||||||
arg0: target_ulong,
|
|
||||||
arg1: target_ulong,
|
|
||||||
arg2: target_ulong,
|
|
||||||
arg3: target_ulong,
|
|
||||||
arg4: target_ulong,
|
|
||||||
arg5: target_ulong,
|
|
||||||
arg6: target_ulong,
|
|
||||||
arg7: target_ulong,
|
|
||||||
) -> syshook_ret,
|
|
||||||
>,
|
|
||||||
data: u64,
|
|
||||||
) -> usize;
|
|
||||||
}
|
}
|
||||||
unsafe extern "C" {
|
unsafe extern "C" {
|
||||||
pub fn libafl_add_post_syscall_hook(
|
pub fn libafl_add_post_syscall_hook(callback: libafl_post_syscall_cb, data: u64) -> usize;
|
||||||
callback: ::std::option::Option<
|
|
||||||
unsafe extern "C" fn(
|
|
||||||
data: u64,
|
|
||||||
ret: target_ulong,
|
|
||||||
sys_num: ::std::os::raw::c_int,
|
|
||||||
arg0: target_ulong,
|
|
||||||
arg1: target_ulong,
|
|
||||||
arg2: target_ulong,
|
|
||||||
arg3: target_ulong,
|
|
||||||
arg4: target_ulong,
|
|
||||||
arg5: target_ulong,
|
|
||||||
arg6: target_ulong,
|
|
||||||
arg7: target_ulong,
|
|
||||||
) -> target_ulong,
|
|
||||||
>,
|
|
||||||
data: u64,
|
|
||||||
) -> usize;
|
|
||||||
}
|
}
|
||||||
unsafe extern "C" {
|
unsafe extern "C" {
|
||||||
pub fn libafl_qemu_remove_pre_syscall_hook(num: usize) -> ::std::os::raw::c_int;
|
pub fn libafl_qemu_remove_pre_syscall_hook(num: usize) -> ::std::os::raw::c_int;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* 1.87.0-nightly */
|
/* 1.87.0-nightly */
|
||||||
/* qemu git hash: 2a676d9cd8c474b5c0db1d77d2769e56e2ed8524 */
|
/* qemu git hash: 97bef506eed24ee8d0eda4a07c4419c55dae4acb */
|
||||||
/* automatically generated by rust-bindgen 0.71.1 */
|
/* automatically generated by rust-bindgen 0.71.1 */
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* 1.87.0-nightly */
|
/* 1.87.0-nightly */
|
||||||
/* qemu git hash: 2a676d9cd8c474b5c0db1d77d2769e56e2ed8524 */
|
/* qemu git hash: 97bef506eed24ee8d0eda4a07c4419c55dae4acb */
|
||||||
/* automatically generated by rust-bindgen 0.71.1 */
|
/* automatically generated by rust-bindgen 0.71.1 */
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
@ -98,7 +98,7 @@ pub fn python_module(m: &Bound<'_, PyModule>) -> PyResult<()> {
|
|||||||
#[cfg(feature = "usermode")]
|
#[cfg(feature = "usermode")]
|
||||||
m.add_class::<GuestMaps>()?;
|
m.add_class::<GuestMaps>()?;
|
||||||
|
|
||||||
m.add_class::<SyscallHookResult>()?;
|
m.add_class::<pybind::SyscallHookResult>()?;
|
||||||
m.add_class::<pybind::Qemu>()?;
|
m.add_class::<pybind::Qemu>()?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -578,9 +578,9 @@ impl AsanGiovese {
|
|||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
SyscallHookResult::new(Some(r))
|
SyscallHookResult::Skip(r)
|
||||||
} else {
|
} else {
|
||||||
SyscallHookResult::new(None)
|
SyscallHookResult::Run
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1350,9 +1350,9 @@ where
|
|||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
SyscallHookResult::new(Some(0))
|
SyscallHookResult::Skip(0)
|
||||||
} else {
|
} else {
|
||||||
SyscallHookResult::new(None)
|
SyscallHookResult::Run
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,13 +400,13 @@ where
|
|||||||
|
|
||||||
let first_parameter = unsafe {
|
let first_parameter = unsafe {
|
||||||
if (*c_array.offset(1)).is_null() {
|
if (*c_array.offset(1)).is_null() {
|
||||||
return SyscallHookResult::new(None);
|
return SyscallHookResult::Run;
|
||||||
}
|
}
|
||||||
CStr::from_ptr(*c_array.offset(1)).to_string_lossy()
|
CStr::from_ptr(*c_array.offset(1)).to_string_lossy()
|
||||||
};
|
};
|
||||||
let second_parameter = unsafe {
|
let second_parameter = unsafe {
|
||||||
if (*c_array.offset(2)).is_null() {
|
if (*c_array.offset(2)).is_null() {
|
||||||
return SyscallHookResult::new(None);
|
return SyscallHookResult::Run;
|
||||||
}
|
}
|
||||||
CStr::from_ptr(*c_array.offset(2)).to_string_lossy()
|
CStr::from_ptr(*c_array.offset(2)).to_string_lossy()
|
||||||
};
|
};
|
||||||
@ -419,9 +419,9 @@ where
|
|||||||
|
|
||||||
//println!("PARAMETERS First {} Second {}", first_parameter, second_
|
//println!("PARAMETERS First {} Second {}", first_parameter, second_
|
||||||
}
|
}
|
||||||
SyscallHookResult::new(Some(0))
|
SyscallHookResult::Skip(0)
|
||||||
} else {
|
} else {
|
||||||
SyscallHookResult::new(None)
|
SyscallHookResult::Run
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ where
|
|||||||
{
|
{
|
||||||
let h = emulator_modules.get_mut::<RedirectStdinModule>().unwrap();
|
let h = emulator_modules.get_mut::<RedirectStdinModule>().unwrap();
|
||||||
if h.input_addr.is_null() {
|
if h.input_addr.is_null() {
|
||||||
return SyscallHookResult::new(None);
|
return SyscallHookResult::Run;
|
||||||
}
|
}
|
||||||
if syscall == SYS_read as i32 && x0 == 0 {
|
if syscall == SYS_read as i32 && x0 == 0 {
|
||||||
/*
|
/*
|
||||||
@ -143,7 +143,7 @@ where
|
|||||||
};
|
};
|
||||||
// println!("copied {}", size);
|
// println!("copied {}", size);
|
||||||
h.read += size as usize;
|
h.read += size as usize;
|
||||||
return SyscallHookResult::new(Some(size));
|
return SyscallHookResult::Skip(size);
|
||||||
}
|
}
|
||||||
SyscallHookResult::new(None)
|
SyscallHookResult::Run
|
||||||
}
|
}
|
||||||
|
@ -888,11 +888,11 @@ where
|
|||||||
if i64::from(sys_num) == SYS_munmap {
|
if i64::from(sys_num) == SYS_munmap {
|
||||||
let h = emulator_modules.get_mut::<SnapshotModule>().unwrap();
|
let h = emulator_modules.get_mut::<SnapshotModule>().unwrap();
|
||||||
if !h.is_unmap_allowed(a0 as GuestAddr, a1 as usize) {
|
if !h.is_unmap_allowed(a0 as GuestAddr, a1 as usize) {
|
||||||
return SyscallHookResult::new(Some(0));
|
return SyscallHookResult::Skip(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SyscallHookResult::new(None)
|
SyscallHookResult::Run
|
||||||
}
|
}
|
||||||
|
|
||||||
#[expect(non_upper_case_globals, clippy::too_many_arguments)]
|
#[expect(non_upper_case_globals, clippy::too_many_arguments)]
|
||||||
|
@ -8,8 +8,6 @@ use core::{ffi::c_void, fmt::Debug, mem::transmute, ptr};
|
|||||||
|
|
||||||
use libafl::executors::hooks::inprocess::inprocess_get_state;
|
use libafl::executors::hooks::inprocess::inprocess_get_state;
|
||||||
use libafl_qemu_sys::{CPUArchStatePtr, CPUStatePtr, FatPtr, GuestAddr, GuestUsize};
|
use libafl_qemu_sys::{CPUArchStatePtr, CPUStatePtr, FatPtr, GuestAddr, GuestUsize};
|
||||||
#[cfg(feature = "python")]
|
|
||||||
use pyo3::{FromPyObject, pyclass, pymethods};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
HookData, HookId,
|
HookData, HookId,
|
||||||
@ -85,12 +83,20 @@ pub enum Hook<F, C, R: Clone> {
|
|||||||
Empty,
|
Empty,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Syshook result representation
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// This enum is shadowed by another enum in QEMU (`libafl_syshook_ret`). Any change made to this
|
||||||
|
/// enum should be propagated to the C enum as well.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[cfg_attr(feature = "python", pyclass)]
|
pub enum SyscallHookResult {
|
||||||
#[cfg_attr(feature = "python", derive(FromPyObject))]
|
/// Runs the syscall after the hook is executed. The return value will be the one of the
|
||||||
pub struct SyscallHookResult {
|
/// syscall itself.
|
||||||
pub retval: GuestAddr,
|
/// If you need to change the return value of the syscall, please use a post-syscall hook.
|
||||||
pub skip_syscall: bool,
|
Run,
|
||||||
|
/// Skip the syscall, and make the syscall return the value provided in the field in the target.
|
||||||
|
Skip(GuestAddr),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F, C, R: Clone> Hook<F, C, R> {
|
impl<F, C, R: Clone> Hook<F, C, R> {
|
||||||
@ -1281,7 +1287,7 @@ impl QemuHooks {
|
|||||||
GuestAddr,
|
GuestAddr,
|
||||||
GuestAddr,
|
GuestAddr,
|
||||||
GuestAddr,
|
GuestAddr,
|
||||||
) -> libafl_qemu_sys::syshook_ret = transmute(callback);
|
) -> libafl_qemu_sys::libafl_syshook_ret = transmute(callback);
|
||||||
let num = libafl_qemu_sys::libafl_add_pre_syscall_hook(Some(callback), data);
|
let num = libafl_qemu_sys::libafl_add_pre_syscall_hook(Some(callback), data);
|
||||||
PreSyscallHookId(num)
|
PreSyscallHookId(num)
|
||||||
}
|
}
|
||||||
@ -1324,38 +1330,3 @@ impl QemuHooks {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "python")]
|
|
||||||
#[pymethods]
|
|
||||||
impl SyscallHookResult {
|
|
||||||
#[new]
|
|
||||||
#[pyo3(signature = (
|
|
||||||
value=None
|
|
||||||
))]
|
|
||||||
#[must_use]
|
|
||||||
pub fn new(value: Option<GuestAddr>) -> Self {
|
|
||||||
Self::new_internal(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SyscallHookResult {
|
|
||||||
#[cfg(not(feature = "python"))]
|
|
||||||
#[must_use]
|
|
||||||
pub fn new(value: Option<GuestAddr>) -> Self {
|
|
||||||
Self::new_internal(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
fn new_internal(value: Option<GuestAddr>) -> Self {
|
|
||||||
value.map_or(
|
|
||||||
Self {
|
|
||||||
retval: 0,
|
|
||||||
skip_syscall: false,
|
|
||||||
},
|
|
||||||
|v| Self {
|
|
||||||
retval: v,
|
|
||||||
skip_syscall: true,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1238,6 +1238,8 @@ impl QemuMemoryChunk {
|
|||||||
pub mod pybind {
|
pub mod pybind {
|
||||||
use pyo3::{exceptions::PyValueError, prelude::*};
|
use pyo3::{exceptions::PyValueError, prelude::*};
|
||||||
|
|
||||||
|
#[cfg(feature = "usermode")]
|
||||||
|
pub use super::usermode::pybind::*;
|
||||||
use super::{GuestAddr, GuestUsize};
|
use super::{GuestAddr, GuestUsize};
|
||||||
|
|
||||||
static mut PY_GENERIC_HOOKS: Vec<(GuestAddr, PyObject)> = vec![];
|
static mut PY_GENERIC_HOOKS: Vec<(GuestAddr, PyObject)> = vec![];
|
||||||
|
@ -467,17 +467,24 @@ impl Qemu {
|
|||||||
pub mod pybind {
|
pub mod pybind {
|
||||||
use libafl_qemu_sys::{GuestAddr, MmapPerms};
|
use libafl_qemu_sys::{GuestAddr, MmapPerms};
|
||||||
use pyo3::{
|
use pyo3::{
|
||||||
Bound, PyObject, PyResult, Python,
|
Bound, FromPyObject, PyObject, PyResult, Python,
|
||||||
conversion::FromPyObject,
|
|
||||||
exceptions::PyValueError,
|
exceptions::PyValueError,
|
||||||
pymethods,
|
pyclass, pymethods,
|
||||||
types::{PyAnyMethods, PyInt},
|
types::{PyAnyMethods, PyInt},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{pybind::Qemu, qemu::hooks::SyscallHookResult};
|
use crate::{pybind::Qemu, qemu::hooks};
|
||||||
|
|
||||||
static mut PY_SYSCALL_HOOK: Option<PyObject> = None;
|
static mut PY_SYSCALL_HOOK: Option<PyObject> = None;
|
||||||
|
|
||||||
|
#[pyclass]
|
||||||
|
#[derive(FromPyObject)]
|
||||||
|
pub struct SyscallHookResult {
|
||||||
|
/// if None: run.
|
||||||
|
/// else: skip with given value.
|
||||||
|
skip: Option<GuestAddr>,
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" fn py_syscall_hook_wrapper(
|
extern "C" fn py_syscall_hook_wrapper(
|
||||||
_data: u64,
|
_data: u64,
|
||||||
sys_num: i32,
|
sys_num: i32,
|
||||||
@ -489,25 +496,31 @@ pub mod pybind {
|
|||||||
a5: u64,
|
a5: u64,
|
||||||
a6: u64,
|
a6: u64,
|
||||||
a7: u64,
|
a7: u64,
|
||||||
) -> SyscallHookResult {
|
) -> hooks::SyscallHookResult {
|
||||||
unsafe { (&raw const PY_SYSCALL_HOOK).read() }.map_or_else(
|
unsafe { (&raw const PY_SYSCALL_HOOK).read() }.map_or_else(
|
||||||
|| SyscallHookResult::new(None),
|
|| hooks::SyscallHookResult::Run,
|
||||||
|obj| {
|
|obj| {
|
||||||
let args = (sys_num, a0, a1, a2, a3, a4, a5, a6, a7);
|
let args = (sys_num, a0, a1, a2, a3, a4, a5, a6, a7);
|
||||||
Python::with_gil(|py| {
|
Python::with_gil(|py| {
|
||||||
let ret = obj.call1(py, args).expect("Error in the syscall hook");
|
let ret = obj.call1(py, args).expect("Error in the syscall hook");
|
||||||
let any = ret.bind(py);
|
let any = ret.bind(py);
|
||||||
if any.is_none() {
|
if any.is_none() {
|
||||||
SyscallHookResult::new(None)
|
hooks::SyscallHookResult::Run
|
||||||
} else {
|
} else {
|
||||||
let a: Result<&Bound<'_, PyInt>, _> = any.downcast_exact();
|
let a: Result<&Bound<'_, PyInt>, _> = any.downcast_exact();
|
||||||
if let Ok(i) = a {
|
if let Ok(i) = a {
|
||||||
SyscallHookResult::new(Some(
|
hooks::SyscallHookResult::Skip(
|
||||||
i.extract().expect("Invalid syscall hook return value"),
|
i.extract().expect("Invalid syscall hook return value"),
|
||||||
))
|
)
|
||||||
} else {
|
} else {
|
||||||
SyscallHookResult::extract_bound(ret.bind(py))
|
let syscall = SyscallHookResult::extract_bound(ret.bind(py))
|
||||||
.expect("The syscall hook must return a SyscallHookResult")
|
.expect("The syscall hook must return a SyscallHookResult");
|
||||||
|
|
||||||
|
if let Some(ret) = syscall.skip {
|
||||||
|
hooks::SyscallHookResult::Skip(ret)
|
||||||
|
} else {
|
||||||
|
hooks::SyscallHookResult::Run
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user