[Windows] Add libfuzzer example for windows with ASAN (#934)
* Add libfuzzer example for window with ASAN * Fix formatting * Add link * Fix cpp format * Skip windows fuzzers * Fix format * Fix testing fuzzer * Fix taks name Co-authored-by: Dongjia "toka" Zhang <tokazerkje@outlook.com> Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com> Co-authored-by: Dominik Maier <domenukk@gmail.com>
This commit is contained in:
parent
3c7dcac41d
commit
4d8b566a87
1
fuzzers/libfuzzer_windows_asan/.gitignore
vendored
Normal file
1
fuzzers/libfuzzer_windows_asan/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
libfuzzer_windows_asan*
|
26
fuzzers/libfuzzer_windows_asan/Cargo.toml
Normal file
26
fuzzers/libfuzzer_windows_asan/Cargo.toml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
[package]
|
||||||
|
name = "libfuzzer_windows_asan"
|
||||||
|
version = "0.8.2"
|
||||||
|
authors = ["Max Ammann <max@maxammann.org>"]
|
||||||
|
edition = "2021"
|
||||||
|
categories = ["development-tools::testing"]
|
||||||
|
|
||||||
|
[features]
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
lto = true
|
||||||
|
codegen-units = 1
|
||||||
|
opt-level = 3
|
||||||
|
debug = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
libafl = { path = "../../libafl/" }
|
||||||
|
libafl_targets = { path = "../../libafl_targets/", features = ["libfuzzer", "sancov_pcguard_edges"] }
|
||||||
|
libafl_cc = { path = "../../libafl_cc/" }
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
cc = { version = "1.0" }
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "libfuzzer_windows_asan"
|
||||||
|
crate-type = ["staticlib"]
|
98
fuzzers/libfuzzer_windows_asan/Makefile.toml
Normal file
98
fuzzers/libfuzzer_windows_asan/Makefile.toml
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
# Variables
|
||||||
|
[env]
|
||||||
|
FUZZER_NAME='libfuzzer_windows_asan'
|
||||||
|
CARGO_TARGET_DIR = { value = "./target", condition = { env_not_set = ["CARGO_TARGET_DIR"] } }
|
||||||
|
|
||||||
|
[tasks.unsupported]
|
||||||
|
script_runner="@shell"
|
||||||
|
script='''
|
||||||
|
echo "Cargo-make not integrated yet on this"
|
||||||
|
'''
|
||||||
|
|
||||||
|
# Compilers
|
||||||
|
[tasks.cxx]
|
||||||
|
linux_alias = "unsupported"
|
||||||
|
mac_alias = "unsupported"
|
||||||
|
windows_alias = "cxx_unix"
|
||||||
|
|
||||||
|
[tasks.cxx_unix]
|
||||||
|
command = "cargo"
|
||||||
|
args = ["build" , "--release"]
|
||||||
|
|
||||||
|
[tasks.cc]
|
||||||
|
linux_alias = "cc_unix"
|
||||||
|
mac_alias = "cc_unix"
|
||||||
|
windows_alias = "cc_unix"
|
||||||
|
|
||||||
|
[tasks.cc_unix]
|
||||||
|
command = "cargo"
|
||||||
|
args = ["build" , "--release"]
|
||||||
|
|
||||||
|
[tasks.crash_cxx]
|
||||||
|
linux_alias = "unsupported"
|
||||||
|
mac_alias = "unsupported"
|
||||||
|
windows_alias = "unsupported"
|
||||||
|
|
||||||
|
[tasks.crash_cc]
|
||||||
|
linux_alias = "unsupported"
|
||||||
|
mac_alias = "unsupported"
|
||||||
|
windows_alias = "unsupported"
|
||||||
|
|
||||||
|
# Library
|
||||||
|
[tasks.lib]
|
||||||
|
linux_alias = "unsupported"
|
||||||
|
mac_alias = "unsupported"
|
||||||
|
windows_alias = "lib_unix"
|
||||||
|
|
||||||
|
[tasks.lib_unix]
|
||||||
|
dependencies = [ "cxx", "cc" ]
|
||||||
|
|
||||||
|
# Harness
|
||||||
|
[tasks.fuzzer]
|
||||||
|
linux_alias = "unsupported"
|
||||||
|
mac_alias = "unsupported"
|
||||||
|
windows_alias = "fuzzer_windows"
|
||||||
|
|
||||||
|
[tasks.fuzzer_windows]
|
||||||
|
command = "${CARGO_TARGET_DIR}/release/libafl_cxx"
|
||||||
|
args = ["./harness.cpp", "-o", "${FUZZER_NAME}.exe"]
|
||||||
|
dependencies = [ "lib", "cxx", "cc" ]
|
||||||
|
|
||||||
|
# Run the fuzzer
|
||||||
|
[tasks.run]
|
||||||
|
linux_alias = "unsupported"
|
||||||
|
mac_alias = "unsupported"
|
||||||
|
windows_alias = "run_windows" # TODO
|
||||||
|
|
||||||
|
[tasks.run_windows]
|
||||||
|
script_runner = "@shell"
|
||||||
|
script='''
|
||||||
|
'''
|
||||||
|
dependencies = [ "fuzzer" ]
|
||||||
|
|
||||||
|
# Test
|
||||||
|
[tasks.test]
|
||||||
|
linux_alias = "unsupported"
|
||||||
|
mac_alias = "unsupported"
|
||||||
|
windows_alias = "test_windows" # TODO
|
||||||
|
|
||||||
|
[tasks.test_windows]
|
||||||
|
script_runner = "@shell"
|
||||||
|
script='''
|
||||||
|
'''
|
||||||
|
dependencies = [ "fuzzer" ]
|
||||||
|
|
||||||
|
# Clean up
|
||||||
|
[tasks.clean]
|
||||||
|
linux_alias = "unsupported"
|
||||||
|
mac_alias = "unsupported"
|
||||||
|
windows_alias = "clean_windows"
|
||||||
|
|
||||||
|
[tasks.clean_windows]
|
||||||
|
# Disable default `clean` definition
|
||||||
|
clear = true
|
||||||
|
script_runner="@shell"
|
||||||
|
script='''
|
||||||
|
del ./${FUZZER_NAME}
|
||||||
|
cargo clean
|
||||||
|
'''
|
49
fuzzers/libfuzzer_windows_asan/README.md
Normal file
49
fuzzers/libfuzzer_windows_asan/README.md
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
# LibFuzzer Example for Windows with ASAN
|
||||||
|
|
||||||
|
This folder contains an example fuzzer for Windows which also uses ASAN.
|
||||||
|
|
||||||
|
We are initializing LibAFL to be compatible with ASAN.
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
We are currently using Clang on Windows. Make sure to install Clang through the Visual Studio installer.
|
||||||
|
|
||||||
|
We recommend using Powershell and enabling the Visual Studio environment using this script:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Push-Location "C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Auxiliary\Build\"
|
||||||
|
& "C:\\Windows\System32\cmd.exe" /c "vcvars64.bat & set" |
|
||||||
|
ForEach-Object {
|
||||||
|
if ($_ -match "=") {
|
||||||
|
$v = $_.split("=", 2); set-item -force -path "ENV:\$($v[0])" -value "$($v[1])"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Pop-Location
|
||||||
|
Write-Host "`nVisual Studio 2022 Command Prompt variables set." -ForegroundColor Yellow
|
||||||
|
````
|
||||||
|
|
||||||
|
After that clang should be available in the PATH.
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
To build the fuzzer and link against the `harness.cpp` in this example run:
|
||||||
|
|
||||||
|
```
|
||||||
|
cargo make fuzzer
|
||||||
|
```
|
||||||
|
|
||||||
|
## Running
|
||||||
|
|
||||||
|
```
|
||||||
|
.\libfuzzer_windows_asan.exe
|
||||||
|
```
|
||||||
|
|
||||||
|
## Note on MSVC
|
||||||
|
|
||||||
|
The MSVC compiler (`cl.exe`) will work in the future. Currently, it is blocked because of a [bug](https://developercommunity.visualstudio.com/t/__sanitizer_cov_trace_pc_guard_init-neve/10218995) with coverage.
|
||||||
|
|
||||||
|
### Note on ASAN
|
||||||
|
|
||||||
|
Using ASAN on Windows with MSVC is not trivial as of 2022. Depending on the harness and fuzzing target, the required compilation flags differ. Most notably, the usage of `/MT` and `/MD` for the CRT is important. All compilation artifacts should use the same config for the CRT (either all `/MT` or all `/MD`). [Rust uses as of 2022](https://rust-lang.github.io/rfcs/1721-crt-static.html) `/MD` as default. So compile everything with `/MD`.
|
||||||
|
|
||||||
|
Depending on the linking mode different ASAN libraries get linked. Definitely read [this](https://devblogs.microsoft.com/cppblog/addresssanitizer-asan-for-windows-with-msvc/) blog post by Microsoft.
|
1
fuzzers/libfuzzer_windows_asan/corpus/hello_world
Normal file
1
fuzzers/libfuzzer_windows_asan/corpus/hello_world
Normal file
@ -0,0 +1 @@
|
|||||||
|
Hello World
|
16
fuzzers/libfuzzer_windows_asan/harness.cpp
Normal file
16
fuzzers/libfuzzer_windows_asan/harness.cpp
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
void asan_crash() {
|
||||||
|
int *array = new int[100];
|
||||||
|
delete[] array;
|
||||||
|
array[5] += 1;
|
||||||
|
fprintf(stdout, "%d\n", array[5]);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||||
|
// abort();
|
||||||
|
asan_crash();
|
||||||
|
return 0;
|
||||||
|
}
|
43
fuzzers/libfuzzer_windows_asan/src/bin/libafl_cc.rs
Normal file
43
fuzzers/libfuzzer_windows_asan/src/bin/libafl_cc.rs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
use std::env;
|
||||||
|
|
||||||
|
use libafl_cc::{ClangWrapper, CompilerWrapper};
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
let args: Vec<String> = env::args().collect();
|
||||||
|
if args.len() > 1 {
|
||||||
|
let mut dir = env::current_exe().unwrap();
|
||||||
|
let wrapper_name = dir
|
||||||
|
.file_name()
|
||||||
|
.unwrap()
|
||||||
|
.to_str()
|
||||||
|
.unwrap()
|
||||||
|
.replace(".exe", "");
|
||||||
|
|
||||||
|
let is_cpp = match wrapper_name[wrapper_name.len()-2..].to_lowercase().as_str() {
|
||||||
|
"cc" => false,
|
||||||
|
"++" | "pp" | "xx" => true,
|
||||||
|
_ => panic!("Could not figure out if c or c++ warpper was called. Expected {:?} to end with c or cxx", dir),
|
||||||
|
};
|
||||||
|
|
||||||
|
dir.pop();
|
||||||
|
|
||||||
|
let mut cc = ClangWrapper::new();
|
||||||
|
if let Some(code) = cc
|
||||||
|
.cpp(is_cpp)
|
||||||
|
// silence the compiler wrapper output, needed for some configure scripts.
|
||||||
|
.silence(true)
|
||||||
|
.parse_args(&args)
|
||||||
|
.expect("Failed to parse the command line")
|
||||||
|
.link_staticlib(&dir, "libfuzzer_windows_asan")
|
||||||
|
.add_arg("-lOleAut32.lib")
|
||||||
|
.add_arg("-fsanitize-coverage=trace-pc-guard")
|
||||||
|
.add_arg("-fsanitize=address")
|
||||||
|
.run()
|
||||||
|
.expect("Failed to run the wrapped compiler")
|
||||||
|
{
|
||||||
|
std::process::exit(code);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
panic!("LibAFL CC: No Arguments given");
|
||||||
|
}
|
||||||
|
}
|
5
fuzzers/libfuzzer_windows_asan/src/bin/libafl_cxx.rs
Normal file
5
fuzzers/libfuzzer_windows_asan/src/bin/libafl_cxx.rs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
pub mod libafl_cc;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
libafl_cc::main()
|
||||||
|
}
|
187
fuzzers/libfuzzer_windows_asan/src/lib.rs
Normal file
187
fuzzers/libfuzzer_windows_asan/src/lib.rs
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
use core::time::Duration;
|
||||||
|
use std::{env, path::PathBuf};
|
||||||
|
|
||||||
|
use libafl::{
|
||||||
|
bolts::{
|
||||||
|
current_nanos,
|
||||||
|
rands::StdRand,
|
||||||
|
tuples::{tuple_list, Merge},
|
||||||
|
AsSlice,
|
||||||
|
},
|
||||||
|
corpus::{Corpus, InMemoryCorpus, OnDiskCorpus},
|
||||||
|
events::{setup_restarting_mgr_std, EventConfig, EventRestarter},
|
||||||
|
executors::{inprocess::InProcessExecutor, ExitKind, TimeoutExecutor},
|
||||||
|
feedback_or, feedback_or_fast,
|
||||||
|
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback},
|
||||||
|
fuzzer::{Fuzzer, StdFuzzer},
|
||||||
|
inputs::{BytesInput, HasTargetBytes},
|
||||||
|
monitors::MultiMonitor,
|
||||||
|
mutators::{
|
||||||
|
scheduled::{havoc_mutations, tokens_mutations, StdScheduledMutator},
|
||||||
|
token_mutations::Tokens,
|
||||||
|
},
|
||||||
|
observers::{HitcountsMapObserver, StdMapObserver, TimeObserver},
|
||||||
|
schedulers::{
|
||||||
|
powersched::PowerSchedule, IndexesLenTimeMinimizerScheduler, StdWeightedScheduler,
|
||||||
|
},
|
||||||
|
stages::{calibrate::CalibrationStage, power::StdPowerMutationalStage},
|
||||||
|
state::{HasCorpus, HasMetadata, StdState},
|
||||||
|
Error,
|
||||||
|
};
|
||||||
|
use libafl_targets::{libfuzzer_initialize, libfuzzer_test_one_input, EDGES_MAP, MAX_EDGES_NUM};
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn libafl_main() {
|
||||||
|
println!(
|
||||||
|
"Workdir: {:?}",
|
||||||
|
env::current_dir().unwrap().to_string_lossy().to_string()
|
||||||
|
);
|
||||||
|
fuzz(
|
||||||
|
&[PathBuf::from("./corpus")],
|
||||||
|
PathBuf::from("./crashes"),
|
||||||
|
1337,
|
||||||
|
)
|
||||||
|
.expect("An error occurred while fuzzing");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The actual fuzzer
|
||||||
|
#[cfg(not(test))]
|
||||||
|
fn fuzz(corpus_dirs: &[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 monitor = MultiMonitor::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_std(monitor, broker_port, EventConfig::AlwaysUnique) {
|
||||||
|
Ok(res) => res,
|
||||||
|
Err(err) => match err {
|
||||||
|
Error::ShuttingDown => {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
panic!("Failed to setup the restarter: {}", err);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create an observation channel using the coverage map
|
||||||
|
let edges = unsafe { &mut EDGES_MAP[0..MAX_EDGES_NUM] };
|
||||||
|
let edges_observer = HitcountsMapObserver::new(StdMapObserver::new("edges", edges));
|
||||||
|
|
||||||
|
// Create an observation channel to keep track of the execution time
|
||||||
|
let time_observer = TimeObserver::new("time");
|
||||||
|
|
||||||
|
let map_feedback = MaxMapFeedback::new_tracking(&edges_observer, true, false);
|
||||||
|
|
||||||
|
let calibration = CalibrationStage::new(&map_feedback);
|
||||||
|
|
||||||
|
// Feedback to rate the interestingness of an input
|
||||||
|
// This one is composed by two Feedbacks in OR
|
||||||
|
let mut feedback = feedback_or!(
|
||||||
|
// New maximization map feedback linked to the edges observer and the feedback state
|
||||||
|
map_feedback,
|
||||||
|
// Time feedback, this one does not need a feedback state
|
||||||
|
TimeFeedback::new_with_observer(&time_observer)
|
||||||
|
);
|
||||||
|
|
||||||
|
// A feedback to choose if an input is a solution or not
|
||||||
|
let mut objective = feedback_or_fast!(CrashFeedback::new(), TimeoutFeedback::new());
|
||||||
|
|
||||||
|
// If not restarting, create a State from scratch
|
||||||
|
let mut state = state.unwrap_or_else(|| {
|
||||||
|
StdState::new(
|
||||||
|
// RNG
|
||||||
|
StdRand::with_seed(current_nanos()),
|
||||||
|
// Corpus that will be evolved, we keep it in memory for performance
|
||||||
|
InMemoryCorpus::new(),
|
||||||
|
// Corpus in which we store solutions (crashes in this example),
|
||||||
|
// on disk so the user can get them after stopping the fuzzer
|
||||||
|
OnDiskCorpus::new(objective_dir).unwrap(),
|
||||||
|
// States of the feedbacks.
|
||||||
|
// The feedbacks can report the data that should persist in the State.
|
||||||
|
&mut feedback,
|
||||||
|
// Same for objective feedbacks
|
||||||
|
&mut objective,
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
});
|
||||||
|
|
||||||
|
println!("We're a client, let's fuzz :)");
|
||||||
|
|
||||||
|
// Setup a basic mutator with a mutational stage
|
||||||
|
|
||||||
|
let mutator = StdScheduledMutator::new(havoc_mutations().merge(tokens_mutations()));
|
||||||
|
|
||||||
|
let power = StdPowerMutationalStage::new(mutator, &edges_observer);
|
||||||
|
|
||||||
|
let mut stages = tuple_list!(calibration, power);
|
||||||
|
|
||||||
|
// A minimization+queue policy to get testcasess from the corpus
|
||||||
|
let scheduler = IndexesLenTimeMinimizerScheduler::new(StdWeightedScheduler::with_schedule(
|
||||||
|
PowerSchedule::FAST,
|
||||||
|
));
|
||||||
|
|
||||||
|
// A fuzzer with feedbacks and a corpus scheduler
|
||||||
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
|
||||||
|
// The wrapped harness function, calling out to the LLVM-style harness
|
||||||
|
let mut harness = |input: &BytesInput| {
|
||||||
|
let target = input.target_bytes();
|
||||||
|
let buf = target.as_slice();
|
||||||
|
libfuzzer_test_one_input(buf);
|
||||||
|
ExitKind::Ok
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create the executor for an in-process function with one observer for edge coverage and one for the execution time
|
||||||
|
let mut executor = TimeoutExecutor::new(
|
||||||
|
InProcessExecutor::new(
|
||||||
|
&mut harness,
|
||||||
|
tuple_list!(edges_observer, time_observer),
|
||||||
|
&mut fuzzer,
|
||||||
|
&mut state,
|
||||||
|
&mut restarting_mgr,
|
||||||
|
)?,
|
||||||
|
// 10 seconds timeout
|
||||||
|
Duration::new(10, 0),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Initialize ASAN, call this before any ASAN crashes can occur (directly after initializing executor e.g.)
|
||||||
|
#[cfg(windows)]
|
||||||
|
unsafe {
|
||||||
|
libafl_targets::setup_asan_callback(&executor, &restarting_mgr, &fuzzer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The actual target run starts here.
|
||||||
|
// Call LLVMFUzzerInitialize() if present.
|
||||||
|
let args: Vec<String> = env::args().collect();
|
||||||
|
if libfuzzer_initialize(&args) == -1 {
|
||||||
|
println!("Warning: LLVMFuzzerInitialize failed with -1")
|
||||||
|
}
|
||||||
|
|
||||||
|
// In case the corpus is empty (on first run), reset
|
||||||
|
if state.corpus().count() < 1 {
|
||||||
|
state
|
||||||
|
.load_initial_inputs(&mut fuzzer, &mut executor, &mut restarting_mgr, corpus_dirs)
|
||||||
|
.unwrap_or_else(|_| panic!("Failed to load initial corpus at {:?}", &corpus_dirs));
|
||||||
|
println!("We imported {} inputs from disk.", state.corpus().count());
|
||||||
|
}
|
||||||
|
|
||||||
|
// This fuzzer restarts after 1 mio `fuzz_one` executions.
|
||||||
|
// Each fuzz_one will internally do many executions of the target.
|
||||||
|
// If your target is very instable, setting a low count here may help.
|
||||||
|
// However, you will lose a lot of performance that way.
|
||||||
|
let iters = 1_000_000;
|
||||||
|
fuzzer.fuzz_loop_for(
|
||||||
|
&mut stages,
|
||||||
|
&mut executor,
|
||||||
|
&mut state,
|
||||||
|
&mut restarting_mgr,
|
||||||
|
iters,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// It's important, that we store the state before restarting!
|
||||||
|
// Else, the parent will not respawn a new child and quit.
|
||||||
|
restarting_mgr.on_restart(&mut state)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
@ -10,7 +10,7 @@ typedef long double max_align_t;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
|
#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
|
||||||
//#define USE_NEW_PM 1
|
// #define USE_NEW_PM 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* #if LLVM_VERSION_STRING >= "4.0.1" */
|
/* #if LLVM_VERSION_STRING >= "4.0.1" */
|
||||||
|
@ -22,6 +22,15 @@ EXT_FUNC_IMPL(main, int, (int argc, char** argv), false) {
|
|||||||
libafl_main();
|
libafl_main();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
// If we do not add the main, the MSVC linker fails with:
|
||||||
|
// LINK : fatal error LNK1561: entry point must be defined
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
libafl_main();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
EXPORT_FN int libafl_targets_has_libfuzzer_init() {
|
EXPORT_FN int libafl_targets_has_libfuzzer_init() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user