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:
expend20 2022-10-05 22:26:19 +02:00 committed by GitHub
parent 00227e8058
commit 8fa4bca2d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 74 additions and 4 deletions

View File

@ -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"

View File

@ -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()

View File

@ -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,

View File

@ -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")]

View 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");
}
}