Fix frida_gdiplus (#1045)

* fix

* I don't like prelude

* clp

* cargo make test

* poc

* one to_vec()

* fix?

* del

* fix
This commit is contained in:
Dongjia "toka" Zhang 2023-02-08 00:20:38 +09:00 committed by GitHub
parent 0173d722c6
commit b7a0b823c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 126 additions and 28 deletions

View File

@ -0,0 +1,66 @@
# Variables
[env]
CARGO_TARGET_DIR = { value = "target", condition = { env_not_set = ["CARGO_TARGET_DIR"] } }
FUZZER_NAME={ source = "${CARGO_MAKE_RUST_TARGET_OS}", default_value = "frida_gdiplus", mapping = {"linux" = "frida_gdiplus", "macos" = "frida_gdiplus", "windows" = "frida_gdiplus.exe"} }
[tasks.unsupported]
script_runner="@shell"
script='''
echo "Cargo-make not integrated yet on this"
'''
# Harness
[tasks.harness]
linux_alias = "unsupported"
mac_alias = "unsupported"
windows_alias = "harness_windows"
[tasks.harness_windows]
script_runner="@shell"
script='''
cl.exe /LD harness.cc /link /dll gdiplus.lib ole32.lib
'''
# Fuzzer
[tasks.fuzzer]
linux_alias = "unsupported"
mac_alias = "unsupported"
windows_alias = "fuzzer_windows"
[tasks.fuzzer_windows]
script_runner="@shell"
script='''
cargo build --release
cp ./target/release/${FUZZER_NAME} .
'''
# Run the fuzzer
[tasks.run]
linux_alias = "unsupported"
mac_alias = "unsupported"
windows_alias = "run_windows"
[tasks.run_windows]
script_runner = "@shell"
script='''
./${FUZZER_NAME} -H harness.dll -i corpus -o output --libs-to-instrument gdi32.dll --libs-to-instrument gdi32full.dll --libs-to-instrument gdiplus.dll --libs-to-instrument WindowsCodecs.dll --disable-excludes
'''
dependencies = [ "fuzzer", "harness" ]
# Test
[tasks.test]
linux_alias = "unsupported"
mac_alias = "unsupported"
windows_alias = "test_windows"
[tasks.test_windows]
script_runner = "@shell"
script='''
start "" "frida_gdiplus.exe" -H harness.dll -i corpus -o output --libs-to-instrument gdi32.dll --libs-to-instrument gdi32full.dll --libs-to-instrument gdiplus.dll --libs-to-instrument WindowsCodecs.dll --disable-excludes
#ping is for timeout
ping -n 10 127.0.0.1>NUL && taskkill /im frida_gdiplus.exe /F
>nul 2>nul dir /a-d "corpus_discovered\*" && (echo Files exist) || (exit /b 1337)
'''
dependencies = [ "fuzzer", "harness" ]

View File

@ -27,7 +27,7 @@ use crate::Error;
const EXCEPTION_CONTINUE_EXECUTION: c_long = -1; const EXCEPTION_CONTINUE_EXECUTION: c_long = -1;
// For VEH // For VEH
//const EXCEPTION_CONTINUE_SEARCH: c_long = 0; const EXCEPTION_CONTINUE_SEARCH: c_long = 0;
// For SEH // For SEH
//const EXCEPTION_EXECUTE_HANDLER: c_long = 1; //const EXCEPTION_EXECUTE_HANDLER: c_long = 1;
@ -297,10 +297,12 @@ struct HandlerHolder {
handler: UnsafeCell<*mut dyn Handler>, handler: UnsafeCell<*mut dyn Handler>,
} }
pub const EXCEPTION_HANDLERS_SIZE: usize = 64;
unsafe impl Send for HandlerHolder {} unsafe impl Send for HandlerHolder {}
/// Keep track of which handler is registered for which exception /// Keep track of which handler is registered for which exception
static mut EXCEPTION_HANDLERS: [Option<HandlerHolder>; 64] = [ static mut EXCEPTION_HANDLERS: [Option<HandlerHolder>; EXCEPTION_HANDLERS_SIZE] = [
None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None,
None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None,
None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None,
@ -321,7 +323,15 @@ unsafe fn internal_handle_exception(
handler.handle(exception_code, exception_pointers); handler.handle(exception_code, exception_pointers);
EXCEPTION_CONTINUE_EXECUTION EXCEPTION_CONTINUE_EXECUTION
} }
None => EXCEPTION_CONTINUE_EXECUTION, None => {
// Go to Default one
let handler_holder = &EXCEPTION_HANDLERS[EXCEPTION_HANDLERS_SIZE - 1]
.as_ref()
.unwrap();
let handler = &mut **handler_holder.handler.get();
handler.handle(exception_code, exception_pointers);
EXCEPTION_CONTINUE_SEARCH
}
} }
} }
@ -339,7 +349,7 @@ pub unsafe extern "system" fn handle_exception(
.unwrap() .unwrap()
.ExceptionCode; .ExceptionCode;
let exception_code = ExceptionCode::try_from(code.0).unwrap(); let exception_code = ExceptionCode::try_from(code.0).unwrap();
// println!("Received {}", exception_code); // println!("Received exception; code: {exception_code}");
internal_handle_exception(exception_code, exception_pointers) internal_handle_exception(exception_code, exception_pointers)
} }
@ -374,6 +384,13 @@ pub unsafe fn setup_exception_handler<T: 'static + Handler>(handler: &mut T) ->
}), }),
); );
} }
write_volatile(
&mut EXCEPTION_HANDLERS[EXCEPTION_HANDLERS_SIZE - 1],
Some(HandlerHolder {
handler: UnsafeCell::new(handler as *mut dyn Handler),
}),
);
compiler_fence(Ordering::SeqCst); compiler_fence(Ordering::SeqCst);
if catch_assertions { if catch_assertions {
signal(SIGABRT, handle_signal); signal(SIGABRT, handle_signal);

View File

@ -929,11 +929,6 @@ pub mod windows_asan_handler {
// Make sure we don't crash in the crash handler forever. // Make sure we don't crash in the crash handler forever.
let input = data.take_current_input::<<E::State as UsesInput>::Input>(); let input = data.take_current_input::<<E::State as UsesInput>::Input>();
#[cfg(feature = "std")]
eprintln!("Child crashed!");
#[cfg(feature = "std")]
drop(stdout().flush());
run_observers_and_save_state::<E, EM, OF, Z>( run_observers_and_save_state::<E, EM, OF, Z>(
executor, executor,
state, state,
@ -971,7 +966,7 @@ mod windows_exception_handler {
use crate::{ use crate::{
bolts::os::windows_exceptions::{ bolts::os::windows_exceptions::{
ExceptionCode, Handler, CRASH_EXCEPTIONS, EXCEPTION_POINTERS, ExceptionCode, Handler, CRASH_EXCEPTIONS, EXCEPTION_HANDLERS_SIZE, EXCEPTION_POINTERS,
}, },
events::{EventFirer, EventRestarter}, events::{EventFirer, EventRestarter},
executors::{ executors::{
@ -1007,7 +1002,9 @@ mod windows_exception_handler {
} }
fn exceptions(&self) -> Vec<ExceptionCode> { fn exceptions(&self) -> Vec<ExceptionCode> {
CRASH_EXCEPTIONS.to_vec() let crash_list = CRASH_EXCEPTIONS.to_vec();
assert!(crash_list.len() < EXCEPTION_HANDLERS_SIZE - 1);
crash_list
} }
} }
@ -1161,6 +1158,8 @@ mod windows_exception_handler {
compiler_fence(Ordering::SeqCst); compiler_fence(Ordering::SeqCst);
} }
// Is this really crash?
let mut is_crash = true;
#[cfg(feature = "std")] #[cfg(feature = "std")]
if let Some(exception_pointers) = exception_pointers.as_mut() { if let Some(exception_pointers) = exception_pointers.as_mut() {
let code = ExceptionCode::try_from( let code = ExceptionCode::try_from(
@ -1172,7 +1171,14 @@ mod windows_exception_handler {
.0, .0,
) )
.unwrap(); .unwrap();
let exception_list = data.exceptions();
if exception_list.contains(&code) {
eprintln!("Crashed with {code}"); eprintln!("Crashed with {code}");
} else {
// eprintln!("Exception code received, but {code} is not in CRASH_EXCEPTIONS");
is_crash = false;
}
} else { } else {
eprintln!("Crashed without exception (probably due to SIGABRT)"); eprintln!("Crashed without exception (probably due to SIGABRT)");
}; };
@ -1216,18 +1222,19 @@ mod windows_exception_handler {
let event_mgr = data.event_mgr_mut::<EM>(); let event_mgr = data.event_mgr_mut::<EM>();
#[cfg(feature = "std")] #[cfg(feature = "std")]
if is_crash {
eprintln!("Child crashed!"); eprintln!("Child crashed!");
} else {
// eprintln!("Exception received!");
}
#[cfg(feature = "std")] #[cfg(feature = "std")]
drop(stdout().flush()); drop(stdout().flush());
// Make sure we don't crash in the crash handler forever. // Make sure we don't crash in the crash handler forever.
if is_crash {
let input = data.take_current_input::<<E::State as UsesInput>::Input>(); let input = data.take_current_input::<<E::State as UsesInput>::Input>();
#[cfg(feature = "std")]
eprintln!("Child crashed!");
#[cfg(feature = "std")]
drop(stdout().flush());
run_observers_and_save_state::<E, EM, OF, Z>( run_observers_and_save_state::<E, EM, OF, Z>(
executor, executor,
state, state,
@ -1236,9 +1243,17 @@ mod windows_exception_handler {
event_mgr, event_mgr,
ExitKind::Crash, ExitKind::Crash,
); );
} else {
// This is not worth saving
} }
}
if is_crash {
println!("Exiting!");
ExitProcess(1); ExitProcess(1);
} }
// println!("Not Exiting!");
}
} }
/// The signature of the crash handler function /// The signature of the crash handler function