Skip to content

Commit

Permalink
WIP: Working gdiplus fuzzing with frida-ASAN, no false positives
Browse files Browse the repository at this point in the history
  • Loading branch information
s1341 committed Feb 5, 2024
1 parent 6734c25 commit 3d6d8f5
Show file tree
Hide file tree
Showing 12 changed files with 539 additions and 130 deletions.
5 changes: 3 additions & 2 deletions fuzzers/frida_gdiplus/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ tar = "0.4.37"
reqwest = { version = "0.11.4", features = ["blocking"] }

[dependencies]
libafl = { path = "../../libafl/", features = [ "std", "llmp_compression", "llmp_bind_public", "frida_cli" ] } #, "llmp_small_maps", "llmp_debug"]}
libafl = { path = "../../libafl/", features = [ "std", "llmp_compression",
"llmp_bind_public", "frida_cli", "errors_backtrace" ] } #, "llmp_small_maps", "llmp_debug"]}
libafl_bolts = { path = "../../libafl_bolts/" }
frida-gum = { version = "0.13.3", features = [ "auto-download", "event-sink", "invocation-listener"] }
frida-gum = { path = "../../../frida-rust/frida-gum", version = "0.13.3", features = [ "event-sink", "invocation-listener"] }
libafl_frida = { path = "../../libafl_frida", features = ["cmplog"] }
libafl_targets = { path = "../../libafl_targets", features = ["sancov_cmplog"] }
libloading = "0.7"
Expand Down
15 changes: 10 additions & 5 deletions fuzzers/frida_gdiplus/harness.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,13 @@ ULONG_PTR gdiplusToken;
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
LoadLibraryA("ole32.dll");
LoadLibraryA("gdi32full.dll");
LoadLibraryA("WindowsCodecs.dll");
LoadLibraryA("shcore.dll");
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
LoadLibraryA("gdi32.dll");
// DebugBreak();
break;
}
return TRUE;
Expand All @@ -31,16 +36,16 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
extern "C" __declspec(dllexport) int LLVMFuzzerTestOneInput(const uint8_t *data,
size_t size) {
static DWORD init = 0;
if (!init) {
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
init = 1;
}
// if (!init) {
// init = 1;
// }

HGLOBAL m_hBuffer = ::GlobalAlloc(GMEM_MOVEABLE, size);
if (m_hBuffer) {
void *pBuffer = ::GlobalLock(m_hBuffer);
if (pBuffer) {
CopyMemory(pBuffer, data, size);
memcpy(pBuffer, data, size);
// CopyMemory(pBuffer, data, size);

IStream *pStream = NULL;
if (::CreateStreamOnHGlobal(m_hBuffer, FALSE, &pStream) == S_OK) {
Expand Down
24 changes: 14 additions & 10 deletions fuzzers/frida_gdiplus/src/fuzzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ use libafl_frida::{
cmplog_rt::CmpLogRuntime,
coverage_rt::{CoverageRuntime, MAP_SIZE},
executor::FridaInProcessExecutor,
helper::FridaInstrumentationHelper,
helper::FridaInstrumentationHelper, hook_rt::HookRuntime,
};
use libafl_targets::cmplog::CmpLogObserver;

Expand Down Expand Up @@ -100,9 +100,10 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {

let coverage = CoverageRuntime::new();
let asan = AsanRuntime::new(&options);

let hooks = HookRuntime::new();

let mut frida_helper =
FridaInstrumentationHelper::new(&gum, options, tuple_list!(coverage, asan));
FridaInstrumentationHelper::new(&gum, options, tuple_list!(coverage, asan, hooks));
//
// Create an observation channel using the coverage map
let edges_observer = HitcountsMapObserver::new(StdMapObserver::from_mut_ptr(
Expand All @@ -126,7 +127,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {
// Feedbacks to recognize an input as solution
let mut objective = feedback_or_fast!(
CrashFeedback::new(),
TimeoutFeedback::new(),
// TimeoutFeedback::new(),
// true enables the AsanErrorFeedback
feedback_and_fast!(ConstFeedback::from(true), AsanErrorsFeedback::new())
);
Expand Down Expand Up @@ -178,12 +179,13 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {
// Create the executor for an in-process function with just one observer for edge coverage
let mut executor = FridaInProcessExecutor::new(
&gum,
InProcessExecutor::new(
InProcessExecutor::with_timeout(
&mut frida_harness,
observers,
&mut fuzzer,
&mut state,
&mut mgr,
options.timeout,
)?,
&mut frida_helper,
);
Expand All @@ -210,9 +212,10 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {

let coverage = CoverageRuntime::new();
let cmplog = CmpLogRuntime::new();
let hooks = HookRuntime::new();

let mut frida_helper =
FridaInstrumentationHelper::new(&gum, options, tuple_list!(coverage, cmplog));
FridaInstrumentationHelper::new(&gum, options, tuple_list!(coverage, cmplog, hooks));

// Create an observation channel using the coverage map
let edges_observer = HitcountsMapObserver::new(StdMapObserver::from_mut_ptr(
Expand All @@ -235,7 +238,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {

let mut objective = feedback_or_fast!(
CrashFeedback::new(),
TimeoutFeedback::new(),
// TimeoutFeedback::new(),
feedback_and_fast!(ConstFeedback::from(false), AsanErrorsFeedback::new())
);

Expand Down Expand Up @@ -360,7 +363,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {

let mut objective = feedback_or_fast!(
CrashFeedback::new(),
TimeoutFeedback::new(),
// TimeoutFeedback::new(),
feedback_and_fast!(ConstFeedback::from(false), AsanErrorsFeedback::new())
);

Expand Down Expand Up @@ -412,12 +415,13 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {
// Create the executor for an in-process function with just one observer for edge coverage
let mut executor = FridaInProcessExecutor::new(
&gum,
InProcessExecutor::new(
InProcessExecutor::with_timeout(
&mut frida_harness,
observers,
&mut fuzzer,
&mut state,
&mut mgr,
options.timeout
)?,
&mut frida_helper,
);
Expand All @@ -434,7 +438,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {

let mut stages = tuple_list!(StdMutationalStage::new(mutator));

fuzzer.fuzz_loop(&mut stages, &mut executor, &mut state, &mut mgr)?;
fuzzer.fuzz_loop(&mut stages, &mut executor, &mut state, &mut mgr).unwrap();

Ok(())
})(state, mgr, core_id)
Expand Down
22 changes: 20 additions & 2 deletions libafl/src/executors/hooks/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ pub mod windows_exception_handler {
ptr::addr_of_mut,
sync::atomic::{compiler_fence, Ordering},
};

#[cfg(feature = "std")]
use std::io::Write;

#[cfg(feature = "std")]
use std::panic;

Expand All @@ -131,7 +135,7 @@ pub mod windows_exception_handler {
},
feedbacks::Feedback,
fuzzer::HasObjective,
inputs::UsesInput,
inputs::{UsesInput, Input},
state::{HasCorpus, HasExecutions, HasSolutions, State},
};

Expand Down Expand Up @@ -388,14 +392,28 @@ pub mod windows_exception_handler {

if is_crash {
log::error!("Child crashed!");

} else {
// log::info!("Exception received!");
}

// 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 mut bsod = Vec::new();
{
let mut writer = std::io::BufWriter::new(&mut bsod);
writeln!(writer, "input: {:?}", input.generate_name(0)).unwrap();
libafl_bolts::minibsod::generate_minibsod(
&mut writer,
exception_pointers
)
.unwrap();
writer.flush().unwrap();
}
log::error!("{}", std::str::from_utf8(&bsod).unwrap());
}
run_observers_and_save_state::<E, EM, OF, Z>(
executor,
state,
Expand Down
4 changes: 2 additions & 2 deletions libafl_frida/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,12 @@ nix = "0.26"
libc = "0.2"
hashbrown = "0.14"
rangemap = "1.3"
frida-gum-sys = { version = "0.8.3", features = [
frida-gum-sys = { path = "../../frida-rust/frida-gum-sys/", version = "0.8.3", features = [
"auto-download",
"event-sink",
"invocation-listener",
] }
frida-gum = { version = "0.13.4", features = [
frida-gum = { path = "../../frida-rust/frida-gum/", version = "0.13.4", features = [
"auto-download",
"event-sink",
"invocation-listener",
Expand Down
2 changes: 1 addition & 1 deletion libafl_frida/src/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ impl Allocator {
#[inline]
#[must_use]
pub fn check_shadow(&mut self, address: *const c_void, size: usize) -> bool {
if size == 0 {
if size == 0 || !self.is_managed(address as *mut c_void){
return true;
}
let address = address as usize;
Expand Down
Loading

0 comments on commit 3d6d8f5

Please sign in to comment.