From 949a25a29a035316c0f3371ef2b102033141e57b Mon Sep 17 00:00:00 2001 From: Aarnav Date: Mon, 5 Aug 2024 18:10:45 +0200 Subject: [PATCH 1/3] It's frida time for libafl-fuzz (#2469) * libafl-fuzz: misc nit in check_autoresume * libafl-fuzz: add FRIDA mode * libafl-fuzz: improve Makefile * libafl-fuzz: fix Ci * libafl-fuzz: clang-format test-cmpcov.c * libafl-fuzz: no cmplog for persistent frida * libafl-fuzz: minor CI fix * libafl-fuzz: fix frida persistent mode * libafl-fuzz: add frida seeds * misc: typo --- fuzzers/others/libafl-fuzz/Makefile.toml | 68 +++++++++++++++++-- fuzzers/others/libafl-fuzz/src/corpus.rs | 8 +-- fuzzers/others/libafl-fuzz/src/env_parser.rs | 3 + fuzzers/others/libafl-fuzz/src/executor.rs | 66 +++++++++++++++++- fuzzers/others/libafl-fuzz/src/fuzzer.rs | 34 ++++++++-- fuzzers/others/libafl-fuzz/src/main.rs | 3 + .../others/libafl-fuzz/test/seeds-frida/init | 1 + fuzzers/others/libafl-fuzz/test/test-cmpcov.c | 56 +++++++++++++++ 8 files changed, 222 insertions(+), 17 deletions(-) create mode 100644 fuzzers/others/libafl-fuzz/test/seeds-frida/init create mode 100644 fuzzers/others/libafl-fuzz/test/test-cmpcov.c diff --git a/fuzzers/others/libafl-fuzz/Makefile.toml b/fuzzers/others/libafl-fuzz/Makefile.toml index c5a9404e9af..b8f9598a0ff 100644 --- a/fuzzers/others/libafl-fuzz/Makefile.toml +++ b/fuzzers/others/libafl-fuzz/Makefile.toml @@ -15,7 +15,7 @@ LLVM_CONFIG = { value = "llvm-config-18", condition = { env_not_set = [ AFL_VERSION = "db23931e7c1727ddac8691a6241c97b2203ec6fc" AFL_DIR_NAME = { value = "./AFLplusplus-${AFL_VERSION}" } AFL_CC_PATH = { value = "${AFL_DIR_NAME}/afl-clang-fast" } - +CC = { value = "clang" } [tasks.build_afl] script_runner = "@shell" @@ -28,7 +28,9 @@ if [ ! -d "$AFL_DIR_NAME" ]; then unzip ${AFL_VERSION}.zip cd ${AFL_DIR_NAME} LLVM_CONFIG=${LLVM_CONFIG} make - cd .. + cd frida_mode + LLVM_CONFIG=${LLVM_CONFIG} make + cd ../.. fi ''' @@ -40,6 +42,11 @@ windows_alias = "unsupported" [tasks.test_unix] script_runner = "@shell" +script = "echo done" +dependencies = ["build_afl", "test_instr", "test_cmplog", "test_frida"] + +[tasks.test_instr] +script_runner = "@shell" script = ''' cargo build --profile ${PROFILE} AFL_PATH=${AFL_DIR_NAME} ${AFL_CC_PATH} ./test/test-instr.c -o ./test/out-instr @@ -64,16 +71,63 @@ test -d "./test/output/fuzzer_main/crashes" || { echo "No crashes directory found" exit 1 } +''' +dependencies = ["build_afl"] + +[tasks.test_cmplog] +script_runner = "@shell" +script = ''' +cargo build --profile ${PROFILE} # cmplog TODO: AFL_BENCH_UNTIL_CRASH=1 instead of timeout 15s AFL_LLVM_CMPLOG=1 AFL_PATH=${AFL_DIR_NAME} ${AFL_CC_PATH} ./test/test-cmplog.c -o ./test/out-cmplog -AFL_CORES=1 timeout 5 ${FUZZER} -Z -l 3 -m 0 -V30 -i ./test/seeds_cmplog -o ./test/cmplog-output -c 0 ./test/out-cmplog || true -test -n "$( find "./test/cmplog-output/fuzzer_main/crashes/" -maxdepth 1 -type f) 2>/dev/null )" || { +AFL_CORES=1 timeout 5 ${FUZZER} -Z -l 3 -m 0 -V30 -i ./test/seeds_cmplog -o ./test/output-cmplog -c 0 ./test/out-cmplog || true +test -n "$( ls -A ./test/output-cmplog/fuzzer_main/crashes/)" || { echo "No crashes found" exit 1 } ''' dependencies = ["build_afl"] +[tasks.test_frida] +script_runner = "@shell" +script = ''' +cargo build --profile ${PROFILE} +${CC} -no-pie ./test/test-instr.c -o ./test/out-frida +AFL_PATH=${AFL_DIR_NAME} AFL_CORES=1 AFL_STATS_INTERVAL=1 timeout 5 ${FUZZER} -m 0 -V07 -O -i ./test/seeds-frida -o ./test/output-frida -- ./test/out-frida || true +test -n "$( ls ./test/output-frida/fuzzer_main/queue/id:000002* 2>/dev/null )" || { + echo "No new corpus entries found for FRIDA mode" + exit 1 +} + +${CC} ./test/test-cmpcov.c -o ./test/out-frida-cmpcov +AFL_PATH=${AFL_DIR_NAME} LIBAFL_DEBUG_OUTPUT=1 AFL_DEBUG=1 AFL_CORES=1 AFL_FRIDA_VERBOSE=1 timeout 10 ${FUZZER} -m 0 -V07 -O -c 0 -l 3 -i ./test/seeds-frida -o ./test/output-frida-cmpcov -- ./test/out-frida-cmpcov || true +test -n "$( ls ./test/output-frida-cmpcov/fuzzer_main/queue/id:000003* 2>/dev/null )" || { + echo "No new corpus entries found for FRIDA cmplog mode" + exit 1 +} +export AFL_FRIDA_PERSISTENT_ADDR=0x`nm ./test/out-frida | grep -Ei "T _main|T main" | awk '{print $1}'` +AFL_PATH=${AFL_DIR_NAME} AFL_STATS_INTERVAL=1 AFL_CORES=1 timeout 5 ${FUZZER} -m 0 -V07 -O -i ./test/seeds-frida -o ./test/output-frida-persistent -- ./test/out-frida || true +# TODO: change it to id:000003* once persistent mode is fixed +test -n "$( ls ./test/output-frida-persistent/fuzzer_main/queue/id:000002* 2>/dev/null )" || { + echo "No new corpus entries found for FRIDA persistent mode" + exit 1 +} +RUNTIME_PERSISTENT=`grep execs_done ./test/output-frida-persistent/fuzzer_main/fuzzer_stats | awk '{print$3}'` +RUNTIME=`grep execs_done ./test/output-frida/fuzzer_main/fuzzer_stats | awk '{print$3}'` +test -n "$RUNTIME" -a -n "$RUNTIME_PERSISTENT" && { + DIFF=`expr $RUNTIME_PERSISTENT / $RUNTIME` + test "$DIFF" -gt 1 && { # must be at least twice as fast + echo "persistent frida_mode was noticeably faster than standard frida_mode" + } || { + echo "persistent frida_mode" $RUNTIME_PERSISTENT "was not noticeably faster than standard frida_mode" $RUNTIME + exit 1 + } +} || { + echo "we got no data on executions performed? weird!" +} +''' +dependencies = ["build_afl"] + [tasks.clean] linux_alias = "clean_unix" mac_alias = "clean_unix" @@ -86,4 +140,10 @@ rm -rf AFLplusplus-${AFL_VERSION} rm ${AFL_VERSION}.zip rm -rf ./test/out-instr rm -rf ./test/output +rm -rf ./test/cmplog-output +rm -rf ./test/output-frida +rm -rf ./test/output-frida-cmpcov +rm -rf ./test/output-frida-persistent +rm -rf ./test/output-cmplog +rm ./test/out-* ''' diff --git a/fuzzers/others/libafl-fuzz/src/corpus.rs b/fuzzers/others/libafl-fuzz/src/corpus.rs index cc95ff51068..ed2a9f82d26 100644 --- a/fuzzers/others/libafl-fuzz/src/corpus.rs +++ b/fuzzers/others/libafl-fuzz/src/corpus.rs @@ -151,12 +151,12 @@ pub fn check_autoresume( path.display() )))?), ); - if let Err(e) = cpy_res { - if matches!(e.kind(), io::ErrorKind::InvalidInput) { + match cpy_res { + Err(e) if e.kind() == io::ErrorKind::InvalidInput => { println!("skipping {} since it is not a regular file", path.display()); - } else { - return Err(e.into()); } + Err(e) => return Err(e.into()), + Ok(_) => {} } } } diff --git a/fuzzers/others/libafl-fuzz/src/env_parser.rs b/fuzzers/others/libafl-fuzz/src/env_parser.rs index c1e6f385daf..fc58715ffe6 100644 --- a/fuzzers/others/libafl-fuzz/src/env_parser.rs +++ b/fuzzers/others/libafl-fuzz/src/env_parser.rs @@ -110,6 +110,9 @@ pub fn parse_envs(opt: &mut Opt) -> Result<(), Error> { } else { opt.foreign_sync_interval = Duration::from_secs(AFL_DEFAULT_FOREIGN_SYNC_INTERVAL); } + if let Ok(res) = std::env::var("AFL_USE_FASAN") { + opt.frida_asan = parse_bool(&res)?; + } Ok(()) } diff --git a/fuzzers/others/libafl-fuzz/src/executor.rs b/fuzzers/others/libafl-fuzz/src/executor.rs index bf7dabeeda9..f4685d7c1ac 100644 --- a/fuzzers/others/libafl-fuzz/src/executor.rs +++ b/fuzzers/others/libafl-fuzz/src/executor.rs @@ -6,9 +6,13 @@ use std::{ use libafl::Error; use memmap2::{Mmap, MmapOptions}; +use nix::libc::{S_IRUSR, S_IXUSR}; use crate::{Opt, DEFER_SIG, PERSIST_SIG}; +const AFL_PATH: &str = "/usr/local/lib/afl/"; +const BIN_PATH: &str = "/usr/local/bin/"; + // TODO better error messages and logging pub fn check_binary(opt: &mut Opt, shmem_env_var: &str) -> Result<(), Error> { println!("Validating target binary..."); @@ -115,7 +119,9 @@ pub fn check_binary(opt: &mut Opt, shmem_env_var: &str) -> Result<(), Error> { if opt.forkserver_cs || opt.qemu_mode || opt.frida_mode && is_instrumented(&mmap, shmem_env_var) { - return Err(Error::illegal_argument("Instrumentation found in -Q mode")); + return Err(Error::illegal_argument( + "Instrumentation found in -Q/-O mode", + )); } if mmap_has_substr(&mmap, "__asan_init") @@ -130,6 +136,8 @@ pub fn check_binary(opt: &mut Opt, shmem_env_var: &str) -> Result<(), Error> { } else if opt.is_persistent { println!("persistent mode enforced"); } else if opt.frida_persistent_addr.is_some() { + opt.is_persistent = true; + opt.defer_forkserver = true; println!("FRIDA persistent mode configuration options detected"); } @@ -162,7 +170,7 @@ fn is_instrumented(mmap: &Mmap, shmem_env_var: &str) -> bool { mmap_has_substr(mmap, shmem_env_var) } -fn find_executable_in_path(executable: &Path) -> Option { +fn find_executable_in_path>(executable: &P) -> Option { std::env::var_os("PATH").and_then(|paths| { std::env::split_paths(&paths).find_map(|dir| { let full_path = dir.join(executable); @@ -174,3 +182,57 @@ fn find_executable_in_path(executable: &Path) -> Option { }) }) } + +pub fn find_afl_binary(filename: &str, same_dir_as: Option) -> Result { + let is_library = + filename.contains('.') && filename.ends_with(".so") || filename.ends_with(".dylib"); + + let permission = if is_library { + S_IRUSR // user can read + } else { + S_IXUSR // user can exec + }; + + // First we check if it is present in AFL_PATH + if let Ok(afl_path) = std::env::var("AFL_PATH") { + let file = PathBuf::from(afl_path).join(filename); + if check_file_found(&file, permission) { + return Ok(file); + } + } + + // next we check the same directory as the provided parameter + if let Some(same_dir_as) = same_dir_as { + if let Some(parent_dir) = same_dir_as.parent() { + let file = parent_dir.join(filename); + if check_file_found(&file, permission) { + return Ok(file); + } + } + } + + // check sensible defaults + let file = PathBuf::from(if is_library { AFL_PATH } else { BIN_PATH }).join(filename); + let found = check_file_found(&file, permission); + if found { + return Ok(file); + } + + if !is_library { + // finally, check the path for the binary + return find_executable_in_path(&filename) + .ok_or(Error::unknown(format!("cannot find {filename}"))); + } + + Err(Error::unknown(format!("cannot find {filename}"))) +} + +fn check_file_found(file: &PathBuf, perm: u32) -> bool { + if !file.exists() { + return false; + } + if let Ok(metadata) = file.metadata() { + return metadata.permissions().mode() & perm != 0; + } + false +} diff --git a/fuzzers/others/libafl-fuzz/src/fuzzer.rs b/fuzzers/others/libafl-fuzz/src/fuzzer.rs index 7d69a21e267..f9a360bfd1c 100644 --- a/fuzzers/others/libafl-fuzz/src/fuzzer.rs +++ b/fuzzers/others/libafl-fuzz/src/fuzzer.rs @@ -46,6 +46,7 @@ use crate::{ afl_stats::{AflStatsStage, CalibrationTime, FuzzTime, SyncTime}, corpus::{set_corpus_filepath, set_solution_filepath}, env_parser::AFL_DEFAULT_MAP_SIZE, + executor::find_afl_binary, feedback::{ filepath::CustomFilepathToTestcaseFeedback, persistent_record::PersitentRecordFeedback, seed::SeedFeedback, @@ -209,6 +210,29 @@ where // Create our Fuzzer let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); + // Set LD_PRELOAD (Linux) && DYLD_INSERT_LIBRARIES (OSX) for target. + if let Some(preload_env) = &opt.afl_preload { + std::env::set_var("LD_PRELOAD", preload_env); + std::env::set_var("DYLD_INSERT_LIBRARIES", preload_env); + } + + // Insert appropriate shared libraries if frida_mode + if opt.frida_mode { + if opt.frida_asan { + std::env::set_var("ASAN_OPTIONS", "detect_leaks=false"); + } + let frida_bin = find_afl_binary("afl-frida-trace.so", Some(opt.executable.clone()))? + .display() + .to_string(); + let preload = if let Some(preload_env) = &opt.afl_preload { + format!("{preload_env}:{frida_bin}") + } else { + frida_bin + }; + std::env::set_var("LD_PRELOAD", &preload); + std::env::set_var("DYLD_INSERT_LIBRARIES", &preload); + } + // Create the base Executor let mut executor = base_executor(opt, &mut shmem_provider); // Set a custom exit code to be interpreted as a Crash if configured. @@ -279,12 +303,6 @@ where // Tell [`SeedFeedback`] that we're done loading seeds; rendering it benign. fuzzer.feedback_mut().done_loading_seeds(); - // Set LD_PRELOAD (Linux) && DYLD_INSERT_LIBRARIES (OSX) for target. - if let Some(preload_env) = &opt.afl_preload { - std::env::set_var("LD_PRELOAD", preload_env); - std::env::set_var("DYLD_INSERT_LIBRARIES", preload_env); - } - // Create a Sync stage to sync from foreign fuzzers let sync_stage = IfStage::new( |_, _, _, _| Ok(is_main_node && !opt.foreign_sync_dirs.is_empty()), @@ -395,7 +413,6 @@ fn base_executor<'a>( ) -> ForkserverExecutorBuilder<'a, StdShMemProvider> { let mut executor = ForkserverExecutor::builder() .program(opt.executable.clone()) - .shmem_provider(shmem_provider) .coverage_map_size(opt.map_size.unwrap_or(AFL_DEFAULT_MAP_SIZE)) .debug_child(opt.debug_child) .is_persistent(opt.is_persistent) @@ -409,6 +426,9 @@ fn base_executor<'a>( if let Some(kill_signal) = opt.kill_signal { executor = executor.kill_signal(kill_signal); } + if opt.is_persistent { + executor = executor.shmem_provider(shmem_provider); + } if let Some(harness_input_type) = &opt.harness_input_type { executor = executor.parse_afl_cmdline([harness_input_type]); } diff --git a/fuzzers/others/libafl-fuzz/src/main.rs b/fuzzers/others/libafl-fuzz/src/main.rs index 4df2a894f7f..3bcb8098d9e 100644 --- a/fuzzers/others/libafl-fuzz/src/main.rs +++ b/fuzzers/others/libafl-fuzz/src/main.rs @@ -6,6 +6,7 @@ #![allow(clippy::similar_names)] #![allow(clippy::too_many_lines)] #![allow(clippy::struct_excessive_bools)] +#![allow(clippy::case_sensitive_file_extension_comparisons)] use std::{collections::HashMap, path::PathBuf, time::Duration}; mod afl_stats; @@ -236,6 +237,8 @@ struct Opt { /// use binary-only instrumentation (FRIDA mode) #[arg(short = 'O')] frida_mode: bool, + #[clap(skip)] + frida_asan: bool, /// use binary-only instrumentation (QEMU mode) #[arg(short = 'Q')] qemu_mode: bool, diff --git a/fuzzers/others/libafl-fuzz/test/seeds-frida/init b/fuzzers/others/libafl-fuzz/test/seeds-frida/init new file mode 100644 index 00000000000..5c0ac06f554 --- /dev/null +++ b/fuzzers/others/libafl-fuzz/test/seeds-frida/init @@ -0,0 +1 @@ +00000 diff --git a/fuzzers/others/libafl-fuzz/test/test-cmpcov.c b/fuzzers/others/libafl-fuzz/test/test-cmpcov.c new file mode 100644 index 00000000000..eb0eb4fbc18 --- /dev/null +++ b/fuzzers/others/libafl-fuzz/test/test-cmpcov.c @@ -0,0 +1,56 @@ +#include +#include +#include +#include + +char global_cmpval[] = "GLOBALVARIABLE"; + +int main(int argc, char **argv) { + char *input = argv[1], *buf, buffer[20]; + char cmpval[] = "LOCALVARIABLE"; + char shortval[4] = "abc"; + + if (argc < 2) { + ssize_t ret = read(0, buffer, sizeof(buffer) - 1); + buffer[ret] = 0; + input = buffer; + } + + if (strcmp(input, "LIBTOKENCAP") == 0) + printf("your string was LIBTOKENCAP\n"); + else if (strcmp(input, "BUGMENOT") == 0) + printf("your string was BUGMENOT\n"); + else if (strncmp(input, "BANANA", 3) == 0) + printf("your string started with BAN\n"); + else if (strcmp(input, "APRI\0COT") == 0) + printf("your string was APRI\n"); + else if (strcasecmp(input, "Kiwi") == 0) + printf("your string was Kiwi\n"); + else if (strncasecmp(input, "avocado", 9) == 0) + printf("your string was avocado\n"); + else if (strncasecmp(input, "Grapes", argc > 2 ? atoi(argv[2]) : 3) == 0) + printf("your string was a prefix of Grapes\n"); + else if (strstr(input, "tsala") != NULL) + printf("your string is a fruit salad\n"); + else if (strcmp(input, "BUFFEROVERFLOW") == 0) { + buf = (char *)malloc(16); + strcpy(buf, "TEST"); + strcat(buf, input); + printf("This will only crash with libdislocator: %s\n", buf); + + } else if (*(unsigned int *)input == 0xabadcafe) + + printf("GG you eat cmp tokens for breakfast!\n"); + else if (memcmp(cmpval, input, 8) == 0) + printf("local var memcmp works!\n"); + else if (memcmp(shortval, input, 4) == 0) + printf("short local var memcmp works!\n"); + else if (memcmp(global_cmpval, input, sizeof(global_cmpval)) == 0) + printf("global var memcmp works!\n"); + else if (strncasecmp("-h", input, 2) == 0) + printf("this is not the help you are looking for\n"); + else + printf("I do not know your string\n"); + + return 0; +} From 3bebbe0dacd69cbaf520df45d7991b28b9d4f6de Mon Sep 17 00:00:00 2001 From: Max Ammann Date: Mon, 5 Aug 2024 21:10:46 +0100 Subject: [PATCH 2/3] Update AsanBacktrace documentation (#2377) * Add AsanBacktrace documentation * Update stacktrace.rs --- libafl/src/observers/stacktrace.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libafl/src/observers/stacktrace.rs b/libafl/src/observers/stacktrace.rs index dacc00f5c8f..8480a48caa0 100644 --- a/libafl/src/observers/stacktrace.rs +++ b/libafl/src/observers/stacktrace.rs @@ -267,7 +267,7 @@ pub fn get_asan_runtime_flags() -> String { flags.join(":") } -/// An observer looking at the backtrace of target command using ASAN output +/// An observer looking at the backtrace of target command using ASAN output. This observer is only compatible with a `ForkserverExecutor`. #[derive(Serialize, Deserialize, Debug, Clone)] pub struct AsanBacktraceObserver { observer_name: Cow<'static, str>, From 723f4a1cb0f49956ffad18c453d9615dafd0415b Mon Sep 17 00:00:00 2001 From: Romain Malmain Date: Mon, 5 Aug 2024 23:48:35 +0200 Subject: [PATCH 3/3] Fix various QEMU bugs (#2475) * Update LibAFL QEMU to the latest version (V9.0.2 update, important bug fixes, ... - check the dedicated repo for more info) * fix bug in hook execution, causing first execution hooks to be run multiple times. --- .dockerignore | 3 ++- fuzzers/qemu/qemu_launcher/Cargo.toml | 8 ++++---- libafl_qemu/Cargo.toml | 2 +- libafl_qemu/libafl_qemu_build/src/build.rs | 2 +- libafl_qemu/src/emu/mod.rs | 7 ++++++- libafl_qemu/src/modules/edges.rs | 4 ++-- 6 files changed, 16 insertions(+), 10 deletions(-) diff --git a/.dockerignore b/.dockerignore index a00386f1f7d..4d7b3cf3cd8 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,4 +1,5 @@ -target +**/target +**/.git Cargo.lock *.o diff --git a/fuzzers/qemu/qemu_launcher/Cargo.toml b/fuzzers/qemu/qemu_launcher/Cargo.toml index f5f34bbbdf4..5809f5676aa 100644 --- a/fuzzers/qemu/qemu_launcher/Cargo.toml +++ b/fuzzers/qemu/qemu_launcher/Cargo.toml @@ -48,13 +48,13 @@ vergen = { version = "8.2", features = [ [dependencies] clap = { version = "4.3", features = ["derive", "string"] } -libafl = { path = "../../../libafl/" } -libafl_bolts = { path = "../../../libafl_bolts/", features = [ +libafl = { path = "../../../libafl" } +libafl_bolts = { path = "../../../libafl_bolts", features = [ "errors_backtrace", ] } -libafl_qemu = { path = "../../../libafl_qemu/", features = ["usermode"] } +libafl_qemu = { path = "../../../libafl_qemu", features = ["usermode"] } log = { version = "0.4.20" } nix = { version = "0.29", features = ["fs"] } rangemap = { version = "1.3" } readonly = { version = "0.2.10" } -typed-builder = { version = "0.18" } +typed-builder = { version = "0.19" } diff --git a/libafl_qemu/Cargo.toml b/libafl_qemu/Cargo.toml index f634a474104..5081a25a634 100644 --- a/libafl_qemu/Cargo.toml +++ b/libafl_qemu/Cargo.toml @@ -125,7 +125,7 @@ serde_yaml = { version = "0.9", optional = true } # For parsing the injections y toml = { version = "0.8.13", optional = true } # For parsing the injections toml file pyo3 = { version = "0.22", optional = true, features = ["multiple-pymethods"] } bytes-utils = "0.1" -typed-builder = "0.18" +typed-builder = "0.19" memmap2 = "0.9" # Document all features of this crate (for `cargo doc`) document-features = { version = "0.2", optional = true } diff --git a/libafl_qemu/libafl_qemu_build/src/build.rs b/libafl_qemu/libafl_qemu_build/src/build.rs index ff4793b5723..55a28e28bf6 100644 --- a/libafl_qemu/libafl_qemu_build/src/build.rs +++ b/libafl_qemu/libafl_qemu_build/src/build.rs @@ -11,7 +11,7 @@ use crate::cargo_add_rpath; pub const QEMU_URL: &str = "https://github.com/AFLplusplus/qemu-libafl-bridge"; pub const QEMU_DIRNAME: &str = "qemu-libafl-bridge"; -pub const QEMU_REVISION: &str = "4cafaa9a087dae6674b0fdc11ba34d3e6a8364d2"; +pub const QEMU_REVISION: &str = "24abc2a717226bedc047167f639aef0edc9ce92d"; #[allow(clippy::module_name_repetitions)] pub struct BuildResult { diff --git a/libafl_qemu/src/emu/mod.rs b/libafl_qemu/src/emu/mod.rs index 8dfb316907e..a0ec4efda57 100644 --- a/libafl_qemu/src/emu/mod.rs +++ b/libafl_qemu/src/emu/mod.rs @@ -477,6 +477,7 @@ where breakpoints_by_id: RefCell>>, #[builder(setter(transform = |args: &[String], env: &[(String, String)]| Qemu::init(args, env).unwrap()))] qemu: Qemu, + first_exec: bool, _phantom: PhantomData<(ET, S)>, } @@ -513,6 +514,7 @@ where exit_handler: RefCell::new(exit_handler), breakpoints_by_addr: RefCell::new(HashMap::new()), breakpoints_by_id: RefCell::new(HashMap::new()), + first_exec: true, _phantom: PhantomData, qemu, }) @@ -678,7 +680,10 @@ where } pub fn first_exec_all(&mut self) { - self.modules.first_exec_all(); + if self.first_exec { + self.modules.first_exec_all(); + self.first_exec = false; + } } pub fn pre_exec_all(&mut self, input: &S::Input) { diff --git a/libafl_qemu/src/modules/edges.rs b/libafl_qemu/src/modules/edges.rs index a8522788cfa..767ea5b20cf 100644 --- a/libafl_qemu/src/modules/edges.rs +++ b/libafl_qemu/src/modules/edges.rs @@ -162,7 +162,7 @@ where ET: EmulatorModuleTuple, { if self.use_hitcounts { - // hooks.edges( + // emulator_modules.edges( // Hook::Function(gen_unique_edge_ids::), // Hook::Raw(trace_edge_hitcount), // ); @@ -175,7 +175,7 @@ where ); } } else { - // hooks.edges( + // emulator_modules.edges( // Hook::Function(gen_unique_edge_ids::), // Hook::Raw(trace_edge_single), // );