From 82c05630ba201bfc631e4e2335c6d8c2e76d91c0 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 1 Mar 2021 10:12:42 +0100 Subject: 3.11a init --- include/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/config.h b/include/config.h index c583f23b..a3aa9a4a 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 "++3.10c" +#define VERSION "++3.11a" /****************************************************** * * -- cgit 1.4.1 From 108e588e888df5c2679600ea49846a565bac23f9 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 2 Mar 2021 17:46:43 +0100 Subject: add de-unicoded dictionary entries --- docs/Changelog.md | 2 + include/afl-fuzz.h | 1 + src/afl-fuzz-extras.c | 149 ++++++++++++++++++++++++++++++++++++++++++-------- src/afl-fuzz.c | 7 ++- 4 files changed, 134 insertions(+), 25 deletions(-) (limited to 'include') diff --git a/docs/Changelog.md b/docs/Changelog.md index 01240b2a..376f5f06 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -9,6 +9,8 @@ Want to stay in the loop on major new features? Join our mailing list by sending a mail to . ### Version ++3.11a (dev) + - afl-fuzz + - add non-unicode variants from unicode-looking dictionary entries - afl-cc - fixed for a crash that can occur with ASAN + CMPLOG together plus better support for unicode (thanks to @stbergmann for reporting!) diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 3531d672..5003b563 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -1062,6 +1062,7 @@ u8 has_new_bits_unclassified(afl_state_t *, u8 *); void load_extras_file(afl_state_t *, u8 *, u32 *, u32 *, u32); void load_extras(afl_state_t *, u8 *); void dedup_extras(afl_state_t *); +void deunicode_extras(afl_state_t *); void add_extra(afl_state_t *afl, u8 *mem, u32 len); void maybe_add_auto(afl_state_t *, u8 *, u32); void save_auto(afl_state_t *); diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c index 7ecad233..52100fa1 100644 --- a/src/afl-fuzz-extras.c +++ b/src/afl-fuzz-extras.c @@ -387,6 +387,130 @@ static inline u8 memcmp_nocase(u8 *m1, u8 *m2, u32 len) { } +/* add an extra/dict/token - no checks performed, no sorting */ + +static void add_extra_nocheck(afl_state_t *afl, u8 *mem, u32 len) { + + afl->extras = afl_realloc((void **)&afl->extras, + (afl->extras_cnt + 1) * sizeof(struct extra_data)); + + if (unlikely(!afl->extras)) { PFATAL("alloc"); } + + afl->extras[afl->extras_cnt].data = ck_alloc(len); + afl->extras[afl->extras_cnt].len = len; + memcpy(afl->extras[afl->extras_cnt].data, mem, len); + afl->extras_cnt++; + + /* We only want to print this once */ + + if (afl->extras_cnt == afl->max_det_extras + 1) { + + WARNF("More than %u tokens - will use them probabilistically.", + afl->max_det_extras); + + } + +} + +/* Sometimes strings in input is transformed to unicode internally, so for + fuzzing we should attempt to de-unicode if it looks like simple unicode */ + +void deunicode_extras(afl_state_t *afl) { + + if (!afl->extras_cnt) return; + + u32 i, j, orig_cnt = afl->extras_cnt; + u8 buf[64]; + + for (i = 0; i < orig_cnt; ++i) { + + if (afl->extras[i].len < 6 || afl->extras[i].len > 64 || + afl->extras[i].len % 2) { + + continue; + + } + + u32 k = 0, z1 = 0, z2 = 0, z3 = 0, z4 = 0, half = afl->extras[i].len >> 1; + u32 quarter = half >> 1; + + for (j = 0; j < afl->extras[i].len; ++j) { + + switch (j % 4) { + + case 2: + if (!afl->extras[i].data[j]) { ++z3; } + // fall through + case 0: + if (!afl->extras[i].data[j]) { ++z1; } + break; + case 3: + if (!afl->extras[i].data[j]) { ++z4; } + // fall through + case 1: + if (!afl->extras[i].data[j]) { ++z2; } + break; + + } + + } + + if ((z1 < half && z2 < half) || z1 + z2 == afl->extras[i].len) { continue; } + + // also maybe 32 bit unicode? + if (afl->extras[i].len % 4 == 0 && afl->extras[i].len >= 12 && + (z3 == quarter || z4 == quarter) && z1 + z2 == quarter * 3) { + + for (j = 0; j < afl->extras[i].len; ++j) { + + if (z4 < quarter) { + + if (j % 4 == 3) { buf[k++] = afl->extras[i].data[j]; } + + } else if (z3 < quarter) { + + if (j % 4 == 2) { buf[k++] = afl->extras[i].data[j]; } + + } else if (z2 < half) { + + if (j % 4 == 1) { buf[k++] = afl->extras[i].data[j]; } + + } else { + + if (j % 4 == 0) { buf[k++] = afl->extras[i].data[j]; } + + } + + } + + add_extra_nocheck(afl, buf, k); + k = 0; + + } + + for (j = 0; j < afl->extras[i].len; ++j) { + + if (z1 < half) { + + if (j % 2 == 0) { buf[k++] = afl->extras[i].data[j]; } + + } else { + + if (j % 2 == 1) { buf[k++] = afl->extras[i].data[j]; } + + } + + } + + add_extra_nocheck(afl, buf, k); + + } + + qsort(afl->extras, afl->extras_cnt, sizeof(struct extra_data), + compare_extras_len); + +} + /* Removes duplicates from the loaded extras. This can happen if multiple files are loaded */ @@ -396,9 +520,9 @@ void dedup_extras(afl_state_t *afl) { u32 i, j, orig_cnt = afl->extras_cnt; - for (i = 0; i < afl->extras_cnt - 1; i++) { + for (i = 0; i < afl->extras_cnt - 1; ++i) { - for (j = i + 1; j < afl->extras_cnt; j++) { + for (j = i + 1; j < afl->extras_cnt; ++j) { restart_dedup: @@ -462,30 +586,11 @@ void add_extra(afl_state_t *afl, u8 *mem, u32 len) { } - afl->extras = afl_realloc((void **)&afl->extras, - (afl->extras_cnt + 1) * sizeof(struct extra_data)); - - if (unlikely(!afl->extras)) { PFATAL("alloc"); } - - afl->extras[afl->extras_cnt].data = ck_alloc(len); - afl->extras[afl->extras_cnt].len = len; - - memcpy(afl->extras[afl->extras_cnt].data, mem, len); - - afl->extras_cnt++; + add_extra_nocheck(afl, mem, len); qsort(afl->extras, afl->extras_cnt, sizeof(struct extra_data), compare_extras_len); - /* We only want to print this once */ - - if (afl->extras_cnt == afl->max_det_extras + 1) { - - WARNF("More than %u tokens - will use them probabilistically.", - afl->max_det_extras); - - } - } /* Maybe add automatic extra. */ diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index a02eadb2..90f77919 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1449,9 +1449,6 @@ int main(int argc, char **argv_orig, char **envp) { } - dedup_extras(afl); - OKF("Loaded a total of %u extras.", afl->extras_cnt); - } if (!afl->timeout_given) { find_timeout(afl); } // only for resumes! @@ -1681,6 +1678,10 @@ int main(int argc, char **argv_orig, char **envp) { } + deunicode_extras(afl); + dedup_extras(afl); + if (afl->extras_cnt) { OKF("Loaded a total of %u extras.", afl->extras_cnt); } + // after we have the correct bitmap size we can read the bitmap -B option // and set the virgin maps if (afl->in_bitmap) { -- cgit 1.4.1 From 8bdb40b7631ea0a6f7dec8e51a6c69c6b3c7513d Mon Sep 17 00:00:00 2001 From: realmadsci <71108352+realmadsci@users.noreply.github.com> Date: Tue, 2 Mar 2021 15:28:26 -0500 Subject: cpu-exec: Add AFL_QEMU_EXCLUDE_RANGES This environment variable allows rejection of specific regions from instrumentation. It takes priority over AFL_INST_LIBS and AFL_QEMU_INST_RANGES, so it can be used to poke a "hole" in previously included sections. --- include/envs.h | 1 + qemu_mode/README.md | 7 +++++++ 2 files changed, 8 insertions(+) (limited to 'include') diff --git a/include/envs.h b/include/envs.h index 143979c6..26f4de90 100644 --- a/include/envs.h +++ b/include/envs.h @@ -141,6 +141,7 @@ static char *afl_environment_variables[] = { "AFL_QEMU_PERSISTENT_RETADDR_OFFSET", "AFL_QEMU_PERSISTENT_EXITS", "AFL_QEMU_INST_RANGES", + "AFL_QEMU_EXCLUDE_RANGES", "AFL_QEMU_SNAPSHOT", "AFL_QUIET", "AFL_RANDOM_ALLOC_CANARY", diff --git a/qemu_mode/README.md b/qemu_mode/README.md index bc4c1d2c..a14cbe64 100644 --- a/qemu_mode/README.md +++ b/qemu_mode/README.md @@ -99,6 +99,13 @@ Just set AFL_QEMU_INST_RANGES=A,B,C... The format of the items in the list is either a range of addresses like 0x123-0x321 or a module name like module.so (that is matched in the mapped object filename). +Alternatively you can tell QEMU to ignore part of an address space for instrumentation. + +Just set AFL_QEMU_EXCLUDE_RANGES=A,B,C... + +The format of the items on the list is the same as for AFL_QEMU_INST_RANGES, and excluding ranges +takes priority over any included ranges or AFL_INST_LIBS. + ## 7) CompareCoverage CompareCoverage is a sub-instrumentation with effects similar to laf-intel. -- cgit 1.4.1 From be5274d4a9c7fb835530be5054132253d2559ade Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Thu, 4 Mar 2021 15:12:08 +0100 Subject: fix kctx compilation hang --- include/envs.h | 1 + instrumentation/afl-llvm-pass.so.cc | 13 ++++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/envs.h b/include/envs.h index 26f4de90..e8595ef7 100644 --- a/include/envs.h +++ b/include/envs.h @@ -81,6 +81,7 @@ static char *afl_environment_variables[] = { "AFL_LLVM_CMPLOG", "AFL_LLVM_INSTRIM", "AFL_LLVM_CTX", + "AFL_LLVM_CTX_K", "AFL_LLVM_DICT2FILE", "AFL_LLVM_DOCUMENT_IDS", "AFL_LLVM_INSTRIM_LOOPHEAD", diff --git a/instrumentation/afl-llvm-pass.so.cc b/instrumentation/afl-llvm-pass.so.cc index c58e9d95..fbf55f81 100644 --- a/instrumentation/afl-llvm-pass.so.cc +++ b/instrumentation/afl-llvm-pass.so.cc @@ -363,15 +363,18 @@ bool AFLCoverage::runOnModule(Module &M) { Constant *PrevLocShuffleMask = ConstantVector::get(PrevLocShuffle); + Constant *PrevCallerShuffleMask = NULL; SmallVector PrevCallerShuffle = {UndefValue::get(Int32Ty)}; - for (unsigned I = 0; I < PrevCallerSize - 1; ++I) - PrevCallerShuffle.push_back(ConstantInt::get(Int32Ty, I)); + if (ctx_k) { + for (unsigned I = 0; I < PrevCallerSize - 1; ++I) + PrevCallerShuffle.push_back(ConstantInt::get(Int32Ty, I)); - for (int I = PrevCallerSize; I < PrevCallerVecSize; ++I) - PrevCallerShuffle.push_back(ConstantInt::get(Int32Ty, PrevCallerSize)); + for (int I = PrevCallerSize; I < PrevCallerVecSize; ++I) + PrevCallerShuffle.push_back(ConstantInt::get(Int32Ty, PrevCallerSize)); - Constant *PrevCallerShuffleMask = ConstantVector::get(PrevCallerShuffle); + PrevCallerShuffleMask = ConstantVector::get(PrevCallerShuffle); + } #endif // other constants we need -- cgit 1.4.1 From 47f2650a32470172a32c4ebd446003cb8a4b80e8 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 9 Mar 2021 16:53:56 +0100 Subject: add AFL_NOOPT --- README.md | 17 +++++++++++++---- docs/env_variables.md | 11 +++++++++++ include/envs.h | 4 +++- src/afl-cc.c | 21 +++++++++++++++++++-- src/afl-common.c | 1 + 5 files changed, 47 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/README.md b/README.md index 6b11fee4..d4e39566 100644 --- a/README.md +++ b/README.md @@ -399,10 +399,19 @@ How to do this is described below. Then build the target. (Usually with `make`) -**NOTE**: sometimes configure and build systems are fickle and do not like -stderr output (and think this means a test failure) - which is something -afl++ like to do to show statistics. It is recommended to disable them via -`export AFL_QUIET=1`. +**NOTES** + +1. sometimes configure and build systems are fickle and do not like + stderr output (and think this means a test failure) - which is something + afl++ like to do to show statistics. It is recommended to disable them via + `export AFL_QUIET=1`. + +2. sometimes configure and build systems error on warnings - these should be + disabled (e.g. `--disable-werror` for some configure scripts` + +3. in case the configure/build system complains about afl++'s compiler and + aborts then set `export AFL_NOOPT=1` which will then just behave like the + real compiler. This option has to be unset again before building the target! ##### configure diff --git a/docs/env_variables.md b/docs/env_variables.md index f6ed12d0..a20f1e42 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -26,6 +26,17 @@ Because (with the exception of the --afl-MODE command line option) the compile-time tools do not accept afl specific command-line options, they make fairly broad use of environmental variables instead: + - Some build/configure scripts break with afl++ compilers. To be able to + pass them, do: +``` + export CC=afl-cc + export CXX=afl-c++ + export AFL_NOOPT=1 + ./configure --disable-shared --disabler-werror + unset AFL_NOOPT + make +``` + - Most afl tools do not print any output if stdout/stderr are redirected. If you want to get the output into a file then set the `AFL_DEBUG` environment variable. diff --git a/include/envs.h b/include/envs.h index e8595ef7..37748a56 100644 --- a/include/envs.h +++ b/include/envs.h @@ -119,10 +119,12 @@ static char *afl_environment_variables[] = { "AFL_NO_PYTHON", "AFL_UNTRACER_FILE", "AFL_LLVM_USE_TRACE_PC", - "AFL_NO_X86", // not really an env but we dont want to warn on it "AFL_MAP_SIZE", "AFL_MAPSIZE", "AFL_MAX_DET_EXTRAS", + "AFL_NO_X86", // not really an env but we dont want to warn on it + "AFL_NOOPT", + "AFL_PASSTHROUGH", "AFL_PATH", "AFL_PERFORMANCE_FILE", "AFL_PRELOAD", diff --git a/src/afl-cc.c b/src/afl-cc.c index bb136fb9..8f9bb397 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1025,7 +1025,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { int main(int argc, char **argv, char **envp) { - int i; + int i, passthrough = 0; char *callname = argv[0], *ptr = NULL; if (getenv("AFL_DEBUG")) { @@ -1045,6 +1045,13 @@ int main(int argc, char **argv, char **envp) { } + if (getenv("AFL_PASSTHROUGH") || getenv("AFL_NOOPT")) { + + passthrough = 1; + if (!debug) { be_quiet = 1; } + + } + if ((ptr = strrchr(callname, '/')) != NULL) callname = ptr + 1; argvnull = (u8 *)argv[0]; check_environment_vars(envp); @@ -1665,6 +1672,7 @@ int main(int argc, char **argv, char **envp) { " AFL_DONT_OPTIMIZE: disable optimization instead of -O3\n" " AFL_NO_BUILTIN: no builtins for string compare functions (for " "libtokencap.so)\n" + " AFL_NOOP: behave lik a normal compiler (to pass configure tests)\n" " AFL_PATH: path to instrumenting pass and runtime " "(afl-compiler-rt.*o)\n" " AFL_IGNORE_UNKNOWN_ENVS: don't warn on unknown env vars\n" @@ -1977,7 +1985,16 @@ int main(int argc, char **argv, char **envp) { } - execvp(cc_params[0], (char **)cc_params); + if (passthrough) { + + argv[0] = cc_params[0]; + execvp(cc_params[0], (char **)argv); + + } else { + + execvp(cc_params[0], (char **)cc_params); + + } FATAL("Oops, failed to execute '%s' - check your PATH", cc_params[0]); diff --git a/src/afl-common.c b/src/afl-common.c index a306fe5e..68f82a5e 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -682,6 +682,7 @@ void check_environment_vars(char **envp) { env[strlen(afl_environment_variables[i])] == '=') { match = 1; + if ((val = getenv(afl_environment_variables[i])) && !*val) { WARNF( -- cgit 1.4.1 From 791c5c171d9e4e7391a9c3760a4a8eb4ce2b4058 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 9 Mar 2021 18:44:42 +0100 Subject: fix ctx-1 --- include/envs.h | 1 + instrumentation/afl-llvm-pass.so.cc | 4 ++-- src/afl-cc.c | 29 +++++++++++++++++++++++++---- 3 files changed, 28 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/envs.h b/include/envs.h index 37748a56..4d4d6b0e 100644 --- a/include/envs.h +++ b/include/envs.h @@ -80,6 +80,7 @@ static char *afl_environment_variables[] = { "AFL_LLVM_BLOCKLIST", "AFL_LLVM_CMPLOG", "AFL_LLVM_INSTRIM", + "AFL_LLVM_CALLER", "AFL_LLVM_CTX", "AFL_LLVM_CTX_K", "AFL_LLVM_DICT2FILE", diff --git a/instrumentation/afl-llvm-pass.so.cc b/instrumentation/afl-llvm-pass.so.cc index f4717345..0f773aba 100644 --- a/instrumentation/afl-llvm-pass.so.cc +++ b/instrumentation/afl-llvm-pass.so.cc @@ -217,8 +217,8 @@ bool AFLCoverage::runOnModule(Module &M) { VectorType *PrevCallerTy = NULL; if (ctx_k_str) - if (sscanf(ctx_k_str, "%u", &ctx_k) != 1 || ctx_k < 2 || ctx_k > CTX_MAX_K) - FATAL("Bad value of AFL_CTX_K (must be between 2 and CTX_MAX_K (%u))", + if (sscanf(ctx_k_str, "%u", &ctx_k) != 1 || ctx_k < 1 || ctx_k > CTX_MAX_K) + FATAL("Bad value of AFL_CTX_K (must be between 1 and CTX_MAX_K (%u))", CTX_MAX_K); if (ctx_k == 1) { diff --git a/src/afl-cc.c b/src/afl-cc.c index a517124f..b9e0c101 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1298,11 +1298,21 @@ int main(int argc, char **argv, char **envp) { if (getenv("AFL_LLVM_CTX_K")) { - instrument_opt_mode |= INSTRUMENT_OPT_CTX_K; ctx_k = atoi(getenv("AFL_LLVM_CTX_K")); if (ctx_k < 1 || ctx_k > CTX_MAX_K) FATAL("K-CTX instrumentation mode must be between 1 and CTX_MAX_K (%u)", CTX_MAX_K); + if (ctx_k == 1) { + + setenv("AFL_LLVM_CALLER", "1", 1); + unsetenv("AFL_LLVM_CTX_K"); + instrument_opt_mode |= INSTRUMENT_OPT_CALLER; + + } else { + + instrument_opt_mode |= INSTRUMENT_OPT_CTX_K; + + } } @@ -1422,9 +1432,20 @@ int main(int argc, char **argv, char **envp) { "K-CTX instrumentation option must be between 1 and CTX_MAX_K " "(%u)", CTX_MAX_K); - instrument_opt_mode |= (INSTRUMENT_OPT_CTX_K); - u8 *ptr4 = alloc_printf("%u", ctx_k); - setenv("AFL_LLVM_CTX_K", ptr4, 1); + + if (ctx_k == 1) { + + instrument_opt_mode |= INSTRUMENT_OPT_CALLER; + setenv("AFL_LLVM_CALLER", "1", 1); + unsetenv("AFL_LLVM_CTX_K"); + + } else { + + instrument_opt_mode |= (INSTRUMENT_OPT_CTX_K); + u8 *ptr4 = alloc_printf("%u", ctx_k); + setenv("AFL_LLVM_CTX_K", ptr4, 1); + + } } -- cgit 1.4.1 From 4bd0d4cbaf3a3de63f737ff86df5de0b809f6631 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 10 Mar 2021 15:52:27 +0100 Subject: cmplog finetuning --- include/config.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/config.h b/include/config.h index a3aa9a4a..6ada0fbe 100644 --- a/include/config.h +++ b/include/config.h @@ -54,10 +54,10 @@ /* Number of potential positions from which we decide if cmplog becomes useless, default 8096 */ -#define CMPLOG_POSITIONS_MAX 8096U +#define CMPLOG_POSITIONS_MAX (12 * 1024) /* Maximum allowed fails per CMP value. Default: 128 */ -#define CMPLOG_FAIL_MAX 128 +#define CMPLOG_FAIL_MAX 96 /* Now non-cmplog configuration options */ -- cgit 1.4.1 From ac795ae1e154df87d422eb9a307ee1f40fcb701f Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 15 Mar 2021 23:08:28 +0100 Subject: v3.11c release --- README.md | 4 ++-- docs/Changelog.md | 4 +++- include/config.h | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/README.md b/README.md index 0deaca22..69e5bb74 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ AFL++ Logo - Release Version: [3.10c](https://github.com/AFLplusplus/AFLplusplus/releases) + Release Version: [3.11c](https://github.com/AFLplusplus/AFLplusplus/releases) - Github Version: 3.11a + Github Version: 3.12a Repository: [https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus) diff --git a/docs/Changelog.md b/docs/Changelog.md index 8f3e588c..1c735a70 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -8,9 +8,11 @@ Want to stay in the loop on major new features? Join our mailing list by sending a mail to . -### Version ++3.11a (dev) +### Version ++3.11c (release) - afl-fuzz: + - better auto detection of map size - fix sanitizer settings (bug since 3.10c) + - fix an off-by-one overwrite in cmplog - add non-unicode variants from unicode-looking dictionary entries - Rust custom mutator API improvements - Imported crash stats painted yellow on resume (only new ones are red) diff --git a/include/config.h b/include/config.h index 6ada0fbe..cc8024ea 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 "++3.11a" +#define VERSION "++3.11c" /****************************************************** * * -- cgit 1.4.1