compile libfuzzer_libpng on windows
This commit is contained in:
parent
82f5dad784
commit
a0550b3154
@ -1,12 +1,11 @@
|
||||
//! A libfuzzer-like fuzzer with llmp-multithreading support and restarts
|
||||
//! The example harness is built for libpng.
|
||||
|
||||
#[cfg(unix)]
|
||||
use core::time::Duration;
|
||||
use std::{env, path::PathBuf};
|
||||
|
||||
use libafl::{
|
||||
bolts::{shmem::UnixShMem, tuples::tuple_list},
|
||||
bolts::{shmem::StdShMem, tuples::tuple_list},
|
||||
corpus::{
|
||||
Corpus, InMemoryCorpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus,
|
||||
QueueCorpusScheduler,
|
||||
@ -46,21 +45,14 @@ pub fn main() {
|
||||
.expect("An error occurred while fuzzing");
|
||||
}
|
||||
|
||||
/// Not supported on windows right now
|
||||
#[cfg(windows)]
|
||||
fn fuzz(_corpus_dirs: Vec<PathBuf>, _objective_dir: PathBuf, _broker_port: u16) -> Result<(), ()> {
|
||||
todo!("Example not supported on Windows");
|
||||
}
|
||||
|
||||
/// The actual fuzzer
|
||||
#[cfg(unix)]
|
||||
fn fuzz(corpus_dirs: Vec<PathBuf>, objective_dir: PathBuf, broker_port: u16) -> Result<(), Error> {
|
||||
// 'While the stats are state, they are usually used in the broker - which is likely never restarted
|
||||
let stats = SimpleStats::new(|s| println!("{}", s));
|
||||
|
||||
// The restarting state will spawn the same process again as child, then restarted it each time it crashes.
|
||||
let (state, mut restarting_mgr) =
|
||||
match setup_restarting_mgr::<_, _, UnixShMem, _>(stats, broker_port) {
|
||||
match setup_restarting_mgr::<_, _, StdShMem, _>(stats, broker_port) {
|
||||
Ok(res) => res,
|
||||
Err(err) => match err {
|
||||
Error::ShuttingDown => {
|
||||
@ -139,7 +131,8 @@ fn fuzz(corpus_dirs: Vec<PathBuf>, objective_dir: PathBuf, broker_port: u16) ->
|
||||
|
||||
// The actual target run starts here.
|
||||
// Call LLVMFUzzerInitialize() if present.
|
||||
if libfuzzer_initialize() == -1 {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
if libfuzzer_initialize(&args) == -1 {
|
||||
println!("Warning: LLVMFuzzerInitialize failed with -1")
|
||||
}
|
||||
|
||||
|
@ -3,9 +3,13 @@
|
||||
|
||||
#[cfg(all(feature = "std", unix))]
|
||||
pub use unix_shmem::UnixShMem;
|
||||
#[cfg(all(feature = "std", unix))]
|
||||
pub type StdShMem = UnixShMem;
|
||||
|
||||
#[cfg(all(windows, feature = "std"))]
|
||||
pub use shmem::Win32ShMem;
|
||||
pub use win32_shmem::Win32ShMem;
|
||||
#[cfg(all(windows, feature = "std"))]
|
||||
pub type StdShMem = Win32ShMem;
|
||||
|
||||
use alloc::string::{String, ToString};
|
||||
use core::fmt::Debug;
|
||||
@ -442,7 +446,7 @@ pub mod unix_shmem {
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "std", windows))]
|
||||
pub mod shmem {
|
||||
pub mod win32_shmem {
|
||||
|
||||
use super::ShMem;
|
||||
use crate::{
|
||||
|
@ -3,10 +3,7 @@
|
||||
pub mod inprocess;
|
||||
pub use inprocess::InProcessExecutor;
|
||||
pub mod timeout;
|
||||
#[cfg(unix)]
|
||||
pub use timeout::TimeoutExecutor;
|
||||
#[cfg(feature = "runtime")]
|
||||
pub mod runtime;
|
||||
|
||||
use core::cmp::PartialEq;
|
||||
use core::marker::PhantomData;
|
||||
|
@ -1,9 +1,7 @@
|
||||
//! A TimeoutExecutor set a timeout before each target run
|
||||
|
||||
#[cfg(unix)]
|
||||
use core::{marker::PhantomData, time::Duration};
|
||||
|
||||
#[cfg(unix)]
|
||||
use crate::{
|
||||
bolts::tuples::Named,
|
||||
events::EventManager,
|
||||
@ -41,7 +39,6 @@ extern "C" {
|
||||
const ITIMER_REAL: c_int = 0;
|
||||
|
||||
/// The timeout excutor is a wrapper that set a timeout before each run
|
||||
#[cfg(unix)]
|
||||
pub struct TimeoutExecutor<E, I, OT>
|
||||
where
|
||||
E: Executor<I> + HasObservers<OT>,
|
||||
@ -53,7 +50,6 @@ where
|
||||
phantom: PhantomData<(I, OT)>,
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
impl<E, I, OT> Named for TimeoutExecutor<E, I, OT>
|
||||
where
|
||||
E: Executor<I> + HasObservers<OT>,
|
||||
@ -65,7 +61,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
impl<E, I, OT> HasObservers<OT> for TimeoutExecutor<E, I, OT>
|
||||
where
|
||||
E: Executor<I> + HasObservers<OT>,
|
||||
@ -83,7 +78,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
impl<E, I, OT> TimeoutExecutor<E, I, OT>
|
||||
where
|
||||
E: Executor<I> + HasObservers<OT>,
|
||||
@ -99,7 +93,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
impl<E, I, OT> Executor<I> for TimeoutExecutor<E, I, OT>
|
||||
where
|
||||
E: Executor<I> + HasObservers<OT>,
|
||||
|
@ -1,25 +1,80 @@
|
||||
static int orig_argc;
|
||||
static char **orig_argv;
|
||||
static char **orig_envp;
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static void save_main_args(int argc, char** argv, char** envp) {
|
||||
orig_argc = argc;
|
||||
orig_argv = argv;
|
||||
orig_envp = envp;
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define LIBFUZZER_MSVC 1
|
||||
#else
|
||||
#define LIBFUZZER_MSVC 0
|
||||
#endif // _MSC_VER
|
||||
|
||||
// From Libfuzzer
|
||||
// Intermediate macro to ensure the parameter is expanded before stringified.
|
||||
#define STRINGIFY_(A) #A
|
||||
#define STRINGIFY(A) STRINGIFY_(A)
|
||||
|
||||
#if LIBFUZZER_MSVC
|
||||
// Copied from compiler-rt/lib/sanitizer_common/sanitizer_win_defs.h
|
||||
#if defined(_M_IX86) || defined(__i386__)
|
||||
#define WIN_SYM_PREFIX "_"
|
||||
#else
|
||||
#define WIN_SYM_PREFIX
|
||||
#endif
|
||||
|
||||
// Declare external functions as having alternativenames, so that we can
|
||||
// determine if they are not defined.
|
||||
#define EXTERNAL_FUNC(Name, Default) \
|
||||
__pragma(comment(linker, "/alternatename:" WIN_SYM_PREFIX STRINGIFY( \
|
||||
Name) "=" WIN_SYM_PREFIX STRINGIFY(Default)))
|
||||
#else
|
||||
// Declare external functions as weak to allow them to default to a specified
|
||||
// function if not defined explicitly. We must use weak symbols because clang's
|
||||
// support for alternatename is not 100%, see
|
||||
// https://bugs.llvm.org/show_bug.cgi?id=40218 for more details.
|
||||
#define EXTERNAL_FUNC(Name, Default) \
|
||||
__attribute__((weak, alias(STRINGIFY(Default))))
|
||||
#endif // LIBFUZZER_MSVC
|
||||
|
||||
#define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \
|
||||
RETURN_TYPE NAME##Def FUNC_SIG { \
|
||||
printf("ERROR: Function \"%s\" not defined.\n", #NAME); \
|
||||
exit(1); \
|
||||
} \
|
||||
EXTERNAL_FUNC(NAME, NAME##Def) RETURN_TYPE NAME FUNC_SIG
|
||||
|
||||
#else
|
||||
|
||||
// Declare these symbols as weak to allow them to be optionally defined.
|
||||
#define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \
|
||||
__attribute__((weak, visibility("default"))) RETURN_TYPE NAME FUNC_SIG
|
||||
|
||||
#endif
|
||||
|
||||
EXT_FUNC(LLVMFuzzerInitialize, int, (int *argc, char ***argv), false);
|
||||
EXT_FUNC(LLVMFuzzerCustomMutator, size_t,
|
||||
(uint8_t *Data, size_t Size, size_t MaxSize, unsigned int Seed),
|
||||
false);
|
||||
EXT_FUNC(LLVMFuzzerCustomCrossOver, size_t,
|
||||
(const uint8_t *Data1, size_t Size1,
|
||||
const uint8_t *Data2, size_t Size2,
|
||||
uint8_t *Out, size_t MaxOutSize, unsigned int Seed),
|
||||
false);
|
||||
|
||||
#undef EXT_FUNC
|
||||
|
||||
int libafl_targets_has_libfuzzer_init() {
|
||||
return LLVMFuzzerInitialize != NULL;
|
||||
}
|
||||
|
||||
__attribute__((section(".init_array")))
|
||||
void (*p_libafl_targets_save_main_args)(int, char*[], char*[]) = &save_main_args;
|
||||
|
||||
__attribute__((weak))
|
||||
int LLVMFuzzerInitialize(int *argc, char ***argv);
|
||||
|
||||
int libafl_targets_libfuzzer_init() {
|
||||
|
||||
int libafl_targets_libfuzzer_init(int *argc, char ***argv) {
|
||||
if (LLVMFuzzerInitialize) {
|
||||
return LLVMFuzzerInitialize(&orig_argc, &orig_argv);
|
||||
return LLVMFuzzerInitialize(argc, argv);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,11 +4,13 @@ extern "C" {
|
||||
fn LLVMFuzzerTestOneInput(data: *const u8, size: usize) -> i32;
|
||||
|
||||
// libafl_targets_libfuzzer_init calls LLVMFUzzerInitialize()
|
||||
fn libafl_targets_libfuzzer_init() -> i32;
|
||||
fn libafl_targets_libfuzzer_init(argc: *const i32, argv: *const *const *const u8) -> i32;
|
||||
}
|
||||
|
||||
pub fn libfuzzer_initialize() -> i32 {
|
||||
unsafe { libafl_targets_libfuzzer_init() }
|
||||
pub fn libfuzzer_initialize(args: &[String]) -> i32 {
|
||||
let argv: Vec<*const u8> = args.iter().map(|x| x.as_bytes().as_ptr()).collect();
|
||||
let argc = argv.len() as i32;
|
||||
unsafe { libafl_targets_libfuzzer_init(&argc as *const i32, &argv.as_ptr() as *const *const *const u8) }
|
||||
}
|
||||
|
||||
pub fn libfuzzer_test_one_input(buf: &[u8]) -> i32 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user