Use AddVectoredExceptionHandler to register exception handlers (#403)
* add * unix fix * unsafe positions * another unsafe! * ignore * ignore * make changes back * fix * fix * fmt * exception fix * fix * bug fix * fmt * fix things messed up during merge * stack overflow fix * fix * fix * fix Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com> Co-authored-by: Dominik Maier <domenukk@gmail.com>
This commit is contained in:
parent
d93f97309a
commit
79f9bcd3e0
@ -1,7 +1,7 @@
|
||||
//! Exception handling for Windows
|
||||
|
||||
pub use windows::Win32::System::Diagnostics::Debug::{
|
||||
SetUnhandledExceptionFilter, EXCEPTION_POINTERS,
|
||||
AddVectoredExceptionHandler, EXCEPTION_POINTERS,
|
||||
};
|
||||
|
||||
pub use windows::Win32::Foundation::NTSTATUS;
|
||||
@ -309,8 +309,6 @@ unsafe fn internal_handle_exception(
|
||||
}
|
||||
}
|
||||
|
||||
type NativeHandlerType = extern "system" fn(*mut EXCEPTION_POINTERS) -> c_long;
|
||||
|
||||
/// Internal function that is being called whenever an exception arrives (stdcall).
|
||||
unsafe extern "system" fn handle_exception(exception_pointers: *mut EXCEPTION_POINTERS) -> c_long {
|
||||
let code = exception_pointers
|
||||
@ -361,8 +359,11 @@ pub unsafe fn setup_exception_handler<T: 'static + Handler>(handler: &mut T) ->
|
||||
if catch_assertions {
|
||||
signal(SIGABRT, handle_signal);
|
||||
}
|
||||
if let Some(prev) = SetUnhandledExceptionFilter(Some(core::mem::transmute(
|
||||
handle_exception as *const c_void,
|
||||
))) {}
|
||||
// SetUnhandledFilter does not work with frida since the stack is changed and exception handler is lost with Stalker enabled.
|
||||
// See https://github.com/AFLplusplus/LibAFL/pull/403
|
||||
AddVectoredExceptionHandler(
|
||||
1,
|
||||
Some(core::mem::transmute(handle_exception as *const c_void)),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
@ -25,6 +25,9 @@ use crate::bolts::os::unix_signals::setup_signal_handler;
|
||||
#[cfg(all(windows, feature = "std"))]
|
||||
use crate::bolts::os::windows_exceptions::setup_exception_handler;
|
||||
|
||||
#[cfg(windows)]
|
||||
use windows::Win32::System::Threading::SetThreadStackGuarantee;
|
||||
|
||||
use crate::{
|
||||
corpus::Corpus,
|
||||
events::{EventFirer, EventRestarter},
|
||||
@ -121,6 +124,21 @@ where
|
||||
Z: HasObjective<I, OF, S>,
|
||||
{
|
||||
let handlers = InProcessHandlers::new::<Self, EM, I, OC, OF, OT, S, Z>()?;
|
||||
#[cfg(windows)]
|
||||
unsafe {
|
||||
/*
|
||||
See https://github.com/AFLplusplus/LibAFL/pull/403
|
||||
This one reserves certain amount of memory for the stack.
|
||||
If stack overflow happens during fuzzing on windows, the program is transferred to our exception handler for windows.
|
||||
However, if we run out of the stack memory again in this exception handler, we'll crash with STATUS_ACCESS_VIOLATION.
|
||||
We need this API call because with the llmp_compression
|
||||
feature enabled, the exception handler uses a lot of stack memory (in the compression lib code) on release build.
|
||||
As far as I have observed, the compression uses around 0x10000 bytes, but for safety let's just reserve 0x20000 bytes for our exception handlers.
|
||||
This number 0x20000 could vary depending on the compilers optimization for future compression library changes.
|
||||
*/
|
||||
let mut stack_reserved = 0x20000;
|
||||
SetThreadStackGuarantee(&mut stack_reserved);
|
||||
}
|
||||
Ok(Self {
|
||||
harness_fn,
|
||||
observers,
|
||||
@ -569,7 +587,7 @@ mod unix_signal_handler {
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
{
|
||||
println!("Type QUIT to restart the child");
|
||||
eprintln!("Type QUIT to restart the child");
|
||||
let mut line = String::new();
|
||||
while line.trim() != "QUIT" {
|
||||
std::io::stdin().read_line(&mut line).unwrap();
|
||||
@ -629,10 +647,10 @@ mod unix_signal_handler {
|
||||
event_mgr.on_restart(state).unwrap();
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
println!("Waiting for broker...");
|
||||
eprintln!("Waiting for broker...");
|
||||
event_mgr.await_restart_safe();
|
||||
#[cfg(feature = "std")]
|
||||
println!("Bye!");
|
||||
eprintln!("Bye!");
|
||||
}
|
||||
|
||||
libc::_exit(128 + (signal as i32));
|
||||
@ -735,7 +753,7 @@ mod windows_exception_handler {
|
||||
dbg!("TIMEOUT or SIGUSR2 happened, but currently not fuzzing. Exiting");
|
||||
} else {
|
||||
#[cfg(feature = "std")]
|
||||
println!("Timeout in fuzz run.");
|
||||
eprintln!("Timeout in fuzz run.");
|
||||
#[cfg(feature = "std")]
|
||||
let _res = stdout().flush();
|
||||
|
||||
@ -771,10 +789,10 @@ mod windows_exception_handler {
|
||||
event_mgr.on_restart(state).unwrap();
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
println!("Waiting for broker...");
|
||||
eprintln!("Waiting for broker...");
|
||||
event_mgr.await_restart_safe();
|
||||
#[cfg(feature = "std")]
|
||||
println!("Bye!");
|
||||
eprintln!("Bye!");
|
||||
|
||||
event_mgr.await_restart_safe();
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
@ -834,11 +852,11 @@ mod windows_exception_handler {
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
println!("Crashed with {}", code);
|
||||
eprintln!("Crashed with {}", code);
|
||||
if data.current_input_ptr.is_null() {
|
||||
#[cfg(feature = "std")]
|
||||
{
|
||||
println!("Double crash\n");
|
||||
eprintln!("Double crash\n");
|
||||
let crash_addr = exception_pointers
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
@ -847,14 +865,14 @@ mod windows_exception_handler {
|
||||
.unwrap()
|
||||
.ExceptionAddress as usize;
|
||||
|
||||
println!(
|
||||
eprintln!(
|
||||
"We crashed at addr 0x{:x}, but are not in the target... Bug in the fuzzer? Exiting.",
|
||||
crash_addr
|
||||
);
|
||||
}
|
||||
#[cfg(feature = "std")]
|
||||
{
|
||||
println!("Type QUIT to restart the child");
|
||||
eprintln!("Type QUIT to restart the child");
|
||||
let mut line = String::new();
|
||||
while line.trim() != "QUIT" {
|
||||
std::io::stdin().read_line(&mut line).unwrap();
|
||||
@ -870,7 +888,7 @@ mod windows_exception_handler {
|
||||
let observers = executor.observers();
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
println!("Child crashed!");
|
||||
eprintln!("Child crashed!");
|
||||
#[cfg(feature = "std")]
|
||||
drop(stdout().flush());
|
||||
|
||||
@ -908,10 +926,10 @@ mod windows_exception_handler {
|
||||
event_mgr.on_restart(state).unwrap();
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
println!("Waiting for broker...");
|
||||
eprintln!("Waiting for broker...");
|
||||
event_mgr.await_restart_safe();
|
||||
#[cfg(feature = "std")]
|
||||
println!("Bye!");
|
||||
eprintln!("Bye!");
|
||||
}
|
||||
ExitProcess(1);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user