diff options
34 files changed, 403 insertions, 199 deletions
diff --git a/CITATION.cff b/CITATION.cff index 37a4a174..5ae7211d 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -27,5 +27,5 @@ keywords: - qemu - llvm - unicorn-emulator - - securiy + - security license: AGPL-3.0-or-later diff --git a/GNUmakefile b/GNUmakefile index 73fa366f..dee9bbb3 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -52,7 +52,7 @@ endif ifdef ASAN_BUILD $(info Compiling ASAN version of binaries) override CFLAGS += $(ASAN_CFLAGS) - LDFLAGS += $(ASAN_LDFLAGS) + override LDFLAGS += $(ASAN_LDFLAGS) endif ifdef UBSAN_BUILD $(info Compiling UBSAN version of binaries) @@ -106,22 +106,22 @@ ifneq "$(SYS)" "Darwin" # SPECIAL_PERFORMANCE += -march=native #endif #ifndef DEBUG - # CFLAGS_OPT += -D_FORTIFY_SOURCE=1 + # override CFLAGS_OPT += -D_FORTIFY_SOURCE=1 #endif else # On some odd MacOS system configurations, the Xcode sdk path is not set correctly SDK_LD = -L$(shell xcrun --show-sdk-path)/usr/lib - LDFLAGS += $(SDK_LD) + override LDFLAGS += $(SDK_LD) endif COMPILER_TYPE=$(shell $(CC) --version|grep "Free Software Foundation") ifneq "$(COMPILER_TYPE)" "" #$(info gcc is being used) - CFLAGS_OPT += -Wno-error=format-truncation -Wno-format-truncation + override CFLAGS_OPT += -Wno-error=format-truncation -Wno-format-truncation endif ifeq "$(SYS)" "SunOS" - LDFLAGS = -lkstat -lrt -lsocket -lnsl + override LDFLAGS = -lkstat -lrt -lsocket -lnsl endif ifdef STATIC @@ -131,8 +131,8 @@ ifdef STATIC PYFLAGS= PYTHON_INCLUDE = / - CFLAGS_OPT += -static - LDFLAGS += -lm -lpthread -lz -lutil + override CFLAGS_OPT += -static + override LDFLAGS += -lm -lpthread -lz -lutil endif ifdef PROFILING @@ -759,7 +759,7 @@ endif @test -e SanitizerCoveragePCGUARD.so && echo "[+] LLVM mode successfully built" || echo "[-] LLVM mode could not be built, please install at least llvm-13 and clang-13 or newer, see docs/INSTALL.md" @test -e SanitizerCoverageLTO.so && echo "[+] LLVM LTO mode successfully built" || echo "[-] LLVM LTO mode could not be built, it is optional, if you want it, please install LLVM 11-14. More information at instrumentation/README.lto.md on how to build it" ifneq "$(SYS)" "Darwin" - test -e afl-gcc-pass.so && echo "[+] gcc_mode successfully built" || echo "[-] gcc_mode could not be built, it is optional, install gcc-VERSION-plugin-dev to enable this" + @test -e afl-gcc-pass.so && echo "[+] gcc_mode successfully built" || echo "[-] gcc_mode could not be built, it is optional, install gcc-VERSION-plugin-dev to enable this" endif ifeq "$(SYS)" "Linux" ifndef NO_NYX diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm index ec8fefe4..98ae461c 100644 --- a/GNUmakefile.llvm +++ b/GNUmakefile.llvm @@ -44,7 +44,7 @@ endif LLVMVER = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/git//' | sed 's/svn//' ) LLVM_MAJOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/\..*//' ) -LLVM_MINOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/.*\.//' | sed 's/git//' | sed 's/svn//' | sed 's/ .*//' ) +LLVM_MINOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/.*\.//' | sed 's/git//' | sed 's/svn//' | sed 's/ .*//' | sed 's/rc.*//' ) LLVM_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^[0-2]\.|^3.[0-8]\.' && echo 1 || echo 0 ) LLVM_TOO_NEW = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[8-9]|^2[0-9]' && echo 1 || echo 0 ) LLVM_TOO_OLD = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^[1-9]\.|^1[012]\.' && echo 1 || echo 0 ) diff --git a/README.md b/README.md index f15089c2..2583407e 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ <img align="right" src="https://raw.githubusercontent.com/AFLplusplus/Website/main/static/aflpp_bg.svg" alt="AFL++ logo" width="250" heigh="250"> -Release version: [4.10c](https://github.com/AFLplusplus/AFLplusplus/releases) +Release version: [4.20c](https://github.com/AFLplusplus/AFLplusplus/releases) -GitHub version: 4.20a +GitHub version: 4.20c Repository: [https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus) diff --git a/custom_mutators/aflpp/aflpp.c b/custom_mutators/aflpp/aflpp.c index e15d0391..0b236f76 100644 --- a/custom_mutators/aflpp/aflpp.c +++ b/custom_mutators/aflpp/aflpp.c @@ -1,3 +1,4 @@ +#include "afl-fuzz.h" #include "afl-mutations.h" typedef struct my_mutator { diff --git a/custom_mutators/aflpp/standalone/aflpp-standalone.c b/custom_mutators/aflpp/standalone/aflpp-standalone.c index 361feaba..3a2cbc2f 100644 --- a/custom_mutators/aflpp/standalone/aflpp-standalone.c +++ b/custom_mutators/aflpp/standalone/aflpp-standalone.c @@ -1,9 +1,6 @@ +#include "afl-fuzz.h" #include "afl-mutations.h" -s8 interesting_8[] = {INTERESTING_8}; -s16 interesting_16[] = {INTERESTING_8, INTERESTING_16}; -s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32}; - typedef struct my_mutator { afl_state_t *afl; @@ -155,7 +152,7 @@ int main(int argc, char *argv[]) { return -1; } - if (verbose) fprintf(stderr, "Mutation output length: %zu\n", outlen); + if (verbose) fprintf(stderr, "Mutation output length: %u\n", outlen); if (fwrite(outbuf, 1, outlen, out) != outlen) { fprintf(stderr, "Warning: incomplete write.\n"); diff --git a/docs/Changelog.md b/docs/Changelog.md index 51f8dc4f..2428d63f 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -3,12 +3,12 @@ This is the list of all noteworthy changes made in every public release of the tool. See README.md for the general instruction manual. -### Version ++4.20a (dev) +### Version ++4.20c (release) ! A new forkserver communication model is now introduced. afl-fuzz is backward compatible to old compiled targets if they are not built for CMPLOG/Redqueen, but new compiled targets will not work with old afl-fuzz versions! - ! Recompiled all targets that are instrumented for CMPLOG/Redqueen! + ! Recompile all targets that are instrumented for CMPLOG/Redqueen! - AFL++ now supports up to 4 billion coverage edges, up from 6 million. - New compile option: `make PERFORMANCE=1` - this will enable special CPU dependent optimizations that make everything more performant - but @@ -23,16 +23,20 @@ - workround for a bug with MOpt -L when used with -M - in the future we will either remove or rewrite MOpt. - fix for `-t xxx+` feature - - -e extension option now saves the queue items crashes etc. with the + - -e extension option now saves the queue items, crashes, etc. with the extension too + - fixes for trimmming, correct -V time and reading stats on resume by eqv + thanks a lot! - afl-cc: - added collision free caller instrumentation to LTO mode. activate with `AFL_LLVM_LTO_CALLER=1`. You can set a max depth to go through single block functions with `AFL_LLVM_LTO_CALLER_DEPTH` (default 0) + - fixes for COMPCOV/LAF and most other modules - fix for GCC_PLUGIN cmplog that broke on std::strings - afl-whatsup: - now also displays current average speed - small bugfixes + - Fixes for aflpp custom mutator and standalone tool - Minor edits to afl-persistent-config - Prevent temporary files being left behind on aborted afl-whatsup - More CPU benchmarks added to benchmark/ diff --git a/docs/fuzzing_in_depth.md b/docs/fuzzing_in_depth.md index 6a217641..82437807 100644 --- a/docs/fuzzing_in_depth.md +++ b/docs/fuzzing_in_depth.md @@ -958,7 +958,7 @@ too long for your overall available fuzz run time. campaign but not good for short CI runs. How this can look like can, e.g., be seen at AFL++'s setup in Google's -[oss-fuzz](https://github.com/google/oss-fuzz/blob/master/infra/base-images/base-builder/compile_afl) +[previous oss-fuzz version](https://github.com/google/oss-fuzz/blob/3e2c5312417d1a6f9564472f3df1fd27759b289d/infra/base-images/base-builder/compile_afl) and [clusterfuzz](https://github.com/google/clusterfuzz/blob/master/src/clusterfuzz/_internal/bot/fuzzers/afl/launcher.py). diff --git a/frida_mode/update_frida_version.sh b/frida_mode/update_frida_version.sh index 18243fbb..2fafbf2f 100755 --- a/frida_mode/update_frida_version.sh +++ b/frida_mode/update_frida_version.sh @@ -2,7 +2,7 @@ test -n "$1" && { echo This script has no options. It updates the referenced Frida version in GNUmakefile to the most current one. ; exit 1 ; } OLD=$(grep -E '^GUM_DEVKIT_VERSION=' GNUmakefile 2>/dev/null|awk -F= '{print$2}') -NEW=$(curl https://github.com/frida/frida/releases/ 2>/dev/null|grep -E 'frida-gum-devkit-[0-9.]*-linux-x86_64'|head -n 1|sed 's/.*frida-gum-devkit-//'|sed 's/-linux.*//') +NEW=$(curl https://github.com/frida/frida/releases/ 2>/dev/null|grep 'Frida\ [0-9.]*'|head -n 1|sed 's/.*Frida\ //'| sed 's/<\/h2>//') echo Current set version: $OLD echo Newest available version: $NEW diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index be86910e..c813ae7e 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -5,9 +5,9 @@ Originally written by Michal Zalewski Now maintained by Marc Heuse <mh@mh-sec.de>, - Heiko Eißfeldt <heiko.eissfeldt@hexco.de>, - Andrea Fioraldi <andreafioraldi@gmail.com>, - Dominik Maier <mail@dmnk.co> + Dominik Maier <mail@dmnk.co>, + Andrea Fioraldi <andreafioraldi@gmail.com>, and + Heiko Eissfeldt <heiko.eissfeldt@hexco.de> Copyright 2016, 2017 Google Inc. All rights reserved. Copyright 2019-2024 AFLplusplus Project. All rights reserved. @@ -648,7 +648,10 @@ typedef struct afl_state { longest_find_time, /* Longest time taken for a find */ exit_on_time, /* Delay to exit if no new paths */ sync_time, /* Sync time (ms) */ - switch_fuzz_mode; /* auto or fixed fuzz mode */ + switch_fuzz_mode, /* auto or fixed fuzz mode */ + calibration_time_us, /* Time spend on calibration */ + sync_time_us, /* Time spend on sync */ + trim_time_us; /* Time spend on trimming */ u32 slowest_exec_ms, /* Slowest testcase non hang in ms */ subseq_tmouts; /* Number of timeouts in a row */ @@ -1215,6 +1218,10 @@ void show_stats_normal(afl_state_t *); void show_stats_pizza(afl_state_t *); void show_init_stats(afl_state_t *); +void update_calibration_time(afl_state_t *afl, u64 *time); +void update_trim_time(afl_state_t *afl, u64 *time); +void update_sync_time(afl_state_t *afl, u64 *time); + /* StatsD */ void statsd_setup_format(afl_state_t *afl); diff --git a/include/afl-mutations.h b/include/afl-mutations.h index 75e66484..79cf7c6a 100644 --- a/include/afl-mutations.h +++ b/include/afl-mutations.h @@ -30,10 +30,13 @@ #include <stdbool.h> #include <inttypes.h> -#include "afl-fuzz.h" #define MUT_STRATEGY_ARRAY_SIZE 256 +s8 interesting_8[] = {INTERESTING_8}; +s16 interesting_16[] = {INTERESTING_8, INTERESTING_16}; +s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32}; + enum { /* 00 */ MUT_FLIPBIT, diff --git a/include/afl-record-compat.h b/include/afl-record-compat.h index 2c79595d..3e5d60e3 100644 --- a/include/afl-record-compat.h +++ b/include/afl-record-compat.h @@ -28,7 +28,7 @@ int __afl_persistent_loop(unsigned int max_cnt) { static unsigned short int inited = 0; char tcase[PATH_MAX]; - if (is_replay_record) { + if (is_replay_record && cycle_cnt) { if (!inited) { @@ -59,7 +59,7 @@ int __afl_persistent_loop(unsigned int max_cnt) { } - return --cycle_cnt; + return cycle_cnt--; } diff --git a/include/config.h b/include/config.h index 31d66b14..3ea059ff 100644 --- a/include/config.h +++ b/include/config.h @@ -26,7 +26,7 @@ /* Version string: */ // c = release, a = volatile github dev, e = experimental branch -#define VERSION "++4.20a" +#define VERSION "++4.20c" /****************************************************** * * diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc index 43c6ca40..4518c1c7 100644 --- a/instrumentation/SanitizerCoverageLTO.so.cc +++ b/instrumentation/SanitizerCoverageLTO.so.cc @@ -341,7 +341,7 @@ llvmGetPassPluginInfo() { using OptimizationLevel = typename PassBuilder::OptimizationLevel; #endif #if LLVM_VERSION_MAJOR >= 15 - PB.registerFullLinkTimeOptimizationLastEPCallback( + PB.registerFullLinkTimeOptimizationEarlyEPCallback( #else PB.registerOptimizerLastEPCallback( #endif @@ -1304,7 +1304,12 @@ u32 countCallers(Function *F) { for (auto *U : F->users()) { - if (auto *CI = dyn_cast<CallInst>(U)) { ++callers; } + if (auto *CI = dyn_cast<CallInst>(U)) { + + ++callers; + (void)(CI); + + } } diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index aa58e8de..e450dc45 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -1617,7 +1617,7 @@ void __sanitizer_cov_pcs_init(const uintptr_t *pcs_beg, } - if (pc_filter) { + if (pc_filter && !mod_info->next) { char PcDescr[1024]; // This function is a part of the sanitizer run-time. @@ -1644,7 +1644,8 @@ void __sanitizer_cov_pcs_init(const uintptr_t *pcs_beg, } - if (__afl_filter_pcs && strstr(mod_info->name, __afl_filter_pcs_module)) { + if (__afl_filter_pcs && !mod_info->next && + strstr(mod_info->name, __afl_filter_pcs_module)) { u32 result_index; if (locate_in_pcs(PC, &result_index)) { @@ -1669,7 +1670,7 @@ void __sanitizer_cov_pcs_init(const uintptr_t *pcs_beg, } - mod_info->mapped = 1; + if (__afl_pcmap_ptr) { mod_info->mapped = 1; } if (__afl_debug) { diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc index ac497b5b..b93f61f0 100644 --- a/instrumentation/afl-llvm-dict2file.so.cc +++ b/instrumentation/afl-llvm-dict2file.so.cc @@ -746,7 +746,7 @@ bool AFLdict2filePass::runOnModule(Module &M) { auto PA = PreservedAnalyses::all(); return PA; #else - return true; + return false; #endif } diff --git a/instrumentation/afl-llvm-pass.so.cc b/instrumentation/afl-llvm-pass.so.cc index 62f5023d..75b8532b 100644 --- a/instrumentation/afl-llvm-pass.so.cc +++ b/instrumentation/afl-llvm-pass.so.cc @@ -128,7 +128,11 @@ llvmGetPassPluginInfo() { #if LLVM_VERSION_MAJOR <= 13 using OptimizationLevel = typename PassBuilder::OptimizationLevel; #endif + #if LLVM_VERSION_MAJOR >= 16 + PB.registerOptimizerEarlyEPCallback( + #else PB.registerOptimizerLastEPCallback( + #endif [](ModulePassManager &MPM, OptimizationLevel OL) { MPM.addPass(AFLCoverage()); @@ -212,10 +216,6 @@ bool AFLCoverage::runOnModule(Module &M) { u32 rand_seed; unsigned int cur_loc = 0; -#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ - auto PA = PreservedAnalyses::all(); -#endif - /* Setup random() so we get Actually Random(TM) outputs from AFL_R() */ gettimeofday(&tv, &tz); rand_seed = tv.tv_sec ^ tv.tv_usec ^ getpid(); @@ -1081,7 +1081,7 @@ bool AFLCoverage::runOnModule(Module &M) { } #if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ - return PA; + return PreservedAnalyses(); #else return true; #endif diff --git a/instrumentation/cmplog-instructions-pass.cc b/instrumentation/cmplog-instructions-pass.cc index dc60221e..fe5c2926 100644 --- a/instrumentation/cmplog-instructions-pass.cc +++ b/instrumentation/cmplog-instructions-pass.cc @@ -680,13 +680,16 @@ bool CmpLogInstructions::runOnModule(Module &M) { printf("Running cmplog-instructions-pass by andreafioraldi@gmail.com\n"); else be_quiet = 1; - hookInstrs(M); + bool ret = hookInstrs(M); verifyModule(M); #if LLVM_MAJOR >= 11 /* use new pass manager */ - return PreservedAnalyses::all(); + if (ret == false) + return PreservedAnalyses::all(); + else + return PreservedAnalyses(); #else - return true; + return ret; #endif } diff --git a/instrumentation/cmplog-routines-pass.cc b/instrumentation/cmplog-routines-pass.cc index 78317d5d..560bd73b 100644 --- a/instrumentation/cmplog-routines-pass.cc +++ b/instrumentation/cmplog-routines-pass.cc @@ -758,16 +758,16 @@ bool CmpLogRoutines::runOnModule(Module &M) { printf("Running cmplog-routines-pass by andreafioraldi@gmail.com\n"); else be_quiet = 1; - hookRtns(M); -#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ - auto PA = PreservedAnalyses::all(); -#endif + bool ret = hookRtns(M); verifyModule(M); #if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ - return PA; + if (ret == false) + return PreservedAnalyses::all(); + else + return PreservedAnalyses(); #else - return true; + return ret; #endif } diff --git a/instrumentation/cmplog-switches-pass.cc b/instrumentation/cmplog-switches-pass.cc index 3e05c13d..2b87ea8c 100644 --- a/instrumentation/cmplog-switches-pass.cc +++ b/instrumentation/cmplog-switches-pass.cc @@ -442,16 +442,16 @@ bool CmplogSwitches::runOnModule(Module &M) { printf("Running cmplog-switches-pass by andreafioraldi@gmail.com\n"); else be_quiet = 1; - hookInstrs(M); -#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ - auto PA = PreservedAnalyses::all(); -#endif + bool ret = hookInstrs(M); verifyModule(M); #if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ - return PA; + if (ret == false) + return PreservedAnalyses::all(); + else + return PreservedAnalyses(); #else - return true; + return ret; #endif } diff --git a/instrumentation/compare-transform-pass.so.cc b/instrumentation/compare-transform-pass.so.cc index b0d6355a..f8ba9de5 100644 --- a/instrumentation/compare-transform-pass.so.cc +++ b/instrumentation/compare-transform-pass.so.cc @@ -89,7 +89,7 @@ class CompareTransform : public ModulePass { #endif - return "cmplog transform"; + return "compcov transform"; } @@ -123,7 +123,11 @@ llvmGetPassPluginInfo() { #if LLVM_VERSION_MAJOR <= 13 using OptimizationLevel = typename PassBuilder::OptimizationLevel; #endif + #if LLVM_VERSION_MAJOR >= 16 + PB.registerOptimizerEarlyEPCallback( + #else PB.registerOptimizerLastEPCallback( + #endif [](ModulePassManager &MPM, OptimizationLevel OL) { MPM.addPass(CompareTransform()); @@ -746,6 +750,8 @@ bool CompareTransform::runOnModule(Module &M) { #endif + bool ret = false; + if ((isatty(2) && getenv("AFL_QUIET") == NULL) || getenv("AFL_DEBUG") != NULL) printf( "Running compare-transform-pass by laf.intel@gmail.com, extended by " @@ -753,11 +759,7 @@ bool CompareTransform::runOnModule(Module &M) { else be_quiet = 1; -#if LLVM_MAJOR >= 11 /* use new pass manager */ - auto PA = PreservedAnalyses::all(); -#endif - - transformCmps(M, true, true, true, true, true); + if (transformCmps(M, true, true, true, true, true) == true) ret = true; verifyModule(M); #if LLVM_MAJOR >= 11 /* use new pass manager */ @@ -767,9 +769,18 @@ bool CompareTransform::runOnModule(Module &M) { }*/ - return PA; + if (ret == true) { + + return PreservedAnalyses(); + + } else { + + return PreservedAnalyses::all(); + + } + #else - return true; + return ret; #endif } diff --git a/instrumentation/injection-pass.cc b/instrumentation/injection-pass.cc index 2280208b..47ddabd9 100644 --- a/instrumentation/injection-pass.cc +++ b/instrumentation/injection-pass.cc @@ -204,6 +204,8 @@ bool InjectionRoutines::hookRtns(Module &M) { Function *FuncPtr; #endif + bool ret = false; + /* iterate over all functions, bbs and instruction and add suitable calls */ for (auto &F : M) { @@ -281,6 +283,7 @@ bool InjectionRoutines::hookRtns(Module &M) { IRBuilder<> IRB(callInst->getParent()); IRB.SetInsertPoint(callInst); + ret = true; Value *parameter = callInst->getArgOperand(param); @@ -299,7 +302,7 @@ bool InjectionRoutines::hookRtns(Module &M) { } - return true; + return ret; } @@ -328,16 +331,16 @@ bool InjectionRoutines::runOnModule(Module &M) { if (getenv("AFL_LLVM_INJECTIONS_LDAP")) { doLDAP = true; } if (getenv("AFL_LLVM_INJECTIONS_XSS")) { doXSS = true; } - hookRtns(M); -#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ - auto PA = PreservedAnalyses::all(); -#endif + bool ret = hookRtns(M); verifyModule(M); #if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ - return PA; + if (ret == false) + return PreservedAnalyses::all(); + else + return PreservedAnalyses(); #else - return true; + return ret; #endif } diff --git a/instrumentation/split-compares-pass.so.cc b/instrumentation/split-compares-pass.so.cc index 144025fb..421a7c39 100644 --- a/instrumentation/split-compares-pass.so.cc +++ b/instrumentation/split-compares-pass.so.cc @@ -189,7 +189,11 @@ llvmGetPassPluginInfo() { #if LLVM_VERSION_MAJOR <= 13 using OptimizationLevel = typename PassBuilder::OptimizationLevel; #endif + #if LLVM_VERSION_MAJOR >= 16 + PB.registerOptimizerEarlyEPCallback( + #else PB.registerOptimizerLastEPCallback( + #endif [](ModulePassManager &MPM, OptimizationLevel OL) { MPM.addPass(SplitComparesTransform()); @@ -935,7 +939,7 @@ size_t SplitComparesTransform::nextPowerOfTwo(size_t in) { /* splits fcmps into two nested fcmps with sign compare and the rest */ size_t SplitComparesTransform::splitFPCompares(Module &M) { - size_t count = 0; + size_t counts = 0; LLVMContext &C = M.getContext(); @@ -951,7 +955,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { } else { - return count; + return counts; } @@ -1004,7 +1008,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { } - if (!fcomps.size()) { return count; } + if (!fcomps.size()) { return counts; } IntegerType *Int1Ty = IntegerType::getInt1Ty(C); @@ -1690,11 +1694,11 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { #else ReplaceInstWithInst(FcmpInst->getParent()->getInstList(), ii, PN); #endif - ++count; + ++counts; } - return count; + return counts; } @@ -1743,10 +1747,6 @@ bool SplitComparesTransform::runOnModule(Module &M) { } -#if LLVM_MAJOR >= 11 - auto PA = PreservedAnalyses::all(); -#endif - if (enableFPSplit) { simplifyFPCompares(M); @@ -1778,15 +1778,7 @@ bool SplitComparesTransform::runOnModule(Module &M) { auto op0 = CI->getOperand(0); auto op1 = CI->getOperand(1); - if (!op0 || !op1) { - -#if LLVM_MAJOR >= 11 - return PA; -#else - return false; -#endif - - } + if (!op0 || !op1) { continue; } auto iTy1 = dyn_cast<IntegerType>(op0->getType()); if (iTy1 && isa<IntegerType>(op1->getType())) { @@ -1814,6 +1806,8 @@ bool SplitComparesTransform::runOnModule(Module &M) { } + bool ret = count == 0 ? false : true; + bool brokenDebug = false; if (verifyModule(M, &errs() #if LLVM_VERSION_MAJOR >= 4 || \ @@ -1852,9 +1846,12 @@ bool SplitComparesTransform::runOnModule(Module &M) { }*/ - return PA; + if (ret == false) + return PreservedAnalyses::all(); + else + return PreservedAnalyses(); #else - return true; + return ret; #endif } diff --git a/instrumentation/split-switches-pass.so.cc b/instrumentation/split-switches-pass.so.cc index e3dfea0d..aa552a42 100644 --- a/instrumentation/split-switches-pass.so.cc +++ b/instrumentation/split-switches-pass.so.cc @@ -137,7 +137,11 @@ llvmGetPassPluginInfo() { #if LLVM_VERSION_MAJOR <= 13 using OptimizationLevel = typename PassBuilder::OptimizationLevel; #endif + #if LLVM_VERSION_MAJOR >= 16 + PB.registerOptimizerEarlyEPCallback( + #else PB.registerOptimizerLastEPCallback( + #endif [](ModulePassManager &MPM, OptimizationLevel OL) { MPM.addPass(SplitSwitchesTransform()); @@ -516,11 +520,7 @@ bool SplitSwitchesTransform::runOnModule(Module &M) { else be_quiet = 1; -#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ - auto PA = PreservedAnalyses::all(); -#endif - - splitSwitches(M); + bool ret = splitSwitches(M); verifyModule(M); #if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ @@ -530,9 +530,12 @@ bool SplitSwitchesTransform::runOnModule(Module &M) { }*/ - return PA; + if (ret == false) + return PreservedAnalyses::all(); + else + return PreservedAnalyses(); #else - return true; + return ret; #endif } diff --git a/qemu_mode/build_qemu_support.sh b/qemu_mode/build_qemu_support.sh index 45019cc8..ecc90ef5 100755 --- a/qemu_mode/build_qemu_support.sh +++ b/qemu_mode/build_qemu_support.sh @@ -215,8 +215,10 @@ if [ "$STATIC" = "1" ]; then echo Building STATIC binary # static PIE causes https://github.com/AFLplusplus/AFLplusplus/issues/892 + # plugin support requires dynamic linking QEMU_CONF_FLAGS="$QEMU_CONF_FLAGS \ --static --disable-pie \ + --disable-plugins \ --extra-cflags=-DAFL_QEMU_STATIC_BUILD=1 \ " diff --git a/src/afl-cc.c b/src/afl-cc.c index faa46103..45fd398b 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1369,6 +1369,13 @@ void mode_final_checkout(aflcc_state_t *aflcc, int argc, char **argv) { } + if (getenv("AFL_LLVM_DICT2FILE") && + (getenv("AFL_LLVM_LAF_SPLIT_SWITCHES") || + getenv("AFL_LLVM_LAF_SPLIT_COMPARES") || + getenv("AFL_LLVM_LAF_SPLIT_FLOATS") || + getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES"))) + FATAL("AFL_LLVM_DICT2FILE is incompatible with AFL_LLVM_LAF_*"); + aflcc->cmplog_mode = getenv("AFL_CMPLOG") || getenv("AFL_LLVM_CMPLOG") || getenv("AFL_GCC_CMPLOG"); diff --git a/src/afl-common.c b/src/afl-common.c index 87003b03..6d915b00 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -34,6 +34,7 @@ #endif #include <string.h> #include <strings.h> +#include <time.h> #include <math.h> #include <sys/mman.h> @@ -58,6 +59,27 @@ u8 last_intr = 0; #define AFL_PATH "/usr/local/lib/afl/" #endif +/* - Some BSD (i.e.: FreeBSD) offer the FAST clock source as + * equivalent to Linux COARSE clock source. Aliasing COARSE to + * FAST on such systems when COARSE is not already defined. + * - macOS has no support of CLOCK_MONOTONIC_COARSE clock type. + */ +#if defined(OS_DARWIN) || defined(OS_SUNOS) || defined(__APPLE__) || \ + defined(__sun) || defined(__NetBSD__) + #define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC +#elif defined(OS_FREEBSD) + #define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC_FAST +#endif + +/* Convert seconds to milliseconds. */ +#define SEC_TO_MS(sec) ((sec) * 1000) +/* Convert seconds to microseconds. */ +#define SEC_TO_US(sec) ((sec) * 1000000) +/* Convert nanoseconds to milliseconds. */ +#define NS_TO_MS(ns) ((ns) / 1000000) +/* Convert nanoseconds to microseconds. */ +#define NS_TO_US(ns) ((ns) / 1000) + void *afl_memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) { @@ -974,12 +996,16 @@ void read_bitmap(u8 *fname, u8 *map, size_t len) { inline u64 get_cur_time(void) { - struct timeval tv; - struct timezone tz; + struct timespec ts; + int rc = clock_gettime(CLOCK_MONOTONIC_COARSE, &ts); + if (rc == -1) { - gettimeofday(&tv, &tz); + PFATAL("Failed to obtain timestamp (errno = %i: %s)\n", errno, + strerror(errno)); - return (tv.tv_sec * 1000ULL) + (tv.tv_usec / 1000); + } + + return SEC_TO_MS((uint64_t)ts.tv_sec) + NS_TO_MS((uint64_t)ts.tv_nsec); } @@ -987,12 +1013,16 @@ inline u64 get_cur_time(void) { u64 get_cur_time_us(void) { - struct timeval tv; - struct timezone tz; + struct timespec ts; + int rc = clock_gettime(CLOCK_MONOTONIC_COARSE, &ts); + if (rc == -1) { - gettimeofday(&tv, &tz); + PFATAL("Failed to obtain timestamp (errno = %i: %s)\n", errno, + strerror(errno)); + + } - return (tv.tv_sec * 1000000ULL) + tv.tv_usec; + return SEC_TO_US((uint64_t)ts.tv_sec) + NS_TO_US((uint64_t)ts.tv_nsec); } diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index cf5c511e..f28a2a64 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -1111,8 +1111,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, } - if ((status & FS_NEW_OPT_SHDMEM_FUZZ) && fsrv->add_extra_func && - !ignore_autodict) { + if (status & FS_NEW_OPT_SHDMEM_FUZZ) { if (fsrv->support_shmem_fuzz) { @@ -1129,7 +1128,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, } - if ((status & FS_NEW_OPT_AUTODICT)) { + if (status & FS_NEW_OPT_AUTODICT) { // even if we do not need the dictionary we have to read it @@ -1875,7 +1874,7 @@ afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, territory. */ #ifdef __linux__ - if (!fsrv->nyx_mode) { + if (likely(!fsrv->nyx_mode)) { memset(fsrv->trace_bits, 0, fsrv->map_size); MEM_BARRIER(); diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index d764952c..edcddc8e 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -409,6 +409,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, u32 use_tmout = afl->fsrv.exec_tmout; u8 *old_sn = afl->stage_name; + u64 calibration_start_us = get_cur_time_us(); if (unlikely(afl->shm.cmplog_mode)) { q->exec_cksum = 0; } /* Be a bit more generous about timeouts when resuming sessions, or when @@ -504,6 +505,10 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, fault = fuzz_run_target(afl, &afl->fsrv, use_tmout); + // update the time spend in calibration after each execution, as those may + // be slow + update_calibration_time(afl, &calibration_start_us); + /* afl->stop_soon is set by the handler for Ctrl+C. When it's pressed, we want to bail out quickly. */ @@ -650,6 +655,7 @@ abort_calibration: if (!first_run) { show_stats(afl); } + update_calibration_time(afl, &calibration_start_us); return fault; } @@ -669,11 +675,16 @@ void sync_fuzzers(afl_state_t *afl) { afl->stage_max = afl->stage_cur = 0; afl->cur_depth = 0; + u64 sync_start_us = get_cur_time_us(); /* Look at the entries created for every other fuzzer in the sync directory. */ while ((sd_ent = readdir(sd))) { + // since sync can take substantial amounts of time, update time spend every + // iteration + update_sync_time(afl, &sync_start_us); + u8 qd_synced_path[PATH_MAX], qd_path[PATH_MAX]; u32 min_accept = 0, next_min_accept = 0; @@ -811,7 +822,7 @@ void sync_fuzzers(afl_state_t *afl) { /* See what happens. We rely on save_if_interesting() to catch major errors and save the test case. */ - (void)write_to_testcase(afl, (void **)&mem, st.st_size, 1); + u32 new_len = write_to_testcase(afl, (void **)&mem, st.st_size, 1); fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout); @@ -819,7 +830,7 @@ void sync_fuzzers(afl_state_t *afl) { afl->syncing_party = sd_ent->d_name; afl->queued_imported += - save_if_interesting(afl, mem, st.st_size, fault); + save_if_interesting(afl, mem, new_len, fault); afl->syncing_party = 0; munmap(mem, st.st_size); @@ -861,6 +872,9 @@ void sync_fuzzers(afl_state_t *afl) { if (afl->foreign_sync_cnt) read_foreign_testcases(afl, 0); + // add time in sync one last time + update_sync_time(afl, &sync_start_us); + afl->last_sync_time = get_cur_time(); afl->last_sync_cycle = afl->queue_cycle; @@ -872,8 +886,9 @@ void sync_fuzzers(afl_state_t *afl) { u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { + u8 needs_write = 0, fault = 0; u32 orig_len = q->len; - + u64 trim_start_us = get_cur_time_us(); /* Custom mutator trimmer */ if (afl->custom_mutators_count) { @@ -897,11 +912,15 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { } - if (custom_trimmed) return trimmed_case; + if (custom_trimmed) { + + fault = trimmed_case; + goto abort_trimming; + + } } - u8 needs_write = 0, fault = 0; u32 trim_exec = 0; u32 remove_len; u32 len_p2; @@ -912,7 +931,12 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { detected, it will still work to some extent, so we don't check for this. */ - if (unlikely(q->len < 5)) { return 0; } + if (unlikely(q->len < 5)) { + + fault = 0; + goto abort_trimming; + + } afl->stage_name = afl->stage_name_buf; afl->bytes_trim_in += q->len; @@ -946,6 +970,8 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout); + update_trim_time(afl, &trim_start_us); + if (afl->stop_soon || fault == FSRV_RUN_ERROR) { goto abort_trimming; } /* Note that we don't keep track of crashes or hangs here; maybe TODO? @@ -972,7 +998,6 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { /* Let's save a clean trace, which will be needed by update_bitmap_score once we're done with the trimming stuff. */ - if (!needs_write) { needs_write = 1; @@ -987,7 +1012,6 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { } /* Since this can be slow, update the screen every now and then. */ - if (!(trim_exec++ % afl->stats_update_freq)) { show_stats(afl); } ++afl->stage_cur; @@ -1039,8 +1063,9 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { } abort_trimming: - afl->bytes_trim_out += q->len; + update_trim_time(afl, &trim_start_us); + return fault; } diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index ae327117..c61f00bd 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -28,10 +28,6 @@ #include "afl-fuzz.h" #include "envs.h" -s8 interesting_8[] = {INTERESTING_8}; -s16 interesting_16[] = {INTERESTING_8, INTERESTING_16}; -s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32}; - char *power_names[POWER_SCHEDULES_NUM] = {"explore", "mmopt", "exploit", "fast", "coe", "lin", "quad", "rare", "seek"}; diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index b6900506..7e1a3b92 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -133,6 +133,12 @@ void write_setup_file(afl_state_t *afl, u32 argc, char **argv) { } +static bool starts_with(char *key, char *line) { + + return strncmp(key, line, strlen(key)) == 0; + +} + /* load some of the existing stats file when resuming.*/ void load_stats_file(afl_state_t *afl) { @@ -175,58 +181,84 @@ void load_stats_file(afl_state_t *afl) { strcpy(keystring, lstartptr); lptr++; char *nptr; - switch (lineno) { - - case 3: - if (!strcmp(keystring, "run_time ")) - afl->prev_run_time = 1000 * strtoull(lptr, &nptr, 10); - break; - case 5: - if (!strcmp(keystring, "cycles_done ")) - afl->queue_cycle = - strtoull(lptr, &nptr, 10) ? strtoull(lptr, &nptr, 10) + 1 : 0; - break; - case 7: - if (!strcmp(keystring, "execs_done ")) - afl->fsrv.total_execs = strtoull(lptr, &nptr, 10); - break; - case 10: - if (!strcmp(keystring, "corpus_count ")) { - - u32 corpus_count = strtoul(lptr, &nptr, 10); - if (corpus_count != afl->queued_items) { - - WARNF( - "queue/ has been modified -- things might not work, you're " - "on your own!"); - - } - - } - - break; - case 12: - if (!strcmp(keystring, "corpus_found ")) - afl->queued_discovered = strtoul(lptr, &nptr, 10); - break; - case 13: - if (!strcmp(keystring, "corpus_imported ")) - afl->queued_imported = strtoul(lptr, &nptr, 10); - break; - case 14: - if (!strcmp(keystring, "max_depth ")) - afl->max_depth = strtoul(lptr, &nptr, 10); - break; - case 21: - if (!strcmp(keystring, "saved_crashes ")) - afl->saved_crashes = strtoull(lptr, &nptr, 10); - break; - case 22: - if (!strcmp(keystring, "saved_hangs ")) - afl->saved_hangs = strtoull(lptr, &nptr, 10); - break; - default: - break; + if (starts_with("run_time", keystring)) { + + afl->prev_run_time = 1000 * strtoull(lptr, &nptr, 10); + + } + + if (starts_with("cycles_done", keystring)) { + + afl->queue_cycle = + strtoull(lptr, &nptr, 10) ? strtoull(lptr, &nptr, 10) + 1 : 0; + + } + + if (starts_with("calibration_time", keystring)) { + + afl->calibration_time_us = strtoull(lptr, &nptr, 10) * 1000000; + + } + + if (starts_with("sync_time", keystring)) { + + afl->sync_time_us = strtoull(lptr, &nptr, 10) * 1000000; + + } + + if (starts_with("trim_time", keystring)) { + + afl->trim_time_us = strtoull(lptr, &nptr, 10) * 1000000; + + } + + if (starts_with("execs_done", keystring)) { + + afl->fsrv.total_execs = strtoull(lptr, &nptr, 10); + + } + + if (starts_with("corpus_count", keystring)) { + + u32 corpus_count = strtoul(lptr, &nptr, 10); + if (corpus_count != afl->queued_items) { + + WARNF( + "queue/ has been modified -- things might not work, you're " + "on your own!"); + sleep(3); + + } + + } + + if (starts_with("corpus_found", keystring)) { + + afl->queued_discovered = strtoul(lptr, &nptr, 10); + + } + + if (starts_with("corpus_imported", keystring)) { + + afl->queued_imported = strtoul(lptr, &nptr, 10); + + } + + if (starts_with("max_depth", keystring)) { + + afl->max_depth = strtoul(lptr, &nptr, 10); + + } + + if (starts_with("saved_crashes", keystring)) { + + afl->saved_crashes = strtoull(lptr, &nptr, 10); + + } + + if (starts_with("saved_hangs", keystring)) { + + afl->saved_hangs = strtoull(lptr, &nptr, 10); } @@ -300,6 +332,10 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg, "cycles_done : %llu\n" "cycles_wo_finds : %llu\n" "time_wo_finds : %llu\n" + "fuzz_time : %llu\n" + "calibration_time : %llu\n" + "sync_time : %llu\n" + "trim_time : %llu\n" "execs_done : %llu\n" "execs_per_sec : %0.02f\n" "execs_ps_last_min : %0.02f\n" @@ -337,7 +373,7 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg, "\n" "target_mode : %s%s%s%s%s%s%s%s%s%s\n" "command_line : %s\n", - (afl->start_time - afl->prev_run_time) / 1000, cur_time / 1000, + (afl->start_time /*- afl->prev_run_time*/) / 1000, cur_time / 1000, runtime / 1000, (u32)getpid(), afl->queue_cycle ? (afl->queue_cycle - 1) : 0, afl->cycles_wo_finds, afl->longest_find_time > cur_time - afl->last_find_time @@ -345,7 +381,13 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg, : ((afl->start_time == 0 || afl->last_find_time == 0) ? 0 : (cur_time - afl->last_find_time) / 1000), - afl->fsrv.total_execs, afl->fsrv.total_execs / ((double)(runtime) / 1000), + (runtime - + (afl->calibration_time_us + afl->sync_time_us + afl->trim_time_us) / + 1000) / + 1000, + afl->calibration_time_us / 1000000, afl->sync_time_us / 1000000, + afl->trim_time_us / 1000000, afl->fsrv.total_execs, + afl->fsrv.total_execs / ((double)(runtime) / 1000), afl->last_avg_execs_saved, afl->queued_items, afl->queued_favored, afl->queued_discovered, afl->queued_imported, afl->queued_variable, afl->max_depth, afl->current_entry, afl->pending_favored, @@ -876,6 +918,10 @@ void show_stats_normal(afl_state_t *afl) { #endif + if (banner_pad) + for (u32 i = 0; i < banner_pad; ++i) + strcat(banner, " "); + } SAYF("\n%s\n", banner); @@ -2435,3 +2481,27 @@ void show_init_stats(afl_state_t *afl) { } +void update_calibration_time(afl_state_t *afl, u64 *time) { + + u64 cur = get_cur_time_us(); + afl->calibration_time_us += cur - *time; + *time = cur; + +} + +void update_trim_time(afl_state_t *afl, u64 *time) { + + u64 cur = get_cur_time_us(); + afl->trim_time_us += cur - *time; + *time = cur; + +} + +void update_sync_time(afl_state_t *afl, u64 *time) { + + u64 cur = get_cur_time_us(); + afl->sync_time_us += cur - *time; + *time = cur; + +} + diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 443d93b0..00d24ab1 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -5,8 +5,9 @@ Originally written by Michal Zalewski Now maintained by Marc Heuse <mh@mh-sec.de>, - Heiko Eißfeldt <heiko.eissfeldt@hexco.de> and - Andrea Fioraldi <andreafioraldi@gmail.com> + Dominik Meier <mail@dmnk.co>, + Andrea Fioraldi <andreafioraldi@gmail.com>, and + Heiko Eissfeldt <heiko.eissfeldt@hexco.de> Copyright 2016, 2017 Google Inc. All rights reserved. Copyright 2019-2024 AFLplusplus Project. All rights reserved. @@ -199,7 +200,8 @@ static void usage(u8 *argv0, int more_help) { "Test settings:\n" " -s seed - use a fixed seed for the RNG\n" - " -V seconds - fuzz for a specified time then terminate\n" + " -V seconds - fuzz for a specified time then terminate (fuzz time " + "only!)\n" " -E execs - fuzz for an approx. no. of total executions then " "terminate\n" " Note: not precise and can have several more " @@ -2073,6 +2075,17 @@ int main(int argc, char **argv_orig, char **envp) { } + /* Simply code if AFL_TMPDIR is used or not */ + if (!afl->afl_env.afl_tmpdir) { + + afl->tmp_dir = afl->out_dir; + + } else { + + afl->tmp_dir = afl->afl_env.afl_tmpdir; + + } + write_setup_file(afl, argc, argv); setup_cmdline_file(afl, argv + optind); @@ -2085,8 +2098,7 @@ int main(int argc, char **argv_orig, char **envp) { if (!afl->timeout_given) { find_timeout(afl); } // only for resumes! - if ((afl->tmp_dir = afl->afl_env.afl_tmpdir) != NULL && - !afl->in_place_resume) { + if (afl->afl_env.afl_tmpdir && !afl->in_place_resume) { char tmpfile[PATH_MAX]; @@ -2111,10 +2123,6 @@ int main(int argc, char **argv_orig, char **envp) { } - } else { - - afl->tmp_dir = afl->out_dir; - } /* If we don't have a file name chosen yet, use a safe default. */ @@ -2537,8 +2545,6 @@ int main(int argc, char **argv_orig, char **envp) { } // (void)nice(-20); // does not improve the speed - // real start time, we reset, so this works correctly with -V - afl->start_time = get_cur_time(); #ifdef INTROSPECTION u32 prev_saved_crashes = 0, prev_saved_tmouts = 0; @@ -2559,6 +2565,9 @@ int main(int argc, char **argv_orig, char **envp) { OKF("Writing mutation introspection to '%s'", ifn); #endif + // real start time, we reset, so this works correctly with -V + afl->start_time = get_cur_time(); + while (likely(!afl->stop_soon)) { cull_queue(afl); @@ -2579,6 +2588,13 @@ int main(int argc, char **argv_orig, char **envp) { sync_fuzzers(afl); + if (!afl->queue_cycle && afl->afl_env.afl_import_first) { + + // real start time, we reset, so this works correctly with -V + afl->start_time = get_cur_time(); + + } + } ++afl->queue_cycle; @@ -3068,7 +3084,7 @@ stop_fuzzing: afl_fsrv_deinit(&afl->fsrv); /* remove tmpfile */ - if (afl->tmp_dir != NULL && !afl->in_place_resume && afl->fsrv.out_file) { + if (!afl->in_place_resume && afl->fsrv.out_file) { (void)unlink(afl->fsrv.out_file); diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 4e5dab41..994174ed 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -82,6 +82,8 @@ static u8 crash_mode, /* Crash-centric mode? */ remove_shm = 1, /* remove shmem on exit? */ debug; /* debug mode */ +static u32 del_len_limit = 1; /* Minimum block deletion length */ + static volatile u8 stop_soon; /* Ctrl-C pressed? */ static afl_forkserver_t *fsrv; @@ -480,7 +482,7 @@ next_del_blksize: } - if (del_len > 1 && in_len >= 1) { + if (del_len > del_len_limit && in_len >= 1) { del_len /= 2; goto next_del_blksize; @@ -796,8 +798,9 @@ static void usage(u8 *argv0) { "Minimization settings:\n" " -e - solve for edge coverage only, ignore hit counts\n" - " -x - treat non-zero exit codes as crashes\n\n" - " -H - minimize a hang (hang mode)\n" + " -l bytes - set minimum block deletion length to speed up minimization\n" + " -x - treat non-zero exit codes as crashes\n" + " -H - minimize a hang (hang mode)\n\n" "For additional tips, please consult %s/README.md.\n\n" @@ -829,8 +832,9 @@ static void usage(u8 *argv0) { int main(int argc, char **argv_orig, char **envp) { - s32 opt; - u8 mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0; + s32 opt; + u8 mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0, + del_limit_given = 0; char **use_argv; char **argv = argv_cpy_dup(argc, argv_orig); @@ -846,7 +850,7 @@ int main(int argc, char **argv_orig, char **envp) { SAYF(cCYA "afl-tmin" VERSION cRST " by Michal Zalewski\n"); - while ((opt = getopt(argc, argv, "+i:o:f:m:t:B:xeAOQUWXYHh")) > 0) { + while ((opt = getopt(argc, argv, "+i:o:f:m:t:l:B:xeAOQUWXYHh")) > 0) { switch (opt) { @@ -1055,6 +1059,24 @@ int main(int argc, char **argv_orig, char **envp) { read_bitmap(optarg, mask_bitmap, map_size); break; + case 'l': + if (del_limit_given) { FATAL("Multiple -l options not supported"); } + del_limit_given = 1; + + if (!optarg) { FATAL("Wrong usage of -l"); } + + if (optarg[0] == '-') { FATAL("Dangerously low value of -l"); } + + del_len_limit = atoi(optarg); + + if (del_len_limit < 1 || del_len_limit > TMIN_MAX_FILE) { + + FATAL("Value of -l out of range between 1 and TMIN_MAX_FILE"); + + } + + break; + case 'h': usage(argv[0]); return -1; diff --git a/unicorn_mode/helper_scripts/unicorn_dumper_gdb.py b/unicorn_mode/helper_scripts/unicorn_dumper_gdb.py index 1ac4c9f3..a202ac0e 100644 --- a/unicorn_mode/helper_scripts/unicorn_dumper_gdb.py +++ b/unicorn_mode/helper_scripts/unicorn_dumper_gdb.py @@ -89,8 +89,8 @@ def dump_arch_info(): def dump_regs(): reg_state = {} - for reg in current_arch.all_registers: - reg_val = get_register(reg) + for reg in gef.arch.registers: + reg_val = gef.arch.register(reg) reg_state[reg.strip().strip("$")] = reg_val return reg_state @@ -101,7 +101,9 @@ def dump_process_memory(output_dir): final_segment_list = [] # GEF: - vmmap = get_process_maps() + vmmap = gef.memory.maps + memory = GefMemoryManager() + if not vmmap: print("No address mapping information found") return final_segment_list @@ -126,7 +128,7 @@ def dump_process_memory(output_dir): if entry.is_readable() and not "(deleted)" in entry.path: try: # Compress and dump the content to a file - seg_content = read_memory(entry.page_start, entry.size) + seg_content = memory.read(entry.page_start, entry.size) if seg_content == None: print( "Segment empty: @0x{0:016x} (size:UNKNOWN) {1}".format( |