Hook IsProcessorFeaturePresent to crash with STATUS_STACK_BUFFER_OVERRUN exception (#804)
* First working attempt * formatting issues * Safety comment * got rid of mutex * Pass gum as a parameter * removed debug println * Review comments * review: switched back to panic
This commit is contained in:
parent
00227e8058
commit
8fa4bca2d9
@ -29,7 +29,6 @@ capstone = "0.11.0"
|
||||
frida-gum = { version = "0.8.1", features = [ "auto-download", "event-sink", "invocation-listener"] }
|
||||
libafl_frida = { path = "../../libafl_frida", features = ["cmplog"] }
|
||||
libafl_targets = { path = "../../libafl_targets", features = ["sancov_cmplog"] }
|
||||
lazy_static = "1.4.0"
|
||||
libc = "0.2"
|
||||
libloading = "0.7"
|
||||
num-traits = "0.2"
|
||||
|
@ -13,7 +13,10 @@ use std::os::raw::{c_long, c_void};
|
||||
use num_enum::TryFromPrimitive;
|
||||
pub use windows::Win32::{
|
||||
Foundation::NTSTATUS,
|
||||
System::Diagnostics::Debug::{AddVectoredExceptionHandler, EXCEPTION_POINTERS},
|
||||
System::{
|
||||
Diagnostics::Debug::{AddVectoredExceptionHandler, EXCEPTION_POINTERS},
|
||||
Threading::{IsProcessorFeaturePresent, PROCESSOR_FEATURE_ID},
|
||||
},
|
||||
};
|
||||
|
||||
use crate::Error;
|
||||
@ -315,8 +318,12 @@ unsafe fn internal_handle_exception(
|
||||
}
|
||||
}
|
||||
|
||||
/// Internal function that is being called whenever an exception arrives (stdcall).
|
||||
unsafe extern "system" fn handle_exception(exception_pointers: *mut EXCEPTION_POINTERS) -> c_long {
|
||||
/// Function that is being called whenever an exception arrives (stdcall).
|
||||
/// # Safety
|
||||
/// This function is unsafe because it is called by the OS
|
||||
pub unsafe extern "system" fn handle_exception(
|
||||
exception_pointers: *mut EXCEPTION_POINTERS,
|
||||
) -> c_long {
|
||||
let code = exception_pointers
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
|
@ -17,6 +17,8 @@ use libafl::{
|
||||
#[cfg(unix)]
|
||||
use crate::asan::errors::ASAN_ERRORS;
|
||||
use crate::helper::{FridaInstrumentationHelper, FridaRuntimeTuple};
|
||||
#[cfg(windows)]
|
||||
use crate::windows_hooks::initialize;
|
||||
|
||||
/// The [`FridaInProcessExecutor`] is an [`Executor`] that executes the target in the same process, usinig [`frida`](https://frida.re/) for binary-only instrumentation.
|
||||
pub struct FridaInProcessExecutor<'a, 'b, 'c, H, I, OT, RT, S>
|
||||
@ -146,6 +148,9 @@ where
|
||||
));
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
initialize(&gum);
|
||||
|
||||
Self {
|
||||
base,
|
||||
stalker,
|
||||
|
@ -69,6 +69,10 @@ pub mod alloc;
|
||||
#[cfg(unix)]
|
||||
pub mod asan;
|
||||
|
||||
#[cfg(windows)]
|
||||
/// Windows specific hooks to catch __fastfail like exceptions with Frida, see https://github.com/AFLplusplus/LibAFL/issues/395 for more details
|
||||
pub mod windows_hooks;
|
||||
|
||||
pub mod coverage_rt;
|
||||
|
||||
#[cfg(feature = "cmplog")]
|
||||
|
55
libafl_frida/src/windows_hooks.rs
Normal file
55
libafl_frida/src/windows_hooks.rs
Normal file
@ -0,0 +1,55 @@
|
||||
// Based on the example of setting hooks: Https://github.com/frida/frida-rust/blob/main/examples/gum/hook_open/src/lib.rs
|
||||
use frida_gum::{interceptor::Interceptor, Gum, Module, NativePointer};
|
||||
use libafl::bolts::os::windows_exceptions::{
|
||||
handle_exception, IsProcessorFeaturePresent, EXCEPTION_POINTERS, PROCESSOR_FEATURE_ID,
|
||||
};
|
||||
|
||||
/// Initialize the hooks
|
||||
pub fn initialize(gum: &Gum) {
|
||||
let is_processor_feature_present =
|
||||
Module::find_export_by_name(Some("kernel32.dll"), "IsProcessorFeaturePresent");
|
||||
let is_processor_feature_present = is_processor_feature_present.unwrap();
|
||||
if is_processor_feature_present.is_null() {
|
||||
panic!("IsProcessorFeaturePresent not found");
|
||||
}
|
||||
let unhandled_exception_filter =
|
||||
Module::find_export_by_name(Some("kernel32.dll"), "UnhandledExceptionFilter");
|
||||
let unhandled_exception_filter = unhandled_exception_filter.unwrap();
|
||||
if unhandled_exception_filter.is_null() {
|
||||
panic!("UnhandledExceptionFilter not found");
|
||||
}
|
||||
|
||||
let mut interceptor = Interceptor::obtain(&gum);
|
||||
use std::ffi::c_void;
|
||||
|
||||
interceptor
|
||||
.replace(
|
||||
is_processor_feature_present,
|
||||
NativePointer(is_processor_feature_present_detour as *mut c_void),
|
||||
NativePointer(std::ptr::null_mut()),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
interceptor
|
||||
.replace(
|
||||
unhandled_exception_filter,
|
||||
NativePointer(unhandled_exception_filter_detour as *mut c_void),
|
||||
NativePointer(std::ptr::null_mut()),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
unsafe extern "C" fn is_processor_feature_present_detour(feature: u32) -> bool {
|
||||
let result = match feature {
|
||||
0x17 => false,
|
||||
_ => IsProcessorFeaturePresent(PROCESSOR_FEATURE_ID(feature)).as_bool(),
|
||||
};
|
||||
result
|
||||
}
|
||||
|
||||
unsafe extern "C" fn unhandled_exception_filter_detour(
|
||||
exception_pointers: *mut EXCEPTION_POINTERS,
|
||||
) -> i32 {
|
||||
handle_exception(exception_pointers);
|
||||
unreachable!("handle_exception should not return");
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user