Abort on triple fault for in process executors, refactor AddressFilter and PageFilter (#3026)
* abort on triple fault in generic inprocess signal handler * refactor qemu filters --------- Co-authored-by: Toka <tokazerkje@outlook.com>
This commit is contained in:
parent
191bc6d12d
commit
e864bc28b1
4
.github/workflows/build_and_test.yml
vendored
4
.github/workflows/build_and_test.yml
vendored
@ -120,6 +120,10 @@ jobs:
|
|||||||
# ---- build normal and examples ----
|
# ---- build normal and examples ----
|
||||||
- name: Run a normal build
|
- name: Run a normal build
|
||||||
run: cargo build --verbose
|
run: cargo build --verbose
|
||||||
|
- name: Run libafl_qemu usermode tests
|
||||||
|
run: cd libafl_qemu && cargo test
|
||||||
|
- name: Run libafl_qemu systemmode tests
|
||||||
|
run: cd libafl_qemu && cargo test --no-default-features --features x86_64,systemmode
|
||||||
- name: Build examples
|
- name: Build examples
|
||||||
run: cargo build --examples --verbose
|
run: cargo build --examples --verbose
|
||||||
|
|
||||||
|
6
.gitignore
vendored
6
.gitignore
vendored
@ -79,3 +79,9 @@ fuzzer_libpng*
|
|||||||
|
|
||||||
# Sometimes this happens
|
# Sometimes this happens
|
||||||
rustc-ice-*
|
rustc-ice-*
|
||||||
|
|
||||||
|
# perf files
|
||||||
|
*.mm_profdata
|
||||||
|
|
||||||
|
# backup files
|
||||||
|
*.bak
|
||||||
|
@ -41,7 +41,7 @@ use libafl_qemu::{
|
|||||||
executor::QemuExecutor,
|
executor::QemuExecutor,
|
||||||
modules::{
|
modules::{
|
||||||
cmplog::CmpLogObserver, edges::StdEdgeCoverageClassicModule,
|
cmplog::CmpLogObserver, edges::StdEdgeCoverageClassicModule,
|
||||||
utils::filters::HasAddressFilterTuples, CmpLogModule, EmulatorModuleTuple,
|
utils::filters::HasAddressFilterTuple, CmpLogModule, EmulatorModuleTuple,
|
||||||
},
|
},
|
||||||
FastSnapshotManager, NopSnapshotManager, QemuInitError,
|
FastSnapshotManager, NopSnapshotManager, QemuInitError,
|
||||||
};
|
};
|
||||||
@ -78,12 +78,12 @@ fn get_emulator<C, ET, I, S>(
|
|||||||
QemuInitError,
|
QemuInitError,
|
||||||
>
|
>
|
||||||
where
|
where
|
||||||
ET: EmulatorModuleTuple<I, S> + HasAddressFilterTuples,
|
ET: EmulatorModuleTuple<I, S> + HasAddressFilterTuple,
|
||||||
I: HasTargetBytes + Unpin,
|
I: HasTargetBytes + Unpin,
|
||||||
S: HasExecutions + Unpin,
|
S: HasExecutions + Unpin,
|
||||||
{
|
{
|
||||||
// Allow linux process address space addresses as feedback
|
// Allow linux process address space addresses as feedback
|
||||||
modules.allow_address_range_all(LINUX_PROCESS_ADDRESS_RANGE);
|
modules.allow_address_range_all(&LINUX_PROCESS_ADDRESS_RANGE);
|
||||||
|
|
||||||
Emulator::builder()
|
Emulator::builder()
|
||||||
.qemu_parameters(args)
|
.qemu_parameters(args)
|
||||||
|
@ -41,7 +41,7 @@ use libafl_qemu::{
|
|||||||
executor::QemuExecutor,
|
executor::QemuExecutor,
|
||||||
modules::{
|
modules::{
|
||||||
cmplog::CmpLogObserver, edges::StdEdgeCoverageClassicModule,
|
cmplog::CmpLogObserver, edges::StdEdgeCoverageClassicModule,
|
||||||
utils::filters::HasAddressFilterTuples, CmpLogModule, EmulatorModuleTuple,
|
utils::filters::HasAddressFilterTuple, CmpLogModule, EmulatorModuleTuple,
|
||||||
},
|
},
|
||||||
FastSnapshotManager, NopSnapshotManager, QemuInitError, QemuSnapshotManager,
|
FastSnapshotManager, NopSnapshotManager, QemuInitError, QemuSnapshotManager,
|
||||||
};
|
};
|
||||||
@ -78,12 +78,12 @@ fn get_emulator<C, ET, I, S>(
|
|||||||
QemuInitError,
|
QemuInitError,
|
||||||
>
|
>
|
||||||
where
|
where
|
||||||
ET: EmulatorModuleTuple<I, S> + HasAddressFilterTuples,
|
ET: EmulatorModuleTuple<I, S> + HasAddressFilterTuple,
|
||||||
I: HasTargetBytes + Unpin,
|
I: HasTargetBytes + Unpin,
|
||||||
S: HasExecutions + Unpin,
|
S: HasExecutions + Unpin,
|
||||||
{
|
{
|
||||||
// Allow linux process address space addresses as feedback
|
// Allow linux process address space addresses as feedback
|
||||||
modules.allow_address_range_all(LINUX_PROCESS_ADDRESS_RANGE);
|
modules.allow_address_range_all(&LINUX_PROCESS_ADDRESS_RANGE);
|
||||||
|
|
||||||
Emulator::builder()
|
Emulator::builder()
|
||||||
.qemu_parameters(args)
|
.qemu_parameters(args)
|
||||||
|
@ -8,10 +8,10 @@ use core::{fmt::Debug, marker::PhantomData, time::Duration};
|
|||||||
use libafl_bolts::ClientId;
|
use libafl_bolts::ClientId;
|
||||||
#[cfg(all(feature = "std", any(windows, not(feature = "fork"))))]
|
#[cfg(all(feature = "std", any(windows, not(feature = "fork"))))]
|
||||||
use libafl_bolts::os::startable_self;
|
use libafl_bolts::os::startable_self;
|
||||||
#[cfg(all(unix, feature = "std", not(miri)))]
|
|
||||||
use libafl_bolts::os::unix_signals::setup_signal_handler;
|
|
||||||
#[cfg(all(feature = "std", feature = "fork", unix))]
|
#[cfg(all(feature = "std", feature = "fork", unix))]
|
||||||
use libafl_bolts::os::{ForkResult, fork};
|
use libafl_bolts::os::{ForkResult, fork};
|
||||||
|
#[cfg(all(unix, feature = "std", not(miri)))]
|
||||||
|
use libafl_bolts::os::{SIGNAL_RECURSION_EXIT, unix_signals::setup_signal_handler};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
os::CTRL_C_EXIT,
|
os::CTRL_C_EXIT,
|
||||||
@ -510,6 +510,13 @@ where
|
|||||||
return Err(Error::shutting_down());
|
return Err(Error::shutting_down());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(all(unix, feature = "std"))]
|
||||||
|
if child_status == SIGNAL_RECURSION_EXIT {
|
||||||
|
return Err(Error::illegal_state(
|
||||||
|
"The client is stuck in an unexpected signal handler recursion. It is most likely a fuzzer bug.",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
#[expect(clippy::manual_assert)]
|
#[expect(clippy::manual_assert)]
|
||||||
if !staterestorer.has_content() {
|
if !staterestorer.has_content() {
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
|
@ -355,7 +355,9 @@ pub struct InProcessExecutorHandlerData {
|
|||||||
/// the pointer to the executor
|
/// the pointer to the executor
|
||||||
pub executor_ptr: *const c_void,
|
pub executor_ptr: *const c_void,
|
||||||
pub(crate) current_input_ptr: *const c_void,
|
pub(crate) current_input_ptr: *const c_void,
|
||||||
pub(crate) in_handler: bool,
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
pub(crate) signal_handler_depth: usize,
|
||||||
|
|
||||||
/// The timeout handler
|
/// The timeout handler
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
@ -376,6 +378,9 @@ unsafe impl Send for InProcessExecutorHandlerData {}
|
|||||||
unsafe impl Sync for InProcessExecutorHandlerData {}
|
unsafe impl Sync for InProcessExecutorHandlerData {}
|
||||||
|
|
||||||
impl InProcessExecutorHandlerData {
|
impl InProcessExecutorHandlerData {
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
const SIGNAL_HANDLER_MAX_DEPTH: usize = 3;
|
||||||
|
|
||||||
/// # Safety
|
/// # Safety
|
||||||
/// Only safe if not called twice and if the executor is not used from another borrow after this.
|
/// Only safe if not called twice and if the executor is not used from another borrow after this.
|
||||||
#[cfg(all(feature = "std", any(unix, windows)))]
|
#[cfg(all(feature = "std", any(unix, windows)))]
|
||||||
@ -418,11 +423,19 @@ impl InProcessExecutorHandlerData {
|
|||||||
!self.current_input_ptr.is_null()
|
!self.current_input_ptr.is_null()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if signal handling max depth has been reached, false otherwise
|
||||||
#[cfg(all(feature = "std", any(unix, windows)))]
|
#[cfg(all(feature = "std", any(unix, windows)))]
|
||||||
pub(crate) fn set_in_handler(&mut self, v: bool) -> bool {
|
pub(crate) fn signal_handler_enter(&mut self) -> (bool, usize) {
|
||||||
let old = self.in_handler;
|
self.signal_handler_depth += 1;
|
||||||
self.in_handler = v;
|
(
|
||||||
old
|
self.signal_handler_depth >= Self::SIGNAL_HANDLER_MAX_DEPTH,
|
||||||
|
self.signal_handler_depth,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(all(feature = "std", any(unix, windows)))]
|
||||||
|
pub(crate) fn signal_handler_exit(&mut self) {
|
||||||
|
self.signal_handler_depth -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// if data is valid, safely report a crash and return true.
|
/// if data is valid, safely report a crash and return true.
|
||||||
@ -500,7 +513,8 @@ pub static mut GLOBAL_STATE: InProcessExecutorHandlerData = InProcessExecutorHan
|
|||||||
// The current input for signal handling
|
// The current input for signal handling
|
||||||
current_input_ptr: ptr::null(),
|
current_input_ptr: ptr::null(),
|
||||||
|
|
||||||
in_handler: false,
|
#[cfg(feature = "std")]
|
||||||
|
signal_handler_depth: 0,
|
||||||
|
|
||||||
// The crash handler fn
|
// The crash handler fn
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
@ -560,11 +574,3 @@ pub unsafe fn inprocess_get_executor<'a, E>() -> Option<&'a mut E> {
|
|||||||
pub unsafe fn inprocess_get_input<'a, I>() -> Option<&'a I> {
|
pub unsafe fn inprocess_get_input<'a, I>() -> Option<&'a I> {
|
||||||
unsafe { (GLOBAL_STATE.current_input_ptr as *const I).as_ref() }
|
unsafe { (GLOBAL_STATE.current_input_ptr as *const I).as_ref() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns if we are executing in a crash/timeout handler
|
|
||||||
#[must_use]
|
|
||||||
pub fn inprocess_in_handler() -> bool {
|
|
||||||
// # Safety
|
|
||||||
// Safe because the state is set up and the handler is a single bool. Worst case we read an old value.
|
|
||||||
unsafe { GLOBAL_STATE.in_handler }
|
|
||||||
}
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
//! These will be executed right before and after the executor's harness run.
|
//! These will be executed right before and after the executor's harness run.
|
||||||
|
|
||||||
/// windows crash/timeout handler and asan death callback
|
/// windows crash/timeout handler and asan death callback
|
||||||
#[cfg(windows)]
|
#[cfg(all(windows, feature = "std"))]
|
||||||
pub mod windows;
|
pub mod windows;
|
||||||
|
|
||||||
/// *nix crash handler
|
/// *nix crash handler
|
||||||
|
@ -5,7 +5,10 @@ pub mod unix_signal_handler {
|
|||||||
use core::mem::transmute;
|
use core::mem::transmute;
|
||||||
use std::{io::Write, panic};
|
use std::{io::Write, panic};
|
||||||
|
|
||||||
use libafl_bolts::os::unix_signals::{Signal, SignalHandler, ucontext_t};
|
use libafl_bolts::os::{
|
||||||
|
SIGNAL_RECURSION_EXIT,
|
||||||
|
unix_signals::{Signal, SignalHandler, ucontext_t},
|
||||||
|
};
|
||||||
use libc::siginfo_t;
|
use libc::siginfo_t;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -50,11 +53,13 @@ pub mod unix_signal_handler {
|
|||||||
) {
|
) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let data = &raw mut GLOBAL_STATE;
|
let data = &raw mut GLOBAL_STATE;
|
||||||
let in_handler = (*data).set_in_handler(true);
|
let (max_depth_reached, signal_depth) = (*data).signal_handler_enter();
|
||||||
|
|
||||||
if in_handler {
|
if max_depth_reached {
|
||||||
log::error!("We crashed inside a crash handler, but this should never happen!");
|
log::error!(
|
||||||
libc::exit(56);
|
"The in process signal handler has been triggered {signal_depth} times recursively, which is not expected. Exiting with error code {SIGNAL_RECURSION_EXIT}..."
|
||||||
|
);
|
||||||
|
libc::exit(SIGNAL_RECURSION_EXIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
match signal {
|
match signal {
|
||||||
@ -67,11 +72,11 @@ pub mod unix_signal_handler {
|
|||||||
_ => {
|
_ => {
|
||||||
if !(*data).crash_handler.is_null() {
|
if !(*data).crash_handler.is_null() {
|
||||||
let func: HandlerFuncPtr = transmute((*data).crash_handler);
|
let func: HandlerFuncPtr = transmute((*data).crash_handler);
|
||||||
(func)(signal, info, context, data);
|
func(signal, info, context, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(*data).set_in_handler(in_handler);
|
(*data).signal_handler_exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,11 +100,13 @@ pub mod unix_signal_handler {
|
|||||||
panic::set_hook(Box::new(move |panic_info| unsafe {
|
panic::set_hook(Box::new(move |panic_info| unsafe {
|
||||||
old_hook(panic_info);
|
old_hook(panic_info);
|
||||||
let data = &raw mut GLOBAL_STATE;
|
let data = &raw mut GLOBAL_STATE;
|
||||||
let in_handler = (*data).set_in_handler(true);
|
let (max_depth_reached, signal_depth) = (*data).signal_handler_enter();
|
||||||
|
|
||||||
if in_handler {
|
if max_depth_reached {
|
||||||
log::error!("We crashed inside a crash panic hook, but this should never happen!");
|
log::error!(
|
||||||
libc::exit(56);
|
"The in process signal handler has been triggered {signal_depth} times recursively, which is not expected. Exiting with error code {SIGNAL_RECURSION_EXIT}..."
|
||||||
|
);
|
||||||
|
libc::exit(SIGNAL_RECURSION_EXIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*data).is_valid() {
|
if (*data).is_valid() {
|
||||||
@ -121,7 +128,8 @@ pub mod unix_signal_handler {
|
|||||||
|
|
||||||
libc::_exit(128 + 6); // SIGABRT exit code
|
libc::_exit(128 + 6); // SIGABRT exit code
|
||||||
}
|
}
|
||||||
(*data).set_in_handler(in_handler);
|
|
||||||
|
(*data).signal_handler_exit();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/// In-Process crash handling for `Windows`
|
/// In-Process crash handling for `Windows`
|
||||||
#[cfg(all(windows, feature = "std"))]
|
|
||||||
pub mod windows_asan_handler {
|
pub mod windows_asan_handler {
|
||||||
use alloc::string::String;
|
use alloc::string::String;
|
||||||
use core::sync::atomic::{Ordering, compiler_fence};
|
use core::sync::atomic::{Ordering, compiler_fence};
|
||||||
|
|
||||||
|
use libafl_bolts::os::SIGNAL_RECURSION_EXIT;
|
||||||
use windows::Win32::System::Threading::{
|
use windows::Win32::System::Threading::{
|
||||||
CRITICAL_SECTION, EnterCriticalSection, ExitProcess, LeaveCriticalSection,
|
CRITICAL_SECTION, EnterCriticalSection, ExitProcess, LeaveCriticalSection,
|
||||||
};
|
};
|
||||||
@ -35,13 +35,13 @@ pub mod windows_asan_handler {
|
|||||||
{
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
let data = &raw mut GLOBAL_STATE;
|
let data = &raw mut GLOBAL_STATE;
|
||||||
let in_handler = (*data).set_in_handler(true);
|
let (max_depth_reached, _signal_depth) = (*data).signal_handler_enter();
|
||||||
|
|
||||||
if in_handler {
|
if max_depth_reached {
|
||||||
log::error!(
|
log::error!(
|
||||||
"We crashed inside a asan death handler, but this should never happen!"
|
"We crashed inside a asan death handler, but this should never happen!"
|
||||||
);
|
);
|
||||||
ExitProcess(56);
|
ExitProcess(SIGNAL_RECURSION_EXIT as u32);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Have we set a timer_before?
|
// Have we set a timer_before?
|
||||||
@ -109,7 +109,6 @@ pub mod windows_asan_handler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(windows, feature = "std"))]
|
|
||||||
/// The module to take care of windows crash or timeouts
|
/// The module to take care of windows crash or timeouts
|
||||||
pub mod windows_exception_handler {
|
pub mod windows_exception_handler {
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
@ -126,9 +125,12 @@ pub mod windows_exception_handler {
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::panic;
|
use std::panic;
|
||||||
|
|
||||||
use libafl_bolts::os::windows_exceptions::{
|
use libafl_bolts::os::{
|
||||||
|
SIGNAL_RECURSION_EXIT,
|
||||||
|
windows_exceptions::{
|
||||||
CRASH_EXCEPTIONS, EXCEPTION_HANDLERS_SIZE, EXCEPTION_POINTERS, ExceptionCode,
|
CRASH_EXCEPTIONS, EXCEPTION_HANDLERS_SIZE, EXCEPTION_POINTERS, ExceptionCode,
|
||||||
ExceptionHandler,
|
ExceptionHandler,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use windows::Win32::System::Threading::{
|
use windows::Win32::System::Threading::{
|
||||||
CRITICAL_SECTION, EnterCriticalSection, ExitProcess, LeaveCriticalSection,
|
CRITICAL_SECTION, EnterCriticalSection, ExitProcess, LeaveCriticalSection,
|
||||||
@ -168,18 +170,18 @@ pub mod windows_exception_handler {
|
|||||||
) {
|
) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let data = &raw mut GLOBAL_STATE;
|
let data = &raw mut GLOBAL_STATE;
|
||||||
let in_handler = (*data).set_in_handler(true);
|
let (max_depth_reached, _signal_depth) = (*data).signal_handler_enter();
|
||||||
|
|
||||||
if in_handler {
|
if max_depth_reached {
|
||||||
log::error!("We crashed inside a crash handler, but this should never happen!");
|
log::error!("We crashed inside a crash handler, but this should never happen!");
|
||||||
ExitProcess(56);
|
ExitProcess(SIGNAL_RECURSION_EXIT as u32);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !(*data).crash_handler.is_null() {
|
if !(*data).crash_handler.is_null() {
|
||||||
let func: HandlerFuncPtr = transmute((*data).crash_handler);
|
let func: HandlerFuncPtr = transmute((*data).crash_handler);
|
||||||
(func)(exception_pointers, data);
|
(func)(exception_pointers, data);
|
||||||
}
|
}
|
||||||
(*data).set_in_handler(in_handler);
|
(*data).signal_handler_exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,11 +210,11 @@ pub mod windows_exception_handler {
|
|||||||
let old_hook = panic::take_hook();
|
let old_hook = panic::take_hook();
|
||||||
panic::set_hook(Box::new(move |panic_info| unsafe {
|
panic::set_hook(Box::new(move |panic_info| unsafe {
|
||||||
let data = &raw mut GLOBAL_STATE;
|
let data = &raw mut GLOBAL_STATE;
|
||||||
let in_handler = (*data).set_in_handler(true);
|
let (max_depth_reached, _signal_depth) = (*data).signal_handler_enter();
|
||||||
|
|
||||||
if in_handler {
|
if max_depth_reached {
|
||||||
log::error!("We crashed inside a crash handler, but this should never happen!");
|
log::error!("We crashed inside a crash handler, but this should never happen!");
|
||||||
ExitProcess(56);
|
ExitProcess(SIGNAL_RECURSION_EXIT as u32);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Have we set a timer_before?
|
// Have we set a timer_before?
|
||||||
@ -252,7 +254,7 @@ pub mod windows_exception_handler {
|
|||||||
ExitProcess(1);
|
ExitProcess(1);
|
||||||
}
|
}
|
||||||
old_hook(panic_info);
|
old_hook(panic_info);
|
||||||
(*data).set_in_handler(in_handler);
|
(*data).signal_handler_exit();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +48,9 @@ pub struct ChildHandle {
|
|||||||
pub pid: pid_t,
|
pub pid: pid_t,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The special exit code when the target signal handler is crashing recursively
|
||||||
|
pub const SIGNAL_RECURSION_EXIT: i32 = 101;
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
impl ChildHandle {
|
impl ChildHandle {
|
||||||
/// Block until the child exited and the status code becomes available
|
/// Block until the child exited and the status code becomes available
|
||||||
|
@ -25,7 +25,7 @@ use crate::{
|
|||||||
VersionCommandParser,
|
VersionCommandParser,
|
||||||
},
|
},
|
||||||
get_exit_arch_regs,
|
get_exit_arch_regs,
|
||||||
modules::{EmulatorModuleTuple, utils::filters::HasAddressFilterTuples},
|
modules::{EmulatorModuleTuple, utils::filters::HasStdFiltersTuple},
|
||||||
sync_exit::ExitArgs,
|
sync_exit::ExitArgs,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -96,7 +96,7 @@ macro_rules! define_std_command_manager {
|
|||||||
|
|
||||||
impl<C, ET, I, S, SM> CommandManager<C, StdEmulatorDriver, ET, I, S, SM> for $name<S>
|
impl<C, ET, I, S, SM> CommandManager<C, StdEmulatorDriver, ET, I, S, SM> for $name<S>
|
||||||
where
|
where
|
||||||
ET: EmulatorModuleTuple<I, S> + HasAddressFilterTuples,
|
ET: EmulatorModuleTuple<I, S> + HasStdFiltersTuple,
|
||||||
I: HasTargetBytes + Unpin,
|
I: HasTargetBytes + Unpin,
|
||||||
S: Unpin,
|
S: Unpin,
|
||||||
SM: IsSnapshotManager,
|
SM: IsSnapshotManager,
|
||||||
@ -125,7 +125,7 @@ macro_rules! define_std_command_manager {
|
|||||||
|
|
||||||
impl<C, ET, I, S, SM> IsCommand<C, $name<S>, StdEmulatorDriver, ET, I, S, SM> for [<$name Commands>]
|
impl<C, ET, I, S, SM> IsCommand<C, $name<S>, StdEmulatorDriver, ET, I, S, SM> for [<$name Commands>]
|
||||||
where
|
where
|
||||||
ET: EmulatorModuleTuple<I, S> + HasAddressFilterTuples,
|
ET: EmulatorModuleTuple<I, S> + HasStdFiltersTuple,
|
||||||
I: HasTargetBytes + Unpin,
|
I: HasTargetBytes + Unpin,
|
||||||
S: Unpin,
|
S: Unpin,
|
||||||
SM: IsSnapshotManager,
|
SM: IsSnapshotManager,
|
||||||
@ -383,7 +383,7 @@ pub struct StartCommand {
|
|||||||
impl<C, ET, I, S, SM> IsCommand<C, StdCommandManager<S>, StdEmulatorDriver, ET, I, S, SM>
|
impl<C, ET, I, S, SM> IsCommand<C, StdCommandManager<S>, StdEmulatorDriver, ET, I, S, SM>
|
||||||
for StartCommand
|
for StartCommand
|
||||||
where
|
where
|
||||||
ET: EmulatorModuleTuple<I, S> + HasAddressFilterTuples,
|
ET: EmulatorModuleTuple<I, S> + HasStdFiltersTuple,
|
||||||
I: HasTargetBytes + Unpin,
|
I: HasTargetBytes + Unpin,
|
||||||
S: Unpin,
|
S: Unpin,
|
||||||
SM: IsSnapshotManager,
|
SM: IsSnapshotManager,
|
||||||
@ -544,7 +544,7 @@ pub struct PageAllowCommand {
|
|||||||
#[cfg(feature = "systemmode")]
|
#[cfg(feature = "systemmode")]
|
||||||
impl<C, CM, ED, ET, I, S, SM> IsCommand<C, CM, ED, ET, I, S, SM> for PageAllowCommand
|
impl<C, CM, ED, ET, I, S, SM> IsCommand<C, CM, ED, ET, I, S, SM> for PageAllowCommand
|
||||||
where
|
where
|
||||||
ET: EmulatorModuleTuple<I, S> + HasAddressFilterTuples,
|
ET: EmulatorModuleTuple<I, S> + HasStdFiltersTuple,
|
||||||
I: Unpin,
|
I: Unpin,
|
||||||
S: Unpin,
|
S: Unpin,
|
||||||
{
|
{
|
||||||
@ -572,7 +572,7 @@ pub struct AddressAllowCommand {
|
|||||||
}
|
}
|
||||||
impl<C, CM, ED, ET, I, S, SM> IsCommand<C, CM, ED, ET, I, S, SM> for AddressAllowCommand
|
impl<C, CM, ED, ET, I, S, SM> IsCommand<C, CM, ED, ET, I, S, SM> for AddressAllowCommand
|
||||||
where
|
where
|
||||||
ET: EmulatorModuleTuple<I, S> + HasAddressFilterTuples,
|
ET: EmulatorModuleTuple<I, S> + HasStdFiltersTuple,
|
||||||
I: Unpin,
|
I: Unpin,
|
||||||
S: Unpin,
|
S: Unpin,
|
||||||
{
|
{
|
||||||
@ -589,7 +589,7 @@ where
|
|||||||
) -> Result<Option<EmulatorDriverResult<C>>, EmulatorDriverError> {
|
) -> Result<Option<EmulatorDriverResult<C>>, EmulatorDriverError> {
|
||||||
emu.modules_mut()
|
emu.modules_mut()
|
||||||
.modules_mut()
|
.modules_mut()
|
||||||
.allow_address_range_all(self.address_range.clone());
|
.allow_address_range_all(&self.address_range);
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
get_exit_arch_regs,
|
get_exit_arch_regs,
|
||||||
modules::{EmulatorModuleTuple, utils::filters::HasAddressFilterTuples},
|
modules::{EmulatorModuleTuple, utils::filters::HasStdFiltersTuple},
|
||||||
sync_exit::ExitArgs,
|
sync_exit::ExitArgs,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -99,7 +99,7 @@ macro_rules! define_nyx_command_manager {
|
|||||||
|
|
||||||
impl<C, ET, I, S, SM> CommandManager<C, NyxEmulatorDriver, ET, I, S, SM> for $name<S>
|
impl<C, ET, I, S, SM> CommandManager<C, NyxEmulatorDriver, ET, I, S, SM> for $name<S>
|
||||||
where
|
where
|
||||||
ET: EmulatorModuleTuple<I, S> + HasAddressFilterTuples,
|
ET: EmulatorModuleTuple<I, S> + HasStdFiltersTuple,
|
||||||
I: HasTargetBytes + Unpin,
|
I: HasTargetBytes + Unpin,
|
||||||
S: Unpin,
|
S: Unpin,
|
||||||
SM: IsSnapshotManager,
|
SM: IsSnapshotManager,
|
||||||
@ -134,7 +134,7 @@ macro_rules! define_nyx_command_manager {
|
|||||||
|
|
||||||
impl<C, ET, I, S, SM> IsCommand<C, $name<S>, NyxEmulatorDriver, ET, I, S, SM> for [<$name Commands>]
|
impl<C, ET, I, S, SM> IsCommand<C, $name<S>, NyxEmulatorDriver, ET, I, S, SM> for [<$name Commands>]
|
||||||
where
|
where
|
||||||
ET: EmulatorModuleTuple<I, S> + HasAddressFilterTuples,
|
ET: EmulatorModuleTuple<I, S> + HasStdFiltersTuple,
|
||||||
I: HasTargetBytes + Unpin,
|
I: HasTargetBytes + Unpin,
|
||||||
S: Unpin,
|
S: Unpin,
|
||||||
SM: IsSnapshotManager,
|
SM: IsSnapshotManager,
|
||||||
@ -296,7 +296,7 @@ pub struct NextPayloadCommand;
|
|||||||
impl<C, ET, I, S, SM> IsCommand<C, NyxCommandManager<S>, NyxEmulatorDriver, ET, I, S, SM>
|
impl<C, ET, I, S, SM> IsCommand<C, NyxCommandManager<S>, NyxEmulatorDriver, ET, I, S, SM>
|
||||||
for NextPayloadCommand
|
for NextPayloadCommand
|
||||||
where
|
where
|
||||||
ET: EmulatorModuleTuple<I, S> + HasAddressFilterTuples,
|
ET: EmulatorModuleTuple<I, S> + HasStdFiltersTuple,
|
||||||
I: HasTargetBytes + Unpin,
|
I: HasTargetBytes + Unpin,
|
||||||
S: Unpin,
|
S: Unpin,
|
||||||
SM: IsSnapshotManager,
|
SM: IsSnapshotManager,
|
||||||
@ -360,7 +360,7 @@ pub struct SubmitCR3Command;
|
|||||||
impl<C, ET, I, S, SM> IsCommand<C, NyxCommandManager<S>, NyxEmulatorDriver, ET, I, S, SM>
|
impl<C, ET, I, S, SM> IsCommand<C, NyxCommandManager<S>, NyxEmulatorDriver, ET, I, S, SM>
|
||||||
for SubmitCR3Command
|
for SubmitCR3Command
|
||||||
where
|
where
|
||||||
ET: EmulatorModuleTuple<I, S> + HasAddressFilterTuples,
|
ET: EmulatorModuleTuple<I, S> + HasStdFiltersTuple,
|
||||||
I: HasTargetBytes + Unpin,
|
I: HasTargetBytes + Unpin,
|
||||||
S: Unpin,
|
S: Unpin,
|
||||||
SM: IsSnapshotManager,
|
SM: IsSnapshotManager,
|
||||||
@ -408,7 +408,7 @@ impl RangeSubmitCommand {
|
|||||||
impl<C, ET, I, S, SM> IsCommand<C, NyxCommandManager<S>, NyxEmulatorDriver, ET, I, S, SM>
|
impl<C, ET, I, S, SM> IsCommand<C, NyxCommandManager<S>, NyxEmulatorDriver, ET, I, S, SM>
|
||||||
for RangeSubmitCommand
|
for RangeSubmitCommand
|
||||||
where
|
where
|
||||||
ET: EmulatorModuleTuple<I, S> + HasAddressFilterTuples,
|
ET: EmulatorModuleTuple<I, S> + HasStdFiltersTuple,
|
||||||
I: HasTargetBytes + Unpin,
|
I: HasTargetBytes + Unpin,
|
||||||
S: Unpin,
|
S: Unpin,
|
||||||
SM: IsSnapshotManager,
|
SM: IsSnapshotManager,
|
||||||
@ -440,7 +440,7 @@ where
|
|||||||
|
|
||||||
emu.modules_mut()
|
emu.modules_mut()
|
||||||
.modules_mut()
|
.modules_mut()
|
||||||
.allow_address_range_all(self.allowed_range.clone());
|
.allow_address_range_all(&self.allowed_range);
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ use crate::{
|
|||||||
LoadCommand, LqprintfCommand, NativeExitKind, SaveCommand, StartCommand, StdCommandManager,
|
LoadCommand, LqprintfCommand, NativeExitKind, SaveCommand, StartCommand, StdCommandManager,
|
||||||
TestCommand, VersionCommand, bindings,
|
TestCommand, VersionCommand, bindings,
|
||||||
},
|
},
|
||||||
modules::{EmulatorModuleTuple, utils::filters::HasAddressFilterTuples},
|
modules::{EmulatorModuleTuple, utils::filters::HasStdFiltersTuple},
|
||||||
sync_exit::ExitArgs,
|
sync_exit::ExitArgs,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ pub struct StartPhysCommandParser;
|
|||||||
impl<C, ET, I, S, SM> NativeCommandParser<C, StdCommandManager<S>, StdEmulatorDriver, ET, I, S, SM>
|
impl<C, ET, I, S, SM> NativeCommandParser<C, StdCommandManager<S>, StdEmulatorDriver, ET, I, S, SM>
|
||||||
for StartPhysCommandParser
|
for StartPhysCommandParser
|
||||||
where
|
where
|
||||||
ET: EmulatorModuleTuple<I, S> + HasAddressFilterTuples,
|
ET: EmulatorModuleTuple<I, S> + HasStdFiltersTuple,
|
||||||
I: HasTargetBytes + Unpin,
|
I: HasTargetBytes + Unpin,
|
||||||
S: Unpin,
|
S: Unpin,
|
||||||
SM: IsSnapshotManager,
|
SM: IsSnapshotManager,
|
||||||
@ -121,7 +121,7 @@ pub struct StartVirtCommandParser;
|
|||||||
impl<C, ET, I, S, SM> NativeCommandParser<C, StdCommandManager<S>, StdEmulatorDriver, ET, I, S, SM>
|
impl<C, ET, I, S, SM> NativeCommandParser<C, StdCommandManager<S>, StdEmulatorDriver, ET, I, S, SM>
|
||||||
for StartVirtCommandParser
|
for StartVirtCommandParser
|
||||||
where
|
where
|
||||||
ET: EmulatorModuleTuple<I, S> + HasAddressFilterTuples,
|
ET: EmulatorModuleTuple<I, S> + HasStdFiltersTuple,
|
||||||
I: HasTargetBytes + Unpin,
|
I: HasTargetBytes + Unpin,
|
||||||
S: Unpin,
|
S: Unpin,
|
||||||
SM: IsSnapshotManager,
|
SM: IsSnapshotManager,
|
||||||
@ -242,7 +242,7 @@ pub struct VaddrFilterAllowRangeCommandParser;
|
|||||||
impl<C, CM, ED, ET, I, S, SM> NativeCommandParser<C, CM, ED, ET, I, S, SM>
|
impl<C, CM, ED, ET, I, S, SM> NativeCommandParser<C, CM, ED, ET, I, S, SM>
|
||||||
for VaddrFilterAllowRangeCommandParser
|
for VaddrFilterAllowRangeCommandParser
|
||||||
where
|
where
|
||||||
ET: EmulatorModuleTuple<I, S> + HasAddressFilterTuples,
|
ET: EmulatorModuleTuple<I, S> + HasStdFiltersTuple,
|
||||||
I: Unpin,
|
I: Unpin,
|
||||||
S: Unpin,
|
S: Unpin,
|
||||||
{
|
{
|
||||||
|
@ -17,7 +17,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
parser::NativeCommandParser,
|
parser::NativeCommandParser,
|
||||||
},
|
},
|
||||||
modules::{EmulatorModuleTuple, utils::filters::HasAddressFilterTuples},
|
modules::{EmulatorModuleTuple, utils::filters::HasStdFiltersTuple},
|
||||||
sync_exit::ExitArgs,
|
sync_exit::ExitArgs,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ pub struct SubmitCR3CommandParser;
|
|||||||
impl<C, ET, I, S, SM> NativeCommandParser<C, NyxCommandManager<S>, NyxEmulatorDriver, ET, I, S, SM>
|
impl<C, ET, I, S, SM> NativeCommandParser<C, NyxCommandManager<S>, NyxEmulatorDriver, ET, I, S, SM>
|
||||||
for SubmitCR3CommandParser
|
for SubmitCR3CommandParser
|
||||||
where
|
where
|
||||||
ET: EmulatorModuleTuple<I, S> + HasAddressFilterTuples,
|
ET: EmulatorModuleTuple<I, S> + HasStdFiltersTuple,
|
||||||
I: HasTargetBytes + Unpin,
|
I: HasTargetBytes + Unpin,
|
||||||
S: Unpin,
|
S: Unpin,
|
||||||
SM: IsSnapshotManager,
|
SM: IsSnapshotManager,
|
||||||
@ -101,7 +101,7 @@ pub struct RangeSubmitCommandParser;
|
|||||||
impl<C, ET, I, S, SM> NativeCommandParser<C, NyxCommandManager<S>, NyxEmulatorDriver, ET, I, S, SM>
|
impl<C, ET, I, S, SM> NativeCommandParser<C, NyxCommandManager<S>, NyxEmulatorDriver, ET, I, S, SM>
|
||||||
for RangeSubmitCommandParser
|
for RangeSubmitCommandParser
|
||||||
where
|
where
|
||||||
ET: EmulatorModuleTuple<I, S> + HasAddressFilterTuples,
|
ET: EmulatorModuleTuple<I, S> + HasStdFiltersTuple,
|
||||||
I: HasTargetBytes + Unpin,
|
I: HasTargetBytes + Unpin,
|
||||||
S: Unpin,
|
S: Unpin,
|
||||||
SM: IsSnapshotManager,
|
SM: IsSnapshotManager,
|
||||||
@ -189,7 +189,7 @@ pub struct NextPayloadCommandParser;
|
|||||||
impl<C, ET, I, S, SM> NativeCommandParser<C, NyxCommandManager<S>, NyxEmulatorDriver, ET, I, S, SM>
|
impl<C, ET, I, S, SM> NativeCommandParser<C, NyxCommandManager<S>, NyxEmulatorDriver, ET, I, S, SM>
|
||||||
for NextPayloadCommandParser
|
for NextPayloadCommandParser
|
||||||
where
|
where
|
||||||
ET: EmulatorModuleTuple<I, S> + HasAddressFilterTuples,
|
ET: EmulatorModuleTuple<I, S> + HasStdFiltersTuple,
|
||||||
I: HasTargetBytes + Unpin,
|
I: HasTargetBytes + Unpin,
|
||||||
S: Unpin,
|
S: Unpin,
|
||||||
SM: IsSnapshotManager,
|
SM: IsSnapshotManager,
|
||||||
|
@ -12,7 +12,7 @@ use thread_local::ThreadLocal;
|
|||||||
|
|
||||||
use super::utils::filters::HasAddressFilter;
|
use super::utils::filters::HasAddressFilter;
|
||||||
#[cfg(feature = "systemmode")]
|
#[cfg(feature = "systemmode")]
|
||||||
use crate::modules::utils::filters::{NOP_PAGE_FILTER, NopPageFilter};
|
use crate::modules::utils::filters::{HasPageFilter, NOP_PAGE_FILTER, NopPageFilter};
|
||||||
use crate::{
|
use crate::{
|
||||||
Qemu, capstone,
|
Qemu, capstone,
|
||||||
modules::{
|
modules::{
|
||||||
@ -361,8 +361,11 @@ where
|
|||||||
iaddr += insn.bytes().len() as GuestAddr;
|
iaddr += insn.bytes().len() as GuestAddr;
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(feature = "usermode")]
|
||||||
|
{
|
||||||
code = unsafe { std::slice::from_raw_parts(qemu.g2h(iaddr), 512) };
|
code = unsafe { std::slice::from_raw_parts(qemu.g2h(iaddr), 512) };
|
||||||
|
}
|
||||||
#[cfg(feature = "systemmode")]
|
#[cfg(feature = "systemmode")]
|
||||||
|
{
|
||||||
if let Err(err) = qemu.read_mem(pc, code) {
|
if let Err(err) = qemu.read_mem(pc, code) {
|
||||||
// TODO handle faults
|
// TODO handle faults
|
||||||
log::error!(
|
log::error!(
|
||||||
@ -372,6 +375,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (call_addr, call_len) in call_addrs {
|
for (call_addr, call_len) in call_addrs {
|
||||||
// TODO do not use a closure, find a more efficient way to pass call_len
|
// TODO do not use a closure, find a more efficient way to pass call_len
|
||||||
@ -459,24 +463,29 @@ impl<T> HasAddressFilter for CallTracerModule<T>
|
|||||||
where
|
where
|
||||||
T: CallTraceCollectorTuple,
|
T: CallTraceCollectorTuple,
|
||||||
{
|
{
|
||||||
type ModuleAddressFilter = StdAddressFilter;
|
type AddressFilter = StdAddressFilter;
|
||||||
#[cfg(feature = "systemmode")]
|
|
||||||
type ModulePageFilter = NopPageFilter;
|
fn address_filter(&self) -> &Self::AddressFilter {
|
||||||
fn address_filter(&self) -> &Self::ModuleAddressFilter {
|
|
||||||
&self.filter
|
&self.filter
|
||||||
}
|
}
|
||||||
|
|
||||||
fn address_filter_mut(&mut self) -> &mut Self::ModuleAddressFilter {
|
fn address_filter_mut(&mut self) -> &mut Self::AddressFilter {
|
||||||
&mut self.filter
|
&mut self.filter
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "systemmode")]
|
#[cfg(feature = "systemmode")]
|
||||||
fn page_filter(&self) -> &Self::ModulePageFilter {
|
impl<T> HasPageFilter for CallTracerModule<T>
|
||||||
|
where
|
||||||
|
T: CallTraceCollectorTuple,
|
||||||
|
{
|
||||||
|
type PageFilter = NopPageFilter;
|
||||||
|
|
||||||
|
fn page_filter(&self) -> &Self::PageFilter {
|
||||||
&NopPageFilter
|
&NopPageFilter
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "systemmode")]
|
fn page_filter_mut(&mut self) -> &mut Self::PageFilter {
|
||||||
fn page_filter_mut(&mut self) -> &mut Self::ModulePageFilter {
|
|
||||||
unsafe { (&raw mut NOP_PAGE_FILTER).as_mut().unwrap().get_mut() }
|
unsafe { (&raw mut NOP_PAGE_FILTER).as_mut().unwrap().get_mut() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
#[cfg(feature = "usermode")]
|
#[cfg(feature = "usermode")]
|
||||||
use crate::capstone;
|
use crate::capstone;
|
||||||
#[cfg(feature = "systemmode")]
|
#[cfg(feature = "systemmode")]
|
||||||
use crate::modules::utils::filters::{NOP_PAGE_FILTER, NopPageFilter};
|
use crate::modules::utils::filters::{HasPageFilter, NOP_PAGE_FILTER, NopPageFilter};
|
||||||
use crate::{
|
use crate::{
|
||||||
Qemu,
|
Qemu,
|
||||||
emu::EmulatorModules,
|
emu::EmulatorModules,
|
||||||
@ -95,25 +95,26 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl HasAddressFilter for CmpLogModule {
|
impl HasAddressFilter for CmpLogModule {
|
||||||
type ModuleAddressFilter = StdAddressFilter;
|
type AddressFilter = StdAddressFilter;
|
||||||
#[cfg(feature = "systemmode")]
|
|
||||||
type ModulePageFilter = NopPageFilter;
|
|
||||||
|
|
||||||
fn address_filter(&self) -> &Self::ModuleAddressFilter {
|
fn address_filter(&self) -> &Self::AddressFilter {
|
||||||
&self.address_filter
|
&self.address_filter
|
||||||
}
|
}
|
||||||
|
|
||||||
fn address_filter_mut(&mut self) -> &mut Self::ModuleAddressFilter {
|
fn address_filter_mut(&mut self) -> &mut Self::AddressFilter {
|
||||||
&mut self.address_filter
|
&mut self.address_filter
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "systemmode")]
|
#[cfg(feature = "systemmode")]
|
||||||
fn page_filter(&self) -> &Self::ModulePageFilter {
|
impl HasPageFilter for CmpLogModule {
|
||||||
|
type PageFilter = NopPageFilter;
|
||||||
|
|
||||||
|
fn page_filter(&self) -> &Self::PageFilter {
|
||||||
&NopPageFilter
|
&NopPageFilter
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "systemmode")]
|
fn page_filter_mut(&mut self) -> &mut Self::PageFilter {
|
||||||
fn page_filter_mut(&mut self) -> &mut Self::ModulePageFilter {
|
|
||||||
unsafe { (&raw mut NOP_PAGE_FILTER).as_mut().unwrap().get_mut() }
|
unsafe { (&raw mut NOP_PAGE_FILTER).as_mut().unwrap().get_mut() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -167,25 +168,26 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl HasAddressFilter for CmpLogChildModule {
|
impl HasAddressFilter for CmpLogChildModule {
|
||||||
type ModuleAddressFilter = StdAddressFilter;
|
type AddressFilter = StdAddressFilter;
|
||||||
#[cfg(feature = "systemmode")]
|
|
||||||
type ModulePageFilter = NopPageFilter;
|
|
||||||
|
|
||||||
fn address_filter(&self) -> &Self::ModuleAddressFilter {
|
fn address_filter(&self) -> &Self::AddressFilter {
|
||||||
&self.address_filter
|
&self.address_filter
|
||||||
}
|
}
|
||||||
|
|
||||||
fn address_filter_mut(&mut self) -> &mut Self::ModuleAddressFilter {
|
fn address_filter_mut(&mut self) -> &mut Self::AddressFilter {
|
||||||
&mut self.address_filter
|
&mut self.address_filter
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "systemmode")]
|
#[cfg(feature = "systemmode")]
|
||||||
fn page_filter(&self) -> &Self::ModulePageFilter {
|
impl HasPageFilter for CmpLogChildModule {
|
||||||
|
type PageFilter = NopPageFilter;
|
||||||
|
|
||||||
|
fn page_filter(&self) -> &Self::PageFilter {
|
||||||
&NopPageFilter
|
&NopPageFilter
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "systemmode")]
|
fn page_filter_mut(&mut self) -> &mut Self::PageFilter {
|
||||||
fn page_filter_mut(&mut self) -> &mut Self::ModulePageFilter {
|
|
||||||
unsafe { (&raw mut NOP_PAGE_FILTER).as_mut().unwrap().get_mut() }
|
unsafe { (&raw mut NOP_PAGE_FILTER).as_mut().unwrap().get_mut() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -345,16 +347,18 @@ impl CmpLogRoutinesModule {
|
|||||||
#[allow(unused_mut)] // cfg dependent
|
#[allow(unused_mut)] // cfg dependent
|
||||||
let mut code = {
|
let mut code = {
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(feature = "usermode")]
|
||||||
unsafe {
|
{
|
||||||
std::slice::from_raw_parts(qemu.g2h(pc), 512);
|
unsafe { std::slice::from_raw_parts(qemu.g2h(pc), 512) }
|
||||||
}
|
}
|
||||||
#[cfg(feature = "systemmode")]
|
#[cfg(feature = "systemmode")]
|
||||||
|
{
|
||||||
&mut [0; 512]
|
&mut [0; 512]
|
||||||
|
}
|
||||||
};
|
};
|
||||||
#[cfg(feature = "systemmode")]
|
#[cfg(feature = "systemmode")]
|
||||||
unsafe {
|
{
|
||||||
qemu.read_mem(pc, code)
|
unsafe { qemu.read_mem(pc, code) }; // TODO handle faults
|
||||||
}; // TODO handle faults
|
}
|
||||||
|
|
||||||
let mut iaddr = pc;
|
let mut iaddr = pc;
|
||||||
|
|
||||||
@ -389,13 +393,17 @@ impl CmpLogRoutinesModule {
|
|||||||
iaddr += insn.bytes().len() as GuestAddr;
|
iaddr += insn.bytes().len() as GuestAddr;
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(feature = "usermode")]
|
||||||
|
{
|
||||||
code = unsafe { std::slice::from_raw_parts(qemu.g2h(iaddr), 512) };
|
code = unsafe { std::slice::from_raw_parts(qemu.g2h(iaddr), 512) };
|
||||||
|
}
|
||||||
#[cfg(feature = "systemmode")]
|
#[cfg(feature = "systemmode")]
|
||||||
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
qemu.read_mem(pc, code);
|
qemu.read_mem(pc, code);
|
||||||
} // TODO handle faults
|
} // TODO handle faults
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -425,15 +433,15 @@ where
|
|||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(feature = "usermode")]
|
||||||
impl HasAddressFilter for CmpLogRoutinesModule {
|
impl HasAddressFilter for CmpLogRoutinesModule {
|
||||||
type ModuleAddressFilter = StdAddressFilter;
|
type AddressFilter = StdAddressFilter;
|
||||||
#[cfg(feature = "systemmode")]
|
#[cfg(feature = "systemmode")]
|
||||||
type ModulePageFilter = NopPageFilter;
|
type ModulePageFilter = NopPageFilter;
|
||||||
|
|
||||||
fn address_filter(&self) -> &Self::ModuleAddressFilter {
|
fn address_filter(&self) -> &Self::AddressFilter {
|
||||||
&self.address_filter
|
&self.address_filter
|
||||||
}
|
}
|
||||||
|
|
||||||
fn address_filter_mut(&mut self) -> &mut Self::ModuleAddressFilter {
|
fn address_filter_mut(&mut self) -> &mut Self::AddressFilter {
|
||||||
&mut self.address_filter
|
&mut self.address_filter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use super::utils::filters::HasAddressFilter;
|
use super::utils::filters::HasAddressFilter;
|
||||||
#[cfg(feature = "systemmode")]
|
#[cfg(feature = "systemmode")]
|
||||||
use crate::modules::utils::filters::{NOP_PAGE_FILTER, NopPageFilter};
|
use crate::modules::utils::filters::{HasPageFilter, NOP_PAGE_FILTER, NopPageFilter};
|
||||||
use crate::{
|
use crate::{
|
||||||
Qemu,
|
Qemu,
|
||||||
emu::EmulatorModules,
|
emu::EmulatorModules,
|
||||||
@ -522,25 +522,26 @@ impl<F> HasAddressFilter for DrCovModule<F>
|
|||||||
where
|
where
|
||||||
F: AddressFilter,
|
F: AddressFilter,
|
||||||
{
|
{
|
||||||
type ModuleAddressFilter = F;
|
type AddressFilter = F;
|
||||||
#[cfg(feature = "systemmode")]
|
|
||||||
type ModulePageFilter = NopPageFilter;
|
|
||||||
|
|
||||||
fn address_filter(&self) -> &Self::ModuleAddressFilter {
|
fn address_filter(&self) -> &Self::AddressFilter {
|
||||||
&self.filter
|
&self.filter
|
||||||
}
|
}
|
||||||
|
|
||||||
fn address_filter_mut(&mut self) -> &mut Self::ModuleAddressFilter {
|
fn address_filter_mut(&mut self) -> &mut Self::AddressFilter {
|
||||||
&mut self.filter
|
&mut self.filter
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "systemmode")]
|
#[cfg(feature = "systemmode")]
|
||||||
fn page_filter(&self) -> &Self::ModulePageFilter {
|
impl<F> HasPageFilter for DrCovModule<F> {
|
||||||
|
type PageFilter = NopPageFilter;
|
||||||
|
|
||||||
|
fn page_filter(&self) -> &Self::PageFilter {
|
||||||
&NopPageFilter
|
&NopPageFilter
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "systemmode")]
|
fn page_filter_mut(&mut self) -> &mut Self::PageFilter {
|
||||||
fn page_filter_mut(&mut self) -> &mut Self::ModulePageFilter {
|
|
||||||
unsafe { (&raw mut NOP_PAGE_FILTER).as_mut().unwrap().get_mut() }
|
unsafe { (&raw mut NOP_PAGE_FILTER).as_mut().unwrap().get_mut() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,8 @@ pub use child::{
|
|||||||
use libafl::observers::ConstLenMapObserver;
|
use libafl::observers::ConstLenMapObserver;
|
||||||
|
|
||||||
use super::utils::filters::HasAddressFilter;
|
use super::utils::filters::HasAddressFilter;
|
||||||
|
#[cfg(feature = "systemmode")]
|
||||||
|
use super::utils::filters::HasPageFilter;
|
||||||
|
|
||||||
/// Standard edge coverage module, adapted to most use cases
|
/// Standard edge coverage module, adapted to most use cases
|
||||||
pub type StdEdgeCoverageModule = StdEdgeCoverageFullModule;
|
pub type StdEdgeCoverageModule = StdEdgeCoverageFullModule;
|
||||||
@ -366,27 +368,31 @@ impl<AF, PF, V, const IS_CONST_MAP: bool, const MAP_SIZE: usize> HasAddressFilte
|
|||||||
for EdgeCoverageModule<AF, PF, V, IS_CONST_MAP, MAP_SIZE>
|
for EdgeCoverageModule<AF, PF, V, IS_CONST_MAP, MAP_SIZE>
|
||||||
where
|
where
|
||||||
AF: AddressFilter,
|
AF: AddressFilter,
|
||||||
PF: PageFilter,
|
|
||||||
{
|
{
|
||||||
type ModuleAddressFilter = AF;
|
type AddressFilter = AF;
|
||||||
|
|
||||||
#[cfg(feature = "systemmode")]
|
fn address_filter(&self) -> &Self::AddressFilter {
|
||||||
type ModulePageFilter = PF;
|
|
||||||
fn address_filter(&self) -> &Self::ModuleAddressFilter {
|
|
||||||
&self.address_filter
|
&self.address_filter
|
||||||
}
|
}
|
||||||
|
|
||||||
fn address_filter_mut(&mut self) -> &mut Self::ModuleAddressFilter {
|
fn address_filter_mut(&mut self) -> &mut Self::AddressFilter {
|
||||||
&mut self.address_filter
|
&mut self.address_filter
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "systemmode")]
|
#[cfg(feature = "systemmode")]
|
||||||
fn page_filter(&self) -> &Self::ModulePageFilter {
|
impl<AF, PF, V, const IS_CONST_MAP: bool, const MAP_SIZE: usize> HasPageFilter
|
||||||
|
for EdgeCoverageModule<AF, PF, V, IS_CONST_MAP, MAP_SIZE>
|
||||||
|
where
|
||||||
|
PF: PageFilter,
|
||||||
|
{
|
||||||
|
type PageFilter = PF;
|
||||||
|
|
||||||
|
fn page_filter(&self) -> &Self::PageFilter {
|
||||||
&self.page_filter
|
&self.page_filter
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "systemmode")]
|
fn page_filter_mut(&mut self) -> &mut Self::PageFilter {
|
||||||
fn page_filter_mut(&mut self) -> &mut Self::ModulePageFilter {
|
|
||||||
&mut self.page_filter
|
&mut self.page_filter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1118,12 +1118,12 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl HasAddressFilter for AsanModule {
|
impl HasAddressFilter for AsanModule {
|
||||||
type ModuleAddressFilter = StdAddressFilter;
|
type AddressFilter = StdAddressFilter;
|
||||||
fn address_filter(&self) -> &Self::ModuleAddressFilter {
|
fn address_filter(&self) -> &Self::AddressFilter {
|
||||||
&self.filter
|
&self.filter
|
||||||
}
|
}
|
||||||
|
|
||||||
fn address_filter_mut(&mut self) -> &mut Self::ModuleAddressFilter {
|
fn address_filter_mut(&mut self) -> &mut Self::AddressFilter {
|
||||||
&mut self.filter
|
&mut self.filter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -342,13 +342,13 @@ impl<F> HasAddressFilter for AsanGuestModule<F>
|
|||||||
where
|
where
|
||||||
F: AddressFilter,
|
F: AddressFilter,
|
||||||
{
|
{
|
||||||
type ModuleAddressFilter = F;
|
type AddressFilter = F;
|
||||||
|
|
||||||
fn address_filter(&self) -> &Self::ModuleAddressFilter {
|
fn address_filter(&self) -> &Self::AddressFilter {
|
||||||
&self.filter
|
&self.filter
|
||||||
}
|
}
|
||||||
|
|
||||||
fn address_filter_mut(&mut self) -> &mut Self::ModuleAddressFilter {
|
fn address_filter_mut(&mut self) -> &mut Self::AddressFilter {
|
||||||
&mut self.filter
|
&mut self.filter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -346,13 +346,13 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl HasAddressFilter for InjectionModule {
|
impl HasAddressFilter for InjectionModule {
|
||||||
type ModuleAddressFilter = NopAddressFilter;
|
type AddressFilter = NopAddressFilter;
|
||||||
|
|
||||||
fn address_filter(&self) -> &Self::ModuleAddressFilter {
|
fn address_filter(&self) -> &Self::AddressFilter {
|
||||||
&NopAddressFilter
|
&NopAddressFilter
|
||||||
}
|
}
|
||||||
|
|
||||||
fn address_filter_mut(&mut self) -> &mut Self::ModuleAddressFilter {
|
fn address_filter_mut(&mut self) -> &mut Self::AddressFilter {
|
||||||
unsafe { (&raw mut NOP_ADDRESS_FILTER).as_mut().unwrap().get_mut() }
|
unsafe { (&raw mut NOP_ADDRESS_FILTER).as_mut().unwrap().get_mut() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -775,12 +775,12 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl HasAddressFilter for SnapshotModule {
|
impl HasAddressFilter for SnapshotModule {
|
||||||
type ModuleAddressFilter = NopAddressFilter;
|
type AddressFilter = NopAddressFilter;
|
||||||
fn address_filter(&self) -> &Self::ModuleAddressFilter {
|
fn address_filter(&self) -> &Self::AddressFilter {
|
||||||
&NopAddressFilter
|
&NopAddressFilter
|
||||||
}
|
}
|
||||||
|
|
||||||
fn address_filter_mut(&mut self) -> &mut Self::ModuleAddressFilter {
|
fn address_filter_mut(&mut self) -> &mut Self::AddressFilter {
|
||||||
unsafe { (&raw mut NOP_ADDRESS_FILTER).as_mut().unwrap().get_mut() }
|
unsafe { (&raw mut NOP_ADDRESS_FILTER).as_mut().unwrap().get_mut() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ impl<T> AddressFilter for FilterList<T>
|
|||||||
where
|
where
|
||||||
T: AddressFilter,
|
T: AddressFilter,
|
||||||
{
|
{
|
||||||
fn register(&mut self, address_range: Range<GuestAddr>) {
|
fn register(&mut self, address_range: &Range<GuestAddr>) {
|
||||||
match self {
|
match self {
|
||||||
FilterList::AllowList(allow_list) => allow_list.register(address_range),
|
FilterList::AllowList(allow_list) => allow_list.register(address_range),
|
||||||
FilterList::DenyList(deny_list) => deny_list.register(address_range),
|
FilterList::DenyList(deny_list) => deny_list.register(address_range),
|
||||||
@ -69,62 +69,133 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "usermode")]
|
||||||
|
pub trait HasStdFilters: HasAddressFilter {}
|
||||||
|
|
||||||
|
#[cfg(feature = "systemmode")]
|
||||||
|
pub trait HasStdFilters: HasAddressFilter + HasPageFilter {}
|
||||||
|
|
||||||
|
#[cfg(feature = "usermode")]
|
||||||
|
pub trait HasStdFiltersTuple: HasAddressFilterTuple {}
|
||||||
|
|
||||||
|
#[cfg(feature = "systemmode")]
|
||||||
|
pub trait HasStdFiltersTuple: HasAddressFilterTuple + HasPageFilterTuple {}
|
||||||
|
|
||||||
/// Offers accessors to modules' address filters.
|
/// Offers accessors to modules' address filters.
|
||||||
pub trait HasAddressFilter {
|
pub trait HasAddressFilter {
|
||||||
type ModuleAddressFilter: AddressFilter;
|
type AddressFilter: AddressFilter;
|
||||||
#[cfg(feature = "systemmode")]
|
|
||||||
type ModulePageFilter: PageFilter;
|
|
||||||
fn address_filter(&self) -> &Self::ModuleAddressFilter;
|
|
||||||
|
|
||||||
fn address_filter_mut(&mut self) -> &mut Self::ModuleAddressFilter;
|
fn address_filter(&self) -> &Self::AddressFilter;
|
||||||
|
fn address_filter_mut(&mut self) -> &mut Self::AddressFilter;
|
||||||
fn update_address_filter(&mut self, qemu: Qemu, filter: Self::ModuleAddressFilter) {
|
fn update_address_filter(&mut self, qemu: Qemu, filter: Self::AddressFilter) {
|
||||||
*self.address_filter_mut() = filter;
|
*self.address_filter_mut() = filter;
|
||||||
// Necessary because some hooks filter during TB generation.
|
// Necessary because some hooks filter during TB generation.
|
||||||
qemu.flush_jit();
|
qemu.flush_jit();
|
||||||
}
|
}
|
||||||
|
fn allow_address_range(&mut self, address_range: &Range<GuestAddr>) {
|
||||||
|
self.address_filter_mut().register(address_range);
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "systemmode")]
|
fn allowed_address(&self, address: &GuestAddr) -> bool {
|
||||||
fn page_filter(&self) -> &Self::ModulePageFilter;
|
self.address_filter().allowed(address)
|
||||||
#[cfg(feature = "systemmode")]
|
}
|
||||||
fn page_filter_mut(&mut self) -> &mut Self::ModulePageFilter;
|
}
|
||||||
#[cfg(feature = "systemmode")]
|
|
||||||
fn update_page_filter(&mut self, qemu: Qemu, filter: Self::ModulePageFilter) {
|
pub trait HasAddressFilterTuple {
|
||||||
|
fn allow_address_range_all(&mut self, address_range: &Range<GuestAddr>);
|
||||||
|
|
||||||
|
fn allowed_address_all(&self, address: &GuestAddr) -> bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HasAddressFilterTuple for () {
|
||||||
|
fn allow_address_range_all(&mut self, _address_range: &Range<GuestAddr>) {}
|
||||||
|
|
||||||
|
fn allowed_address_all(&self, _address: &GuestAddr) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Head, Tail> HasAddressFilterTuple for (Head, Tail)
|
||||||
|
where
|
||||||
|
Head: HasAddressFilter,
|
||||||
|
Tail: HasAddressFilterTuple,
|
||||||
|
{
|
||||||
|
fn allow_address_range_all(&mut self, address_range: &Range<GuestAddr>) {
|
||||||
|
self.0.allow_address_range(address_range);
|
||||||
|
self.1.allow_address_range_all(address_range);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn allowed_address_all(&self, address: &GuestAddr) -> bool {
|
||||||
|
self.0.allowed_address(address) && self.1.allowed_address_all(address)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "usermode")]
|
||||||
|
impl<M> HasStdFilters for M where M: HasAddressFilter {}
|
||||||
|
|
||||||
|
#[cfg(feature = "systemmode")]
|
||||||
|
impl<M> HasStdFilters for M where M: HasAddressFilter + HasPageFilter {}
|
||||||
|
|
||||||
|
impl HasStdFiltersTuple for () {}
|
||||||
|
|
||||||
|
impl<Head, Tail> HasStdFiltersTuple for (Head, Tail)
|
||||||
|
where
|
||||||
|
Head: HasStdFilters,
|
||||||
|
Tail: HasStdFiltersTuple,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Offers accessors to modules' page filters.
|
||||||
|
#[cfg(feature = "systemmode")]
|
||||||
|
pub trait HasPageFilter {
|
||||||
|
type PageFilter: PageFilter;
|
||||||
|
|
||||||
|
fn page_filter(&self) -> &Self::PageFilter;
|
||||||
|
fn page_filter_mut(&mut self) -> &mut Self::PageFilter;
|
||||||
|
fn update_page_filter(&mut self, qemu: Qemu, filter: Self::PageFilter) {
|
||||||
*self.page_filter_mut() = filter;
|
*self.page_filter_mut() = filter;
|
||||||
// Necessary because some hooks filter during TB generation.
|
// Necessary because some hooks filter during TB generation.
|
||||||
qemu.flush_jit();
|
qemu.flush_jit();
|
||||||
}
|
}
|
||||||
}
|
fn allow_page_id(&mut self, page_id: GuestPhysAddr) {
|
||||||
|
self.page_filter_mut().register(page_id);
|
||||||
pub trait HasAddressFilterTuples {
|
|
||||||
fn allow_address_range_all(&mut self, address_range: Range<GuestAddr>);
|
|
||||||
|
|
||||||
#[cfg(feature = "systemmode")]
|
|
||||||
fn allow_page_id_all(&mut self, page_id: GuestPhysAddr);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HasAddressFilterTuples for () {
|
|
||||||
fn allow_address_range_all(&mut self, _address_range: Range<GuestAddr>) {}
|
|
||||||
|
|
||||||
#[cfg(feature = "systemmode")]
|
|
||||||
fn allow_page_id_all(&mut self, _page_id: GuestPhysAddr) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Head, Tail> HasAddressFilterTuples for (Head, Tail)
|
|
||||||
where
|
|
||||||
Head: HasAddressFilter,
|
|
||||||
Tail: HasAddressFilterTuples,
|
|
||||||
{
|
|
||||||
fn allow_address_range_all(&mut self, address_range: Range<GuestAddr>) {
|
|
||||||
self.0.address_filter_mut().register(address_range.clone());
|
|
||||||
self.1.allow_address_range_all(address_range);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "systemmode")]
|
fn allowed_page_id(&self, page_id: &GuestPhysAddr) -> bool {
|
||||||
|
self.page_filter().allowed(page_id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "systemmode")]
|
||||||
|
pub trait HasPageFilterTuple {
|
||||||
|
fn allow_page_id_all(&mut self, page_id: GuestPhysAddr);
|
||||||
|
|
||||||
|
fn allowed_page_id_all(&self, page_id: &GuestPhysAddr) -> bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "systemmode")]
|
||||||
|
impl HasPageFilterTuple for () {
|
||||||
|
fn allow_page_id_all(&mut self, _page_id: GuestPhysAddr) {}
|
||||||
|
|
||||||
|
fn allowed_page_id_all(&self, _page_id: &GuestPhysAddr) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "systemmode")]
|
||||||
|
impl<Head, Tail> HasPageFilterTuple for (Head, Tail)
|
||||||
|
where
|
||||||
|
Head: HasPageFilter,
|
||||||
|
Tail: HasPageFilterTuple,
|
||||||
|
{
|
||||||
fn allow_page_id_all(&mut self, page_id: GuestPhysAddr) {
|
fn allow_page_id_all(&mut self, page_id: GuestPhysAddr) {
|
||||||
self.0.page_filter_mut().register(page_id);
|
self.0.allow_page_id(page_id);
|
||||||
self.1.allow_page_id_all(page_id);
|
self.1.allow_page_id_all(page_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn allowed_page_id_all(&self, page_id: &GuestPhysAddr) -> bool {
|
||||||
|
self.0.allowed_page_id(page_id) && self.1.allowed_page_id_all(page_id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An address filter list.
|
/// An address filter list.
|
||||||
@ -172,8 +243,8 @@ impl AddressFilterVec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AddressFilter for AddressFilterVec {
|
impl AddressFilter for AddressFilterVec {
|
||||||
fn register(&mut self, address_range: Range<GuestAddr>) {
|
fn register(&mut self, address_range: &Range<GuestAddr>) {
|
||||||
self.registered_addresses.push(address_range);
|
self.registered_addresses.push(address_range.clone());
|
||||||
|
|
||||||
if let Some(qemu) = Qemu::get() {
|
if let Some(qemu) = Qemu::get() {
|
||||||
qemu.flush_jit();
|
qemu.flush_jit();
|
||||||
@ -196,7 +267,7 @@ impl AddressFilter for AddressFilterVec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AddressFilter for StdAddressFilter {
|
impl AddressFilter for StdAddressFilter {
|
||||||
fn register(&mut self, address_range: Range<GuestAddr>) {
|
fn register(&mut self, address_range: &Range<GuestAddr>) {
|
||||||
self.0.register(address_range);
|
self.0.register(address_range);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,7 +350,7 @@ impl PageFilter for StdPageFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait AddressFilter: 'static + Debug {
|
pub trait AddressFilter: 'static + Debug {
|
||||||
fn register(&mut self, address_range: Range<GuestAddr>);
|
fn register(&mut self, address_range: &Range<GuestAddr>);
|
||||||
|
|
||||||
fn allowed(&self, address: &GuestAddr) -> bool;
|
fn allowed(&self, address: &GuestAddr) -> bool;
|
||||||
}
|
}
|
||||||
@ -287,7 +358,7 @@ pub trait AddressFilter: 'static + Debug {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct NopAddressFilter;
|
pub struct NopAddressFilter;
|
||||||
impl AddressFilter for NopAddressFilter {
|
impl AddressFilter for NopAddressFilter {
|
||||||
fn register(&mut self, _address: Range<GuestAddr>) {}
|
fn register(&mut self, _address: &Range<GuestAddr>) {}
|
||||||
|
|
||||||
fn allowed(&self, _address: &GuestAddr) -> bool {
|
fn allowed(&self, _address: &GuestAddr) -> bool {
|
||||||
true
|
true
|
||||||
@ -319,15 +390,12 @@ pub(crate) static mut NOP_PAGE_FILTER: UnsafeCell<NopPageFilter> = UnsafeCell::n
|
|||||||
|
|
||||||
#[cfg(all(feature = "systemmode", test))]
|
#[cfg(all(feature = "systemmode", test))]
|
||||||
mod tests {
|
mod tests {
|
||||||
use libafl::{HasMetadata, inputs::NopInput, state::NopState};
|
|
||||||
use libafl_bolts::tuples::tuple_list;
|
use libafl_bolts::tuples::tuple_list;
|
||||||
|
|
||||||
use crate::modules::{
|
use crate::modules::utils::filters::{
|
||||||
EmulatorModule,
|
AddressFilter, HasAddressFilter, HasAddressFilterTuple, HasPageFilter, HasPageFilterTuple,
|
||||||
utils::filters::{
|
HasStdFilters, NopAddressFilter, NopPageFilter, PageFilter, StdAddressFilter,
|
||||||
AddressFilter, NopAddressFilter, NopPageFilter, PageFilter, StdAddressFilter,
|
|
||||||
StdPageFilter,
|
StdPageFilter,
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@ -336,42 +404,47 @@ mod tests {
|
|||||||
page_filter: PF,
|
page_filter: PF,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, S, AF, PF> EmulatorModule<I, S> for DummyModule<AF, PF>
|
impl<AF, PF> HasAddressFilter for DummyModule<AF, PF>
|
||||||
where
|
where
|
||||||
AF: AddressFilter + 'static,
|
AF: AddressFilter,
|
||||||
PF: PageFilter + 'static,
|
|
||||||
I: Unpin,
|
|
||||||
S: Unpin + HasMetadata,
|
|
||||||
{
|
{
|
||||||
type ModuleAddressFilter = AF;
|
type AddressFilter = AF;
|
||||||
type ModulePageFilter = PF;
|
|
||||||
|
|
||||||
fn address_filter(&self) -> &Self::ModuleAddressFilter {
|
fn address_filter(&self) -> &Self::AddressFilter {
|
||||||
&self.address_filter
|
&self.address_filter
|
||||||
}
|
}
|
||||||
|
|
||||||
fn address_filter_mut(&mut self) -> &mut Self::ModuleAddressFilter {
|
fn address_filter_mut(&mut self) -> &mut Self::AddressFilter {
|
||||||
&mut self.address_filter
|
&mut self.address_filter
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn page_filter(&self) -> &Self::ModulePageFilter {
|
impl<AF, PF> HasPageFilter for DummyModule<AF, PF>
|
||||||
|
where
|
||||||
|
PF: PageFilter,
|
||||||
|
{
|
||||||
|
type PageFilter = PF;
|
||||||
|
|
||||||
|
fn page_filter(&self) -> &Self::PageFilter {
|
||||||
&self.page_filter
|
&self.page_filter
|
||||||
}
|
}
|
||||||
|
|
||||||
fn page_filter_mut(&mut self) -> &mut Self::ModulePageFilter {
|
fn page_filter_mut(&mut self) -> &mut Self::PageFilter {
|
||||||
&mut self.page_filter
|
&mut self.page_filter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gen_module<AF, PF, I, S>(
|
impl<AF, PF> HasStdFilters for DummyModule<AF, PF>
|
||||||
af: AF,
|
where
|
||||||
pf: PF,
|
AF: AddressFilter,
|
||||||
) -> impl EmulatorModule<I, S, ModuleAddressFilter = AF, ModulePageFilter = PF>
|
PF: PageFilter,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gen_module<AF, PF>(af: AF, pf: PF) -> impl HasStdFilters<AddressFilter = AF, PageFilter = PF>
|
||||||
where
|
where
|
||||||
AF: AddressFilter,
|
AF: AddressFilter,
|
||||||
PF: PageFilter,
|
PF: PageFilter,
|
||||||
I: Unpin,
|
|
||||||
S: HasMetadata + Unpin,
|
|
||||||
{
|
{
|
||||||
DummyModule {
|
DummyModule {
|
||||||
address_filter: af,
|
address_filter: af,
|
||||||
@ -399,82 +472,79 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_filter_nop() {
|
fn test_filter_nop() {
|
||||||
let module = gen_module::<NopAddressFilter, NopPageFilter, NopState<NopInput>>(
|
let mut module =
|
||||||
NopAddressFilter,
|
gen_module::<NopAddressFilter, NopPageFilter>(NopAddressFilter, NopPageFilter);
|
||||||
NopPageFilter,
|
|
||||||
);
|
|
||||||
let mut modules = tuple_list!(module);
|
|
||||||
|
|
||||||
modules.allow_address_range_all(0x100..0x200);
|
module.allow_address_range(&(0x100..0x200));
|
||||||
modules.allow_address_range_all(0x300..0x400);
|
module.allow_address_range(&(0x300..0x400));
|
||||||
|
|
||||||
modules.allow_page_id_all(0xaaaa);
|
module.allow_page_id(0xaaaa);
|
||||||
modules.allow_page_id_all(0xbbbb);
|
module.allow_page_id(0xbbbb);
|
||||||
|
|
||||||
assert!(modules.0.address_filter().allowed(&0xff));
|
assert!(module.allowed_address(&0xff));
|
||||||
assert!(modules.0.address_filter().allowed(&0x200));
|
assert!(module.allowed_address(&0x200));
|
||||||
assert!(modules.0.address_filter().allowed(&0x201));
|
assert!(module.allowed_address(&0x201));
|
||||||
assert!(modules.0.address_filter().allowed(&0x300));
|
assert!(module.allowed_address(&0x300));
|
||||||
|
|
||||||
assert!(modules.0.page_filter().allowed(&0xaaaa));
|
assert!(module.allowed_page_id(&0xaaaa));
|
||||||
assert!(modules.0.page_filter().allowed(&0xbbbb));
|
assert!(module.allowed_page_id(&0xbbbb));
|
||||||
assert!(modules.0.page_filter().allowed(&0xcccc));
|
assert!(module.allowed_page_id(&0xcccc));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_filters_simple() {
|
fn test_filters_simple() {
|
||||||
let module = gen_module::<StdAddressFilter, StdPageFilter, NopState<NopInput>>(
|
let module = gen_module::<StdAddressFilter, StdPageFilter>(
|
||||||
StdAddressFilter::default(),
|
StdAddressFilter::default(),
|
||||||
StdPageFilter::default(),
|
StdPageFilter::default(),
|
||||||
);
|
);
|
||||||
let mut modules = tuple_list!(module);
|
let mut modules = tuple_list!(module);
|
||||||
|
|
||||||
assert!(modules.0.address_filter().allowed(&0x000));
|
assert!(modules.allowed_address_all(&0x000));
|
||||||
assert!(modules.0.address_filter().allowed(&0x100));
|
assert!(modules.allowed_address_all(&0x100));
|
||||||
assert!(modules.0.address_filter().allowed(&0x200));
|
assert!(modules.allowed_address_all(&0x200));
|
||||||
assert!(modules.0.address_filter().allowed(&0xffffffff));
|
assert!(modules.allowed_address_all(&0xffffffff));
|
||||||
|
|
||||||
assert!(modules.0.page_filter().allowed(&0xabcd));
|
assert!(modules.allowed_page_id_all(&0xabcd));
|
||||||
|
|
||||||
modules.allow_address_range_all(0x100..0x200);
|
modules.allow_address_range_all(&(0x100..0x200));
|
||||||
modules.allow_address_range_all(0x300..0x400);
|
modules.allow_address_range_all(&(0x300..0x400));
|
||||||
|
|
||||||
modules.allow_page_id_all(0xaaaa);
|
modules.allow_page_id_all(0xaaaa);
|
||||||
modules.allow_page_id_all(0xbbbb);
|
modules.allow_page_id_all(0xbbbb);
|
||||||
|
|
||||||
assert!(modules.0.address_filter().allowed(&0x100));
|
assert!(modules.allowed_address_all(&0x100));
|
||||||
assert!(modules.0.address_filter().allowed(&0x101));
|
assert!(modules.allowed_address_all(&0x101));
|
||||||
assert!(modules.0.address_filter().allowed(&0x1ff));
|
assert!(modules.allowed_address_all(&0x1ff));
|
||||||
assert!(modules.0.address_filter().allowed(&0x301));
|
assert!(modules.allowed_address_all(&0x301));
|
||||||
|
|
||||||
assert!(!modules.0.address_filter().allowed(&0xff));
|
assert!(!modules.allowed_address_all(&0xff));
|
||||||
assert!(!modules.0.address_filter().allowed(&0x200));
|
assert!(!modules.allowed_address_all(&0x200));
|
||||||
assert!(!modules.0.address_filter().allowed(&0x201));
|
assert!(!modules.allowed_address_all(&0x201));
|
||||||
|
|
||||||
assert!(modules.0.page_filter().allowed(&0xaaaa));
|
assert!(modules.allowed_page_id_all(&0xaaaa));
|
||||||
assert!(modules.0.page_filter().allowed(&0xbbbb));
|
assert!(modules.allowed_page_id_all(&0xbbbb));
|
||||||
|
|
||||||
assert!(!modules.0.page_filter().allowed(&0xcccc));
|
assert!(!modules.allowed_page_id_all(&0xcccc));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_filters_multiple() {
|
fn test_filters_multiple() {
|
||||||
let module1 = gen_module::<StdAddressFilter, StdPageFilter, NopState<NopInput>>(
|
let module1 = gen_module::<StdAddressFilter, StdPageFilter>(
|
||||||
StdAddressFilter::default(),
|
StdAddressFilter::default(),
|
||||||
StdPageFilter::default(),
|
StdPageFilter::default(),
|
||||||
);
|
);
|
||||||
let module2 = gen_module::<StdAddressFilter, StdPageFilter, NopState<NopInput>>(
|
let module2 = gen_module::<StdAddressFilter, StdPageFilter>(
|
||||||
StdAddressFilter::default(),
|
StdAddressFilter::default(),
|
||||||
StdPageFilter::default(),
|
StdPageFilter::default(),
|
||||||
);
|
);
|
||||||
let module3 = gen_module::<StdAddressFilter, StdPageFilter, NopState<NopInput>>(
|
let module3 = gen_module::<StdAddressFilter, StdPageFilter>(
|
||||||
StdAddressFilter::default(),
|
StdAddressFilter::default(),
|
||||||
StdPageFilter::default(),
|
StdPageFilter::default(),
|
||||||
);
|
);
|
||||||
let mut modules = tuple_list!(module1, module2, module3);
|
let mut modules = tuple_list!(module1, module2, module3);
|
||||||
|
|
||||||
modules.allow_address_range_all(0x100..0x200);
|
modules.allow_address_range_all(&(0x100..0x200));
|
||||||
modules.allow_address_range_all(0x300..0x400);
|
modules.allow_address_range_all(&(0x300..0x400));
|
||||||
|
|
||||||
modules.allow_page_id_all(0xaaaa);
|
modules.allow_page_id_all(0xaaaa);
|
||||||
modules.allow_page_id_all(0xbbbb);
|
modules.allow_page_id_all(0xbbbb);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user