From 3e84d6a2ae7df5f6b9073a91ccc6acef50b45aab Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 27 Apr 2023 11:49:00 +0200
Subject: afl++ -> AFL++
---
docs/Changelog.md | 2 +-
docs/INSTALL.md | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
(limited to 'docs')
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 20b915fa..cd5ed9fc 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -229,7 +229,7 @@
afl-showmap and other tools.
- afl-cc:
- detect overflow reads on initial input buffer for asan
- - new cmplog mode (incompatible with older afl++ versions)
+ - new cmplog mode (incompatible with older AFL++ versions)
- support llvm IR select instrumentation for default PCGUARD and LTO
- fix for shared linking on MacOS
- better selective instrumentation AFL_LLVM_{ALLOW|DENY}LIST
diff --git a/docs/INSTALL.md b/docs/INSTALL.md
index 591b7ded..c54cb9ad 100644
--- a/docs/INSTALL.md
+++ b/docs/INSTALL.md
@@ -51,7 +51,7 @@ make source-only
These build targets exist:
-* all: the main afl++ binaries and llvm/gcc instrumentation
+* all: the main AFL++ binaries and llvm/gcc instrumentation
* binary-only: everything for binary-only fuzzing: frida_mode, nyx_mode,
qemu_mode, frida_mode, unicorn_mode, coresight_mode, libdislocator,
libtokencap
--
cgit 1.4.1
From 5813a4319c88848b2a1c47c12fe27f5e14dcad44 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 28 Apr 2023 11:42:21 +0200
Subject: doc, code format
---
GNUmakefile | 3 ++-
docs/INSTALL.md | 10 ++++------
instrumentation/afl-compiler-rt.o.c | 14 +++++++-------
src/afl-cc.c | 31 +++++++++++++++++++++++--------
4 files changed, 36 insertions(+), 22 deletions(-)
(limited to 'docs')
diff --git a/GNUmakefile b/GNUmakefile
index 5900ad61..56b8bb42 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -379,6 +379,7 @@ help:
@echo Known build environment options:
@echo "=========================================="
@echo STATIC - compile AFL++ static
+ @echo CODE_COVERAGE - compile the target for code coverage (see docs/instrumentation/README.llvm.md)
@echo ASAN_BUILD - compiles AFL++ with memory sanitizer for debug purposes
@echo UBSAN_BUILD - compiles AFL++ tools with undefined behaviour sanitizer for debug purposes
@echo DEBUG - no optimization, -ggdb3, all warnings and -Werror
@@ -394,7 +395,7 @@ help:
@echo AFL_NO_X86 - if compiling on non-intel/amd platforms
@echo "LLVM_CONFIG - if your distro doesn't use the standard name for llvm-config (e.g., Debian)"
@echo "=========================================="
- @echo e.g.: make ASAN_BUILD=1
+ @echo e.g.: make LLVM_CONFIG=llvm-config-16
.PHONY: test_x86
ifndef AFL_NO_X86
diff --git a/docs/INSTALL.md b/docs/INSTALL.md
index c54cb9ad..637e8658 100644
--- a/docs/INSTALL.md
+++ b/docs/INSTALL.md
@@ -79,22 +79,20 @@ make STATIC=1
These build options exist:
* STATIC - compile AFL++ static
+* CODE_COVERAGE - compile the target for code coverage (see docs/instrumentation/README.llvm.md)
* ASAN_BUILD - compiles AFL++ with memory sanitizer for debug purposes
-* UBSAN_BUILD - compiles AFL++ tools with undefined behaviour sanitizer for
- debug purposes
+* UBSAN_BUILD - compiles AFL++ tools with undefined behaviour sanitizer for debug purposes
* DEBUG - no optimization, -ggdb3, all warnings and -Werror
* LLVM_DEBUG - shows llvm deprecation warnings
* PROFILING - compile afl-fuzz with profiling information
* INTROSPECTION - compile afl-fuzz with mutation introspection
* NO_PYTHON - disable python support
-* NO_SPLICING - disables splicing mutation in afl-fuzz, not recommended for
- normal fuzzing
+* NO_SPLICING - disables splicing mutation in afl-fuzz, not recommended for normal fuzzing
* NO_NYX - disable building nyx mode dependencies
* NO_CORESIGHT - disable building coresight (arm64 only)
* NO_UNICORN_ARM64 - disable building unicorn on arm64
* AFL_NO_X86 - if compiling on non-intel/amd platforms
-* LLVM_CONFIG - if your distro doesn't use the standard name for llvm-config
- (e.g., Debian)
+* LLVM_CONFIG - if your distro doesn't use the standard name for llvm-config (e.g., Debian)
e.g.: `make LLVM_CONFIG=llvm-config-14`
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index 3f8b519b..5372fae0 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -544,12 +544,12 @@ static void __afl_map_shm(void) {
if (__afl_map_size && __afl_map_size > MAP_SIZE) {
- u8 *map_env = (u8 *)getenv("AFL_MAP_SIZE");
- if (!map_env || atoi((char *)map_env) < MAP_SIZE) {
+ u8 *map_env = (u8 *)getenv("AFL_MAP_SIZE");
+ if (!map_env || atoi((char *)map_env) < MAP_SIZE) {
- fprintf(stderr, "FS_ERROR_MAP_SIZE\n");
- send_forkserver_error(FS_ERROR_MAP_SIZE);
- _exit(1);
+ fprintf(stderr, "FS_ERROR_MAP_SIZE\n");
+ send_forkserver_error(FS_ERROR_MAP_SIZE);
+ _exit(1);
}
@@ -561,13 +561,13 @@ static void __afl_map_shm(void) {
if (!__afl_area_ptr || __afl_area_ptr == (void *)-1) {
- if (__afl_map_addr)
+ if (__afl_map_addr)
send_forkserver_error(FS_ERROR_MAP_ADDR);
else
send_forkserver_error(FS_ERROR_SHMAT);
perror("shmat for map");
- _exit(1);
+ _exit(1);
}
diff --git a/src/afl-cc.c b/src/afl-cc.c
index b11a041d..19314555 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -752,15 +752,21 @@ static void edit_params(u32 argc, char **argv, char **envp) {
} else if (instrument_mode == INSTRUMENT_LLVMNATIVE) {
#if LLVM_MAJOR >= 4
- if (instrument_opt_mode & INSTRUMENT_OPT_CODECOV) {
+ if (instrument_opt_mode & INSTRUMENT_OPT_CODECOV) {
+
#if LLVM_MAJOR >= 6
- cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard,bb,no-prune,pc-table";
+ cc_params[cc_par_cnt++] =
+ "-fsanitize-coverage=trace-pc-guard,bb,no-prune,pc-table";
#else
FATAL("pcguard instrumentation with pc-table requires llvm 6.0.1+");
#endif
- } else {
+
+ } else {
+
cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard";
- }
+
+ }
+
#else
FATAL("pcguard instrumentation requires llvm 4.0.1+");
#endif
@@ -1660,13 +1666,17 @@ int main(int argc, char **argv, char **envp) {
instrument_mode = INSTRUMENT_CLASSIC;
lto_mode = 1;
- } else if (!instrument_mode || instrument_mode == INSTRUMENT_AFL)
+ } else if (!instrument_mode || instrument_mode == INSTRUMENT_AFL) {
instrument_mode = INSTRUMENT_AFL;
- else
+
+ } else {
+
FATAL("main instrumentation mode already set with %s",
instrument_mode_string[instrument_mode]);
+ }
+
}
if (strncasecmp(ptr2, "pc-guard", strlen("pc-guard")) == 0 ||
@@ -1695,12 +1705,17 @@ int main(int argc, char **argv, char **envp) {
strncasecmp(ptr2, "llvm-codecov", strlen("llvm-codecov")) == 0) {
if (!instrument_mode || instrument_mode == INSTRUMENT_LLVMNATIVE) {
+
instrument_mode = INSTRUMENT_LLVMNATIVE;
- instrument_opt_mode |= INSTRUMENT_OPT_CODECOV;
- } else
+ instrument_opt_mode |= INSTRUMENT_OPT_CODECOV;
+
+ } else {
+
FATAL("main instrumentation mode already set with %s",
instrument_mode_string[instrument_mode]);
+ }
+
}
if (strncasecmp(ptr2, "cfg", strlen("cfg")) == 0 ||
--
cgit 1.4.1
From ed96f9b209ceed9e0295bd0bce452bd74e797f1f Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 28 Apr 2023 16:02:09 +0200
Subject: add frida mode tutorial
---
docs/tutorials.md | 4 ++++
frida_mode/README.md | 2 ++
2 files changed, 6 insertions(+)
(limited to 'docs')
diff --git a/docs/tutorials.md b/docs/tutorials.md
index 758fddab..342080fd 100644
--- a/docs/tutorials.md
+++ b/docs/tutorials.md
@@ -20,6 +20,10 @@ training, then we can highly recommend the following:
* [https://github.com/antonio-morales/Fuzzing101](https://github.com/antonio-morales/Fuzzing101)
+Here is good workflow description for frida_mode:
+
+* [https://blog.quarkslab.com/android-greybox-fuzzing-with-afl-frida-mode.html](https://blog.quarkslab.com/android-greybox-fuzzing-with-afl-frida-mode.html)
+
If you are interested in fuzzing structured data (where you define what the
structure is), these links have you covered (some are outdated though):
diff --git a/frida_mode/README.md b/frida_mode/README.md
index 49a1fe38..bfca443c 100644
--- a/frida_mode/README.md
+++ b/frida_mode/README.md
@@ -7,6 +7,8 @@ variables.
In FRIDA mode, binary programs are instrumented, similarly to QEMU mode.
+A tutorial can be found at [https://blog.quarkslab.com/android-greybox-fuzzing-with-afl-frida-mode.html](https://blog.quarkslab.com/android-greybox-fuzzing-with-afl-frida-mode.html)
+
## Current progress
As FRIDA mode is new, it is missing a lot of features. The design is such that
--
cgit 1.4.1
From fcab3ec99026e92b688a69de476a0763942a9d67 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 1 May 2023 08:55:37 +0200
Subject: docs
---
docs/FAQ.md | 8 ++++++++
docs/best_practices.md | 5 +++++
2 files changed, 13 insertions(+)
(limited to 'docs')
diff --git a/docs/FAQ.md b/docs/FAQ.md
index 76350c79..8178db46 100644
--- a/docs/FAQ.md
+++ b/docs/FAQ.md
@@ -171,6 +171,14 @@ If you find an interesting or important question missing, submit it via
The more "unstable" edges there are, the harder it is for AFL++ to identify
valid new paths.
+ If you fuzz in persistent mode (`AFL_LOOP` or `LLVMFuzzerTestOneInput()`
+ harnesses, a large number of unstable edges can mean that the target keeps
+ internal state and therefore it is possible that crashes cannot be replayed.
+ In such a case do either **not** fuzz in persistent mode (remove `AFL_LOOP()`
+ from your harness or call `LLVMFuzzerTestOneInput()` harnesses with `@@`),
+ or set a low `AFL_LOOP` value, e.g. 100, and enable `AFL_PERSISTENT_RECORD`
+ in `config.h` with the same value.
+
A value above 90% is usually fine and a value above 80% is also still ok, and
even a value above 20% can still result in successful finds of bugs. However,
it is recommended that for values below 90% or 80% you should take
diff --git a/docs/best_practices.md b/docs/best_practices.md
index 133c645e..459fcaf7 100644
--- a/docs/best_practices.md
+++ b/docs/best_practices.md
@@ -131,6 +131,11 @@ jitter, or is a hash map function etc., then it should not be instrumented.
To be able to exclude these functions (based on AFL++'s measured stability), the
following process will allow to identify functions with variable edges.
+Note that this is only useful for non-persistent targets!
+If a persistent target is unstable whereas when run non-persistent is fine,
+then this means that the target is keeping internal state, which is bad for
+fuzzing. Fuzz such targets **without** persistent mode.
+
Four steps are required to do this and it also requires quite some knowledge of
coding and/or disassembly and is effectively possible only with `afl-clang-fast`
`PCGUARD` and `afl-clang-lto` `LTO` instrumentation.
--
cgit 1.4.1
From 70da0c2e405102dc044cb4bed0f4f1e847c90d0b Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 10 May 2023 16:09:18 +0200
Subject: better tritondse support
---
custom_mutators/aflpp_tritondse/aflpp_tritondse.py | 54 ++++++++++---
docs/custom_mutators.md | 28 +++++++
include/envs.h | 4 +
src/afl-fuzz.c | 91 ++++++++++++++++------
4 files changed, 145 insertions(+), 32 deletions(-)
(limited to 'docs')
diff --git a/custom_mutators/aflpp_tritondse/aflpp_tritondse.py b/custom_mutators/aflpp_tritondse/aflpp_tritondse.py
index 49f67d75..9584b368 100644
--- a/custom_mutators/aflpp_tritondse/aflpp_tritondse.py
+++ b/custom_mutators/aflpp_tritondse/aflpp_tritondse.py
@@ -7,6 +7,7 @@ from tritondse import Config
from tritondse import CoverageStrategy
from tritondse import ProcessState
from tritondse import Program
+from tritondse import CleLoader
from tritondse import Seed
from tritondse import SeedFormat
from tritondse import SymbolicExecutor
@@ -16,7 +17,7 @@ from tritondse import SymbolicExplorator
#logging.basicConfig(level=logging.INFO)
is_debug = False
-out_path = "out/tritondse/queue"
+out_path = ""
input_file = None
prog = None
config = None
@@ -29,28 +30,38 @@ def pre_exec_hook(se: SymbolicExecutor, state: ProcessState):
#logging.info(f"[PRE-EXEC] Processing seed: {se.seed.hash}, \
# ({repr(se.seed.content)})")
global count
- global hasshes
+ global hashes
+ print('DEBUG - prehook')
if se.seed.hash not in hashes:
hashes.add(se.seed.hash)
filename = out_path + "/id:" + f"{count:06}" + "," + se.seed.hash
if not os.path.exists(filename):
+ if is_debug:
+ print('Creating queue input ' + filename)
with open(filename, 'wb') as file:
file.write(se.seed.content)
count += 1
+ else:
+ print('has hash: ' + se.seed.hash)
if input_file:
+ if is_debug:
+ print('Writing to ' + input_file + ' the content: ' + str(se.seed.content))
with open(input_file, 'wb') as file:
file.write(se.seed.content)
+ else:
+ print('no input!')
def init(seed):
global prog
global config
global dse
+ global out_path
global input_file
global is_debug
# Load the program (LIEF-based program loader).
- prog = Program(os.environ['TRITON_DSE_TARGET'])
- # Set the configuration.
+ prog = CleLoader(os.environ['AFL_CUSTOM_INFO_PROGRAM'])
+ # Process other configuration environment variables.
argv = None
try:
foo = os.environ['AFL_DEBUG']
@@ -58,15 +69,42 @@ def init(seed):
except KeyError:
pass
try:
- argv_list = os.environ['TRITON_DSE_TARGET_ARGV']
- argv = argv_list.split()
+ foo = os.environ['AFL_CUSTOM_INFO_OUT']
+ out_path = foo + '/../tritondse/queue'
except KeyError:
pass
try:
- foo = os.environ['TRITON_DSE_TARGET_INPUT']
+ foo = os.environ['AFL_CUSTOM_INFO_PROGRAM_INPUT']
input_file = foo
except KeyError:
pass
+ try:
+ argv_list = os.environ['AFL_CUSTOM_INFO_PROGRAM_ARGV']
+ argv_tmp = [ os.environ['AFL_CUSTOM_INFO_PROGRAM'] ]
+ argv_tmp += argv_list.split()
+ argv = []
+ # now check for @@
+ for item in argv_tmp:
+ if "@@" in item:
+ input_file = out_path + '/../.input'
+ argv.append(input_file)
+ else:
+ argv.append(item)
+ except KeyError:
+ pass
+ # Create the output directory
+ os.makedirs(out_path, exist_ok=True)
+ # Debug
+ if is_debug:
+ print('DEBUG target: ' + os.environ['AFL_CUSTOM_INFO_PROGRAM'])
+ if argv:
+ print('DEBUG argv: ')
+ print(argv)
+ if input_file:
+ print('DEBUG input_file: ' + input_file)
+ print('DEBUG out_path: ' + out_path)
+ print('')
+ # Now set up TritonDSE
config = Config(coverage_strategy = CoverageStrategy.PATH,
debug = is_debug,
pipe_stdout = is_debug,
@@ -79,8 +117,6 @@ def init(seed):
dse = SymbolicExplorator(config, prog)
# Add callbacks.
dse.callback_manager.register_pre_execution_callback(pre_exec_hook)
- # Create the output directory
- os.makedirs(out_path, exist_ok=True)
#def fuzz(buf, add_buf, max_size):
diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md
index a1de479e..3f7e9e6e 100644
--- a/docs/custom_mutators.md
+++ b/docs/custom_mutators.md
@@ -304,6 +304,34 @@ Note: for some distributions, you might also need the package `python[3]-apt`.
In case your setup is different, set the necessary variables like this:
`PYTHON_INCLUDE=/path/to/python/include LDFLAGS=-L/path/to/python/lib make`.
+### Helpers
+
+For C/C++ custom mutators you get a pointer to `afl_state_t *afl` in the
+`afl_custom_init()` which contains all information that you need.
+Note that if you access it, you need to recompile your custom mutator if
+you update AFL++ because the structure might have changed!
+
+For mutators written in Python, Rust, GO, etc. there are a few environment
+variables set to help you to get started:
+
+`AFL_CUSTOM_INFO_PROGRAM` - the program name of the target that is executed.
+If your custom mutator is used with modes like Qemu (`-Q`), this will still
+contain the target program, not afl-qemu-trace.
+
+`AFL_CUSTOM_INFO_PROGRAM_INPUT` - if the `-f` parameter is used with afl-fuzz
+then this value is found in this environment variable.
+
+`AFL_CUSTOM_INFO_PROGRAM_ARGV` - this contains the parameters given to the
+target program and still has the `@@` identifier in there.
+
+Note: If `AFL_CUSTOM_INFO_PROGRAM_INPUT` is empty and `AFL_CUSTOM_INFO_PROGRAM_ARGV`
+is either empty or does not contain `@@` then the target gets the input via
+`stdin`.
+
+`AFL_CUSTOM_INFO_OUT` - This is the output directory for this fuzzer instance,
+so if `afl-fuzz` was called with `-o out -S foobar`, then this will be set to
+`out/foobar`.
+
### Custom Mutator Preparation
For C/C++ mutators, the source code must be compiled as a shared object:
diff --git a/include/envs.h b/include/envs.h
index fe5ee0e3..edfd06e4 100644
--- a/include/envs.h
+++ b/include/envs.h
@@ -37,6 +37,10 @@ static char *afl_environment_variables[] = {
"AFL_CRASH_EXITCODE",
"AFL_CUSTOM_MUTATOR_LIBRARY",
"AFL_CUSTOM_MUTATOR_ONLY",
+ "AFL_CUSTOM_INFO_PROGRAM",
+ "AFL_CUSTOM_INFO_PROGRAM_ARGV",
+ "AFL_CUSTOM_INFO_PROGRAM_INPUT",
+ "AFL_CUSTOM_INFO_OUT",
"AFL_CXX",
"AFL_CYCLE_SCHEDULES",
"AFL_DEBUG",
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index f982258f..4339ddd2 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -1530,29 +1530,6 @@ int main(int argc, char **argv_orig, char **envp) {
}
- if (afl->limit_time_sig > 0 && afl->custom_mutators_count) {
-
- if (afl->custom_only) {
-
- FATAL("Custom mutators are incompatible with MOpt (-L)");
-
- }
-
- u32 custom_fuzz = 0;
- LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
-
- if (el->afl_custom_fuzz) { custom_fuzz = 1; }
-
- });
-
- if (custom_fuzz) {
-
- WARNF("afl_custom_fuzz is incompatible with MOpt (-L)");
-
- }
-
- }
-
if (afl->afl_env.afl_max_det_extras) {
s32 max_det_extras = atoi(afl->afl_env.afl_max_det_extras);
@@ -1827,8 +1804,76 @@ int main(int argc, char **argv_orig, char **envp) {
printf("DEBUG: rand %06d is %u\n", counter, rand_below(afl, 65536));
#endif
+ if (!getenv("AFL_CUSTOM_INFO_PROGRAM")) {
+
+ setenv("AFL_CUSTOM_INFO_PROGRAM", argv[optind], 1);
+
+ }
+
+ if (!getenv("AFL_CUSTOM_INFO_PROGRAM_INPUT") && afl->fsrv.out_file) {
+
+ setenv("AFL_CUSTOM_INFO_PROGRAM_INPUT", afl->fsrv.out_file, 1);
+
+ }
+
+ {
+
+ u8 envbuf[8096] = "", tmpbuf[8096] = "";
+ for (s32 i = optind + 1; i < argc; ++i) {
+
+ strcpy(tmpbuf, envbuf);
+ if (strchr(argv[i], ' ') && !strchr(argv[i], '"') &&
+ !strchr(argv[i], '\'')) {
+
+ if (!strchr(argv[i], '\'')) {
+
+ snprintf(envbuf, sizeof(tmpbuf), "%s '%s'", tmpbuf, argv[i]);
+
+ } else {
+
+ snprintf(envbuf, sizeof(tmpbuf), "%s \"%s\"", tmpbuf, argv[i]);
+
+ }
+
+ } else {
+
+ snprintf(envbuf, sizeof(tmpbuf), "%s %s", tmpbuf, argv[i]);
+
+ }
+
+ }
+
+ setenv("AFL_CUSTOM_INFO_PROGRAM_ARGV", envbuf + 1, 1);
+
+ }
+
+ setenv("AFL_CUSTOM_INFO_OUT", afl->out_dir, 1); // same as __AFL_OUT_DIR
+
setup_custom_mutators(afl);
+ if (afl->limit_time_sig > 0 && afl->custom_mutators_count) {
+
+ if (afl->custom_only) {
+
+ FATAL("Custom mutators are incompatible with MOpt (-L)");
+
+ }
+
+ u32 custom_fuzz = 0;
+ LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
+
+ if (el->afl_custom_fuzz) { custom_fuzz = 1; }
+
+ });
+
+ if (custom_fuzz) {
+
+ WARNF("afl_custom_fuzz is incompatible with MOpt (-L)");
+
+ }
+
+ }
+
write_setup_file(afl, argc, argv);
setup_cmdline_file(afl, argv + optind);
--
cgit 1.4.1
From 3a98d7af18e6ebf12e7cce2eb78bdb9b9927be3e Mon Sep 17 00:00:00 2001
From: Dominik Maier
Date: Thu, 11 May 2023 21:02:46 +0200
Subject: qemuafl: Persistent mode for PPC32 targets
---
docs/Changelog.md | 2 ++
qemu_mode/QEMUAFL_VERSION | 2 +-
qemu_mode/qemuafl | 2 +-
3 files changed, 4 insertions(+), 2 deletions(-)
(limited to 'docs')
diff --git a/docs/Changelog.md b/docs/Changelog.md
index cd5ed9fc..1fe714e8 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -18,6 +18,8 @@
- add `-I filelist` option, an alternative to `-i in_dir`
- afl-cmin + afl-cmin.bash:
- `-T threads` parallel task support, can be a huge speedup!
+ - qemuafl:
+ - Persistent mode support for ppc32 tragets by @worksbutnottested
- a new grammar custom mutator atnwalk was submitted by @voidptr127 !
diff --git a/qemu_mode/QEMUAFL_VERSION b/qemu_mode/QEMUAFL_VERSION
index fa44d173..043a9f82 100644
--- a/qemu_mode/QEMUAFL_VERSION
+++ b/qemu_mode/QEMUAFL_VERSION
@@ -1 +1 @@
-0569eff8a1
+b0abbe2
diff --git a/qemu_mode/qemuafl b/qemu_mode/qemuafl
index 0569eff8..b0abbe2e 160000
--- a/qemu_mode/qemuafl
+++ b/qemu_mode/qemuafl
@@ -1 +1 @@
-Subproject commit 0569eff8a12dec73642b96757f6b5b51a618a03a
+Subproject commit b0abbe2e74ed74ff6ff25b5ea3110d27ba978001
--
cgit 1.4.1
From a752b159212db458d77cd13c46fdfbde01045d91 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 12 May 2023 08:29:31 +0200
Subject: update qemu_mode
---
docs/Changelog.md | 4 ++--
qemu_mode/QEMUAFL_VERSION | 2 +-
qemu_mode/qemuafl | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
(limited to 'docs')
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 1fe714e8..e85de763 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -18,8 +18,8 @@
- add `-I filelist` option, an alternative to `-i in_dir`
- afl-cmin + afl-cmin.bash:
- `-T threads` parallel task support, can be a huge speedup!
- - qemuafl:
- - Persistent mode support for ppc32 tragets by @worksbutnottested
+ - qemu_mode:
+ - Persistent mode +QASAN support for ppc32 tragets by @worksbutnottested
- a new grammar custom mutator atnwalk was submitted by @voidptr127 !
diff --git a/qemu_mode/QEMUAFL_VERSION b/qemu_mode/QEMUAFL_VERSION
index 043a9f82..44ea5345 100644
--- a/qemu_mode/QEMUAFL_VERSION
+++ b/qemu_mode/QEMUAFL_VERSION
@@ -1 +1 @@
-b0abbe2
+a1321713c7
diff --git a/qemu_mode/qemuafl b/qemu_mode/qemuafl
index b0abbe2e..a1321713 160000
--- a/qemu_mode/qemuafl
+++ b/qemu_mode/qemuafl
@@ -1 +1 @@
-Subproject commit b0abbe2e74ed74ff6ff25b5ea3110d27ba978001
+Subproject commit a1321713c7502c152dd7527555e0f8a800d55225
--
cgit 1.4.1
From 93c821aaa3df0cf20f892ce72447ff022161c8ab Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 12 May 2023 08:39:11 +0200
Subject: afl-clang-lto incomptable with -flto=thin
---
docs/Changelog.md | 1 +
src/afl-cc.c | 9 +++++++++
2 files changed, 10 insertions(+)
(limited to 'docs')
diff --git a/docs/Changelog.md b/docs/Changelog.md
index e85de763..799c13af 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -13,6 +13,7 @@
- afl-cc:
- new env `AFL_LLVM_LTO_SKIPINIT` to support the AFL++ based WASM
(https://github.com/fgsect/WAFL) project
+ - error and print help if afl-clan-lto is used with lto=thin
- afl-showmap:
- added custom mutator post_process and send support
- add `-I filelist` option, an alternative to `-i in_dir`
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 19314555..13ca751e 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -853,6 +853,15 @@ static void edit_params(u32 argc, char **argv, char **envp) {
if (cur[0] != '-') { non_dash = 1; }
if (!strncmp(cur, "--afl", 5)) continue;
+
+ if (lto_mode && !strncmp(cur, "-flto=thin", 10)) {
+
+ FATAL(
+ "afl-clang-lto cannot work with -flto=thin. Switch to -flto=full or "
+ "use afl-clang-fast!");
+
+ }
+
if (lto_mode && !strncmp(cur, "-fuse-ld=", 9)) continue;
if (lto_mode && !strncmp(cur, "--ld-path=", 10)) continue;
if (!strncmp(cur, "-fno-unroll", 11)) continue;
--
cgit 1.4.1
From 7f636dbfc247fbe75910fa8fb681ea55d230ba79 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 12 May 2023 15:58:20 +0200
Subject: add @responsefile support for afl-cc
---
docs/Changelog.md | 1 +
src/afl-cc.c | 460 +++++++++++++++++++++++++++++++++++-------------------
2 files changed, 300 insertions(+), 161 deletions(-)
(limited to 'docs')
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 799c13af..3602af50 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -11,6 +11,7 @@
- new env `AFL_IGNORE_PROBLEMS_COVERAGE` to ignore coverage from
loaded libs after forkserver initialization (required by Mozilla)
- afl-cc:
+ - added @responsefile support
- new env `AFL_LLVM_LTO_SKIPINIT` to support the AFL++ based WASM
(https://github.com/fgsect/WAFL) project
- error and print help if afl-clan-lto is used with lto=thin
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 13ca751e..972ac8cd 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -31,6 +31,8 @@
#include
#include
#include
+#include
+#include
#if (LLVM_MAJOR - 0 == 0)
#undef LLVM_MAJOR
@@ -376,15 +378,304 @@ void parse_fsanitize(char *string) {
}
+static u8 fortify_set = 0, asan_set = 0, x_set = 0, bit_mode = 0,
+ shared_linking = 0, preprocessor_only = 0, have_unroll = 0,
+ have_o = 0, have_pic = 0, have_c = 0, partial_linking = 0,
+ non_dash = 0;
+
+static void process_params(u32 argc, char **argv) {
+
+ if (cc_par_cnt + argc >= 1024) { FATAL("Too many command line parameters"); }
+
+ if (lto_mode && argc > 1) {
+
+ u32 idx;
+ for (idx = 1; idx < argc; idx++) {
+
+ if (!strncasecmp(argv[idx], "-fpic", 5)) have_pic = 1;
+
+ }
+
+ }
+
+ // for (u32 x = 0; x < argc; ++x) fprintf(stderr, "[%u] %s\n", x, argv[x]);
+
+ /* Process the argument list. */
+
+ u8 skip_next = 0;
+ while (--argc) {
+
+ u8 *cur = *(++argv);
+
+ if (skip_next) {
+
+ skip_next = 0;
+ continue;
+
+ }
+
+ if (cur[0] != '-') { non_dash = 1; }
+ if (!strncmp(cur, "--afl", 5)) continue;
+
+ if (lto_mode && !strncmp(cur, "-flto=thin", 10)) {
+
+ FATAL(
+ "afl-clang-lto cannot work with -flto=thin. Switch to -flto=full or "
+ "use afl-clang-fast!");
+
+ }
+
+ if (lto_mode && !strncmp(cur, "-fuse-ld=", 9)) continue;
+ if (lto_mode && !strncmp(cur, "--ld-path=", 10)) continue;
+ if (!strncmp(cur, "-fno-unroll", 11)) continue;
+ if (strstr(cur, "afl-compiler-rt") || strstr(cur, "afl-llvm-rt")) continue;
+ if (!strcmp(cur, "-Wl,-z,defs") || !strcmp(cur, "-Wl,--no-undefined") ||
+ !strcmp(cur, "--no-undefined")) {
+
+ continue;
+
+ }
+
+ if (compiler_mode == GCC_PLUGIN && !strcmp(cur, "-pipe")) { continue; }
+
+ if (!strcmp(cur, "-z") || !strcmp(cur, "-Wl,-z")) {
+
+ u8 *param = *(argv + 1);
+ if (!strcmp(param, "defs") || !strcmp(param, "-Wl,defs")) {
+
+ skip_next = 1;
+ continue;
+
+ }
+
+ }
+
+ if ((compiler_mode == GCC || compiler_mode == GCC_PLUGIN) &&
+ !strncmp(cur, "-stdlib=", 8)) {
+
+ if (!be_quiet) { WARNF("Found '%s' - stripping!", cur); }
+ continue;
+
+ }
+
+ if (!strncmp(cur, "-fsanitize-coverage-", 20) && strstr(cur, "list=")) {
+
+ have_instr_list = 1;
+
+ }
+
+ if (!strncmp(cur, "-fsanitize=", strlen("-fsanitize=")) &&
+ strchr(cur, ',')) {
+
+ parse_fsanitize(cur);
+ if (!cur || strlen(cur) <= strlen("-fsanitize=")) { continue; }
+
+ } else if ((!strncmp(cur, "-fsanitize=fuzzer-",
+
+ strlen("-fsanitize=fuzzer-")) ||
+ !strncmp(cur, "-fsanitize-coverage",
+ strlen("-fsanitize-coverage"))) &&
+ (strncmp(cur, "sanitize-coverage-allow",
+ strlen("sanitize-coverage-allow")) &&
+ strncmp(cur, "sanitize-coverage-deny",
+ strlen("sanitize-coverage-deny")) &&
+ instrument_mode != INSTRUMENT_LLVMNATIVE)) {
+
+ if (!be_quiet) { WARNF("Found '%s' - stripping!", cur); }
+ continue;
+
+ }
+
+ if (need_aflpplib || !strcmp(cur, "-fsanitize=fuzzer")) {
+
+ u8 *afllib = find_object("libAFLDriver.a", argv[0]);
+
+ if (!be_quiet) {
+
+ OKF("Found '-fsanitize=fuzzer', replacing with libAFLDriver.a");
+
+ }
+
+ if (!afllib) {
+
+ if (!be_quiet) {
+
+ WARNF(
+ "Cannot find 'libAFLDriver.a' to replace '-fsanitize=fuzzer' in "
+ "the flags - this will fail!");
+
+ }
+
+ } else {
+
+ cc_params[cc_par_cnt++] = afllib;
+
+#ifdef __APPLE__
+ cc_params[cc_par_cnt++] = "-undefined";
+ cc_params[cc_par_cnt++] = "dynamic_lookup";
+#endif
+
+ }
+
+ if (need_aflpplib) {
+
+ need_aflpplib = 0;
+
+ } else {
+
+ continue;
+
+ }
+
+ }
+
+ if (!strcmp(cur, "-m32")) bit_mode = 32;
+ if (!strcmp(cur, "armv7a-linux-androideabi")) bit_mode = 32;
+ if (!strcmp(cur, "-m64")) bit_mode = 64;
+
+ if (!strcmp(cur, "-fsanitize=address") || !strcmp(cur, "-fsanitize=memory"))
+ asan_set = 1;
+
+ if (strstr(cur, "FORTIFY_SOURCE")) fortify_set = 1;
+
+ if (!strcmp(cur, "-x")) x_set = 1;
+ if (!strcmp(cur, "-E")) preprocessor_only = 1;
+ if (!strcmp(cur, "-shared")) shared_linking = 1;
+ if (!strcmp(cur, "-dynamiclib")) shared_linking = 1;
+ if (!strcmp(cur, "--target=wasm32-wasi")) passthrough = 1;
+ if (!strcmp(cur, "-Wl,-r")) partial_linking = 1;
+ if (!strcmp(cur, "-Wl,-i")) partial_linking = 1;
+ if (!strcmp(cur, "-Wl,--relocatable")) partial_linking = 1;
+ if (!strcmp(cur, "-r")) partial_linking = 1;
+ if (!strcmp(cur, "--relocatable")) partial_linking = 1;
+ if (!strcmp(cur, "-c")) have_c = 1;
+
+ if (!strncmp(cur, "-O", 2)) have_o = 1;
+ if (!strncmp(cur, "-funroll-loop", 13)) have_unroll = 1;
+
+ if (*cur == '@') {
+
+ // response file support.
+ // we have two choices - move everything to the command line or
+ // rewrite the response files to temporary files and delete them
+ // afterwards. We choose the first for easiness.
+ // We do *not* support quotes in the rsp files to cope with spaces in
+ // filenames etc! If you need that then send a patch!
+ u8 *filename = cur + 1;
+ if (debug) { DEBUGF("response file=%s\n", filename); }
+ FILE *f = fopen(filename, "r");
+ struct stat st;
+
+ // Check not found or empty? let the compiler complain if so.
+ if (!f || fstat(fileno(f), &st) < 0 || st.st_size < 1) {
+
+ cc_params[cc_par_cnt++] = cur;
+ continue;
+
+ }
+
+ u8 *tmpbuf = malloc(st.st_size + 1), *ptr;
+ char **args = malloc(sizeof(char *) * (st.st_size >> 1));
+ int count = 1, cont = 0, cont_act = 0;
+
+ while (fgets(tmpbuf, st.st_size, f)) {
+
+ ptr = tmpbuf;
+ // no leading whitespace
+ while (isspace(*ptr)) {
+
+ ++ptr;
+ cont_act = 0;
+
+ }
+
+ // no comments, no empty lines
+ if (*ptr == '#' || *ptr == '\n' || !*ptr) { continue; }
+ // remove LF
+ if (ptr[strlen(ptr) - 1] == '\n') { ptr[strlen(ptr) - 1] = 0; }
+ // remove CR
+ if (*ptr && ptr[strlen(ptr) - 1] == '\r') { ptr[strlen(ptr) - 1] = 0; }
+ // handle \ at end of line
+ if (*ptr && ptr[strlen(ptr) - 1] == '\\') {
+
+ cont = 1;
+ ptr[strlen(ptr) - 1] = 0;
+
+ }
+
+ // remove whitespace at end
+ while (*ptr && isspace(ptr[strlen(ptr) - 1])) {
+
+ ptr[strlen(ptr) - 1] = 0;
+ cont = 0;
+
+ }
+
+ if (*ptr) {
+
+ do {
+
+ u8 *value = ptr;
+ while (*ptr && !isspace(*ptr)) {
+
+ ++ptr;
+
+ }
+
+ while (*ptr && isspace(*ptr)) {
+
+ *ptr++ = 0;
+
+ }
+
+ if (cont_act) {
+
+ u32 len = strlen(args[count - 1]) + strlen(value) + 1;
+ u8 *tmp = malloc(len);
+ snprintf(tmp, len, "%s%s", args[count - 1], value);
+ free(args[count - 1]);
+ args[count - 1] = tmp;
+ cont_act = 0;
+
+ } else {
+
+ args[count++] = strdup(value);
+
+ }
+
+ } while (*ptr);
+
+ }
+
+ if (cont) {
+
+ cont_act = 1;
+ cont = 0;
+
+ }
+
+ }
+
+ if (count) { process_params(count, args); }
+
+ // we cannot free args[]
+ free(tmpbuf);
+
+ continue;
+
+ }
+
+ cc_params[cc_par_cnt++] = cur;
+
+ }
+
+}
+
/* Copy argv to cc_params, making the necessary edits. */
static void edit_params(u32 argc, char **argv, char **envp) {
- u8 fortify_set = 0, asan_set = 0, x_set = 0, bit_mode = 0, shared_linking = 0,
- preprocessor_only = 0, have_unroll = 0, have_o = 0, have_pic = 0,
- have_c = 0, partial_linking = 0;
-
- cc_params = ck_alloc((argc + 128) * sizeof(u8 *));
+ cc_params = ck_alloc(1024 * sizeof(u8 *));
if (lto_mode) {
@@ -831,168 +1122,15 @@ static void edit_params(u32 argc, char **argv, char **envp) {
}
- if (!have_pic) cc_params[cc_par_cnt++] = "-fPIC";
-
}
}
- /* Detect stray -v calls from ./configure scripts. */
-
- u8 skip_next = 0, non_dash = 0;
- while (--argc) {
-
- u8 *cur = *(++argv);
-
- if (skip_next) {
-
- skip_next = 0;
- continue;
-
- }
-
- if (cur[0] != '-') { non_dash = 1; }
- if (!strncmp(cur, "--afl", 5)) continue;
-
- if (lto_mode && !strncmp(cur, "-flto=thin", 10)) {
-
- FATAL(
- "afl-clang-lto cannot work with -flto=thin. Switch to -flto=full or "
- "use afl-clang-fast!");
-
- }
-
- if (lto_mode && !strncmp(cur, "-fuse-ld=", 9)) continue;
- if (lto_mode && !strncmp(cur, "--ld-path=", 10)) continue;
- if (!strncmp(cur, "-fno-unroll", 11)) continue;
- if (strstr(cur, "afl-compiler-rt") || strstr(cur, "afl-llvm-rt")) continue;
- if (!strcmp(cur, "-Wl,-z,defs") || !strcmp(cur, "-Wl,--no-undefined") ||
- !strcmp(cur, "--no-undefined")) {
-
- continue;
-
- }
+ /* Inspect the command line parameters. */
- if (compiler_mode == GCC_PLUGIN && !strcmp(cur, "-pipe")) { continue; }
-
- if (!strcmp(cur, "-z") || !strcmp(cur, "-Wl,-z")) {
+ process_params(argc, argv);
- u8 *param = *(argv + 1);
- if (!strcmp(param, "defs") || !strcmp(param, "-Wl,defs")) {
-
- skip_next = 1;
- continue;
-
- }
-
- }
-
- if ((compiler_mode == GCC || compiler_mode == GCC_PLUGIN) &&
- !strncmp(cur, "-stdlib=", 8)) {
-
- if (!be_quiet) { WARNF("Found '%s' - stripping!", cur); }
- continue;
-
- }
-
- if (!strncmp(cur, "-fsanitize-coverage-", 20) && strstr(cur, "list=")) {
-
- have_instr_list = 1;
-
- }
-
- if (!strncmp(cur, "-fsanitize=", strlen("-fsanitize=")) &&
- strchr(cur, ',')) {
-
- parse_fsanitize(cur);
- if (!cur || strlen(cur) <= strlen("-fsanitize=")) { continue; }
-
- } else if ((!strncmp(cur, "-fsanitize=fuzzer-",
-
- strlen("-fsanitize=fuzzer-")) ||
- !strncmp(cur, "-fsanitize-coverage",
- strlen("-fsanitize-coverage"))) &&
- (strncmp(cur, "sanitize-coverage-allow",
- strlen("sanitize-coverage-allow")) &&
- strncmp(cur, "sanitize-coverage-deny",
- strlen("sanitize-coverage-deny")) &&
- instrument_mode != INSTRUMENT_LLVMNATIVE)) {
-
- if (!be_quiet) { WARNF("Found '%s' - stripping!", cur); }
- continue;
-
- }
-
- if (need_aflpplib || !strcmp(cur, "-fsanitize=fuzzer")) {
-
- u8 *afllib = find_object("libAFLDriver.a", argv[0]);
-
- if (!be_quiet) {
-
- OKF("Found '-fsanitize=fuzzer', replacing with libAFLDriver.a");
-
- }
-
- if (!afllib) {
-
- if (!be_quiet) {
-
- WARNF(
- "Cannot find 'libAFLDriver.a' to replace '-fsanitize=fuzzer' in "
- "the flags - this will fail!");
-
- }
-
- } else {
-
- cc_params[cc_par_cnt++] = afllib;
-
-#ifdef __APPLE__
- cc_params[cc_par_cnt++] = "-undefined";
- cc_params[cc_par_cnt++] = "dynamic_lookup";
-#endif
-
- }
-
- if (need_aflpplib) {
-
- need_aflpplib = 0;
-
- } else {
-
- continue;
-
- }
-
- }
-
- if (!strcmp(cur, "-m32")) bit_mode = 32;
- if (!strcmp(cur, "armv7a-linux-androideabi")) bit_mode = 32;
- if (!strcmp(cur, "-m64")) bit_mode = 64;
-
- if (!strcmp(cur, "-fsanitize=address") || !strcmp(cur, "-fsanitize=memory"))
- asan_set = 1;
-
- if (strstr(cur, "FORTIFY_SOURCE")) fortify_set = 1;
-
- if (!strcmp(cur, "-x")) x_set = 1;
- if (!strcmp(cur, "-E")) preprocessor_only = 1;
- if (!strcmp(cur, "-shared")) shared_linking = 1;
- if (!strcmp(cur, "-dynamiclib")) shared_linking = 1;
- if (!strcmp(cur, "--target=wasm32-wasi")) passthrough = 1;
- if (!strcmp(cur, "-Wl,-r")) partial_linking = 1;
- if (!strcmp(cur, "-Wl,-i")) partial_linking = 1;
- if (!strcmp(cur, "-Wl,--relocatable")) partial_linking = 1;
- if (!strcmp(cur, "-r")) partial_linking = 1;
- if (!strcmp(cur, "--relocatable")) partial_linking = 1;
- if (!strcmp(cur, "-c")) have_c = 1;
-
- if (!strncmp(cur, "-O", 2)) have_o = 1;
- if (!strncmp(cur, "-funroll-loop", 13)) have_unroll = 1;
-
- cc_params[cc_par_cnt++] = cur;
-
- }
+ if (!have_pic) { cc_params[cc_par_cnt++] = "-fPIC"; }
// in case LLVM is installed not via a package manager or "make install"
// e.g. compiled download or compiled from github then its ./lib directory
--
cgit 1.4.1
From dfdc6fd12cdae1fe2dab1183f20d3c312a7f2f6d Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 16 May 2023 14:54:02 +0200
Subject: add missing envs in the docs
---
docs/env_variables.md | 8 ++++++++
1 file changed, 8 insertions(+)
(limited to 'docs')
diff --git a/docs/env_variables.md b/docs/env_variables.md
index b1f23159..0f0869d2 100644
--- a/docs/env_variables.md
+++ b/docs/env_variables.md
@@ -619,6 +619,14 @@ The QEMU wrapper used to instrument binary-only code supports several settings:
- Setting `AFL_INST_LIBS` causes the translator to also instrument the code
inside any dynamically linked libraries (notably including glibc).
+ - You can use `AFL_QEMU_INST_RANGES=0xaaaa-0xbbbb,0xcccc-0xdddd` to just
+ instrument specific memory locations, e.g. a specific library.
+ Excluding ranges takes priority over any included ranges or `AFL_INST_LIBS`.
+
+ - You can use `AFL_QEMU_EXCLUDE_RANGES=0xaaaa-0xbbbb,0xcccc-0xdddd` to **NOT**
+ instrument specific memory locations, e.g. a specific library.
+ Excluding ranges takes priority over any included ranges or `AFL_INST_LIBS`.
+
- It is possible to set `AFL_INST_RATIO` to skip the instrumentation on some
of the basic blocks, which can be useful when dealing with very complex
binaries.
--
cgit 1.4.1
From 1d0694df86a3ce70ffac2846f36605eac9300abe Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 17 May 2023 15:25:26 +0200
Subject: add symqemu custom mutator
---
custom_mutators/symcc/README.md | 2 +
custom_mutators/symqemu/Makefile | 14 ++
custom_mutators/symqemu/README.md | 11 +
custom_mutators/symqemu/symqemu.c | 446 ++++++++++++++++++++++++++++++++++++++
docs/Changelog.md | 3 +
instrumentation/afl-llvm-common.h | 2 +-
test-instr.c | 9 +-
7 files changed, 483 insertions(+), 4 deletions(-)
create mode 100644 custom_mutators/symqemu/Makefile
create mode 100644 custom_mutators/symqemu/README.md
create mode 100644 custom_mutators/symqemu/symqemu.c
(limited to 'docs')
diff --git a/custom_mutators/symcc/README.md b/custom_mutators/symcc/README.md
index 364a348e..a6839a37 100644
--- a/custom_mutators/symcc/README.md
+++ b/custom_mutators/symcc/README.md
@@ -5,6 +5,8 @@ This uses the symcc to find new paths into the target.
Note that this is a just a proof of concept example! It is better to use
the fuzzing helpers of symcc, symqemu, Fuzzolic, etc. rather than this.
+Also the symqemu custom mutator is better than this.
+
To use this custom mutator follow the steps in the symcc repository
[https://github.com/eurecom-s3/symcc/](https://github.com/eurecom-s3/symcc/)
on how to build symcc and how to instrument a target binary (the same target
diff --git a/custom_mutators/symqemu/Makefile b/custom_mutators/symqemu/Makefile
new file mode 100644
index 00000000..3361ab0f
--- /dev/null
+++ b/custom_mutators/symqemu/Makefile
@@ -0,0 +1,14 @@
+
+ifdef DEBUG
+ CFLAGS += -DDEBUG
+endif
+
+all: symqemu-mutator.so
+
+CFLAGS += -O3 -funroll-loops
+
+symqemu-mutator.so: symqemu.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) -g -I../../include -shared -fPIC -o symqemu-mutator.so symqemu.c
+
+clean:
+ rm -f symqemu-mutator.so *.o *~ core
diff --git a/custom_mutators/symqemu/README.md b/custom_mutators/symqemu/README.md
new file mode 100644
index 00000000..0d5cd4d7
--- /dev/null
+++ b/custom_mutators/symqemu/README.md
@@ -0,0 +1,11 @@
+# custum mutator: symqemu
+
+This uses the symcc to find new paths into the target.
+
+To use this custom mutator follow the steps in the symqemu repository
+[https://github.com/eurecom-s3/symqemu/](https://github.com/eurecom-s3/symqemu/)
+on how to build symqemu-x86_x64 and put it in your `PATH`.
+
+just type `make` to build this custom mutator.
+
+```AFL_CUSTOM_MUTATOR_LIBRARY=custom_mutators/symqemu/symqemu-mutator.so AFL_SYNC_TIME=1 afl-fuzz ...```
diff --git a/custom_mutators/symqemu/symqemu.c b/custom_mutators/symqemu/symqemu.c
new file mode 100644
index 00000000..9030397b
--- /dev/null
+++ b/custom_mutators/symqemu/symqemu.c
@@ -0,0 +1,446 @@
+#define _GNU_SOURCE
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "config.h"
+#include "debug.h"
+#include "afl-fuzz.h"
+#include "common.h"
+
+afl_state_t *afl_struct;
+static u32 debug = 0;
+
+#define DBG(x...) \
+ if (debug) { fprintf(stderr, x); }
+
+typedef struct my_mutator {
+
+ afl_state_t *afl;
+ u8 *mutator_buf;
+ u8 *out_dir;
+ u8 *queue_dir;
+ u8 *target;
+ u8 *symqemu;
+ u8 *input_file;
+ u32 counter;
+ u32 seed;
+ u32 argc;
+ u8 **argv;
+
+} my_mutator_t;
+
+my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
+
+ if (getenv("AFL_DEBUG")) debug = 1;
+
+ my_mutator_t *data = calloc(1, sizeof(my_mutator_t));
+ if (!data) {
+
+ perror("afl_custom_init alloc");
+ return NULL;
+
+ }
+
+ char *path = getenv("PATH");
+ char *exec_name = "symqemu-x86_64";
+ char *token = strtok(path, ":");
+ char exec_path[4096];
+
+ while (token != NULL && data->symqemu == NULL) {
+
+ snprintf(exec_path, sizeof(exec_path), "%s/%s", token, exec_name);
+ if (access(exec_path, X_OK) == 0) {
+
+ data->symqemu = (u8 *)strdup(exec_path);
+ break;
+
+ }
+
+ token = strtok(NULL, ":");
+
+ }
+
+ if (!data->symqemu) FATAL("symqemu binary %s not found", exec_name);
+ DBG("Found %s\n", data->symqemu);
+
+ if (getenv("AFL_CUSTOM_MUTATOR_ONLY"))
+ FATAL("the symqemu module cannot be used with AFL_CUSTOM_MUTATOR_ONLY.");
+
+ if ((data->mutator_buf = malloc(MAX_FILE)) == NULL) {
+
+ free(data);
+ perror("mutator_buf alloc");
+ return NULL;
+
+ }
+
+ data->target = getenv("AFL_CUSTOM_INFO_PROGRAM");
+
+ u8 *path_tmp = getenv("AFL_CUSTOM_INFO_OUT");
+ u32 len = strlen(path_tmp) + 32;
+ u8 *symqemu_path = malloc(len);
+ data->out_dir = malloc(len);
+ data->queue_dir = malloc(len);
+ snprintf(symqemu_path, len, "%s/../symqemu", path_tmp);
+ snprintf(data->out_dir, len, "%s/../symqemu/out", path_tmp);
+ snprintf(data->queue_dir, len, "%s/../symqemu/queue", path_tmp);
+
+ mkdir(symqemu_path, 0755);
+ mkdir(data->out_dir, 0755);
+ mkdir(data->queue_dir, 0755);
+
+ setenv("SYMCC_OUTPUT_DIR", data->out_dir, 1);
+
+ data->input_file = getenv("AFL_CUSTOM_INFO_PROGRAM_INPUT");
+
+ u8 *tmp = NULL;
+ if ((tmp = getenv("AFL_CUSTOM_INFO_PROGRAM_ARGV")) && *tmp) {
+
+ int argc = 0, index = 2;
+ for (u32 i = 0; i < strlen(tmp); ++i)
+ if (isspace(tmp[i])) ++argc;
+
+ data->argv = (u8 **)malloc((argc + 4) * sizeof(u8 **));
+ u8 *p = strdup(tmp);
+
+ do {
+
+ data->argv[index] = p;
+ while (*p && !isspace(*p))
+ ++p;
+ if (*p) {
+
+ *p++ = 0;
+ while (isspace(*p))
+ ++p;
+
+ }
+
+ if (strcmp(data->argv[index], "@@") == 0) {
+
+ if (!data->input_file) {
+
+ u32 ilen = strlen(symqemu_path) + 32;
+ data->input_file = malloc(ilen);
+ snprintf(data->input_file, ilen, "%s/.input", symqemu_path);
+
+ }
+
+ data->argv[index] = data->input_file;
+
+ }
+
+ DBG("%d: %s\n", index, data->argv[index]);
+ index++;
+
+ } while (*p);
+
+ data->argv[index] = NULL;
+ data->argc = index;
+
+ } else {
+
+ data->argv = (u8 **)malloc(8 * sizeof(u8 **));
+ data->argc = 2;
+ data->argv[2] = NULL;
+
+ }
+
+ data->argv[0] = data->symqemu;
+ data->argv[1] = data->target;
+
+ DBG("out_dir=%s, queue_dir=%s, target=%s, input_file=%s, argc=%u\n",
+ data->out_dir, data->queue_dir, data->target,
+ data->input_file ? (char *)data->input_file : (char *)"",
+ data->argc);
+
+ if (data->input_file) { setenv("SYMCC_INPUT_FILE", data->input_file, 1); }
+
+ data->afl = afl;
+ data->seed = seed;
+ afl_struct = afl;
+
+ if (debug) {
+
+ fprintf(stderr, "[");
+ for (u32 i = 0; i <= data->argc; ++i)
+ fprintf(stderr, " \"%s\"",
+ data->argv[i] ? (char *)data->argv[i] : "");
+ fprintf(stderr, " ]\n");
+
+ }
+
+ OKF("Custom mutator symqemu loaded - note that the initial startup of "
+ "afl-fuzz will be delayed the more starting seeds are present. This is "
+ "fine, do not worry!");
+
+ return data;
+
+}
+
+/* When a new queue entry is added we run this input with the symqemu
+ instrumented binary */
+uint8_t afl_custom_queue_new_entry(my_mutator_t *data,
+ const uint8_t *filename_new_queue,
+ const uint8_t *filename_orig_queue) {
+
+ int pipefd[2];
+ struct stat st;
+ if (data->afl->afl_env.afl_no_ui)
+ ACTF("Sending to symqemu: %s", filename_new_queue);
+ u8 *fn = alloc_printf("%s", filename_new_queue);
+ if (!(stat(fn, &st) == 0 && S_ISREG(st.st_mode) && st.st_size)) {
+
+ ck_free(fn);
+ PFATAL("Couldn't find enqueued file: %s", fn);
+
+ }
+
+ if (afl_struct->fsrv.use_stdin) {
+
+ if (pipe(pipefd) == -1) {
+
+ ck_free(fn);
+ PFATAL(
+ "Couldn't create a pipe for interacting with symqemu child process");
+
+ }
+
+ }
+
+ int fd = open(fn, O_RDONLY);
+ if (fd < 0) return 0;
+ ssize_t r = read(fd, data->mutator_buf, MAX_FILE);
+ DBG("fn=%s, fd=%d, size=%ld\n", fn, fd, r);
+ ck_free(fn);
+ close(fd);
+
+ if (data->input_file) {
+
+ fd = open(data->input_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ ssize_t s = write(fd, data->mutator_buf, r);
+ close(fd);
+ DBG("wrote %zd/%zd to %s\n", s, r, data->input_file);
+
+ }
+
+ int pid = fork();
+
+ if (pid == -1) return 0;
+
+ if (pid) {
+
+ if (!data->input_file || afl_struct->fsrv.use_stdin) {
+
+ close(pipefd[0]);
+
+ if (fd >= 0) {
+
+ if (r <= 0) {
+
+ close(pipefd[1]);
+ return 0;
+
+ }
+
+ if (r > fcntl(pipefd[1], F_GETPIPE_SZ))
+ fcntl(pipefd[1], F_SETPIPE_SZ, MAX_FILE);
+ ck_write(pipefd[1], data->mutator_buf, r, filename_new_queue);
+
+ } else {
+
+ ck_free(fn);
+ close(pipefd[1]);
+ PFATAL(
+ "Something happened to the enqueued file before sending its "
+ "contents to symqemu binary");
+
+ }
+
+ close(pipefd[1]);
+
+ }
+
+ pid = waitpid(pid, NULL, 0);
+ DBG("symqemu finished executing!\n");
+
+ // At this point we need to transfer files to output dir, since their names
+ // collide and symqemu will just overwrite them
+
+ struct dirent **nl;
+ int32_t items = scandir(data->out_dir, &nl, NULL, NULL);
+ u8 *origin_name = basename(filename_new_queue);
+ u8 source_name[4096], destination_name[4096];
+ int32_t i;
+
+ if (items > 0) {
+
+ for (i = 0; i < (u32)items; ++i) {
+
+ // symqemu output files start with a digit
+ if (!isdigit(nl[i]->d_name[0])) continue;
+
+ struct stat st;
+ snprintf(source_name, sizeof(source_name), "%s/%s", data->out_dir,
+ nl[i]->d_name);
+ DBG("file=%s\n", source_name);
+
+ if (stat(source_name, &st) == 0 && S_ISREG(st.st_mode) && st.st_size) {
+
+ snprintf(destination_name, sizeof(destination_name), "%s/id:%06u,%s",
+ data->queue_dir, data->counter++, nl[i]->d_name);
+ DBG("src=%s dst=%s\n", source_name, destination_name);
+ rename(source_name, destination_name);
+
+ }
+
+ free(nl[i]);
+
+ }
+
+ free(nl);
+
+ }
+
+ DBG("Done!\n");
+
+ } else /* (pid == 0) */ { // child
+
+ if (afl_struct->fsrv.use_stdin) {
+
+ close(pipefd[1]);
+ dup2(pipefd[0], 0);
+
+ }
+
+ DBG("exec=%s\n", data->target);
+ if (!debug) {
+
+ close(1);
+ close(2);
+ dup2(afl_struct->fsrv.dev_null_fd, 1);
+ dup2(afl_struct->fsrv.dev_null_fd, 2);
+
+ }
+
+ execvp((char *)data->argv[0], (char **)data->argv);
+ fprintf(stderr, "Executing: [");
+ for (u32 i = 0; i <= data->argc; ++i)
+ fprintf(stderr, " \"%s\"",
+ data->argv[i] ? (char *)data->argv[i] : "");
+ fprintf(stderr, " ]\n");
+ FATAL("Failed to execute %s %s\n", data->argv[0], data->argv[1]);
+ exit(-1);
+
+ }
+
+ return 0;
+
+}
+
+/*
+uint32_t afl_custom_fuzz_count(my_mutator_t *data, const u8 *buf,
+ size_t buf_size) {
+
+ uint32_t count = 0, i;
+ struct dirent **nl;
+ int32_t items = scandir(data->out_dir, &nl, NULL, NULL);
+
+ if (items > 0) {
+
+ for (i = 0; i < (u32)items; ++i) {
+
+ struct stat st;
+ u8 * fn = alloc_printf("%s/%s", data->out_dir, nl[i]->d_name);
+ DBG("test=%s\n", fn);
+ if (stat(fn, &st) == 0 && S_ISREG(st.st_mode) && st.st_size) {
+
+ DBG("found=%s\n", fn);
+ count++;
+
+ }
+
+ ck_free(fn);
+ free(nl[i]);
+
+ }
+
+ free(nl);
+
+ }
+
+ DBG("dir=%s, count=%u\n", data->out_dir, count);
+ return count;
+
+}
+
+*/
+
+// here we actually just read the files generated from symqemu
+/*
+size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
+ u8 **out_buf, uint8_t *add_buf, size_t add_buf_size,
+ size_t max_size) {
+
+ struct dirent **nl;
+ int32_t i, done = 0, items = scandir(data->out_dir, &nl, NULL, NULL);
+ ssize_t size = 0;
+
+ if (items <= 0) return 0;
+
+ for (i = 0; i < (u32)items; ++i) {
+
+ struct stat st;
+ u8 * fn = alloc_printf("%s/%s", data->out_dir, nl[i]->d_name);
+
+ if (done == 0) {
+
+ if (stat(fn, &st) == 0 && S_ISREG(st.st_mode) && st.st_size) {
+
+ int fd = open(fn, O_RDONLY);
+
+ if (fd >= 0) {
+
+ size = read(fd, data->mutator_buf, max_size);
+ *out_buf = data->mutator_buf;
+
+ close(fd);
+ done = 1;
+
+ }
+
+ }
+
+ unlink(fn);
+
+ }
+
+ ck_free(fn);
+ free(nl[i]);
+
+ }
+
+ free(nl);
+ DBG("FUZZ size=%lu\n", size);
+ return (uint32_t)size;
+
+}
+
+*/
+
+/**
+ * Deinitialize everything
+ *
+ * @param data The data ptr from afl_custom_init
+ */
+void afl_custom_deinit(my_mutator_t *data) {
+
+ free(data->mutator_buf);
+ free(data);
+
+}
+
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 3602af50..e99747f6 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -23,6 +23,9 @@
- qemu_mode:
- Persistent mode +QASAN support for ppc32 tragets by @worksbutnottested
- a new grammar custom mutator atnwalk was submitted by @voidptr127 !
+ - two new custom mutators are now available:
+ - TritonDSE in custom_mutators/aflpp_tritondse
+ - SymQEMU in custom_mutators/symqemu
### Version ++4.06c (release)
diff --git a/instrumentation/afl-llvm-common.h b/instrumentation/afl-llvm-common.h
index c9324460..23f67179 100644
--- a/instrumentation/afl-llvm-common.h
+++ b/instrumentation/afl-llvm-common.h
@@ -23,7 +23,7 @@ typedef long double max_align_t;
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
#if LLVM_VERSION_MAJOR < 17
-#include "llvm/Transforms/IPO/PassManagerBuilder.h"
+ #include "llvm/Transforms/IPO/PassManagerBuilder.h"
#endif
#if LLVM_VERSION_MAJOR > 3 || \
diff --git a/test-instr.c b/test-instr.c
index 1d9f2e6e..eda5189c 100644
--- a/test-instr.c
+++ b/test-instr.c
@@ -24,7 +24,7 @@
int main(int argc, char **argv) {
- int fd = 0;
+ int fd = 0, cnt;
char buff[8];
char *buf = buff;
@@ -32,7 +32,6 @@ int main(int argc, char **argv) {
if (argc == 2) {
buf = argv[1];
- printf("Input %s - ", buf);
} else {
@@ -47,15 +46,19 @@ int main(int argc, char **argv) {
}
- if (read(fd, buf, sizeof(buf)) < 1) {
+ if ((cnt = read(fd, buf, sizeof(buf) - 1)) < 1) {
printf("Hum?\n");
return 1;
}
+ buf[cnt] = 0;
+
}
+ if (getenv("AFL_DEBUG")) fprintf(stderr, "test-instr: %s\n", buf);
+
// we support three input cases (plus a 4th if stdin is used but there is no
// input)
switch (buf[0]) {
--
cgit 1.4.1
From b08e6bf8c6433adf7d34d0c0025c5cc5672f61ee Mon Sep 17 00:00:00 2001
From: fanquake
Date: Tue, 30 May 2023 15:57:24 +0100
Subject: doc: recommend llvm/clang-14 in docs
Might as well recommend installing 14, as that's newer, and what's used
in Docker.
Also remove outdated Dockerfile versions, likely easier to remove
versions here entirely, and anyone that wants to see what version is
used, can look in the Dockerfile.
---
docs/INSTALL.md | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
(limited to 'docs')
diff --git a/docs/INSTALL.md b/docs/INSTALL.md
index 637e8658..9005a7eb 100644
--- a/docs/INSTALL.md
+++ b/docs/INSTALL.md
@@ -3,9 +3,8 @@
## Linux on x86
An easy way to install AFL++ with everything compiled is available via docker:
-You can use the [Dockerfile](../Dockerfile) (which has gcc-10 and clang-12 -
-hence afl-clang-lto is available) or just pull directly from the Docker Hub
-(for x86_64 and arm64):
+You can use the [Dockerfile](../Dockerfile) or just pull directly from the
+Docker Hub (for x86_64 and arm64):
```shell
docker pull aflplusplus/aflplusplus:
@@ -21,14 +20,14 @@ development state of AFL++.
If you want to build AFL++ yourself, you have many options. The easiest choice
is to build and install everything:
-NOTE: depending on your Debian/Ubuntu/Kali/... release, replace `-12` with
-whatever llvm version is available. We recommend llvm 12, 13 or 14.
+NOTE: depending on your Debian/Ubuntu/Kali/... release, replace `-14` with
+whatever llvm version is available. We recommend llvm 13, 14, 15 or 16.
```shell
sudo apt-get update
sudo apt-get install -y build-essential python3-dev automake cmake git flex bison libglib2.0-dev libpixman-1-dev python3-setuptools cargo libgtk-3-dev
-# try to install llvm 12 and install the distro default if that fails
-sudo apt-get install -y lld-12 llvm-12 llvm-12-dev clang-12 || sudo apt-get install -y lld llvm llvm-dev clang
+# try to install llvm 14 and install the distro default if that fails
+sudo apt-get install -y lld-14 llvm-14 llvm-14-dev clang-14 || sudo apt-get install -y lld llvm llvm-dev clang
sudo apt-get install -y gcc-$(gcc --version|head -n1|sed 's/\..*//'|sed 's/.* //')-plugin-dev libstdc++-$(gcc --version|head -n1|sed 's/\..*//'|sed 's/.* //')-dev
sudo apt-get install -y ninja-build # for QEMU mode
git clone https://github.com/AFLplusplus/AFLplusplus
--
cgit 1.4.1
From 9324f3f6289c62451e2add1f7553a7eda0d7d642 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 1 Jun 2023 12:19:45 +0200
Subject: rewrote PCGUARD
---
GNUmakefile.llvm | 4 +-
TODO.md | 2 -
afl-cmin.bash | 4 +-
docs/Changelog.md | 5 +-
instrumentation/SanitizerCoveragePCGUARD.so.cc | 603 +++++++++----------------
src/afl-cc.c | 31 +-
6 files changed, 249 insertions(+), 400 deletions(-)
(limited to 'docs')
diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm
index 2bb4e7f8..6c68f1f3 100644
--- a/GNUmakefile.llvm
+++ b/GNUmakefile.llvm
@@ -49,7 +49,7 @@ LLVM_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^[
LLVM_TOO_NEW = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[5-9]' && echo 1 || echo 0 )
LLVM_NEW_API = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[0-9]' && echo 1 || echo 0 )
LLVM_NEWER_API = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[6-9]' && echo 1 || echo 0 )
-LLVM_10_OK = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[1-9]|^10\.[1-9]|^10\.0.[1-9]' && echo 1 || echo 0 )
+LLVM_13_OK = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[3-9]' && echo 1 || echo 0 )
LLVM_HAVE_LTO = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[1-9]' && echo 1 || echo 0 )
LLVM_BINDIR = $(shell $(LLVM_CONFIG) --bindir 2>/dev/null)
LLVM_LIBDIR = $(shell $(LLVM_CONFIG) --libdir 2>/dev/null)
@@ -422,7 +422,7 @@ endif
$(CXX) $(CLANG_CPPFL) -Wdeprecated -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) instrumentation/afl-llvm-common.o
./SanitizerCoveragePCGUARD.so: instrumentation/SanitizerCoveragePCGUARD.so.cc instrumentation/afl-llvm-common.o | test_deps
-ifeq "$(LLVM_10_OK)" "1"
+ifeq "$(LLVM_13_OK)" "1"
-$(CXX) $(CLANG_CPPFL) -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) -Wno-deprecated-copy-dtor -Wdeprecated instrumentation/afl-llvm-common.o
endif
diff --git a/TODO.md b/TODO.md
index dc02a914..2b7e8fcf 100644
--- a/TODO.md
+++ b/TODO.md
@@ -2,9 +2,7 @@
## Should
- - redo PCGUARD + LTO for llvm 15+
- test cmplog for less than 16bit
- - splicing selection weighted?
- support persistent and deferred fork server in afl-showmap?
- better autodetection of shifting runtime timeout values
- Update afl->pending_not_fuzzed for MOpt
diff --git a/afl-cmin.bash b/afl-cmin.bash
index d390ff65..dc6d5342 100755
--- a/afl-cmin.bash
+++ b/afl-cmin.bash
@@ -206,7 +206,7 @@ fi
# Check for obvious errors.
-if [ ! "$T_ARG" = "" -a ! "$F_ARG" = "" -a ! "$NYX_MODE" == 1 ]; then
+if [ ! "$T_ARG" = "" -a -n "$F_ARG" -a ! "$NYX_MODE" == 1 ]; then
echo "[-] Error: -T and -f can not be used together." 1>&2
exit 1
fi
@@ -323,7 +323,7 @@ if [ ! "$T_ARG" = "" ]; then
fi
fi
else
- if [ "$F_ARG" = ""]; then
+ if [ -z "$F_ARG" ]; then
echo "[*] Are you aware of the '-T all' parallelize option that massively improves the speed?"
fi
fi
diff --git a/docs/Changelog.md b/docs/Changelog.md
index e99747f6..facf2196 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -15,13 +15,16 @@
- new env `AFL_LLVM_LTO_SKIPINIT` to support the AFL++ based WASM
(https://github.com/fgsect/WAFL) project
- error and print help if afl-clan-lto is used with lto=thin
+ - rewrote our PCGUARD pass to be compatible with LLVM 15+ shenanigans,
+ requires LLVM 13+ now instead of 10.0.1+
+ - fallback to native LLVM PCGUARD if our PCGUARD is unavailable
- afl-showmap:
- added custom mutator post_process and send support
- add `-I filelist` option, an alternative to `-i in_dir`
- afl-cmin + afl-cmin.bash:
- `-T threads` parallel task support, can be a huge speedup!
- qemu_mode:
- - Persistent mode +QASAN support for ppc32 tragets by @worksbutnottested
+ - Persistent mode + QASAN support for ppc32 targets by @worksbutnottested
- a new grammar custom mutator atnwalk was submitted by @voidptr127 !
- two new custom mutators are now available:
- TritonDSE in custom_mutators/aflpp_tritondse
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index 8fed2042..2abc58ec 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -13,42 +13,64 @@
#include "llvm/Transforms/Instrumentation/SanitizerCoverage.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
+#if LLVM_VERSION_MAJOR >= 15
+ #if LLVM_VERSION_MAJOR < 17
+ #include "llvm/ADT/Triple.h"
+ #endif
+#endif
#if LLVM_VERSION_MAJOR < 17
- #include "llvm/ADT/Triple.h"
#include "llvm/Analysis/EHPersonalities.h"
-#else
- #include "llvm/IR/EHPersonalities.h"
#endif
#include "llvm/Analysis/PostDominators.h"
-#include "llvm/IR/CFG.h"
+#if LLVM_VERSION_MAJOR < 15
+ #include "llvm/IR/CFG.h"
+#endif
#include "llvm/IR/Constant.h"
#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/DebugInfo.h"
+#if LLVM_VERSION_MAJOR < 15
+ #include "llvm/IR/DebugInfo.h"
+#endif
#include "llvm/IR/Dominators.h"
+#if LLVM_VERSION_MAJOR >= 17
+ #include "llvm/Analysis/EHPersonalities.h"
+#endif
#include "llvm/IR/Function.h"
-#include "llvm/IR/GlobalVariable.h"
+#if LLVM_VERSION_MAJOR >= 16
+ #include "llvm/IR/GlobalVariable.h"
+#endif
#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/InlineAsm.h"
+#if LLVM_VERSION_MAJOR < 15
+ #include "llvm/IR/InlineAsm.h"
+#endif
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/MDBuilder.h"
-#include "llvm/IR/Mangler.h"
+#if LLVM_VERSION_MAJOR < 15
+ #include "llvm/IR/MDBuilder.h"
+ #include "llvm/IR/Mangler.h"
+#endif
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/Passes/PassBuilder.h"
+#include "llvm/Passes/PassPlugin.h"
#include "llvm/IR/Type.h"
-#include "llvm/InitializePasses.h"
+#if LLVM_VERSION_MAJOR < 17
+ #include "llvm/InitializePasses.h"
+#endif
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/SpecialCaseList.h"
#include "llvm/Support/VirtualFileSystem.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Transforms/Instrumentation.h"
+#if LLVM_VERSION_MAJOR < 15
+ #include "llvm/Support/raw_ostream.h"
+#endif
+#if LLVM_VERSION_MAJOR < 17
+ #include "llvm/Transforms/Instrumentation.h"
+#else
+ #include "llvm/TargetParser/Triple.h"
+#endif
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"
-#include "llvm/Passes/PassPlugin.h"
-#include "llvm/Passes/PassBuilder.h"
-#include "llvm/IR/PassManager.h"
#include "config.h"
#include "debug.h"
@@ -58,7 +80,8 @@ using namespace llvm;
#define DEBUG_TYPE "sancov"
-const char SanCovTracePCIndirName[] = "__sanitizer_cov_trace_pc_indir";
+static const uint64_t SanCtorAndDtorPriority = 2;
+
const char SanCovTracePCName[] = "__sanitizer_cov_trace_pc";
const char SanCovTraceCmp1[] = "__sanitizer_cov_trace_cmp1";
const char SanCovTraceCmp2[] = "__sanitizer_cov_trace_cmp2";
@@ -68,22 +91,13 @@ const char SanCovTraceConstCmp1[] = "__sanitizer_cov_trace_const_cmp1";
const char SanCovTraceConstCmp2[] = "__sanitizer_cov_trace_const_cmp2";
const char SanCovTraceConstCmp4[] = "__sanitizer_cov_trace_const_cmp4";
const char SanCovTraceConstCmp8[] = "__sanitizer_cov_trace_const_cmp8";
-const char SanCovTraceDiv4[] = "__sanitizer_cov_trace_div4";
-const char SanCovTraceDiv8[] = "__sanitizer_cov_trace_div8";
-const char SanCovTraceGep[] = "__sanitizer_cov_trace_gep";
const char SanCovTraceSwitchName[] = "__sanitizer_cov_trace_switch";
+
const char SanCovModuleCtorTracePcGuardName[] =
"sancov.module_ctor_trace_pc_guard";
-const char SanCovModuleCtor8bitCountersName[] =
- "sancov.module_ctor_8bit_counters";
-const char SanCovModuleCtorBoolFlagName[] = "sancov.module_ctor_bool_flag";
-static const uint64_t SanCtorAndDtorPriority = 2;
+const char SanCovTracePCGuardInitName[] = "__sanitizer_cov_trace_pc_guard_init";
const char SanCovTracePCGuardName[] = "__sanitizer_cov_trace_pc_guard";
-const char SanCovTracePCGuardInitName[] = "__sanitizer_cov_trace_pc_guard_init";
-const char SanCov8bitCountersInitName[] = "__sanitizer_cov_8bit_counters_init";
-const char SanCovBoolFlagInitName[] = "__sanitizer_cov_bool_flag_init";
-const char SanCovPCsInitName[] = "__sanitizer_cov_pcs_init";
const char SanCovGuardsSectionName[] = "sancov_guards";
const char SanCovCountersSectionName[] = "sancov_cntrs";
@@ -99,27 +113,9 @@ namespace {
SanitizerCoverageOptions OverrideFromCL(SanitizerCoverageOptions Options) {
- // Sets CoverageType and IndirectCalls.
- // SanitizerCoverageOptions CLOpts = getOptions(ClCoverageLevel);
- Options.CoverageType =
- SanitizerCoverageOptions::SCK_Edge; // std::max(Options.CoverageType,
- // CLOpts.CoverageType);
- Options.IndirectCalls = false; // CLOpts.IndirectCalls;
- Options.TraceCmp = false; //|= ClCMPTracing;
- Options.TraceDiv = false; //|= ClDIVTracing;
- Options.TraceGep = false; //|= ClGEPTracing;
- Options.TracePC = false; //|= ClTracePC;
- Options.TracePCGuard = true; // |= ClTracePCGuard;
- Options.Inline8bitCounters = 0; //|= ClInline8bitCounters;
- // Options.InlineBoolFlag = 0; //|= ClInlineBoolFlag;
- Options.PCTable = false; //|= ClCreatePCTable;
- Options.NoPrune = false; //|= !ClPruneBlocks;
- Options.StackDepth = false; //|= ClStackDepth;
- if (!Options.TracePCGuard && !Options.TracePC &&
- !Options.Inline8bitCounters && !Options.StackDepth /*&&
- !Options.InlineBoolFlag*/)
- Options.TracePCGuard = true; // TracePCGuard is default.
-
+ Options.CoverageType = SanitizerCoverageOptions::SCK_Edge;
+ // Options.NoPrune = true;
+ Options.TracePCGuard = true; // TracePCGuard is default.
return Options;
}
@@ -139,20 +135,13 @@ class ModuleSanitizerCoverageAFL
}
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
-
- bool instrumentModule(Module &M, DomTreeCallback DTCallback,
- PostDomTreeCallback PDTCallback);
+ bool instrumentModule(Module &M, DomTreeCallback DTCallback,
+ PostDomTreeCallback PDTCallback);
private:
void instrumentFunction(Function &F, DomTreeCallback DTCallback,
PostDomTreeCallback PDTCallback);
- void InjectCoverageForIndirectCalls(Function &F,
- ArrayRef IndirCalls);
void InjectTraceForCmp(Function &F, ArrayRef CmpTraceTargets);
- void InjectTraceForDiv(Function &F,
- ArrayRef DivTraceTargets);
- void InjectTraceForGep(Function &F,
- ArrayRef GepTraceTargets);
void InjectTraceForSwitch(Function &F,
ArrayRef SwitchTraceTargets);
bool InjectCoverage(Function &F, ArrayRef AllBlocks,
@@ -173,20 +162,23 @@ class ModuleSanitizerCoverageAFL
void SetNoSanitizeMetadata(Instruction *I) {
+#if LLVM_VERSION_MAJOR == 15
+ I->setMetadata(LLVMContext::MD_nosanitize, MDNode::get(*C, None));
+#elif LLVM_VERSION_MAJOR >= 16
+ I->setMetadata(LLVMContext::MD_nosanitize, MDNode::get(*C, std::nullopt));
+#else
I->setMetadata(I->getModule()->getMDKindID("nosanitize"),
MDNode::get(*C, None));
+#endif
}
std::string getSectionName(const std::string &Section) const;
std::string getSectionStart(const std::string &Section) const;
std::string getSectionEnd(const std::string &Section) const;
- FunctionCallee SanCovTracePCIndir;
FunctionCallee SanCovTracePC, SanCovTracePCGuard;
FunctionCallee SanCovTraceCmpFunction[4];
FunctionCallee SanCovTraceConstCmpFunction[4];
- FunctionCallee SanCovTraceDivFunction[2];
- FunctionCallee SanCovTraceGepFunction;
FunctionCallee SanCovTraceSwitchFunction;
GlobalVariable *SanCovLowestStack;
Type *IntptrTy, *IntptrPtrTy, *Int64Ty, *Int64PtrTy, *Int32Ty, *Int32PtrTy,
@@ -215,18 +207,16 @@ class ModuleSanitizerCoverageAFL
} // namespace
-#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */
-
extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
llvmGetPassPluginInfo() {
- return {LLVM_PLUGIN_API_VERSION, "SanitizerCoveragePCGUARD", "v0.1",
+ return {LLVM_PLUGIN_API_VERSION, "SanitizerCoveragePCGUARD", "v0.2",
/* lambda to insert our pass into the pass pipeline. */
[](PassBuilder &PB) {
- #if LLVM_VERSION_MAJOR <= 13
+#if LLVM_VERSION_MAJOR == 13
using OptimizationLevel = typename PassBuilder::OptimizationLevel;
- #endif
+#endif
PB.registerOptimizerLastEPCallback(
[](ModulePassManager &MPM, OptimizationLevel OL) {
@@ -238,8 +228,7 @@ llvmGetPassPluginInfo() {
}
-#endif
-
+#if LLVM_VERSION_MAJOR == 1
PreservedAnalyses ModuleSanitizerCoverageAFL::run(Module &M,
ModuleAnalysisManager &MAM) {
@@ -257,34 +246,65 @@ PreservedAnalyses ModuleSanitizerCoverageAFL::run(Module &M,
};
+ if (!ModuleSancov.instrumentModule(M, DTCallback, PDTCallback))
+ return PreservedAnalyses::all();
+
+ PreservedAnalyses PA = PreservedAnalyses::none();
+ // GlobalsAA is considered stateless and does not get invalidated unless
+ // explicitly invalidated; PreservedAnalyses::none() is not enough. Sanitizers
+ // make changes that require GlobalsAA to be invalidated.
+ PA.abandon();
+ return PA;
+
+}
+
+#else
+ #if LLVM_VERSION_MAJOR >= 16
+PreservedAnalyses ModuleSanitizerCoverageAFL::run(Module &M,
+ ModuleAnalysisManager &MAM) {
+
+ #else
+PreservedAnalyses ModuleSanitizerCoverageAFL::run(Module &M,
+ ModuleAnalysisManager &MAM) {
+
+ #endif
+ ModuleSanitizerCoverageAFL ModuleSancov(Options);
+ auto &FAM = MAM.getResult(M).getManager();
+ auto DTCallback = [&FAM](Function &F) -> const DominatorTree * {
+
+ return &FAM.getResult(F);
+
+ };
+
+ auto PDTCallback = [&FAM](Function &F) -> const PostDominatorTree * {
+
+ return &FAM.getResult(F);
+
+ };
+
if (ModuleSancov.instrumentModule(M, DTCallback, PDTCallback))
return PreservedAnalyses::none();
return PreservedAnalyses::all();
}
+#endif
+
std::pair ModuleSanitizerCoverageAFL::CreateSecStartEnd(
Module &M, const char *Section, Type *Ty) {
- GlobalVariable *SecStart =
- new GlobalVariable(M,
-#if LLVM_VERSION_MAJOR >= 15
- Ty,
-#else
- Ty->getPointerElementType(),
-#endif
- false, GlobalVariable::ExternalWeakLinkage, nullptr,
- getSectionStart(Section));
+ // Use ExternalWeak so that if all sections are discarded due to section
+ // garbage collection, the linker will not report undefined symbol errors.
+ // Windows defines the start/stop symbols in compiler-rt so no need for
+ // ExternalWeak.
+ GlobalValue::LinkageTypes Linkage = TargetTriple.isOSBinFormatCOFF()
+ ? GlobalVariable::ExternalLinkage
+ : GlobalVariable::ExternalWeakLinkage;
+ GlobalVariable *SecStart = new GlobalVariable(M, Ty, false, Linkage, nullptr,
+ getSectionStart(Section));
SecStart->setVisibility(GlobalValue::HiddenVisibility);
- GlobalVariable *SecEnd =
- new GlobalVariable(M,
-#if LLVM_VERSION_MAJOR >= 15
- Ty,
-#else
- Ty->getPointerElementType(),
-#endif
- false, GlobalVariable::ExternalWeakLinkage, nullptr,
- getSectionEnd(Section));
+ GlobalVariable *SecEnd = new GlobalVariable(M, Ty, false, Linkage, nullptr,
+ getSectionEnd(Section));
SecEnd->setVisibility(GlobalValue::HiddenVisibility);
IRBuilder<> IRB(M.getContext());
if (!TargetTriple.isOSBinFormatCOFF())
@@ -295,7 +315,8 @@ std::pair ModuleSanitizerCoverageAFL::CreateSecStartEnd(
auto SecStartI8Ptr = IRB.CreatePointerCast(SecStart, Int8PtrTy);
auto GEP = IRB.CreateGEP(Int8Ty, SecStartI8Ptr,
ConstantInt::get(IntptrTy, sizeof(uint64_t)));
- return std::make_pair(IRB.CreatePointerCast(GEP, Ty), SecEnd);
+ return std::make_pair(IRB.CreatePointerCast(GEP, PointerType::getUnqual(Ty)),
+ SecEnd);
}
@@ -307,8 +328,9 @@ Function *ModuleSanitizerCoverageAFL::CreateInitCallsForSections(
auto SecStart = SecStartEnd.first;
auto SecEnd = SecStartEnd.second;
Function *CtorFunc;
+ Type *PtrTy = PointerType::getUnqual(Ty);
std::tie(CtorFunc, std::ignore) = createSanitizerCtorAndInitFunctions(
- M, CtorName, InitFunctionName, {Ty, Ty}, {SecStart, SecEnd});
+ M, CtorName, InitFunctionName, {PtrTy, PtrTy}, {SecStart, SecEnd});
assert(CtorFunc->getName() == CtorName);
if (TargetTriple.supportsCOMDAT()) {
@@ -332,7 +354,6 @@ Function *ModuleSanitizerCoverageAFL::CreateInitCallsForSections(
// to include the sancov constructor. This way the linker can deduplicate
// the constructors but always leave one copy.
CtorFunc->setLinkage(GlobalValue::WeakODRLinkage);
- appendToUsed(M, CtorFunc);
}
@@ -344,37 +365,25 @@ bool ModuleSanitizerCoverageAFL::instrumentModule(
Module &M, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback) {
setvbuf(stdout, NULL, _IONBF, 0);
- if (getenv("AFL_DEBUG")) debug = 1;
+
+ if (getenv("AFL_DEBUG")) { debug = 1; }
if ((isatty(2) && !getenv("AFL_QUIET")) || debug) {
SAYF(cCYA "SanitizerCoveragePCGUARD" VERSION cRST "\n");
- } else
+ } else {
be_quiet = 1;
+ }
+
skip_nozero = getenv("AFL_LLVM_SKIP_NEVERZERO");
use_threadsafe_counters = getenv("AFL_LLVM_THREADSAFE_INST");
initInstrumentList();
scanForDangerousFunctions(&M);
- if (debug) {
-
- fprintf(stderr,
- "SANCOV: covtype:%u indirect:%d stack:%d noprune:%d "
- "createtable:%d tracepcguard:%d tracepc:%d\n",
- Options.CoverageType, Options.IndirectCalls == true ? 1 : 0,
- Options.StackDepth == true ? 1 : 0, Options.NoPrune == true ? 1 : 0,
- // Options.InlineBoolFlag == true ? 1 : 0,
- Options.PCTable == true ? 1 : 0,
- Options.TracePCGuard == true ? 1 : 0,
- Options.TracePC == true ? 1 : 0);
-
- }
-
- if (Options.CoverageType == SanitizerCoverageOptions::SCK_None) return false;
C = &(M.getContext());
DL = &M.getDataLayout();
CurModule = &M;
@@ -397,16 +406,14 @@ bool ModuleSanitizerCoverageAFL::instrumentModule(
Int16Ty = IRB.getInt16Ty();
Int8Ty = IRB.getInt8Ty();
Int1Ty = IRB.getInt1Ty();
- LLVMContext &Ctx = M.getContext();
+ LLVMContext &Ctx = M.getContext();
AFLMapPtr =
new GlobalVariable(M, PointerType::get(Int8Ty, 0), false,
GlobalValue::ExternalLinkage, 0, "__afl_area_ptr");
One = ConstantInt::get(IntegerType::getInt8Ty(Ctx), 1);
Zero = ConstantInt::get(IntegerType::getInt8Ty(Ctx), 0);
- SanCovTracePCIndir =
- M.getOrInsertFunction(SanCovTracePCIndirName, VoidTy, IntptrTy);
// Make sure smaller parameters are zero-extended to i64 if required by the
// target ABI.
AttributeList SanCovTraceCmpZeroExtAL;
@@ -436,26 +443,13 @@ bool ModuleSanitizerCoverageAFL::instrumentModule(
SanCovTraceConstCmpFunction[3] =
M.getOrInsertFunction(SanCovTraceConstCmp8, VoidTy, Int64Ty, Int64Ty);
- {
-
- AttributeList AL;
- AL = AL.addParamAttribute(*C, 0, Attribute::ZExt);
- SanCovTraceDivFunction[0] =
- M.getOrInsertFunction(SanCovTraceDiv4, AL, VoidTy, IRB.getInt32Ty());
-
- }
-
- SanCovTraceDivFunction[1] =
- M.getOrInsertFunction(SanCovTraceDiv8, VoidTy, Int64Ty);
- SanCovTraceGepFunction =
- M.getOrInsertFunction(SanCovTraceGep, VoidTy, IntptrTy);
SanCovTraceSwitchFunction =
M.getOrInsertFunction(SanCovTraceSwitchName, VoidTy, Int64Ty, Int64PtrTy);
Constant *SanCovLowestStackConstant =
M.getOrInsertGlobal(SanCovLowestStackName, IntptrTy);
SanCovLowestStack = dyn_cast(SanCovLowestStackConstant);
- if (!SanCovLowestStack) {
+ if (!SanCovLowestStack || SanCovLowestStack->getValueType() != IntptrTy) {
C->emitError(StringRef("'") + SanCovLowestStackName +
"' should not be declared by the user");
@@ -465,8 +459,6 @@ bool ModuleSanitizerCoverageAFL::instrumentModule(
SanCovLowestStack->setThreadLocalMode(
GlobalValue::ThreadLocalMode::InitialExecTLSModel);
- if (Options.StackDepth && !SanCovLowestStack->isDeclaration())
- SanCovLowestStack->setInitializer(Constant::getAllOnesValue(IntptrTy));
SanCovTracePC = M.getOrInsertFunction(SanCovTracePCName, VoidTy);
SanCovTracePCGuard =
@@ -481,40 +473,25 @@ bool ModuleSanitizerCoverageAFL::instrumentModule(
Ctor = CreateInitCallsForSections(M, SanCovModuleCtorTracePcGuardName,
SanCovTracePCGuardInitName, Int32PtrTy,
SanCovGuardsSectionName);
- if (Function8bitCounterArray)
- Ctor = CreateInitCallsForSections(M, SanCovModuleCtor8bitCountersName,
- SanCov8bitCountersInitName, Int8PtrTy,
- SanCovCountersSectionName);
- if (FunctionBoolArray) {
-
- Ctor = CreateInitCallsForSections(M, SanCovModuleCtorBoolFlagName,
- SanCovBoolFlagInitName, Int1PtrTy,
- SanCovBoolFlagSectionName);
- }
-
- if (Ctor && Options.PCTable) {
+ if (Ctor && debug) {
- auto SecStartEnd = CreateSecStartEnd(M, SanCovPCsSectionName, IntptrPtrTy);
- FunctionCallee InitFunction = declareSanitizerInitFunction(
- M, SanCovPCsInitName, {IntptrPtrTy, IntptrPtrTy});
- IRBuilder<> IRBCtor(Ctor->getEntryBlock().getTerminator());
- IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second});
+ fprintf(stderr, "SANCOV: installed pcguard_init in ctor\n");
}
- // We don't reference these arrays directly in any of our runtime functions,
- // so we need to prevent them from being dead stripped.
- if (TargetTriple.isOSBinFormatMachO()) appendToUsed(M, GlobalsToAppendToUsed);
+ appendToUsed(M, GlobalsToAppendToUsed);
appendToCompilerUsed(M, GlobalsToAppendToCompilerUsed);
if (!be_quiet) {
- if (!instr)
+ if (!instr) {
+
WARNF("No instrumentation targets found.");
- else {
- char modeline[100];
+ } else {
+
+ char modeline[128];
snprintf(modeline, sizeof(modeline), "%s%s%s%s%s%s",
getenv("AFL_HARDEN") ? "hardened" : "non-hardened",
getenv("AFL_USE_ASAN") ? ", ASAN" : "",
@@ -535,39 +512,36 @@ bool ModuleSanitizerCoverageAFL::instrumentModule(
}
// True if block has successors and it dominates all of them.
-bool isFullDominator(const BasicBlock *BB, const DominatorTree *DT) {
+static bool isFullDominator(const BasicBlock *BB, const DominatorTree *DT) {
- if (succ_begin(BB) == succ_end(BB)) return false;
+ if (succ_empty(BB)) return false;
- for (const BasicBlock *SUCC : make_range(succ_begin(BB), succ_end(BB))) {
+ return llvm::all_of(successors(BB), [&](const BasicBlock *SUCC) {
- if (!DT->dominates(BB, SUCC)) return false;
+ return DT->dominates(BB, SUCC);
- }
-
- return true;
+ });
}
// True if block has predecessors and it postdominates all of them.
-bool isFullPostDominator(const BasicBlock *BB, const PostDominatorTree *PDT) {
+static bool isFullPostDominator(const BasicBlock *BB,
+ const PostDominatorTree *PDT) {
- if (pred_begin(BB) == pred_end(BB)) return false;
+ if (pred_empty(BB)) return false;
- for (const BasicBlock *PRED : make_range(pred_begin(BB), pred_end(BB))) {
+ return llvm::all_of(predecessors(BB), [&](const BasicBlock *PRED) {
- if (!PDT->dominates(BB, PRED)) return false;
+ return PDT->dominates(BB, PRED);
- }
-
- return true;
+ });
}
-bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB,
- const DominatorTree *DT,
- const PostDominatorTree *PDT,
- const SanitizerCoverageOptions &Options) {
+static bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB,
+ const DominatorTree *DT,
+ const PostDominatorTree *PDT,
+ const SanitizerCoverageOptions &Options) {
// Don't insert coverage for blocks containing nothing but unreachable: we
// will never call __sanitizer_cov() for them, so counting them in
@@ -582,10 +556,6 @@ bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB,
if (Options.NoPrune || &F.getEntryBlock() == BB) return true;
- if (Options.CoverageType == SanitizerCoverageOptions::SCK_Function &&
- &F.getEntryBlock() != BB)
- return false;
-
// Do not instrument full dominators, or full post-dominators with multiple
// predecessors.
return !isFullDominator(BB, DT) &&
@@ -597,38 +567,47 @@ bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB,
// A twist here is that we treat From->To as a backedge if
// * To dominates From or
// * To->UniqueSuccessor dominates From
-bool IsBackEdge(BasicBlock *From, BasicBlock *To, const DominatorTree *DT) {
+#if 0
+static bool IsBackEdge(BasicBlock *From, BasicBlock *To,
+ const DominatorTree *DT) {
- if (DT->dominates(To, From)) return true;
+ if (DT->dominates(To, From))
+ return true;
if (auto Next = To->getUniqueSuccessor())
- if (DT->dominates(Next, From)) return true;
+ if (DT->dominates(Next, From))
+ return true;
return false;
}
+#endif
+
// Prunes uninteresting Cmp instrumentation:
// * CMP instructions that feed into loop backedge branch.
//
// Note that Cmp pruning is controlled by the same flag as the
// BB pruning.
-bool IsInterestingCmp(ICmpInst *CMP, const DominatorTree *DT,
- const SanitizerCoverageOptions &Options) {
+#if 0
+static bool IsInterestingCmp(ICmpInst *CMP, const DominatorTree *DT,
+ const SanitizerCoverageOptions &Options) {
if (!Options.NoPrune)
if (CMP->hasOneUse())
if (auto BR = dyn_cast(CMP->user_back()))
for (BasicBlock *B : BR->successors())
- if (IsBackEdge(BR->getParent(), B, DT)) return false;
+ if (IsBackEdge(BR->getParent(), B, DT))
+ return false;
return true;
}
+#endif
+
void ModuleSanitizerCoverageAFL::instrumentFunction(
Function &F, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback) {
if (F.empty()) return;
if (!isInInstrumentList(&F, FMNAME)) return;
-
if (F.getName().find(".module_ctor") != std::string::npos)
return; // Should not instrument sanitizer init functions.
if (F.getName().startswith("__sanitizer_"))
@@ -647,15 +626,13 @@ void ModuleSanitizerCoverageAFL::instrumentFunction(
if (F.hasPersonalityFn() &&
isAsynchronousEHPersonality(classifyEHPersonality(F.getPersonalityFn())))
return;
+ if (F.hasFnAttribute(Attribute::NoSanitizeCoverage)) return;
if (Options.CoverageType >= SanitizerCoverageOptions::SCK_Edge)
SplitAllCriticalEdges(
F, CriticalEdgeSplittingOptions().setIgnoreUnreachableDests());
- SmallVector IndirCalls;
- SmallVector BlocksToInstrument;
- SmallVector CmpTraceTargets;
- SmallVector SwitchTraceTargets;
- SmallVector DivTraceTargets;
- SmallVector GepTraceTargets;
+ SmallVector BlocksToInstrument;
+ SmallVector CmpTraceTargets;
+ SmallVector SwitchTraceTargets;
const DominatorTree *DT = DTCallback(F);
const PostDominatorTree *PDT = PDTCallback(F);
@@ -665,47 +642,28 @@ void ModuleSanitizerCoverageAFL::instrumentFunction(
if (shouldInstrumentBlock(F, &BB, DT, PDT, Options))
BlocksToInstrument.push_back(&BB);
- for (auto &Inst : BB) {
-
- if (Options.IndirectCalls) {
-
- CallBase *CB = dyn_cast(&Inst);
- if (CB && !CB->getCalledFunction()) IndirCalls.push_back(&Inst);
-
- }
+ /*
+ for (auto &Inst : BB) {
- if (Options.TraceCmp) {
+ if (Options.TraceCmp) {
- if (ICmpInst *CMP = dyn_cast(&Inst))
- if (IsInterestingCmp(CMP, DT, Options))
- CmpTraceTargets.push_back(&Inst);
- if (isa(&Inst)) SwitchTraceTargets.push_back(&Inst);
+ if (ICmpInst *CMP = dyn_cast(&Inst))
+ if (IsInterestingCmp(CMP, DT, Options))
+ CmpTraceTargets.push_back(&Inst);
+ if (isa(&Inst))
+ SwitchTraceTargets.push_back(&Inst);
- }
+ }
- if (Options.TraceDiv)
- if (BinaryOperator *BO = dyn_cast(&Inst))
- if (BO->getOpcode() == Instruction::SDiv ||
- BO->getOpcode() == Instruction::UDiv)
- DivTraceTargets.push_back(BO);
- if (Options.TraceGep)
- if (GetElementPtrInst *GEP = dyn_cast(&Inst))
- GepTraceTargets.push_back(GEP);
- if (Options.StackDepth)
- if (isa(Inst) ||
- (isa(Inst) && !isa(Inst)))
- IsLeafFunc = false;
+ }
- }
+ */
}
InjectCoverage(F, BlocksToInstrument, IsLeafFunc);
- InjectCoverageForIndirectCalls(F, IndirCalls);
- InjectTraceForCmp(F, CmpTraceTargets);
- InjectTraceForSwitch(F, SwitchTraceTargets);
- InjectTraceForDiv(F, DivTraceTargets);
- InjectTraceForGep(F, GepTraceTargets);
+ // InjectTraceForCmp(F, CmpTraceTargets);
+ // InjectTraceForSwitch(F, SwitchTraceTargets);
}
@@ -717,33 +675,30 @@ GlobalVariable *ModuleSanitizerCoverageAFL::CreateFunctionLocalArrayInSection(
*CurModule, ArrayTy, false, GlobalVariable::PrivateLinkage,
Constant::getNullValue(ArrayTy), "__sancov_gen_");
-#if LLVM_VERSION_MAJOR >= 13
if (TargetTriple.supportsCOMDAT() &&
(TargetTriple.isOSBinFormatELF() || !F.isInterposable()))
if (auto Comdat = getOrCreateFunctionComdat(F, TargetTriple))
Array->setComdat(Comdat);
-#else
- if (TargetTriple.supportsCOMDAT() && !F.isInterposable())
- if (auto Comdat =
- GetOrCreateFunctionComdat(F, TargetTriple, CurModuleUniqueId))
- Array->setComdat(Comdat);
-#endif
-
Array->setSection(getSectionName(Section));
-#if (LLVM_VERSION_MAJOR >= 11) || \
- (LLVM_VERSION_MAJOR == 10 && LLVM_VERSION_MINOR >= 1)
- #if LLVM_VERSION_MAJOR >= 16
+#if LLVM_VERSION_MAJOR >= 16
Array->setAlignment(Align(DL->getTypeStoreSize(Ty).getFixedValue()));
- #else
- Array->setAlignment(Align(DL->getTypeStoreSize(Ty).getFixedSize()));
- #endif
#else
- Array->setAlignment(Align(4)); // cheating
+ Array->setAlignment(Align(DL->getTypeStoreSize(Ty).getFixedSize()));
#endif
- GlobalsToAppendToUsed.push_back(Array);
- GlobalsToAppendToCompilerUsed.push_back(Array);
- MDNode *MD = MDNode::get(F.getContext(), ValueAsMetadata::get(&F));
- Array->addMetadata(LLVMContext::MD_associated, *MD);
+
+ // sancov_pcs parallels the other metadata section(s). Optimizers (e.g.
+ // GlobalOpt/ConstantMerge) may not discard sancov_pcs and the other
+ // section(s) as a unit, so we conservatively retain all unconditionally in
+ // the compiler.
+ //
+ // With comdat (COFF/ELF), the linker can guarantee the associated sections
+ // will be retained or discarded as a unit, so llvm.compiler.used is
+ // sufficient. Otherwise, conservatively make all of them retained by the
+ // linker.
+ if (Array->hasComdat())
+ GlobalsToAppendToCompilerUsed.push_back(Array);
+ else
+ GlobalsToAppendToUsed.push_back(Array);
return Array;
@@ -768,8 +723,12 @@ GlobalVariable *ModuleSanitizerCoverageAFL::CreatePCArray(
PCs.push_back((Constant *)IRB.CreatePointerCast(
BlockAddress::get(AllBlocks[i]), IntptrPtrTy));
+#if LLVM_VERSION_MAJOR >= 16
+ PCs.push_back(Constant::getNullValue(IntptrPtrTy));
+#else
PCs.push_back((Constant *)IRB.CreateIntToPtr(
ConstantInt::get(IntptrTy, 0), IntptrPtrTy));
+#endif
}
@@ -792,21 +751,13 @@ void ModuleSanitizerCoverageAFL::CreateFunctionLocalArrays(
FunctionGuardArray = CreateFunctionLocalArrayInSection(
AllBlocks.size() + special, F, Int32Ty, SanCovGuardsSectionName);
- if (Options.Inline8bitCounters)
- Function8bitCounterArray = CreateFunctionLocalArrayInSection(
- AllBlocks.size(), F, Int8Ty, SanCovCountersSectionName);
- /*
- if (Options.InlineBoolFlag)
- FunctionBoolArray = CreateFunctionLocalArrayInSection(
- AllBlocks.size(), F, Int1Ty, SanCovBoolFlagSectionName);
- */
- if (Options.PCTable) FunctionPCsArray = CreatePCArray(F, AllBlocks);
-
}
bool ModuleSanitizerCoverageAFL::InjectCoverage(
Function &F, ArrayRef AllBlocks, bool IsLeafFunc) {
+ if (AllBlocks.empty()) return false;
+
uint32_t cnt_cov = 0, cnt_sel = 0, cnt_sel_inc = 0;
static uint32_t first = 1;
@@ -855,7 +806,6 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
}
-#if (LLVM_VERSION_MAJOR >= 12)
else if (t->getTypeID() == llvm::Type::FixedVectorTyID) {
FixedVectorType *tt = dyn_cast(t);
@@ -868,16 +818,14 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
}
-#endif
-
}
}
}
- /* Create PCGUARD array */
CreateFunctionLocalArrays(F, AllBlocks, first + cnt_cov + cnt_sel_inc);
+
if (first) { first = 0; }
selects += cnt_sel;
@@ -889,12 +837,6 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
CallInst *callInst = nullptr;
- /*
- std::string errMsg;
- raw_string_ostream os(errMsg);
- IN.print(os);
- fprintf(stderr, "X: %s\n", os.str().c_str());
- */
if ((callInst = dyn_cast(&IN))) {
Function *Callee = callInst->getCalledFunction();
@@ -1033,12 +975,6 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
}
- /*
- std::string errMsg;
- raw_string_ostream os(errMsg);
- x->print(os);
- fprintf(stderr, "X: %s\n", os.str().c_str());
- */
result = IRB.CreateSelect(condition, x, y);
}
@@ -1063,13 +999,6 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
IRB.CreateLoad(PointerType::get(Int8Ty, 0), AFLMapPtr);
ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(MapPtr);
- /*
- std::string errMsg;
- raw_string_ostream os(errMsg);
- result->print(os);
- fprintf(stderr, "X: %s\n", os.str().c_str());
- */
-
while (1) {
/* Get CurLoc */
@@ -1159,29 +1088,6 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
}
-// On every indirect call we call a run-time function
-// __sanitizer_cov_indir_call* with two parameters:
-// - callee address,
-// - global cache array that contains CacheSize pointers (zero-initialized).
-// The cache is used to speed up recording the caller-callee pairs.
-// The address of the caller is passed implicitly via caller PC.
-// CacheSize is encoded in the name of the run-time function.
-void ModuleSanitizerCoverageAFL::InjectCoverageForIndirectCalls(
- Function &F, ArrayRef IndirCalls) {
-
- if (IndirCalls.empty()) return;
- for (auto I : IndirCalls) {
-
- IRBuilder<> IRB(I);
- CallBase &CB = cast(*I);
- Value *Callee = CB.getCalledOperand();
- if (isa(Callee)) continue;
- IRB.CreateCall(SanCovTracePCIndir, IRB.CreatePointerCast(Callee, IntptrTy));
-
- }
-
-}
-
// For every switch statement we insert a call:
// __sanitizer_cov_trace_switch(CondValue,
// {NumCases, ValueSizeInBits, Case0Value, Case1Value, Case2Value, ... })
@@ -1237,41 +1143,6 @@ void ModuleSanitizerCoverageAFL::InjectTraceForSwitch(
}
-void ModuleSanitizerCoverageAFL::InjectTraceForDiv(
- Function &, ArrayRef DivTraceTargets) {
-
- for (auto BO : DivTraceTargets) {
-
- IRBuilder<> IRB(BO);
- Value *A1 = BO->getOperand(1);
- if (isa(A1)) continue;
- if (!A1->getType()->isIntegerTy()) continue;
- uint64_t TypeSize = DL->getTypeStoreSizeInBits(A1->getType());
- int CallbackIdx = TypeSize == 32 ? 0 : TypeSize == 64 ? 1 : -1;
- if (CallbackIdx < 0) continue;
- auto Ty = Type::getIntNTy(*C, TypeSize);
- IRB.CreateCall(SanCovTraceDivFunction[CallbackIdx],
- {IRB.CreateIntCast(A1, Ty, true)});
-
- }
-
-}
-
-void ModuleSanitizerCoverageAFL::InjectTraceForGep(
- Function &, ArrayRef GepTraceTargets) {
-
- for (auto GEP : GepTraceTargets) {
-
- IRBuilder<> IRB(GEP);
- for (Use &Idx : GEP->indices())
- if (!isa(Idx) && Idx->getType()->isIntegerTy())
- IRB.CreateCall(SanCovTraceGepFunction,
- {IRB.CreateIntCast(Idx, IntptrTy, true)});
-
- }
-
-}
-
void ModuleSanitizerCoverageAFL::InjectTraceForCmp(
Function &, ArrayRef CmpTraceTargets) {
@@ -1321,27 +1192,44 @@ void ModuleSanitizerCoverageAFL::InjectCoverageAtBlock(Function &F,
BasicBlock::iterator IP = BB.getFirstInsertionPt();
bool IsEntryBB = &BB == &F.getEntryBlock();
+ DebugLoc EntryLoc;
if (IsEntryBB) {
- // Keep allocas and llvm.localescape calls in the entry block. Even
+ if (auto SP = F.getSubprogram())
+ EntryLoc = DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP);
+ // Keep static allocas and llvm.localescape calls in the entry block. Even
// if we aren't splitting the block, it's nice for allocas to be before
// calls.
IP = PrepareToSplitEntryBlock(BB, IP);
+#if LLVM_VERSION_MAJOR < 15
- }
-
- IRBuilder<> IRB(&*IP);
-
- if (Options.TracePC) {
+ } else {
- IRB.CreateCall(SanCovTracePC);
- // ->setCannotMerge(); // gets the PC using GET_CALLER_PC.
+ EntryLoc = IP->getDebugLoc();
+ if (!EntryLoc)
+ if (auto *SP = F.getSubprogram())
+ EntryLoc = DILocation::get(SP->getContext(), 0, 0, SP);
+#endif
}
+#if LLVM_VERSION_MAJOR >= 15
+ InstrumentationIRBuilder IRB(&*IP);
+#else
+ IRBuilder<> IRB(&*IP);
+#endif
+ if (EntryLoc) IRB.SetCurrentDebugLocation(EntryLoc);
if (Options.TracePCGuard) {
+ /*
+ auto GuardPtr = IRB.CreateIntToPtr(
+ IRB.CreateAdd(IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
+ ConstantInt::get(IntptrTy, Idx * 4)),
+ Int32PtrTy);
+ IRB.CreateCall(SanCovTracePCGuard, GuardPtr)->setCannotMerge();
+ */
+
/* Get CurLoc */
Value *GuardPtr = IRB.CreateIntToPtr(
@@ -1399,57 +1287,6 @@ void ModuleSanitizerCoverageAFL::InjectCoverageAtBlock(Function &F,
}
- if (Options.Inline8bitCounters) {
-
- auto CounterPtr = IRB.CreateGEP(
- Function8bitCounterArray->getValueType(), Function8bitCounterArray,
- {ConstantInt::get(IntptrTy, 0), ConstantInt::get(IntptrTy, Idx)});
- auto Load = IRB.CreateLoad(Int8Ty, CounterPtr);
- auto Inc = IRB.CreateAdd(Load, ConstantInt::get(Int8Ty, 1));
- auto Store = IRB.CreateStore(Inc, CounterPtr);
- SetNoSanitizeMetadata(Load);
- SetNoSanitizeMetadata(Store);
-
- }
-
- /*
- if (Options.InlineBoolFlag) {
-
- auto FlagPtr = IRB.CreateGEP(
- FunctionBoolArray->getValueType(), FunctionBoolArray,
- {ConstantInt::get(IntptrTy, 0), ConstantInt::get(IntptrTy, Idx)});
- auto Load = IRB.CreateLoad(Int1Ty, FlagPtr);
- auto ThenTerm =
- SplitBlockAndInsertIfThen(IRB.CreateIsNull(Load), &*IP, false);
- IRBuilder<> ThenIRB(ThenTerm);
- auto Store = ThenIRB.CreateStore(ConstantInt::getTrue(Int1Ty), FlagPtr);
- SetNoSanitizeMetadata(Load);
- SetNoSanitizeMetadata(Store);
-
- }
-
- */
-
- if (Options.StackDepth && IsEntryBB && !IsLeafFunc) {
-
- // Check stack depth. If it's the deepest so far, record it.
- Module *M = F.getParent();
- Function *GetFrameAddr = Intrinsic::getDeclaration(
- M, Intrinsic::frameaddress,
- IRB.getInt8PtrTy(M->getDataLayout().getAllocaAddrSpace()));
- auto FrameAddrPtr =
- IRB.CreateCall(GetFrameAddr, {Constant::getNullValue(Int32Ty)});
- auto FrameAddrInt = IRB.CreatePtrToInt(FrameAddrPtr, IntptrTy);
- auto LowestStack = IRB.CreateLoad(IntptrTy, SanCovLowestStack);
- auto IsStackLower = IRB.CreateICmpULT(FrameAddrInt, LowestStack);
- auto ThenTerm = SplitBlockAndInsertIfThen(IsStackLower, &*IP, false);
- IRBuilder<> ThenIRB(ThenTerm);
- auto Store = ThenIRB.CreateStore(FrameAddrInt, SanCovLowestStack);
- SetNoSanitizeMetadata(LowestStack);
- SetNoSanitizeMetadata(Store);
-
- }
-
}
std::string ModuleSanitizerCoverageAFL::getSectionName(
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 84fe70ec..9e56828c 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -997,7 +997,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
if (instrument_mode == INSTRUMENT_PCGUARD) {
-#if LLVM_MAJOR >= 11
+#if LLVM_MAJOR >= 13
#if defined __ANDROID__ || ANDROID
cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard";
instrument_mode = INSTRUMENT_LLVMNATIVE;
@@ -1014,7 +1014,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
} else {
- #if LLVM_MAJOR >= 11 /* use new pass manager */
+ #if LLVM_MAJOR >= 13 /* use new pass manager */
#if LLVM_MAJOR < 16
cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
#endif
@@ -1035,12 +1035,12 @@ static void edit_params(u32 argc, char **argv, char **envp) {
#if LLVM_MAJOR >= 4
if (!be_quiet)
SAYF(
- "Using unoptimized trace-pc-guard, upgrade to llvm 10.0.1+ for "
+ "Using unoptimized trace-pc-guard, upgrade to LLVM 13+ for "
"enhanced version.\n");
cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard";
instrument_mode = INSTRUMENT_LLVMNATIVE;
#else
- FATAL("pcguard instrumentation requires llvm 4.0.1+");
+ FATAL("pcguard instrumentation requires LLVM 4.0.1+");
#endif
#endif
@@ -1053,7 +1053,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
cc_params[cc_par_cnt++] =
"-fsanitize-coverage=trace-pc-guard,bb,no-prune,pc-table";
#else
- FATAL("pcguard instrumentation with pc-table requires llvm 6.0.1+");
+ FATAL("pcguard instrumentation with pc-table requires LLVM 6.0.1+");
#endif
} else {
@@ -1063,7 +1063,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
}
#else
- FATAL("pcguard instrumentation requires llvm 4.0.1+");
+ FATAL("pcguard instrumentation requires LLVM 4.0.1+");
#endif
} else {
@@ -2031,7 +2031,7 @@ int main(int argc, char **argv, char **envp) {
if (!compiler_mode) {
// lto is not a default because outside of afl-cc RANLIB and AR have to
- // be set to llvm versions so this would work
+ // be set to LLVM versions so this would work
if (have_llvm)
compiler_mode = LLVM;
else if (have_gcc_plugin)
@@ -2050,6 +2050,17 @@ int main(int argc, char **argv, char **envp) {
}
+ /* if our PCGUARD implementation is not available then silently switch to
+ native LLVM PCGUARD */
+ if (compiler_mode == CLANG &&
+ (instrument_mode == INSTRUMENT_DEFAULT ||
+ instrument_mode == INSTRUMENT_PCGUARD) &&
+ find_object("SanitizerCoveragePCGUARD.so", argv[0]) == NULL) {
+
+ instrument_mode = INSTRUMENT_LLVMNATIVE;
+
+ }
+
if (compiler_mode == GCC) {
if (clang_mode) {
@@ -2096,12 +2107,12 @@ int main(int argc, char **argv, char **envp) {
"-------------|\n"
"MODES: NCC PERSIST DICT LAF "
"CMPLOG SELECT\n"
- " [LTO] llvm LTO: %s%s\n"
+ " [LTO] LLVM LTO: %s%s\n"
" PCGUARD DEFAULT yes yes yes yes yes "
" yes\n"
" CLASSIC yes yes yes yes yes "
" yes\n"
- " [LLVM] llvm: %s%s\n"
+ " [LLVM] LLVM: %s%s\n"
" PCGUARD %s yes yes module yes yes "
"yes\n"
" CLASSIC %s no yes module yes yes "
@@ -2171,7 +2182,7 @@ int main(int argc, char **argv, char **envp) {
" (instrumentation/README.lto.md)\n"
" PERSIST: persistent mode support [code] (huge speed increase!)\n"
" (instrumentation/README.persistent_mode.md)\n"
- " DICT: dictionary in the target [yes=automatic or llvm module "
+ " DICT: dictionary in the target [yes=automatic or LLVM module "
"pass]\n"
" (instrumentation/README.lto.md + "
"instrumentation/README.llvm.md)\n"
--
cgit 1.4.1
From a4b927241651c645cc1a2f5b185681830e7000f9 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 7 Jun 2023 10:58:10 +0200
Subject: fix gcc cmplog crash
---
docs/Changelog.md | 1 +
1 file changed, 1 insertion(+)
(limited to 'docs')
diff --git a/docs/Changelog.md b/docs/Changelog.md
index facf2196..9ed930b3 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -18,6 +18,7 @@
- rewrote our PCGUARD pass to be compatible with LLVM 15+ shenanigans,
requires LLVM 13+ now instead of 10.0.1+
- fallback to native LLVM PCGUARD if our PCGUARD is unavailable
+ - fixed a crash in GCC CMPLOG
- afl-showmap:
- added custom mutator post_process and send support
- add `-I filelist` option, an alternative to `-i in_dir`
--
cgit 1.4.1
From 88603a2c2e770b20373c4002cb4aaf4e7b058ae5 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 7 Jun 2023 15:17:46 +0200
Subject: add issue to faq
---
docs/FAQ.md | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 51 insertions(+)
(limited to 'docs')
diff --git a/docs/FAQ.md b/docs/FAQ.md
index 8178db46..9275eb94 100644
--- a/docs/FAQ.md
+++ b/docs/FAQ.md
@@ -279,3 +279,54 @@ If you find an interesting or important question missing, submit it via
Solution: just do an `export AFL_MAP_SIZE=(the value in the warning)`.
+
+
+ Linker errors.
+
+ If you compile C++ harnesses and see `undefined reference` errors for
+ variables named `__afl_...`, e.g.:
+
+ ```
+ /usr/bin/ld: /tmp/test-d3085f.o: in function `foo::test()':
+ test.cpp:(.text._ZN3fooL4testEv[_ZN3fooL4testEv]+0x35): undefined reference to `foo::__afl_connected'
+ clang: error: linker command failed with exit code 1 (use -v to see invocation)
+ ```
+
+ Then you use AFL++ macros like `__AFL_LOOP` within a namespace and this
+ will not work.
+
+ Solution: Move that harness portion to the global namespace, e.g. before:
+ ```
+ #include
+ namespace foo {
+ static void test() {
+ while(__AFL_LOOP(1000)) {
+ foo::function();
+ }
+ }
+ }
+
+ int main(int argc, char** argv) {
+ foo::test();
+ return 0;
+ }
+ ```
+ after:
+ ```
+ #include
+ static void mytest() {
+ while(__AFL_LOOP(1000)) {
+ foo::function();
+ }
+ }
+ namespace foo {
+ static void test() {
+ mytest();
+ }
+ }
+ int main(int argc, char** argv) {
+ foo::test();
+ return 0;
+ }
+ ```
+
--
cgit 1.4.1
From e71d422b3c9867249dcaac87e40b08010fc43497 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 8 Jun 2023 08:42:23 +0200
Subject: enhance custom mutator docs
---
docs/custom_mutators.md | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
(limited to 'docs')
diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md
index 3f7e9e6e..c5a64622 100644
--- a/docs/custom_mutators.md
+++ b/docs/custom_mutators.md
@@ -145,12 +145,15 @@ def deinit(): # optional for Python
- `fuzz` (optional):
- This method performs custom mutations on a given input. It also accepts an
- additional test case. Note that this function is optional - but it makes
- sense to use it. You would only skip this if `post_process` is used to fix
- checksums etc. so if you are using it, e.g., as a post processing library.
- Note that a length > 0 *must* be returned!
- The returned output buffer is under **your** memory management!
+ This method performs your custom mutations on a given input.
+ The add_buf is the contents of another queue item that can be used for
+ splicing - or anything else - and can also be ignored. If you are not
+ using this additional data then define `splice_optout` (see above).
+ This function is optional.
+ Returing a length of 0 is valid and is interpreted as skipping this
+ one mutation result.
+ For non-Python: the returned output buffer is under **your** memory
+ management!
- `describe` (optional):
--
cgit 1.4.1
From bf2727b76366ce4c9cdc723c3f3ccffae3cc3619 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 12 Jun 2023 08:28:47 +0200
Subject: v4.07c release
---
README.md | 4 ++--
TODO.md | 2 ++
docs/Changelog.md | 2 +-
include/config.h | 2 +-
4 files changed, 6 insertions(+), 4 deletions(-)
(limited to 'docs')
diff --git a/README.md b/README.md
index 0208a9fe..97fd3997 100644
--- a/README.md
+++ b/README.md
@@ -2,9 +2,9 @@
-Release version: [4.06c](https://github.com/AFLplusplus/AFLplusplus/releases)
+Release version: [4.07c](https://github.com/AFLplusplus/AFLplusplus/releases)
-GitHub version: 4.07a
+GitHub version: 4.07c
Repository:
[https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)
diff --git a/TODO.md b/TODO.md
index 2b7e8fcf..26e12cee 100644
--- a/TODO.md
+++ b/TODO.md
@@ -2,6 +2,8 @@
## Should
+ - afl-crash-analysis
+ - show in the UI when fuzzing is "done"
- test cmplog for less than 16bit
- support persistent and deferred fork server in afl-showmap?
- better autodetection of shifting runtime timeout values
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 9ed930b3..c52ddd56 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -3,7 +3,7 @@
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.07a (dev)
+### Version ++4.07c (release)
- afl-fuzz:
- reverse reading the seeds only on restarts (increases performance)
- new env `AFL_POST_PROCESS_KEEP_ORIGINAL` to keep the orignal
diff --git a/include/config.h b/include/config.h
index 194786f7..53be8549 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.07a"
+#define VERSION "++4.07c"
/******************************************************
* *
--
cgit 1.4.1
From 61b6f4ed9e4dce15c39e4350278a95a41ea2522c Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 12 Jun 2023 09:16:15 +0200
Subject: 4.08a init
---
README.md | 2 +-
docs/Changelog.md | 7 +++++++
include/config.h | 2 +-
3 files changed, 9 insertions(+), 2 deletions(-)
(limited to 'docs')
diff --git a/README.md b/README.md
index 97fd3997..05c662c1 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
Release version: [4.07c](https://github.com/AFLplusplus/AFLplusplus/releases)
-GitHub version: 4.07c
+GitHub version: 4.08a
Repository:
[https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)
diff --git a/docs/Changelog.md b/docs/Changelog.md
index c52ddd56..98d59527 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -3,6 +3,13 @@
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.08a (dev)
+ - new mutation engine: mutations that favor discovery more paths are prefered
+ until no new finds for 10 minutes then switching to mutations that favor
+ triggering crashes. Modes and switch time can be configured wie `-P`.
+ - display the state of the fuzzing run in the UI :-)
+
+
### Version ++4.07c (release)
- afl-fuzz:
- reverse reading the seeds only on restarts (increases performance)
diff --git a/include/config.h b/include/config.h
index 53be8549..d8153a2c 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.07c"
+#define VERSION "++4.08a"
/******************************************************
* *
--
cgit 1.4.1
From 3ad8e9856cc48a6f69aa701dafd0623f91f31c5c Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 12 Jun 2023 09:23:57 +0200
Subject: update changelog
---
docs/Changelog.md | 3 +++
1 file changed, 3 insertions(+)
(limited to 'docs')
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 98d59527..70f38d05 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -7,6 +7,9 @@
- new mutation engine: mutations that favor discovery more paths are prefered
until no new finds for 10 minutes then switching to mutations that favor
triggering crashes. Modes and switch time can be configured wie `-P`.
+ - new custom mutator that has the new afl++ engine (so it can easily
+ incorporated into new custom mutators), and also comes with a standalone
+ command line tool! See custom_mutators/aflpp/standalone/
- display the state of the fuzzing run in the UI :-)
--
cgit 1.4.1
From 7b29f2cd244424c5385605d1302b68be44e432bc Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 20 Jun 2023 19:58:08 +0200
Subject: fix timeout for sessions restart and + usage
---
docs/Changelog.md | 17 ++++++++++-------
src/afl-fuzz-stats.c | 14 ++++++--------
src/afl-fuzz.c | 1 +
3 files changed, 17 insertions(+), 15 deletions(-)
(limited to 'docs')
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 70f38d05..4454456e 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -4,13 +4,16 @@
release of the tool. See README.md for the general instruction manual.
### Version ++4.08a (dev)
- - new mutation engine: mutations that favor discovery more paths are prefered
- until no new finds for 10 minutes then switching to mutations that favor
- triggering crashes. Modes and switch time can be configured wie `-P`.
- - new custom mutator that has the new afl++ engine (so it can easily
- incorporated into new custom mutators), and also comes with a standalone
- command line tool! See custom_mutators/aflpp/standalone/
- - display the state of the fuzzing run in the UI :-)
+ - afl-fuzz:
+ - new mutation engine: mutations that favor discovery more paths are
+ prefered until no new finds for 10 minutes then switching to mutations
+ that favor triggering crashes. Modes and switch time can be configured
+ with `-P`.
+ - new custom mutator that has the new afl++ engine (so it can easily
+ incorporated into new custom mutators), and also comes with a standalone
+ command line tool! See custom_mutators/aflpp/standalone/
+ - display the state of the fuzzing run in the UI :-)
+ - fix timeout setting if '+' is used or a session is restarted
### Version ++4.07c (release)
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index 1499a7e4..389b82fc 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -2303,7 +2303,12 @@ void show_init_stats(afl_state_t *afl) {
stringify_int(IB(0), min_us), stringify_int(IB(1), max_us),
stringify_int(IB(2), avg_us));
- if (afl->timeout_given != 1) {
+ if (afl->timeout_given == 3) {
+
+ ACTF("Applying timeout settings from resumed session (%u ms).",
+ afl->fsrv.exec_tmout);
+
+ } else if (afl->timeout_given != 1) {
/* Figure out the appropriate timeout. The basic idea is: 5x average or
1x max, rounded up to EXEC_TM_ROUND ms and capped at 1 second.
@@ -2345,13 +2350,6 @@ void show_init_stats(afl_state_t *afl) {
afl->timeout_given = 1;
- } else if (afl->timeout_given == 3) {
-
- ACTF("Applying timeout settings from resumed session (%u ms).",
- afl->fsrv.exec_tmout);
-
- } else {
-
ACTF("-t option specified. We'll use an exec timeout of %u ms.",
afl->fsrv.exec_tmout);
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index d727fff5..9eabfae1 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -2362,6 +2362,7 @@ int main(int argc, char **argv_orig, char **envp) {
max_ms = afl->queue_buf[entry]->exec_us;
afl->fsrv.exec_tmout = max_ms;
+ afl->timeout_given = 1;
}
--
cgit 1.4.1
From 51ab51ca278dafacfca1131fd339529e9d7dce08 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 21 Jun 2023 09:04:08 +0200
Subject: update tutorial list
---
custom_mutators/README.md | 11 +++++++----
docs/tutorials.md | 5 +++++
2 files changed, 12 insertions(+), 4 deletions(-)
(limited to 'docs')
diff --git a/custom_mutators/README.md b/custom_mutators/README.md
index a5a572c0..2d1220b3 100644
--- a/custom_mutators/README.md
+++ b/custom_mutators/README.md
@@ -70,14 +70,17 @@ requires cmake (among other things):
### libprotobuf Mutators
-There are two WIP protobuf projects, that require work to be working though:
+There are three WIP protobuf projects, that require work to be working though:
+
+ASN.1 example:
+[https://github.com/airbus-seclab/AFLplusplus-blogpost/tree/main/src/mutator](https://github.com/airbus-seclab/AFLplusplus-blogpost/tree/main/src/mutator)
transforms protobuf raw:
-https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/tree/master/4_libprotobuf_aflpp_custom_mutator
+[https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/tree/master/4_libprotobuf_aflpp_custom_mutator](https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/tree/master/4_libprotobuf_aflpp_custom_mutator)
has a transform function you need to fill for your protobuf format, however
needs to be ported to the updated AFL++ custom mutator API (not much work):
-https://github.com/thebabush/afl-libprotobuf-mutator
+[https://github.com/thebabush/afl-libprotobuf-mutator](https://github.com/thebabush/afl-libprotobuf-mutator)
same as above but is for current AFL++:
-https://github.com/P1umer/AFLplusplus-protobuf-mutator
+[https://github.com/P1umer/AFLplusplus-protobuf-mutator](https://github.com/P1umer/AFLplusplus-protobuf-mutator)
\ No newline at end of file
diff --git a/docs/tutorials.md b/docs/tutorials.md
index 342080fd..a5ee3322 100644
--- a/docs/tutorials.md
+++ b/docs/tutorials.md
@@ -8,6 +8,7 @@ Here are some good write-ups to show how to effectively use AFL++:
* [https://aflplus.plus/docs/tutorials/libxml2_tutorial/](https://aflplus.plus/docs/tutorials/libxml2_tutorial/)
* [https://bananamafia.dev/post/gb-fuzz/](https://bananamafia.dev/post/gb-fuzz/)
+* [https://bushido-sec.com/index.php/2023/06/19/the-art-of-fuzzing/](https://bushido-sec.com/index.php/2023/06/19/the-art-of-fuzzing/)
* [https://securitylab.github.com/research/fuzzing-challenges-solutions-1](https://securitylab.github.com/research/fuzzing-challenges-solutions-1)
* [https://securitylab.github.com/research/fuzzing-software-2](https://securitylab.github.com/research/fuzzing-software-2)
* [https://securitylab.github.com/research/fuzzing-sockets-FTP](https://securitylab.github.com/research/fuzzing-sockets-FTP)
@@ -20,6 +21,10 @@ training, then we can highly recommend the following:
* [https://github.com/antonio-morales/Fuzzing101](https://github.com/antonio-morales/Fuzzing101)
+Here is a good forkflow description (and tutorial) for qemu_mode:
+
+* [https://airbus-seclab.github.io/AFLplusplus-blogpost/](https://airbus-seclab.github.io/AFLplusplus-blogpost/)
+
Here is good workflow description for frida_mode:
* [https://blog.quarkslab.com/android-greybox-fuzzing-with-afl-frida-mode.html](https://blog.quarkslab.com/android-greybox-fuzzing-with-afl-frida-mode.html)
--
cgit 1.4.1
From 64b15a00f270f0ac9c00cf13e569481672227635 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 21 Jun 2023 12:20:10 +0200
Subject: fix afl-cmin* for old afl vanilla issue
---
afl-cmin | 35 +++++++++++++++++++++++++++++------
afl-cmin.bash | 4 +++-
docs/Changelog.md | 4 ++++
src/afl-showmap.c | 5 +++--
4 files changed, 39 insertions(+), 9 deletions(-)
(limited to 'docs')
diff --git a/afl-cmin b/afl-cmin
index 3e37dbdb..d0bbed2b 100755
--- a/afl-cmin
+++ b/afl-cmin
@@ -318,7 +318,9 @@ BEGIN {
if (!nyx_mode && target_bin && !exists_and_is_executable(target_bin)) {
- "command -v "target_bin" 2>/dev/null" | getline tnew
+ cmd = "command -v "target_bin" 2>/dev/null"
+ cmd | getline tnew
+ close(cmd)
if (!tnew || !exists_and_is_executable(tnew)) {
print "[-] Error: binary '"target_bin"' not found or not executable." > "/dev/stderr"
exit 1
@@ -330,6 +332,7 @@ BEGIN {
echo "[!] Trying to obtain the map size of the target ..."
get_map_size = "AFL_DUMP_MAP_SIZE=1 " target_bin
get_map_size | getline mapsize
+ close(get_map_size)
if (mapsize && mapsize > 65535 && mapsize < 100000000) {
AFL_MAP_SIZE = "AFL_MAP_SIZE="mapsize" "
print "[+] Setting "AFL_MAP_SIZE
@@ -359,14 +362,18 @@ BEGIN {
system("rm -rf "trace_dir" 2>/dev/null");
system("rm "out_dir"/id[:_]* 2>/dev/null")
- "ls "out_dir"/* 2>/dev/null | wc -l" | getline noofentries
+ cmd = "ls "out_dir"/* 2>/dev/null | wc -l"
+ cmd | getline noofentries
+ close(cmd)
if (0 == system( "test -d "out_dir" -a "noofentries" -gt 0" )) {
print "[-] Error: directory '"out_dir"' exists and is not empty - delete it first." > "/dev/stderr"
exit 1
}
if (threads) {
- "nproc" | getline nproc
+ cmd = "nproc"
+ cmd | getline nproc
+ close(cmd)
if (threads == "all") {
threads = nproc
} else {
@@ -386,12 +393,14 @@ BEGIN {
if (stdin_file) {
# truncate input file
printf "" > stdin_file
- close( stdin_file )
+ close(stdin_file)
}
# First we look in PATH
if (0 == system("command -v afl-showmap >/dev/null 2>&1")) {
- "command -v afl-showmap 2>/dev/null" | getline showmap
+ cmd = "command -v afl-showmap 2>/dev/null"
+ cmd | getline showmap
+ close(cmd)
} else {
# then we look in the current directory
if (0 == system("test -x ./afl-showmap")) {
@@ -413,7 +422,9 @@ BEGIN {
# yuck, gnu stat is option incompatible to bsd stat
# we use a heuristic to differentiate between
# GNU stat and other stats
- "stat --version 2>/dev/null" | getline statversion
+ cmd = "stat --version 2>/dev/null"
+ cmd | getline statversion
+ close(cmd)
if (statversion ~ /GNU coreutils/) {
stat_format = "-c '%s %n'" # GNU
} else {
@@ -432,6 +443,7 @@ BEGIN {
infilesSmallToBigFullMap[infilesSmallToBigFull[i]] = infilesSmallToBig[i]
i++
}
+ close(cmdline)
in_count = i
first_file = infilesSmallToBigFull[0]
@@ -468,6 +480,7 @@ BEGIN {
while ((getline < runtest) > 0) {
++first_count
}
+ close(runtest)
if (first_count) {
print "[+] OK, "first_count" tuples recorded."
@@ -582,6 +595,15 @@ BEGIN {
else { print " Processing file "cur"/"in_count }
# create path for the trace file from afl-showmap
tracefile_path = trace_dir"/"fn
+ # ensure the file size is not zero
+ cmd = "du -b "tracefile_path
+ "ls -l "tracefile_path
+ cmd | getline output
+ close(cmd)
+ split(output, result, "\t")
+ if (result[1] == 0) {
+ print "[!] WARNING: file "fn" is crashing the target, ignoring..."
+ }
# gather all keys, and count them
while ((getline line < tracefile_path) > 0) {
key = line
@@ -643,6 +665,7 @@ BEGIN {
}
}
close(sortedKeys)
+ print ""
print "[+] Found "tuple_count" unique tuples across "in_count" files."
if (out_count == 1) {
diff --git a/afl-cmin.bash b/afl-cmin.bash
index dc6d5342..1d080491 100755
--- a/afl-cmin.bash
+++ b/afl-cmin.bash
@@ -479,7 +479,7 @@ else
echo "[+] all $THREADS running tasks completed."
rm -f ${TMPFILE}*
- echo trace dir files: $(ls $TRACE_DIR/*|wc -l)
+ #echo trace dir files: $(ls $TRACE_DIR/*|wc -l)
fi
@@ -523,6 +523,8 @@ ls -rS "$IN_DIR" | while read -r fn; do
sed "s#\$# $fn#" "$TRACE_DIR/$fn" >>"$TRACE_DIR/.candidate_list"
+ test -s "$TRACE_DIR/$fn" || echo Warning: $fn is ignored because of crashing the target
+
done
echo
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 4454456e..246c3cac 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -14,6 +14,10 @@
command line tool! See custom_mutators/aflpp/standalone/
- display the state of the fuzzing run in the UI :-)
- fix timeout setting if '+' is used or a session is restarted
+ - afl-cmin/afl-cmin.bash:
+ - fixed a bug inherited from vanilla AFL where a coverage of
+ map[123] = 11 would be the same as map[1123] = 1
+ - warn on crashing inputs
### Version ++4.07c (release)
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index 9c029035..13867fda 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -243,7 +243,8 @@ static void analyze_results(afl_forkserver_t *fsrv) {
total += fsrv->trace_bits[i];
if (fsrv->trace_bits[i] > highest) highest = fsrv->trace_bits[i];
- if (!coverage_map[i]) { coverage_map[i] = 1; }
+ // if (!coverage_map[i]) { coverage_map[i] = 1; }
+ coverage_map[i] |= fsrv->trace_bits[i];
}
@@ -328,7 +329,7 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) {
if (cmin_mode) {
- fprintf(f, "%u%u\n", fsrv->trace_bits[i], i);
+ fprintf(f, "%u%03u\n", i, fsrv->trace_bits[i]);
} else {
--
cgit 1.4.1
From 90f83c13d08f44fbf50036076a1772909c4d2c86 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 22 Jun 2023 09:24:00 +0200
Subject: remove dead code, code format
---
.custom-format.py | 2 +-
docs/Changelog.md | 3 ++
include/alloc-inl.h | 8 +++---
instrumentation/SanitizerCoveragePCGUARD.so.cc | 39 ++------------------------
qemu_mode/libqasan/dlmalloc.c | 2 +-
src/afl-fuzz-init.c | 8 +++---
src/afl-fuzz.c | 3 +-
utils/afl_network_proxy/afl-network-server.c | 2 +-
8 files changed, 19 insertions(+), 48 deletions(-)
(limited to 'docs')
diff --git a/.custom-format.py b/.custom-format.py
index 1d5c8839..3521c05d 100755
--- a/.custom-format.py
+++ b/.custom-format.py
@@ -24,7 +24,7 @@ import importlib.metadata
# string_re = re.compile('(\\"(\\\\.|[^"\\\\])*\\")') # TODO: for future use
-CURRENT_LLVM = os.getenv('LLVM_VERSION', 15)
+CURRENT_LLVM = os.getenv('LLVM_VERSION', 16)
CLANG_FORMAT_BIN = os.getenv("CLANG_FORMAT_BIN", "")
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 246c3cac..c850c43e 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -18,6 +18,9 @@
- fixed a bug inherited from vanilla AFL where a coverage of
map[123] = 11 would be the same as map[1123] = 1
- warn on crashing inputs
+ - afl-cc
+ - fixed an off-by-one instrumentation of iselect, hurting coverage a bit.
+ Thanks to @amykweon for spotting and fixing!
### Version ++4.07c (release)
diff --git a/include/alloc-inl.h b/include/alloc-inl.h
index 1e9a192b..cff808b2 100644
--- a/include/alloc-inl.h
+++ b/include/alloc-inl.h
@@ -322,7 +322,7 @@ static inline void DFL_ck_free(void *mem) {
static inline void *DFL_ck_realloc(void *orig, u32 size) {
void *ret;
- u32 old_size = 0;
+ u32 old_size = 0;
if (!size) {
@@ -392,7 +392,7 @@ static inline void *DFL_ck_realloc(void *orig, u32 size) {
static inline u8 *DFL_ck_strdup(u8 *str) {
void *ret;
- u32 size;
+ u32 size;
if (!str) return NULL;
@@ -438,14 +438,14 @@ struct TRK_obj {
void *ptr;
char *file, *func;
- u32 line;
+ u32 line;
};
#ifdef AFL_MAIN
struct TRK_obj *TRK[ALLOC_BUCKETS];
-u32 TRK_cnt[ALLOC_BUCKETS];
+u32 TRK_cnt[ALLOC_BUCKETS];
#define alloc_report() TRK_report()
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index d87af775..57b5d128 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -225,49 +225,18 @@ llvmGetPassPluginInfo() {
}
-#if LLVM_VERSION_MAJOR == 1
+#if LLVM_VERSION_MAJOR >= 16
PreservedAnalyses ModuleSanitizerCoverageAFL::run(Module &M,
ModuleAnalysisManager &MAM) {
- ModuleSanitizerCoverageAFL ModuleSancov(Options);
- auto &FAM = MAM.getResult(M).getManager();
- auto DTCallback = [&FAM](Function &F) -> const DominatorTree *{
-
- return &FAM.getResult(F);
-
- };
-
- auto PDTCallback = [&FAM](Function &F) -> const PostDominatorTree * {
-
- return &FAM.getResult(F);
-
- };
-
- if (!ModuleSancov.instrumentModule(M, DTCallback, PDTCallback))
- return PreservedAnalyses::all();
-
- PreservedAnalyses PA = PreservedAnalyses::none();
- // GlobalsAA is considered stateless and does not get invalidated unless
- // explicitly invalidated; PreservedAnalyses::none() is not enough. Sanitizers
- // make changes that require GlobalsAA to be invalidated.
- PA.abandon();
- return PA;
-
-}
-
#else
- #if LLVM_VERSION_MAJOR >= 16
-PreservedAnalyses ModuleSanitizerCoverageAFL::run(Module &M,
- ModuleAnalysisManager &MAM) {
-
- #else
PreservedAnalyses ModuleSanitizerCoverageAFL::run(Module &M,
ModuleAnalysisManager &MAM) {
- #endif
+#endif
ModuleSanitizerCoverageAFL ModuleSancov(Options);
auto &FAM = MAM.getResult(M).getManager();
- auto DTCallback = [&FAM](Function &F) -> const DominatorTree * {
+ auto DTCallback = [&FAM](Function &F) -> const DominatorTree *{
return &FAM.getResult(F);
@@ -285,8 +254,6 @@ PreservedAnalyses ModuleSanitizerCoverageAFL::run(Module &M,
}
-#endif
-
std::pair ModuleSanitizerCoverageAFL::CreateSecStartEnd(
Module &M, const char *Section, Type *Ty) {
diff --git a/qemu_mode/libqasan/dlmalloc.c b/qemu_mode/libqasan/dlmalloc.c
index 5d0b65ce..b459eb7b 100644
--- a/qemu_mode/libqasan/dlmalloc.c
+++ b/qemu_mode/libqasan/dlmalloc.c
@@ -1762,7 +1762,7 @@ static FORCEINLINE void *win32direct_mmap(size_t size) {
static FORCEINLINE int win32munmap(void *ptr, size_t size) {
MEMORY_BASIC_INFORMATION minfo;
- char *cptr = (char *)ptr;
+ char *cptr = (char *)ptr;
while (size) {
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index 13802f40..24fd7077 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -1542,8 +1542,8 @@ double get_runnable_processes(void) {
processes well. */
FILE *f = fopen("/proc/stat", "r");
- u8 tmp[1024];
- u32 val = 0;
+ u8 tmp[1024];
+ u32 val = 0;
if (!f) { return 0; }
@@ -2226,7 +2226,7 @@ void check_crash_handling(void) {
*BSD, so we can just let it slide for now. */
s32 fd = open("/proc/sys/kernel/core_pattern", O_RDONLY);
- u8 fchar;
+ u8 fchar;
if (fd < 0) { return; }
@@ -2365,7 +2365,7 @@ void check_cpu_governor(afl_state_t *afl) {
FATAL("Suboptimal CPU scaling governor");
#elif defined __APPLE__
- u64 min = 0, max = 0;
+ u64 min = 0, max = 0;
size_t mlen = sizeof(min);
if (afl->afl_env.afl_skip_cpufreq) return;
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 8cf786af..79b05da7 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -164,7 +164,8 @@ static void usage(u8 *argv0, int more_help) {
"\n"
"Mutator settings:\n"
- " -a - target expects ascii text input (prefer text mutators)\n"
+ " -a - target expects ascii text input (prefer text "
+ "mutators)\n"
" -g minlength - set min length of generated fuzz input (default: 1)\n"
" -G maxlength - set max length of generated fuzz input (default: "
"%lu)\n"
diff --git a/utils/afl_network_proxy/afl-network-server.c b/utils/afl_network_proxy/afl-network-server.c
index 7eb3d18e..95b0a551 100644
--- a/utils/afl_network_proxy/afl-network-server.c
+++ b/utils/afl_network_proxy/afl-network-server.c
@@ -173,7 +173,7 @@ static void set_up_environment(afl_forkserver_t *fsrv) {
}
out_file = alloc_printf("%s/.afl-input-temp-%u", use_dir, getpid());
- fsrv->out_file = out_file;
+ fsrv->out_file = out_file;
}
--
cgit 1.4.1
From edd352612da1f58832cbe84d909a8998ce4fa690 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sat, 24 Jun 2023 09:30:09 +0200
Subject: code format
---
docs/Changelog.md | 6 +++++-
instrumentation/split-compares-pass.so.cc | 12 +++++++++---
2 files changed, 14 insertions(+), 4 deletions(-)
(limited to 'docs')
diff --git a/docs/Changelog.md b/docs/Changelog.md
index c850c43e..e6b90d3d 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -18,9 +18,13 @@
- fixed a bug inherited from vanilla AFL where a coverage of
map[123] = 11 would be the same as map[1123] = 1
- warn on crashing inputs
- - afl-cc
+ - afl-cc:
- fixed an off-by-one instrumentation of iselect, hurting coverage a bit.
Thanks to @amykweon for spotting and fixing!
+ - @toka fixed a bug in laf-intel signed integer comparison splitting,
+ thanks a lot!!
+ - frida_mode:
+ - support for long form instrumentation on x86_x64 and arm64
### Version ++4.07c (release)
diff --git a/instrumentation/split-compares-pass.so.cc b/instrumentation/split-compares-pass.so.cc
index 3cfd1964..6eafb332 100644
--- a/instrumentation/split-compares-pass.so.cc
+++ b/instrumentation/split-compares-pass.so.cc
@@ -464,8 +464,11 @@ bool SplitComparesTransform::simplifyOrEqualsCompare(CmpInst *IcmpInst,
ReplaceInstWithInst(IcmpInst->getParent()->getInstList(), ii, PN);
#endif
if (new_pred == CmpInst::ICMP_SGT || new_pred == CmpInst::ICMP_SLT) {
+
simplifySignedCompare(icmp_np, M, worklist);
+
}
+
worklist.push_back(icmp_eq);
return true;
@@ -751,11 +754,14 @@ bool SplitComparesTransform::splitCompare(CmpInst *cmp_inst, Module &M,
icmp_inv_cmp = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGT,
op0_high, op1_high);
- }
- else {
+ } else {
+
// Never gonna appen
if (!be_quiet)
- fprintf(stderr, "Error: split-compare: Equals or signed not removed: %d\n", pred);
+ fprintf(stderr,
+ "Error: split-compare: Equals or signed not removed: %d\n",
+ pred);
+
}
#if LLVM_MAJOR >= 16
--
cgit 1.4.1
From 3e1d7941077b1457f702988063d6b9fdd9b80740 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 29 Jun 2023 16:57:20 +0200
Subject: update mutation strategy
---
docs/Changelog.md | 4 +++-
include/afl-fuzz.h | 59 +++++++++++++++++++++++++------------------------
include/afl-mutations.h | 6 ++---
src/afl-fuzz-one.c | 56 +++++++++++++++++++++++++++-------------------
src/afl-fuzz.c | 26 +++++++++++++++++-----
5 files changed, 90 insertions(+), 61 deletions(-)
(limited to 'docs')
diff --git a/docs/Changelog.md b/docs/Changelog.md
index e6b90d3d..ad58e99e 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -8,7 +8,8 @@
- new mutation engine: mutations that favor discovery more paths are
prefered until no new finds for 10 minutes then switching to mutations
that favor triggering crashes. Modes and switch time can be configured
- with `-P`.
+ with `-P`. Also input mode for the target can be defined with `-a` to
+ be `text` or `binary` (defaults to `generic`)
- new custom mutator that has the new afl++ engine (so it can easily
incorporated into new custom mutators), and also comes with a standalone
command line tool! See custom_mutators/aflpp/standalone/
@@ -23,6 +24,7 @@
Thanks to @amykweon for spotting and fixing!
- @toka fixed a bug in laf-intel signed integer comparison splitting,
thanks a lot!!
+ - more LLVM compatability
- frida_mode:
- support for long form instrumentation on x86_x64 and arm64
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index c6c45fbd..9da5cc03 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -505,36 +505,37 @@ typedef struct afl_state {
is_main_node, /* if this is the main node */
is_secondary_node, /* if this is a secondary instance */
pizza_is_served, /* pizza mode */
- text_input, /* target wants text inputs */
- fuzz_mode, /* current mode: coverage/exploration or crash/exploitation */
+ input_mode, /* target wants text inputs */
+ fuzz_mode, /* coverage/exploration or crash/exploitation mode */
schedule, /* Power schedule (default: EXPLORE)*/
- havoc_max_mult, skip_deterministic, /* Skip deterministic stages? */
- use_splicing, /* Recombine input files? */
- non_instrumented_mode, /* Run in non-instrumented mode? */
- score_changed, /* Scoring for favorites changed? */
- resuming_fuzz, /* Resuming an older fuzzing job? */
- timeout_given, /* Specific timeout given? */
- not_on_tty, /* stdout is not a tty */
- term_too_small, /* terminal dimensions too small */
- no_forkserver, /* Disable forkserver? */
- crash_mode, /* Crash mode! Yeah! */
- in_place_resume, /* Attempt in-place resume? */
- autoresume, /* Resume if afl->out_dir exists? */
- auto_changed, /* Auto-generated tokens changed? */
- no_cpu_meter_red, /* Feng shui on the status screen */
- no_arith, /* Skip most arithmetic ops */
- shuffle_queue, /* Shuffle input queue? */
- bitmap_changed, /* Time to update bitmap? */
- unicorn_mode, /* Running in Unicorn mode? */
- use_wine, /* Use WINE with QEMU mode */
- skip_requested, /* Skip request, via SIGUSR1 */
- run_over10m, /* Run time over 10 minutes? */
- persistent_mode, /* Running in persistent mode? */
- deferred_mode, /* Deferred forkserver mode? */
- fixed_seed, /* do not reseed */
- fast_cal, /* Try to calibrate faster? */
- disable_trim, /* Never trim in fuzz_one */
- shmem_testcase_mode, /* If sharedmem testcases are used */
+ havoc_max_mult, /* havoc multiplier */
+ skip_deterministic, /* Skip deterministic stages? */
+ use_splicing, /* Recombine input files? */
+ non_instrumented_mode, /* Run in non-instrumented mode? */
+ score_changed, /* Scoring for favorites changed? */
+ resuming_fuzz, /* Resuming an older fuzzing job? */
+ timeout_given, /* Specific timeout given? */
+ not_on_tty, /* stdout is not a tty */
+ term_too_small, /* terminal dimensions too small */
+ no_forkserver, /* Disable forkserver? */
+ crash_mode, /* Crash mode! Yeah! */
+ in_place_resume, /* Attempt in-place resume? */
+ autoresume, /* Resume if afl->out_dir exists? */
+ auto_changed, /* Auto-generated tokens changed? */
+ no_cpu_meter_red, /* Feng shui on the status screen */
+ no_arith, /* Skip most arithmetic ops */
+ shuffle_queue, /* Shuffle input queue? */
+ bitmap_changed, /* Time to update bitmap? */
+ unicorn_mode, /* Running in Unicorn mode? */
+ use_wine, /* Use WINE with QEMU mode */
+ skip_requested, /* Skip request, via SIGUSR1 */
+ run_over10m, /* Run time over 10 minutes? */
+ persistent_mode, /* Running in persistent mode? */
+ deferred_mode, /* Deferred forkserver mode? */
+ fixed_seed, /* do not reseed */
+ fast_cal, /* Try to calibrate faster? */
+ disable_trim, /* Never trim in fuzz_one */
+ shmem_testcase_mode, /* If sharedmem testcases are used */
expand_havoc, /* perform expensive havoc after no find */
cycle_schedules, /* cycle power schedules? */
old_seed_selection, /* use vanilla afl seed selection */
diff --git a/include/afl-mutations.h b/include/afl-mutations.h
index cc4840c8..0a9bbbf4 100644
--- a/include/afl-mutations.h
+++ b/include/afl-mutations.h
@@ -14,14 +14,14 @@
Parameters:
afl_state_t *afl - the *afl state pointer
u8 *buf - the input buffer to mutate which will be mutated into.
- NOTE: must be able to contain a size of at least max_len (see below)!
+ NOTE: must be able to contain a size of at least max_len!! (see below)
u32 len - the length of the input
u32 steps - how many mutations to perform on the input
bool is_text - is the target expecting text inputs
bool is_exploration - mutate for exploration mode (instead of exploitation)
splice_buf - a buffer from another corpus item to splice with.
- If NULL then no splicing
- splice_len - the length of the splice buffer. If 0 then no splicing
+ If NULL then no splicing is done (obviously).
+ splice_len - the length of the splice buffer. If 0 then no splicing.
u32 max_len - the maximum size the mutated buffer may grow to
*/
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index c6e49653..0d3c29f2 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -2085,47 +2085,57 @@ havoc_stage:
u32 *mutation_array;
u32 stack_max, rand_max; // stack_max_pow = afl->havoc_stack_pow2;
- /*
+ switch (afl->input_mode) {
- if (unlikely(afl->expand_havoc && afl->ready_for_splicing_count > 1)) {
+ case 1: { // TEXT
- mutation_array = full_splice_array;
- rand_max = MUT_SPLICE_ARRAY_SIZE;
+ if (likely(afl->fuzz_mode == 0)) { // is exploration?
+ mutation_array = (unsigned int *)&binary_array;
+ rand_max = MUT_BIN_ARRAY_SIZE;
- } else {
+ } else { // exploitation mode
- mutation_array = normal_splice_array;
- rand_max = MUT_NORMAL_ARRAY_SIZE;
+ mutation_array = (unsigned int *)&mutation_strategy_exploitation_text;
+ rand_max = MUT_STRATEGY_ARRAY_SIZE;
- }
+ }
- */
+ break;
- if (unlikely(afl->text_input)) { // is text?
+ }
- if (likely(afl->fuzz_mode == 0)) { // is exploration?
+ case 2: { // BINARY
- mutation_array = (unsigned int *)&text_array;
- rand_max = MUT_TXT_ARRAY_SIZE;
+ if (likely(afl->fuzz_mode == 0)) { // is exploration?
+ mutation_array = (unsigned int *)&mutation_strategy_exploration_binary;
+ rand_max = MUT_STRATEGY_ARRAY_SIZE;
- } else { // is exploitation!
+ } else { // exploitation mode
- mutation_array = (unsigned int *)&mutation_strategy_exploitation_text;
- rand_max = MUT_STRATEGY_ARRAY_SIZE;
+ mutation_array = (unsigned int *)&mutation_strategy_exploitation_binary;
+ rand_max = MUT_STRATEGY_ARRAY_SIZE;
+
+ }
+
+ break;
}
- } else { // is binary!
+ default: { // DEFAULT/GENERIC
- if (likely(afl->fuzz_mode == 0)) { // is exploration?
+ if (likely(afl->fuzz_mode == 0)) { // is exploration?
+ mutation_array = (unsigned int *)&binary_array;
+ rand_max = MUT_BIN_ARRAY_SIZE;
- mutation_array = (unsigned int *)&binary_array;
- rand_max = MUT_BIN_ARRAY_SIZE;
+ } else { // exploitation mode
- } else { // is exploitation!
+ // this will need to be changed I guess
+ mutation_array = (unsigned int *)&mutation_strategy_exploration_text;
+ rand_max = MUT_STRATEGY_ARRAY_SIZE;
+
+ }
- mutation_array = (unsigned int *)&mutation_strategy_exploitation_binary;
- rand_max = MUT_STRATEGY_ARRAY_SIZE;
+ break;
}
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 79b05da7..ab7d6534 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -125,7 +125,8 @@ static void usage(u8 *argv0, int more_help) {
"Required parameters:\n"
" -i dir - input directory with test cases (or '-' to resume, "
- "also see AFL_AUTORESUME)\n"
+ "also see \n"
+ " AFL_AUTORESUME)\n"
" -o dir - output directory for fuzzer findings\n\n"
"Execution control settings:\n"
@@ -164,8 +165,8 @@ static void usage(u8 *argv0, int more_help) {
"\n"
"Mutator settings:\n"
- " -a - target expects ascii text input (prefer text "
- "mutators)\n"
+ " -a - target input format, \"text\" or \"binary\" (default: "
+ "generic)\n"
" -g minlength - set min length of generated fuzz input (default: 1)\n"
" -G maxlength - set max length of generated fuzz input (default: "
"%lu)\n"
@@ -506,13 +507,28 @@ int main(int argc, char **argv_orig, char **envp) {
// still available: HjJkKqruvwz
while ((opt = getopt(argc, argv,
- "+aAb:B:c:CdDe:E:f:F:g:G:hi:I:l:L:m:M:nNo:Op:P:QRs:S:t:"
+ "+a:Ab:B:c:CdDe:E:f:F:g:G:hi:I:l:L:m:M:nNo:Op:P:QRs:S:t:"
"T:UV:WXx:YZ")) > 0) {
switch (opt) {
case 'a':
- afl->text_input = 1;
+
+ if (!stricmp(optarg, "text") || !stricmp(optarg, "ascii") ||
+ !stricmp(optarg, "txt") || !stricmp(optarg, "asc")) {
+
+ afl->input_mode = 1;
+
+ } else if (!stricmp(optarg, "bin") || !stricmp(optarg, "binary")) {
+
+ afl->input_mode = 2;
+
+ } else {
+
+ FATAL("-a input mode needs to be \"text\" or \"binary\".");
+
+ }
+
break;
case 'P':
--
cgit 1.4.1
From 20dcb40c53811e36a3ace91a66a70cfddc4b3f1c Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sat, 8 Jul 2023 13:31:06 +0200
Subject: fix cmin -T
---
afl-cmin | 5 +++++
afl-cmin.bash | 7 +++++++
docs/Changelog.md | 1 +
3 files changed, 13 insertions(+)
(limited to 'docs')
diff --git a/afl-cmin b/afl-cmin
index d0bbed2b..f3ae4304 100755
--- a/afl-cmin
+++ b/afl-cmin
@@ -493,6 +493,11 @@ BEGIN {
}
}
+ if (in_count < threads) {
+ threads = in_count
+ print "[!] WARNING: less inputs than threads, reducing threads to "threads" and likely the overhead of threading makes things slower..."
+ }
+
# Let's roll!
#############################
diff --git a/afl-cmin.bash b/afl-cmin.bash
index 1d080491..b326bee8 100755
--- a/afl-cmin.bash
+++ b/afl-cmin.bash
@@ -339,6 +339,13 @@ fi
echo "[*] Are you aware that afl-cmin is faster than this afl-cmin.bash script?"
echo "[+] Found $IN_COUNT files for minimizing."
+if [ -n "$THREADS" ]; then
+ if [ "$IN_COUNT" -lt "$THREADS" ]; then
+ THREADS=$IN_COUNT
+ echo "[!] WARNING: less inputs than threads, reducing threads to $THREADS and likely the overhead of threading makes things slower..."
+ fi
+fi
+
FIRST_FILE=`ls "$IN_DIR" | head -1`
# Make sure that we're not dealing with a directory.
diff --git a/docs/Changelog.md b/docs/Changelog.md
index ad58e99e..032bb774 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -19,6 +19,7 @@
- fixed a bug inherited from vanilla AFL where a coverage of
map[123] = 11 would be the same as map[1123] = 1
- warn on crashing inputs
+ - adjust threads if less inputs than threads specified
- afl-cc:
- fixed an off-by-one instrumentation of iselect, hurting coverage a bit.
Thanks to @amykweon for spotting and fixing!
--
cgit 1.4.1
From 534b3eba143c0532e600eb6da08ac2195fa24570 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 13 Jul 2023 10:10:30 +0200
Subject: qemu_get_symbol_addr.sh
---
Dockerfile | 2 +-
docs/Changelog.md | 3 ++
frida_mode/test/bloaty/GNUmakefile | 2 +-
frida_mode/test/cache/GNUmakefile | 2 +-
frida_mode/test/cmov/GNUmakefile | 2 +-
frida_mode/test/deferred/GNUmakefile | 2 +-
frida_mode/test/dynamic/GNUmakefile | 2 +-
frida_mode/test/entry_point/GNUmakefile | 2 +-
frida_mode/test/freetype2/GNUmakefile | 2 +-
frida_mode/test/jpeg/GNUmakefile | 2 +-
frida_mode/test/libpcap/GNUmakefile | 2 +-
frida_mode/test/libxml/GNUmakefile | 2 +-
frida_mode/test/libxslt/GNUmakefile | 2 +-
frida_mode/test/osx-lib/GNUmakefile | 2 +-
frida_mode/test/perf/GNUmakefile | 2 +-
frida_mode/test/persistent_ret/GNUmakefile | 2 +-
frida_mode/test/png/persistent/GNUmakefile | 2 +-
frida_mode/test/png/persistent/hook/GNUmakefile | 2 +-
frida_mode/test/proj4/GNUmakefile | 2 +-
frida_mode/test/re2/GNUmakefile | 2 +-
frida_mode/test/sqlite/GNUmakefile | 2 +-
frida_mode/test/unstable/GNUmakefile | 2 +-
frida_mode/test/vorbis/GNUmakefile | 2 +-
frida_mode/util/frida_get_symbol_addr.sh | 55 +++++++++++++++++++++++++
frida_mode/util/get_symbol_addr.sh | 32 --------------
qemu_mode/util/qemu_get_symbol_addr.sh | 53 ++++++++++++++++++++++++
26 files changed, 133 insertions(+), 54 deletions(-)
create mode 100755 frida_mode/util/frida_get_symbol_addr.sh
delete mode 100755 frida_mode/util/get_symbol_addr.sh
create mode 100755 qemu_mode/util/qemu_get_symbol_addr.sh
(limited to 'docs')
diff --git a/Dockerfile b/Dockerfile
index 1b5ffd28..e1616198 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -42,7 +42,7 @@ RUN apt-get update && \
python3 python3-dev python3-pip python-is-python3 \
libtool libtool-bin libglib2.0-dev \
apt-transport-https gnupg dialog \
- gnuplot-nox libpixman-1-dev \
+ gnuplot-nox libpixman-1-dev bc \
gcc-${GCC_VERSION} g++-${GCC_VERSION} gcc-${GCC_VERSION}-plugin-dev gdb lcov \
clang-${LLVM_VERSION} clang-tools-${LLVM_VERSION} libc++1-${LLVM_VERSION} \
libc++-${LLVM_VERSION}-dev libc++abi1-${LLVM_VERSION} libc++abi-${LLVM_VERSION}-dev \
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 032bb774..d61ce8ec 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -28,6 +28,9 @@
- more LLVM compatability
- frida_mode:
- support for long form instrumentation on x86_x64 and arm64
+ - renamed utils/get_symbol_addr.sh to utils/frida_get_symbol_addr.sh
+ - qemu_mode:
+ - added qemu_mode/utils/qemu_get_symbol_addr.sh
### Version ++4.07c (release)
diff --git a/frida_mode/test/bloaty/GNUmakefile b/frida_mode/test/bloaty/GNUmakefile
index 8e767fae..02a0a1e2 100644
--- a/frida_mode/test/bloaty/GNUmakefile
+++ b/frida_mode/test/bloaty/GNUmakefile
@@ -35,7 +35,7 @@ endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
diff --git a/frida_mode/test/cache/GNUmakefile b/frida_mode/test/cache/GNUmakefile
index 12736a3f..98776193 100644
--- a/frida_mode/test/cache/GNUmakefile
+++ b/frida_mode/test/cache/GNUmakefile
@@ -11,7 +11,7 @@ QEMU_OUT:=$(BUILD_DIR)qemu-out
FRIDA_OUT:=$(BUILD_DIR)frida-out
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFLPP_FRIDA_DRIVER_HOOK_OBJ=$(ROOT)frida_mode/build/frida_hook.so
diff --git a/frida_mode/test/cmov/GNUmakefile b/frida_mode/test/cmov/GNUmakefile
index 96f1ae5b..0712e33b 100644
--- a/frida_mode/test/cmov/GNUmakefile
+++ b/frida_mode/test/cmov/GNUmakefile
@@ -11,7 +11,7 @@ QEMU_OUT:=$(BUILD_DIR)qemu-out
FRIDA_OUT:=$(BUILD_DIR)frida-out
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFLPP_FRIDA_DRIVER_HOOK_OBJ=$(ROOT)frida_mode/build/frida_hook.so
diff --git a/frida_mode/test/deferred/GNUmakefile b/frida_mode/test/deferred/GNUmakefile
index 22aeb2bf..e0b48797 100644
--- a/frida_mode/test/deferred/GNUmakefile
+++ b/frida_mode/test/deferred/GNUmakefile
@@ -10,7 +10,7 @@ TESTINSTSRC:=$(PWD)testinstr.c
QEMU_OUT:=$(BUILD_DIR)qemu-out
FRIDA_OUT:=$(BUILD_DIR)frida-out
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
ifndef ARCH
diff --git a/frida_mode/test/dynamic/GNUmakefile b/frida_mode/test/dynamic/GNUmakefile
index f43416f7..6c577dff 100644
--- a/frida_mode/test/dynamic/GNUmakefile
+++ b/frida_mode/test/dynamic/GNUmakefile
@@ -17,7 +17,7 @@ FRIDA_OUT:=$(BUILD_DIR)frida-out
AFLPP_FRIDA_DRIVER_HOOK_OBJ=$(ROOT)frida_mode/build/frida_hook.so
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TESTINSTBIN) testinstr $(AFL_FRIDA_BASE_ADDR))
diff --git a/frida_mode/test/entry_point/GNUmakefile b/frida_mode/test/entry_point/GNUmakefile
index 08c660f7..b8c0ecb5 100644
--- a/frida_mode/test/entry_point/GNUmakefile
+++ b/frida_mode/test/entry_point/GNUmakefile
@@ -10,7 +10,7 @@ TESTINSTSRC:=$(PWD)testinstr.c
QEMU_OUT:=$(BUILD_DIR)qemu-out
FRIDA_OUT:=$(BUILD_DIR)frida-out
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
ifndef ARCH
diff --git a/frida_mode/test/freetype2/GNUmakefile b/frida_mode/test/freetype2/GNUmakefile
index 8c35d5de..23318d52 100644
--- a/frida_mode/test/freetype2/GNUmakefile
+++ b/frida_mode/test/freetype2/GNUmakefile
@@ -64,7 +64,7 @@ endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
diff --git a/frida_mode/test/jpeg/GNUmakefile b/frida_mode/test/jpeg/GNUmakefile
index a8242081..a4967039 100644
--- a/frida_mode/test/jpeg/GNUmakefile
+++ b/frida_mode/test/jpeg/GNUmakefile
@@ -47,7 +47,7 @@ endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
diff --git a/frida_mode/test/libpcap/GNUmakefile b/frida_mode/test/libpcap/GNUmakefile
index 1bf9cd7f..745d7057 100644
--- a/frida_mode/test/libpcap/GNUmakefile
+++ b/frida_mode/test/libpcap/GNUmakefile
@@ -56,7 +56,7 @@ endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
diff --git a/frida_mode/test/libxml/GNUmakefile b/frida_mode/test/libxml/GNUmakefile
index 6fc87585..f1f4a738 100644
--- a/frida_mode/test/libxml/GNUmakefile
+++ b/frida_mode/test/libxml/GNUmakefile
@@ -43,7 +43,7 @@ endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
diff --git a/frida_mode/test/libxslt/GNUmakefile b/frida_mode/test/libxslt/GNUmakefile
index 655e652b..48bb0b40 100644
--- a/frida_mode/test/libxslt/GNUmakefile
+++ b/frida_mode/test/libxslt/GNUmakefile
@@ -42,7 +42,7 @@ endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
diff --git a/frida_mode/test/osx-lib/GNUmakefile b/frida_mode/test/osx-lib/GNUmakefile
index 96dbb5ad..fdc9ec04 100644
--- a/frida_mode/test/osx-lib/GNUmakefile
+++ b/frida_mode/test/osx-lib/GNUmakefile
@@ -26,7 +26,7 @@ FRIDA_OUT:=$(BUILD_DIR)frida-out
HARNESS_LDFLAGS:=-Wl,-no_pie
LIB_CFLAGS:=-dynamiclib
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFL_FRIDA_MAIN_ADDR=$(shell $(GET_SYMBOL_ADDR) $(HARNESS_BIN) main 0x0)
AFL_FRIDA_MAIN_ADDR2=$(shell $(GET_SYMBOL_ADDR) $(HARNESS2_BIN) main 0x0)
AFL_FRIDA_FUZZ_ADDR=$(shell $(GET_SYMBOL_ADDR) $(HARNESS_BIN) LLVMFuzzerTestOneInput 0x0)
diff --git a/frida_mode/test/perf/GNUmakefile b/frida_mode/test/perf/GNUmakefile
index 2d7c0239..6b49c2ba 100644
--- a/frida_mode/test/perf/GNUmakefile
+++ b/frida_mode/test/perf/GNUmakefile
@@ -31,7 +31,7 @@ endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
diff --git a/frida_mode/test/persistent_ret/GNUmakefile b/frida_mode/test/persistent_ret/GNUmakefile
index 71f6a124..73d710a1 100644
--- a/frida_mode/test/persistent_ret/GNUmakefile
+++ b/frida_mode/test/persistent_ret/GNUmakefile
@@ -23,7 +23,7 @@ endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
ifeq "$(shell uname)" "Darwin"
TEST_BIN_LDFLAGS:=-Wl,-no_pie
diff --git a/frida_mode/test/png/persistent/GNUmakefile b/frida_mode/test/png/persistent/GNUmakefile
index 94e2be38..3dab713e 100644
--- a/frida_mode/test/png/persistent/GNUmakefile
+++ b/frida_mode/test/png/persistent/GNUmakefile
@@ -22,7 +22,7 @@ endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
diff --git a/frida_mode/test/png/persistent/hook/GNUmakefile b/frida_mode/test/png/persistent/hook/GNUmakefile
index b6a1ca1a..f3d06c87 100644
--- a/frida_mode/test/png/persistent/hook/GNUmakefile
+++ b/frida_mode/test/png/persistent/hook/GNUmakefile
@@ -33,7 +33,7 @@ endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
diff --git a/frida_mode/test/proj4/GNUmakefile b/frida_mode/test/proj4/GNUmakefile
index debc8a88..17850fa8 100644
--- a/frida_mode/test/proj4/GNUmakefile
+++ b/frida_mode/test/proj4/GNUmakefile
@@ -47,7 +47,7 @@ endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
diff --git a/frida_mode/test/re2/GNUmakefile b/frida_mode/test/re2/GNUmakefile
index 220e7616..0b79210b 100644
--- a/frida_mode/test/re2/GNUmakefile
+++ b/frida_mode/test/re2/GNUmakefile
@@ -48,7 +48,7 @@ endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
diff --git a/frida_mode/test/sqlite/GNUmakefile b/frida_mode/test/sqlite/GNUmakefile
index df470af8..6d3c7496 100644
--- a/frida_mode/test/sqlite/GNUmakefile
+++ b/frida_mode/test/sqlite/GNUmakefile
@@ -43,7 +43,7 @@ endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
diff --git a/frida_mode/test/unstable/GNUmakefile b/frida_mode/test/unstable/GNUmakefile
index 59b49449..3b7b6ddb 100644
--- a/frida_mode/test/unstable/GNUmakefile
+++ b/frida_mode/test/unstable/GNUmakefile
@@ -23,7 +23,7 @@ endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
diff --git a/frida_mode/test/vorbis/GNUmakefile b/frida_mode/test/vorbis/GNUmakefile
index 4cb5d417..b10d059e 100644
--- a/frida_mode/test/vorbis/GNUmakefile
+++ b/frida_mode/test/vorbis/GNUmakefile
@@ -54,7 +54,7 @@ endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
diff --git a/frida_mode/util/frida_get_symbol_addr.sh b/frida_mode/util/frida_get_symbol_addr.sh
new file mode 100755
index 00000000..fb0002b7
--- /dev/null
+++ b/frida_mode/util/frida_get_symbol_addr.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+# Copyright 2023 AFLplusplus
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+target="$1"
+symbol="$2"
+base="$3"
+
+test -z "$target" -o -z "$symbol" -o '!' -x "$target" && {
+ echo "Syntax: $0 executable function [baseaddress]"
+ echo
+ echo Help script to calculate the function address of a binary QEMU will load it to.
+ echo function is e.g. LLVMFuzzerTestOneInput, afl_qemu_driver_stdin, etc.
+ echo "baseaddress is tried to be auto-detected, you can use 'AFL_QEMU_DEBUG_MAPS=1 afl-qemu-trace ./executable' to see the maps."
+ exit 1
+}
+
+file=$(file $target|sed 's/.*: //')
+
+arch=$(echo $file|awk -F, '{print$2}'|tr -d ' ')
+bits=$(echo $file|sed 's/-bit .*//'|sed 's/.* //')
+pie=$(echo $file|grep -wqi pie && echo pie)
+
+test $(uname -s) = "Darwin" && symbol=_"$symbol"
+tmp_addr=$(nm "$target" | grep -i "T $symbol" | awk '{print$1}' | tr a-f A-F)
+
+test -z "$tmp_addr" && { echo Error: function $symbol not found 1>&2; exit 1; }
+test -z "$pie" && { echo 0x$tmp_addr; exit 0; }
+
+test -z "$base" && {
+ test "$bits" = 32 -o "$bits" = 64 || { echo "Error: could not identify arch (bits=$bits)" 1>&2 ; exit 1; }
+ # is this true for arm/aarch64/i386 too?
+ base=0x555555554000
+ #test "$arch" = Intel80386 && base=0x5555554000
+ #test "$arch" = x86-64 && base=0x555555554000
+ #test "$arch" = ARMaarch64 && base=0x5500000000
+ # add more here, e.g. "$arch" = ARM
+}
+
+test -z "$base" && { echo "Error: could not identify base address! bits=$bits arch=$arch" 1>&2 ; exit 1; }
+
+hex_base=$(echo "$base" | awk '{sub("^0x","");print $0}' | tr a-f A-F )
+echo $tmp_addr | echo "ibase=16;obase=10;$hex_base + $tmp_addr" | bc | tr A-F a-f | awk '{print "0x"$0}'
+exit 0
diff --git a/frida_mode/util/get_symbol_addr.sh b/frida_mode/util/get_symbol_addr.sh
deleted file mode 100755
index f5d8df91..00000000
--- a/frida_mode/util/get_symbol_addr.sh
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/bash
-# Copyright 2020 Google LLC
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# set -x
-target="$1"
-symbol="$2"
-base="$3"
-
-test -z "$target" -o -z "$symbol" -o '!' -e "$target" && exit 0
-
-test $(uname -s) = "Darwin" && symbol=_"$symbol"
-
-file "$target" | grep -q executable && {
- nm "$target" | grep -i "T $symbol" | awk '{print"0x"$1}'
- exit 0
-}
-
-hex_base=$(echo "$3" | awk '{sub("^0x","");print $0}' | tr a-f A-F )
-nm "$target" | grep -i "T $symbol" | awk '{print$1}' | tr a-f A-F | \
- xargs echo "ibase=16;obase=10;$hex_base + " | bc | tr A-F a-f | awk '{print "0x"$0}'
-exit 0
diff --git a/qemu_mode/util/qemu_get_symbol_addr.sh b/qemu_mode/util/qemu_get_symbol_addr.sh
new file mode 100755
index 00000000..e0a7ae80
--- /dev/null
+++ b/qemu_mode/util/qemu_get_symbol_addr.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+# Copyright 2023 AFLplusplus
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+target="$1"
+symbol="$2"
+base="$3"
+
+test -z "$target" -o -z "$symbol" -o '!' -x "$target" && {
+ echo "Syntax: $0 executable function [baseaddress]"
+ echo
+ echo Help script to calculate the function address of a binary QEMU will load it to.
+ echo function is e.g. LLVMFuzzerTestOneInput, afl_qemu_driver_stdin, etc.
+ echo "baseaddress is tried to be auto-detected, you can use 'AFL_QEMU_DEBUG_MAPS=1 afl-qemu-trace ./executable' to see the maps."
+ exit 1
+}
+
+file=$(file $target|sed 's/.*: //')
+
+arch=$(echo $file|awk -F, '{print$2}'|tr -d ' ')
+bits=$(echo $file|sed 's/-bit .*//'|sed 's/.* //')
+pie=$(echo $file|grep -wqi pie && echo pie)
+
+test $(uname -s) = "Darwin" && symbol=_"$symbol"
+tmp_addr=$(nm "$target" | grep -i "T $symbol" | awk '{print$1}' | tr a-f A-F)
+
+test -z "$tmp_addr" && { echo Error: function $symbol not found 1>&2; exit 1; }
+test -z "$pie" && { echo 0x$tmp_addr; exit 0; }
+
+test -z "$base" && {
+ test "$bits" = 32 -o "$bits" = 64 || { echo "Error: could not identify arch (bits=$bits)" 1>&2 ; exit 1; }
+ test "$arch" = Intel80386 && base=0x40000000
+ test "$arch" = x86-64 && base=0x4000000000
+ test "$arch" = ARMaarch64 && base=0x5500000000
+ # add more here, e.g. "$arch" = ARM
+}
+
+test -z "$base" && { echo "Error: could not identify base address! bits=$bits arch=$arch" 1>&2 ; exit 1; }
+
+hex_base=$(echo "$base" | awk '{sub("^0x","");print $0}' | tr a-f A-F )
+echo $tmp_addr | echo "ibase=16;obase=10;$hex_base + $tmp_addr" | bc | tr A-F a-f | awk '{print "0x"$0}'
+exit 0
--
cgit 1.4.1
From 5f813bbb86e1c9e2480669c44501e9780043728c Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 21 Jul 2023 18:02:30 +0200
Subject: improve cmplog level 3
---
docs/Changelog.md | 1 +
include/afl-fuzz.h | 3 +-
include/config.h | 8 +--
src/afl-fuzz-redqueen.c | 171 +++++++++++++++++++++++++-----------------------
src/afl-fuzz.c | 7 +-
5 files changed, 100 insertions(+), 90 deletions(-)
(limited to 'docs')
diff --git a/docs/Changelog.md b/docs/Changelog.md
index d61ce8ec..75167172 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -15,6 +15,7 @@
command line tool! See custom_mutators/aflpp/standalone/
- display the state of the fuzzing run in the UI :-)
- fix timeout setting if '+' is used or a session is restarted
+ - -c X option to enable base64 transformation solving
- afl-cmin/afl-cmin.bash:
- fixed a bug inherited from vanilla AFL where a coverage of
map[123] = 11 would be the same as map[1123] = 1
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 27668da0..e114b0fc 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -674,7 +674,8 @@ typedef struct afl_state {
u32 cmplog_max_filesize;
u32 cmplog_lvl;
u32 colorize_success;
- u8 cmplog_enable_arith, cmplog_enable_transform, cmplog_random_colorization;
+ u8 cmplog_enable_arith, cmplog_enable_transform,
+ cmplog_enable_xtreme_transform, cmplog_random_colorization;
struct afl_pass_stat *pass_stats;
struct cmp_map *orig_cmp_map;
diff --git a/include/config.h b/include/config.h
index 7c29a674..df545583 100644
--- a/include/config.h
+++ b/include/config.h
@@ -60,10 +60,6 @@
*
*/
-/* if TRANSFORM is enabled with '-l T', this additionally enables base64
- encoding/decoding */
-// #define CMPLOG_SOLVE_TRANSFORM_BASE64
-
/* If a redqueen pass finds more than one solution, try to combine them? */
#define CMPLOG_COMBINE
@@ -71,10 +67,10 @@
#define CMPLOG_CORPUS_PERCENT 5U
/* Number of potential positions from which we decide if cmplog becomes
- useless, default 8096 */
+ useless, default 12288 */
#define CMPLOG_POSITIONS_MAX (12 * 1024)
-/* Maximum allowed fails per CMP value. Default: 128 */
+/* Maximum allowed fails per CMP value. Default: 96 */
#define CMPLOG_FAIL_MAX 96
/* -------------------------------------*/
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index 73e188e7..5a1f512d 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -571,7 +571,6 @@ static u8 its_fuzz(afl_state_t *afl, u8 *buf, u32 len, u8 *status) {
}
-// #ifdef CMPLOG_SOLVE_TRANSFORM
static int strntoll(const char *str, size_t sz, char **end, int base,
long long *out) {
@@ -656,7 +655,6 @@ static int is_hex(const char *str) {
}
-#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64
// tests 4 bytes at location
static int is_base64(const char *str) {
@@ -769,10 +767,6 @@ static void to_base64(u8 *src, u8 *dst, u32 dst_len) {
}
-#endif
-
-// #endif
-
static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
u64 pattern, u64 repl, u64 o_pattern,
u64 changed_val, u8 attr, u32 idx, u32 taint_len,
@@ -797,42 +791,54 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
}
- // fprintf(stderr,
- // "Encode: %llx->%llx into %llx(<-%llx) at idx=%u "
- // "taint_len=%u shape=%u attr=%u\n",
- // o_pattern, pattern, repl, changed_val, idx, taint_len,
- // hshape, attr);
+ /*
+ fprintf(stderr,
+ "Encode: %llx->%llx into %llx(<-%llx) at idx=%u "
+ "taint_len=%u shape=%u attr=%u\n",
+ o_pattern, pattern, repl, changed_val, idx, taint_len,
+ hshape, attr);
+ */
- // #ifdef CMPLOG_SOLVE_TRANSFORM
// reverse atoi()/strnu?toll() is expensive, so we only to it in lvl 3
if (afl->cmplog_enable_transform && (lvl & LVL3)) {
u8 *endptr;
u8 use_num = 0, use_unum = 0;
- unsigned long long unum;
- long long num;
+ unsigned long long unum = 0;
+ long long num = 0;
+
+ // if (afl->queue_cur->is_ascii) {
+
+ // we first check if our input are ascii numbers that are transformed to
+ // an integer and used for comparison:
- if (afl->queue_cur->is_ascii) {
+ endptr = buf_8;
+ if (strntoll(buf_8, len - idx, (char **)&endptr, 0, &num)) {
- endptr = buf_8;
- if (strntoll(buf_8, len - idx, (char **)&endptr, 0, &num)) {
+ if (!strntoull(buf_8, len - idx, (char **)&endptr, 0, &unum)) {
- if (!strntoull(buf_8, len - idx, (char **)&endptr, 0, &unum))
- use_unum = 1;
+ use_unum = 1;
- } else
+ }
+
+ } else {
- use_num = 1;
+ use_num = 1;
}
+ //}
+
#ifdef _DEBUG
if (idx == 0)
- fprintf(stderr, "ASCII is=%u use_num=%u use_unum=%u idx=%u %llx==%llx\n",
- afl->queue_cur->is_ascii, use_num, use_unum, idx, num, pattern);
+ fprintf(stderr,
+ "ASCII is=%u use_num=%u>%lld use_unum=%u>%llu idx=%u "
+ "pattern=0x%llx\n",
+ afl->queue_cur->is_ascii, use_num, num, use_unum, unum, idx,
+ pattern);
#endif
- // num is likely not pattern as atoi("AAA") will be zero...
+ // atoi("AAA") == 0 so !num means we have to investigate
if (use_num && ((u64)num == pattern || !num)) {
u8 tmp_buf[32];
@@ -961,10 +967,12 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
// test for arithmetic, eg. "if ((user_val - 0x1111) == 0x1234) ..."
s64 diff = pattern - b_val;
s64 o_diff = o_pattern - o_b_val;
- /* fprintf(stderr, "DIFF1 idx=%03u shape=%02u %llx-%llx=%lx\n", idx,
- hshape, o_pattern, o_b_val, o_diff);
- fprintf(stderr, "DIFF1 %016llx %llx-%llx=%lx\n", repl, pattern,
- b_val, diff); */
+ /*
+ fprintf(stderr, "DIFF1 idx=%03u shape=%02u %llx-%llx=%lx\n", idx,
+ hshape, o_pattern, o_b_val, o_diff);
+ fprintf(stderr, "DIFF1 %016llx %llx-%llx=%lx\n", repl, pattern,
+ b_val, diff);
+ */
if (diff == o_diff && diff) {
// this could be an arithmetic transformation
@@ -1275,7 +1283,6 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
// 16 = modified float, 32 = modified integer (modified = wont match
// in original buffer)
- // #ifdef CMPLOG_SOLVE_ARITHMETIC
if (!afl->cmplog_enable_arith || lvl < LVL3 || attr == IS_TRANSFORM) {
return 0;
@@ -2009,8 +2016,12 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
its_len = MIN(its_len, taint_len);
u32 saved_its_len = its_len;
+ if (its_len <= 1) { return 0; }
+
if (lvl & LVL3) {
+ if (memcmp(changed_val, repl, its_len) != 0) { return 0; }
+
u32 max_to = MIN(4U, idx);
if (!(lvl & LVL1) && max_to) { from = 1; }
to = max_to;
@@ -2089,9 +2100,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
if (afl->cmplog_enable_transform && (lvl & LVL3)) {
u32 toupper = 0, tolower = 0, xor = 0, arith = 0, tohex = 0, fromhex = 0;
-#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64
u32 tob64 = 0, fromb64 = 0;
-#endif
u32 from_0 = 0, from_x = 0, from_X = 0, from_slash = 0, from_up = 0;
u32 to_0 = 0, to_x = 0, to_slash = 0, to_up = 0;
u8 xor_val[32], arith_val[32], tmp[48];
@@ -2144,7 +2153,8 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
}
- if (i < 16 && is_hex(repl + (i << 1))) {
+ if (afl->cmplog_enable_xtreme_transform && i < 16 &&
+ is_hex(repl + (i << 1))) {
++tohex;
@@ -2163,7 +2173,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
}
- if ((i % 2)) {
+ if (afl->cmplog_enable_xtreme_transform && (i % 2)) {
if (len > idx + i + 1 && is_hex(orig_buf + idx + i)) {
@@ -2187,20 +2197,21 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
}
-#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64
- if (i % 3 == 2 && i < 24) {
+ if (afl->cmplog_enable_xtreme_transform) {
- if (is_base64(repl + ((i / 3) << 2))) tob64 += 3;
+ if (i % 3 == 2 && i < 24) {
- }
+ if (is_base64(repl + ((i / 3) << 2))) tob64 += 3;
+
+ }
- if (i % 4 == 3 && i < 24) {
+ if (i % 4 == 3 && i < 24) {
- if (is_base64(orig_buf + idx + i - 3)) fromb64 += 4;
+ if (is_base64(orig_buf + idx + i - 3)) fromb64 += 4;
- }
+ }
-#endif
+ }
if ((o_pattern[i] ^ orig_buf[idx + i]) == xor_val[i] && xor_val[i]) {
@@ -2229,45 +2240,50 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
}
#ifdef _DEBUG
+ fprintf(stderr, "RTN %s %s %s %s\n", buf, pattern, orig_buf, o_pattern);
fprintf(stderr,
- "RTN idx=%u loop=%u xor=%u arith=%u tolower=%u toupper=%u "
+ "RTN idx=%u len=%u loop=%u xor=%u arith=%u tolower=%u toupper=%u "
"tohex=%u fromhex=%u to_0=%u to_slash=%u to_x=%u "
"from_0=%u from_slash=%u from_x=%u\n",
- idx, i, xor, arith, tolower, toupper, tohex, fromhex, to_0,
- to_slash, to_x, from_0, from_slash, from_x);
- #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64
- fprintf(stderr, "RTN idx=%u loop=%u tob64=%u from64=%u\n", tob64,
- fromb64);
- #endif
+ idx, its_len, i, xor, arith, tolower, toupper, tohex, fromhex,
+ to_0, to_slash, to_x, from_0, from_slash, from_x);
+ if (afl->cmplog_enable_xtreme_transform) {
+
+ fprintf(stderr, "RTN idx=%u loop=%u tob64=%u from64=%u\n", idx, i,
+ tob64, fromb64);
+
+ }
+
#endif
-#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64
- // input is base64 and converted to binary? convert repl to base64!
- if ((i % 4) == 3 && i < 24 && fromb64 > i) {
+ if (afl->cmplog_enable_xtreme_transform) {
- to_base64(repl, tmp, i + 1);
- memcpy(buf + idx, tmp, i + 1);
- if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
- // fprintf(stderr, "RTN ATTEMPT fromb64 %u result %u\n", fromb64,
- // *status);
+ // input is base64 and converted to binary? convert repl to base64!
+ if ((i % 4) == 3 && i < 24 && fromb64 > i) {
- }
+ to_base64(repl, tmp, i + 1);
+ memcpy(buf + idx, tmp, i + 1);
+ if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
+ // fprintf(stderr, "RTN ATTEMPT fromb64 %u result %u\n", fromb64,
+ // *status);
+
+ }
- // input is converted to base64? decode repl with base64!
- if ((i % 3) == 2 && i < 24 && tob64 > i) {
+ // input is converted to base64? decode repl with base64!
+ if ((i % 3) == 2 && i < 24 && tob64 > i) {
- u32 olen = from_base64(repl, tmp, i + 1);
- memcpy(buf + idx, tmp, olen);
- if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
- // fprintf(stderr, "RTN ATTEMPT tob64 %u idx=%u result %u\n", tob64,
- // idx, *status);
+ u32 olen = from_base64(repl, tmp, i + 1);
+ memcpy(buf + idx, tmp, olen);
+ if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
+ // fprintf(stderr, "RTN ATTEMPT tob64 %u idx=%u result %u\n", tob64,
+ // idx, *status);
- }
+ }
-#endif
+ }
// input is converted to hex? convert repl to binary!
- if (i < 16 && tohex > i) {
+ if (afl->cmplog_enable_xtreme_transform && i < 16 && tohex > i) {
u32 off;
if (to_slash + to_x + to_0 == 2) {
@@ -2292,8 +2308,8 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
}
// input is hex and converted to binary? convert repl to hex!
- if (i && (i % 2) && i < 16 && fromhex &&
- fromhex + from_slash + from_x + from_0 > i) {
+ if (afl->cmplog_enable_xtreme_transform && i && (i % 2) && i < 16 &&
+ fromhex && fromhex + from_slash + from_x + from_0 > i) {
u8 off = 0;
if (from_slash && from_x) {
@@ -2401,11 +2417,9 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
if ((i >= 7 &&
(i >= xor&&i >= arith &&i >= tolower &&i >= toupper &&i > tohex &&i >
- (fromhex + from_0 + from_x + from_slash + 1)
-#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64
- && i > tob64 + 3 && i > fromb64 + 4
-#endif
- )) ||
+ (fromhex + from_0 + from_x + from_slash + 1) &&
+ (afl->cmplog_enable_xtreme_transform && i > tob64 + 3 &&
+ i > fromb64 + 4))) ||
repl[i] != changed_val[i] || *status == 1) {
break;
@@ -2418,8 +2432,6 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
}
- // #endif
-
return 0;
}
@@ -2818,12 +2830,7 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) {
}
- } else if ((lvl & LVL1)
-
- // #ifdef CMPLOG_SOLVE_TRANSFORM
- || ((lvl & LVL3) && afl->cmplog_enable_transform)
- // #endif
- ) {
+ } else if ((lvl & LVL1) || ((lvl & LVL3) && afl->cmplog_enable_transform)) {
if (unlikely(rtn_fuzz(afl, k, orig_buf, buf, cbuf, len, lvl, taint))) {
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index d8a88f00..21a8915c 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -185,7 +185,8 @@ static void usage(u8 *argv0, int more_help) {
" 1=small files, 2=larger files (default), 3=all "
"files,\n"
" A=arithmetic solving, T=transformational solving,\n"
- " R=random colorization bytes.\n\n"
+ " X=extreme transform solving, R=random colorization "
+ "bytes.\n\n"
"Fuzzing behavior settings:\n"
" -Z - sequential queue selection instead of weighted "
"random\n"
@@ -1120,6 +1121,10 @@ int main(int argc, char **argv_orig, char **envp) {
case 'T':
afl->cmplog_enable_transform = 1;
break;
+ case 'x':
+ case 'X':
+ afl->cmplog_enable_xtreme_transform = 1;
+ break;
case 'r':
case 'R':
afl->cmplog_random_colorization = 1;
--
cgit 1.4.1
From f87ba7ed6324e9d33c2b93da5103344d53218f2c Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 28 Jul 2023 15:18:12 +0200
Subject: doc fix
---
docs/env_variables.md | 3 ++-
src/afl-fuzz.c | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
(limited to 'docs')
diff --git a/docs/env_variables.md b/docs/env_variables.md
index 0f0869d2..1f73bbdf 100644
--- a/docs/env_variables.md
+++ b/docs/env_variables.md
@@ -585,7 +585,8 @@ checks or alter some of the more exotic semantics of the tool:
Note that this is not a compile time option but a runtime option :-)
- Set `AFL_PIZZA_MODE` to 1 to enable the April 1st stats menu, set to -1
- to disable although it is 1st of April.
+ to disable although it is 1st of April. 0 is the default and means enable
+ on the 1st of April automatically.
- If you need a specific interval to update fuzzer_stats file, you can
set `AFL_FUZZER_STATS_UPDATE_INTERVAL` to the interval in seconds you'd
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 21a8915c..bacbafc4 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -278,7 +278,8 @@ static void usage(u8 *argv0, int more_help) {
"AFL_IGNORE_UNKNOWN_ENVS: don't warn on unknown env vars\n"
"AFL_IMPORT_FIRST: sync and import test cases from other fuzzer instances first\n"
"AFL_INPUT_LEN_MIN/AFL_INPUT_LEN_MAX: like -g/-G set min/max fuzz length produced\n"
- "AFL_PIZZA_MODE: 1 - enforce pizza mode, 0 - disable for April 1st\n"
+ "AFL_PIZZA_MODE: 1 - enforce pizza mode, -1 - disable for April 1st,\n"
+ " 0 (default) - activate on April 1st\n"
"AFL_KILL_SIGNAL: Signal ID delivered to child processes on timeout, etc.\n"
" (default: SIGKILL)\n"
"AFL_FORK_SERVER_KILL_SIGNAL: Kill signal for the fork server on termination\n"
--
cgit 1.4.1
From a61e1ffe4dceb5b4dec3409faf037bea4c05bef9 Mon Sep 17 00:00:00 2001
From: Junwha
Date: Wed, 2 Aug 2023 19:21:41 +0900
Subject: Add AFL_CRASHING_SEEDS_AS_NEW_CRASH to doc
Signed-off-by: Junwha
---
docs/env_variables.md | 3 +++
1 file changed, 3 insertions(+)
(limited to 'docs')
diff --git a/docs/env_variables.md b/docs/env_variables.md
index 1f73bbdf..affc9e3c 100644
--- a/docs/env_variables.md
+++ b/docs/env_variables.md
@@ -365,6 +365,9 @@ checks or alter some of the more exotic semantics of the tool:
- `AFL_EXIT_ON_SEED_ISSUES` will restore the vanilla afl-fuzz behavior which
does not allow crashes or timeout seeds in the initial -i corpus.
+ - `AFL_CRASHING_SEEDS_AS_NEW_CRASH` will treat crashing seeds as new crash. these
+ crashes will be written to crashes folder as op:dry_run, and orig:.
+
- `AFL_EXIT_ON_TIME` causes afl-fuzz to terminate if no new paths were found
within a specified period of time (in seconds). May be convenient for some
types of automated jobs.
--
cgit 1.4.1
From 0a28bce0167416aa5dbe9d23c242f4ec43e79b75 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 4 Aug 2023 09:45:11 +0200
Subject: update docs
---
docs/afl-fuzz_approach.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'docs')
diff --git a/docs/afl-fuzz_approach.md b/docs/afl-fuzz_approach.md
index cb173f10..7d18b178 100644
--- a/docs/afl-fuzz_approach.md
+++ b/docs/afl-fuzz_approach.md
@@ -419,8 +419,8 @@ the process. Be sure to consult this file especially if any UI elements are
highlighted in red.
The fuzzing process will continue until you press Ctrl-C. At a minimum, you want
-to allow the fuzzer to complete one queue cycle, which may take anywhere from a
-couple of hours to a week or so.
+to allow the fuzzer to at least one queue cycle without any new finds, which may
+take anywhere from a couple of hours to a week or so.
There are three subdirectories created within the output directory and updated
in real-time:
--
cgit 1.4.1
From d9cadb2e7db1d1c208cd40299f0e5c4f6364aa2c Mon Sep 17 00:00:00 2001
From: marc
Date: Wed, 9 Aug 2023 16:31:30 +0200
Subject: -c - support
---
docs/Changelog.md | 5 ++++-
src/afl-fuzz.c | 25 ++++++++++++++++++++-----
2 files changed, 24 insertions(+), 6 deletions(-)
(limited to 'docs')
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 75167172..76f98547 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -15,7 +15,10 @@
command line tool! See custom_mutators/aflpp/standalone/
- display the state of the fuzzing run in the UI :-)
- fix timeout setting if '+' is used or a session is restarted
- - -c X option to enable base64 transformation solving
+ - -l X option to enable base64 transformation solving
+ - allow to disable CMPLOG with '-c -' (e.g. afl.rs enforces '-c 0' on
+ every instance which is counterproductive).
+
- afl-cmin/afl-cmin.bash:
- fixed a bug inherited from vanilla AFL where a coverage of
map[123] = 11 would be the same as map[1123] = 1
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index e1f93f0d..cdb3f996 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -180,7 +180,8 @@ static void usage(u8 *argv0, int more_help) {
"it.\n"
" if using QEMU/FRIDA or the fuzzing target is "
"compiled\n"
- " for CmpLog then just use -c 0.\n"
+ " for CmpLog then use '-c 0'. To disable Cmplog use '-c "
+ "-'.\n"
" -l cmplog_opts - CmpLog configuration values (e.g. \"2ATR\"):\n"
" 1=small files, 2=larger files (default), 3=all "
"files,\n"
@@ -600,8 +601,23 @@ int main(int argc, char **argv_orig, char **envp) {
case 'c': {
- afl->shm.cmplog_mode = 1;
- afl->cmplog_binary = ck_strdup(optarg);
+ if (strcmp(optarg, "-") == 0) {
+
+ if (afl->shm.cmplog_mode) {
+
+ ACTF("Disabling cmplog again because of '-c -'.");
+ afl->shm.cmplog_mode = 0;
+ afl->cmplog_binary = NULL;
+
+ }
+
+ } else {
+
+ afl->shm.cmplog_mode = 1;
+ afl->cmplog_binary = ck_strdup(optarg);
+
+ }
+
break;
}
@@ -1510,8 +1526,7 @@ int main(int argc, char **argv_orig, char **envp) {
if (!afl->use_banner) { afl->use_banner = argv[optind]; }
- if (afl->shm.cmplog_mode &&
- (!strcmp("-", afl->cmplog_binary) || !strcmp("0", afl->cmplog_binary))) {
+ if (afl->shm.cmplog_mode && strcmp("0", afl->cmplog_binary) == 0) {
afl->cmplog_binary = strdup(argv[optind]);
--
cgit 1.4.1
From 3721c65a0b7fdf2b24713f8009030c6c241e200b Mon Sep 17 00:00:00 2001
From: marc
Date: Thu, 10 Aug 2023 10:41:55 +0200
Subject: v4.08c release
---
README.md | 10 +++++-----
docs/Changelog.md | 2 +-
include/config.h | 6 +++---
3 files changed, 9 insertions(+), 9 deletions(-)
(limited to 'docs')
diff --git a/README.md b/README.md
index b73cf2c1..951efe59 100644
--- a/README.md
+++ b/README.md
@@ -2,9 +2,9 @@
-Release version: [4.07c](https://github.com/AFLplusplus/AFLplusplus/releases)
+Release version: [4.08c](https://github.com/AFLplusplus/AFLplusplus/releases)
-GitHub version: 4.08a
+GitHub version: 4.08c
Repository:
[https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)
@@ -12,13 +12,13 @@ Repository:
AFL++ is maintained by:
* Marc "van Hauser" Heuse
-* Andrea Fioraldi
* Dominik Maier
-* Heiko "hexcoder-" Eißfeldt
+* Andrea Fioraldi
+* Heiko "hexcoder-" Eissfeldt
* frida_mode is maintained by @Worksbutnottested
* Documentation: Jana Aydinbas
-Originally developed by Michał "lcamtuf" Zalewski.
+Originally developed by Michal "lcamtuf" Zalewski.
AFL++ is a superior fork to Google's AFL - more speed, more and better
mutations, more and better instrumentation, custom module support, etc.
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 76f98547..2c747e42 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -3,7 +3,7 @@
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.08a (dev)
+### Version ++4.08c (release)
- afl-fuzz:
- new mutation engine: mutations that favor discovery more paths are
prefered until no new finds for 10 minutes then switching to mutations
diff --git a/include/config.h b/include/config.h
index df545583..5a81c4e2 100644
--- a/include/config.h
+++ b/include/config.h
@@ -5,9 +5,9 @@
Originally written by Michal Zalewski
Now maintained by Marc Heuse ,
- Heiko Eißfeldt ,
- Andrea Fioraldi ,
Dominik Maier
+ Andrea Fioraldi ,
+ Heiko Eissfeldt ,
Copyright 2016, 2017 Google Inc. All rights reserved.
Copyright 2019-2023 AFLplusplus Project. All rights reserved.
@@ -26,7 +26,7 @@
/* Version string: */
// c = release, a = volatile github dev, e = experimental branch
-#define VERSION "++4.08a"
+#define VERSION "++4.08c"
/******************************************************
* *
--
cgit 1.4.1
From 9607d1db06ebfc2fe1ba565a0ef0123ab3f3e76c Mon Sep 17 00:00:00 2001
From: marc
Date: Thu, 10 Aug 2023 10:56:20 +0200
Subject: v4.09a init
---
README.md | 2 +-
docs/Changelog.md | 4 ++++
include/config.h | 2 +-
3 files changed, 6 insertions(+), 2 deletions(-)
(limited to 'docs')
diff --git a/README.md b/README.md
index 951efe59..322ebcf2 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
Release version: [4.08c](https://github.com/AFLplusplus/AFLplusplus/releases)
-GitHub version: 4.08c
+GitHub version: 4.09a
Repository:
[https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 2c747e42..94b4c502 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -3,6 +3,10 @@
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.09a (dev)
+ - something cool :-)
+
+
### Version ++4.08c (release)
- afl-fuzz:
- new mutation engine: mutations that favor discovery more paths are
diff --git a/include/config.h b/include/config.h
index 5a81c4e2..6a75737f 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.08c"
+#define VERSION "++4.09a"
/******************************************************
* *
--
cgit 1.4.1
From 8823f22a9c87123c1bfcc5bff10044de4c7a4a1f Mon Sep 17 00:00:00 2001
From: marc
Date: Fri, 11 Aug 2023 11:22:18 +0200
Subject: add AFL_FINAL_SYNC
---
docs/Changelog.md | 7 +++----
docs/env_variables.md | 13 +++++++++----
include/afl-fuzz.h | 3 ++-
include/envs.h | 1 +
src/afl-fuzz-state.c | 7 +++++++
src/afl-fuzz.c | 9 +++++++++
6 files changed, 31 insertions(+), 9 deletions(-)
(limited to 'docs')
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 94b4c502..8f2b2545 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -4,7 +4,9 @@
release of the tool. See README.md for the general instruction manual.
### Version ++4.09a (dev)
- - something cool :-)
+ - afl-fuzz:
+ - added `AFL_FINAL_SYNC` which forces a final fuzzer sync (also for `-F`)
+ before terminating.
### Version ++4.08c (release)
@@ -22,7 +24,6 @@
- -l X option to enable base64 transformation solving
- allow to disable CMPLOG with '-c -' (e.g. afl.rs enforces '-c 0' on
every instance which is counterproductive).
-
- afl-cmin/afl-cmin.bash:
- fixed a bug inherited from vanilla AFL where a coverage of
map[123] = 11 would be the same as map[1123] = 1
@@ -40,7 +41,6 @@
- qemu_mode:
- added qemu_mode/utils/qemu_get_symbol_addr.sh
-
### Version ++4.07c (release)
- afl-fuzz:
- reverse reading the seeds only on restarts (increases performance)
@@ -69,7 +69,6 @@
- TritonDSE in custom_mutators/aflpp_tritondse
- SymQEMU in custom_mutators/symqemu
-
### Version ++4.06c (release)
- afl-fuzz:
- ensure temporary file descriptor is closed when not used
diff --git a/docs/env_variables.md b/docs/env_variables.md
index affc9e3c..2ce274d3 100644
--- a/docs/env_variables.md
+++ b/docs/env_variables.md
@@ -412,10 +412,15 @@ checks or alter some of the more exotic semantics of the tool:
set `AFL_IGNORE_PROBLEMS`. If you additionally want to also ignore coverage
from late loaded libraries, you can set `AFL_IGNORE_PROBLEMS_COVERAGE`.
- - When running in the `-M` or `-S` mode, setting `AFL_IMPORT_FIRST` causes the
- fuzzer to import test cases from other instances before doing anything else.
- This makes the "own finds" counter in the UI more accurate. Beyond counter
- aesthetics, not much else should change.
+ - When running with multiple afl-fuzz or with `-F`, setting `AFL_IMPORT_FIRST`
+ causes the fuzzer to import test cases from other instances before doing
+ anything else. This makes the "own finds" counter in the UI more accurate.
+
+ - When running with multiple afl-fuzz or with `-F`, setting `AFL_FINAL_SYNC`
+ will cause the fuzzer to perform a final import of test cases when
+ terminating. This is beneficial for `-M` main fuzzers to ensure it has all
+ unique test cases and hence you only need to `afl-cmin` this single
+ queue.
- Setting `AFL_INPUT_LEN_MIN` and `AFL_INPUT_LEN_MAX` are an alternative to
the afl-fuzz -g/-G command line option to control the minimum/maximum
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index ef84a18c..1f89bbd8 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -402,7 +402,8 @@ typedef struct afl_env_vars {
afl_exit_on_seed_issues, afl_try_affinity, afl_ignore_problems,
afl_keep_timeouts, afl_no_crash_readme, afl_ignore_timeouts,
afl_no_startup_calibration, afl_no_warn_instability,
- afl_post_process_keep_original, afl_crashing_seeds_as_new_crash;
+ afl_post_process_keep_original, afl_crashing_seeds_as_new_crash,
+ afl_final_sync;
u8 *afl_tmpdir, *afl_custom_mutator_library, *afl_python_module, *afl_path,
*afl_hang_tmout, *afl_forksrv_init_tmout, *afl_preload,
diff --git a/include/envs.h b/include/envs.h
index 0007d5a8..3f5a9e1c 100644
--- a/include/envs.h
+++ b/include/envs.h
@@ -59,6 +59,7 @@ static char *afl_environment_variables[] = {
"AFL_EXIT_ON_TIME",
"AFL_EXIT_ON_SEED_ISSUES",
"AFL_FAST_CAL",
+ "AFL_FINAL_SYNC",
"AFL_FORCE_UI",
"AFL_FRIDA_DEBUG_MAPS",
"AFL_FRIDA_DRIVER_NO_HOOK",
diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c
index 5a6b95cf..97e00415 100644
--- a/src/afl-fuzz-state.c
+++ b/src/afl-fuzz-state.c
@@ -269,6 +269,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
afl->afl_env.afl_import_first =
get_afl_env(afl_environment_variables[i]) ? 1 : 0;
+ } else if (!strncmp(env, "AFL_FINAL_SYNC",
+
+ afl_environment_variable_len)) {
+
+ afl->afl_env.afl_final_sync =
+ get_afl_env(afl_environment_variables[i]) ? 1 : 0;
+
} else if (!strncmp(env, "AFL_CUSTOM_MUTATOR_ONLY",
afl_environment_variable_len)) {
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index cdb3f996..c2ec4a1d 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -2899,6 +2899,15 @@ stop_fuzzing:
time_spent_working / afl->fsrv.total_execs);
#endif
+ if (afl->afl_env.afl_final_sync) {
+
+ SAYF(cYEL "[!] " cRST "\nPerforming final sync, this make take some time ...\n");
+ sync_fuzzers(afl);
+ write_bitmap(afl);
+ SAYF(cYEL "[!] " cRST "Done!\n\n");
+
+ }
+
if (afl->is_main_node) {
u8 path[PATH_MAX];
--
cgit 1.4.1
From 4d8d8633ff39cda2f1d48b66c45e5ae6cd2af477 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sun, 13 Aug 2023 11:44:37 +0200
Subject: update faq
---
docs/FAQ.md | 40 ++++++++++++++++++++++++++++++++++++++--
include/afl-fuzz.h | 9 ++++-----
2 files changed, 42 insertions(+), 7 deletions(-)
(limited to 'docs')
diff --git a/docs/FAQ.md b/docs/FAQ.md
index 9275eb94..242a379b 100644
--- a/docs/FAQ.md
+++ b/docs/FAQ.md
@@ -29,8 +29,8 @@ If you find an interesting or important question missing, submit it via
which then implemented their own research and features, making it now by far
the most flexible and feature rich guided fuzzer available as open source. And
in independent fuzzing benchmarks it is one of the best fuzzers available,
- e.g., [Fuzzbench
- Report](https://www.fuzzbench.com/reports/2020-08-03/index.html).
+ e.g.,
+ [Fuzzbench Report](https://www.fuzzbench.com/reports/2020-08-03/index.html).
@@ -103,6 +103,42 @@ If you find an interesting or important question missing, submit it via
to itself, this too would be an edge.
+
+ Should you ever stop afl-fuzz, minimize the corpus and restart?
+
+ To stop afl-fuzz, minimize it's corpus and restart you would usually do:
+
+ ```
+ Control-C # to terminate afl-fuzz
+ $ afl-cmin -T nproc -i out/default/queue -o minimized_queue -- ./target
+ $ AFL_FAST_CAL=1 AFL_CMPLOG_ONLY_NEW=1 afl-fuzz -i minimized_queue -o out2 [other options] -- ./target
+ ```
+
+ If this improves fuzzing or not is debated and no consensus has been reached
+ or in-depth analysis been performed.
+
+ On the pro side:
+ * The queue/corpus is reduced (up to 20%) by removing intermediate paths
+ that are maybe not needed anymore.
+
+ On the con side:
+ * Fuzzing time is lost for the time the fuzzing is stopped, minimized and
+ restarted.
+
+ The the big question:
+ * Does a minimized queue/corpus improve finding new coverage or does it
+ hinder it?
+
+ The AFL++ team's own limited analysis seem to to show that keeping
+ intermediate paths help to find more coverage, at least for afl-fuzz.
+
+ For honggfuzz in comparison it is a good idea to restart it from time to
+ time if you have other fuzzers (e.g: AFL++) running in parallel to sync
+ the finds of other fuzzers to honggfuzz as it has no syncing feature like
+ AFL++ or libfuzzer.
+
+
+
## Targets
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 1f89bbd8..3dfd2b2c 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -158,6 +158,7 @@ struct queue_entry {
u8 colorized, /* Do not run redqueen stage again */
cal_failed; /* Calibration failed? */
+
bool trim_done, /* Trimmed? */
was_fuzzed, /* historical, but needed for MOpt */
passed_det, /* Deterministic stages passed? */
@@ -169,17 +170,15 @@ struct queue_entry {
disabled; /* Is disabled from fuzz selection */
u32 bitmap_size, /* Number of bits set in bitmap */
- fuzz_level, /* Number of fuzzing iterations */
- n_fuzz_entry /* offset in n_fuzz */
#ifdef INTROSPECTION
- ,
stats_selected, /* stats: how often selected */
stats_skipped, /* stats: how often skipped */
stats_finds, /* stats: # of saved finds */
stats_crashes, /* stats: # of saved crashes */
- stats_tmouts /* stats: # of saved timeouts */
+ stats_tmouts, /* stats: # of saved timeouts */
#endif
- ;
+ fuzz_level, /* Number of fuzzing iterations */
+ n_fuzz_entry; /* offset in n_fuzz */
u64 exec_us, /* Execution time (us) */
handicap, /* Number of queue cycles behind */
--
cgit 1.4.1
From c2c8e780a5d10fe7500ec9add0aa5b2cb081fe71 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 16 Aug 2023 10:50:07 +0200
Subject: add benchmark
---
benchmark/COMPARISON | 4 ++++
benchmark/benchmark.sh | 42 ++++++++++++++++++++++++++++++++++++++++++
docs/Changelog.md | 2 ++
3 files changed, 48 insertions(+)
create mode 100644 benchmark/COMPARISON
create mode 100755 benchmark/benchmark.sh
(limited to 'docs')
diff --git a/benchmark/COMPARISON b/benchmark/COMPARISON
new file mode 100644
index 00000000..55ab94b4
--- /dev/null
+++ b/benchmark/COMPARISON
@@ -0,0 +1,4 @@
+CPU | Mz | exec/s | afl-*-config |
+========================================|======|========|==============|
+CPU 12th Gen Intel(R) Core(TM) i7-1270P | 4200 | 12750 | both |
+AMD EPYC 7282 16-Core Processor | 3190 | 10060 | both |
diff --git a/benchmark/benchmark.sh b/benchmark/benchmark.sh
new file mode 100755
index 00000000..3318adce
--- /dev/null
+++ b/benchmark/benchmark.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+test -x ../afl-fuzz -a -x ../afl-cc -a -e ../SanitizerCoveragePCGUARD.so || {
+ echo Error: you need to compile AFL++ first, we need afl-fuzz, afl-clang-fast and SanitizerCoveragePCGUARD.so built.
+ exit 1
+}
+
+echo Preparing environment
+
+env | grep AFL_ | sed 's/=.*//' | while read e; do
+ unset $e
+done
+
+AFL_PATH=`pwd`/..
+export PATH=$AFL_PATH:$PATH
+
+AFL_LLVM_INSTRUMENT=PCGUARD afl-cc -o test-instr ../test-instr.c > afl.log 2>&1 || {
+ echo Error: afl-cc is unable to compile
+ exit 1
+}
+
+{
+mkdir in
+dd if=/dev/zero of=in/in.txt bs=10K count=1
+} > /dev/null 2>&1
+
+echo Ready, starting benchmark - this will take approx 20-30 seconds ...
+
+AFL_DISABLE_TRIM=1 AFL_NO_UI=1 AFL_TRY_AFFINITY=1 AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 AFL_BENCH_JUST_ONE=1 time afl-fuzz -i in -o out -s 123 -D ./test-instr >> afl.log 2>&1
+
+echo Analysis:
+
+CPUID=$(grep 'try binding to' afl.log | tail -n 1 | sed 's/.*#//' | sed 's/\..*//')
+grep 'model name' /proc/cpuinfo | head -n 1 | sed 's/.*:/ CPU:/'
+test -n "$CPUID" && grep -E '^processor|^cpu MHz' /proc/cpuinfo | grep -A1 -w "$CPUID" | grep 'cpu MHz' | head -n 1 | sed 's/.*:/ Mhz:/'
+test -z "$CPUID" && grep 'cpu MHz' /proc/cpuinfo | head -n 1 | sed 's/.*:/ Mhz:/'
+grep execs_per_sec out/default/fuzzer_stats | sed 's/.*:/ execs\/s:/'
+
+echo
+echo "Comparison: (note that values can change by 10-15% per run)"
+cat COMPARISON
+
+rm -rf in out test-instr afl.log
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 8f2b2545..b809559e 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -7,6 +7,8 @@
- afl-fuzz:
- added `AFL_FINAL_SYNC` which forces a final fuzzer sync (also for `-F`)
before terminating.
+ - added benchmark/benchmark.sh if you want to see how good your fuzzing
+ speed is in comparison to other setups.
### Version ++4.08c (release)
--
cgit 1.4.1
From 213298fe5939df730d2341e2d2f75cd6daf77df7 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 21 Aug 2023 16:38:48 +0200
Subject: afl-whatsup add coverage output
---
afl-whatsup | 12 ++++++++++++
docs/Changelog.md | 1 +
2 files changed, 13 insertions(+)
(limited to 'docs')
diff --git a/afl-whatsup b/afl-whatsup
index 6f29ab24..c1f0abaa 100755
--- a/afl-whatsup
+++ b/afl-whatsup
@@ -70,6 +70,8 @@ if [ -d queue ]; then
fi
+BC=`which bc 2>/dev/null`
+
RED=`tput setaf 9 1 1 2>/dev/null`
GREEN=`tput setaf 2 1 1 2>/dev/null`
BLUE=`tput setaf 4 1 1 2>/dev/null`
@@ -91,6 +93,7 @@ TOTAL_CRASHES=0
TOTAL_HANGS=0
TOTAL_PFAV=0
TOTAL_PENDING=0
+TOTAL_COVERAGE=
# Time since last find / crash / hang, formatted as string
FMT_TIME="0 days 0 hours"
@@ -147,6 +150,13 @@ for i in `find . -maxdepth 2 -iname fuzzer_stats | sort`; do
RUN_UNIX=$run_time
RUN_DAYS=$((RUN_UNIX / 60 / 60 / 24))
RUN_HRS=$(((RUN_UNIX / 60 / 60) % 24))
+ COVERAGE=$(echo $bitmap_cvg|tr -d %)
+ if [ -n "$TOTAL_COVERAGE" -a -n "$B" ]; then
+ if [ "$(echo "$TOTAL_COVERAGE < $COVERAGE" | bc)" -eq 1 ]; then
+ TOTAL_COVERAGE=$COVERAGE
+ fi
+ fi
+ if [ -z "$TOTAL_COVERAGE" ]; then TOTAL_COVERAGE=$COVERAGE ; fi
test -n "$cycles_wo_finds" && {
test -z "$FIRST" && TOTAL_WCOP="${TOTAL_WCOP}/"
@@ -227,6 +237,7 @@ for i in `find . -maxdepth 2 -iname fuzzer_stats | sort`; do
echo " last_crash : $FMT_CRASH"
echo " last_hang : $FMT_HANG"
echo " cycles_wo_finds : $FMT_CWOP"
+ echo " coverage : $COVERAGE%"
CPU_USAGE=$(ps aux | grep $fuzzer_pid | grep -v grep | awk '{print $3}')
MEM_USAGE=$(ps aux | grep $fuzzer_pid | grep -v grep | awk '{print $4}')
@@ -302,6 +313,7 @@ if [ "$ALIVE_CNT" -gt "1" ]; then
echo " Pending per fuzzer : $((TOTAL_PFAV/ALIVE_CNT)) faves, $((TOTAL_PENDING/ALIVE_CNT)) total (on average)"
fi
+echo " Coverage reached : ${TOTAL_COVERAGE}%"
echo " Crashes saved : $TOTAL_CRASHES"
echo " Hangs saved : $TOTAL_HANGS"
echo "Cycles without finds : $TOTAL_WCOP"
diff --git a/docs/Changelog.md b/docs/Changelog.md
index b809559e..dfb5afa1 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -7,6 +7,7 @@
- afl-fuzz:
- added `AFL_FINAL_SYNC` which forces a final fuzzer sync (also for `-F`)
before terminating.
+ - afl-whatsup: now also shows coverage reached
- added benchmark/benchmark.sh if you want to see how good your fuzzing
speed is in comparison to other setups.
--
cgit 1.4.1
From f41d121f0767d929e34bbac7cb8d09ba4731730c Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 22 Aug 2023 10:03:03 +0200
Subject: afl-whatsup -m -n
---
afl-whatsup | 89 +++++++++++++++++++++++++++++++++++++++----------------
docs/Changelog.md | 5 +++-
2 files changed, 67 insertions(+), 27 deletions(-)
(limited to 'docs')
diff --git a/afl-whatsup b/afl-whatsup
index c1f0abaa..47133a13 100755
--- a/afl-whatsup
+++ b/afl-whatsup
@@ -24,38 +24,60 @@ test "$1" = "-h" -o "$1" = "-hh" && {
echo "Usage: $0 [-s] [-d] afl_output_directory"
echo
echo Options:
- echo " -s - skip details and output summary results only"
echo " -d - include dead fuzzer stats"
+ echo " -m - just show minimal stats"
+ echo " -n - no color output"
+ echo " -s - skip details and output summary results only"
echo
exit 1
}
-unset SUMMARY_ONLY
+unset MINIMAL_ONLY
+unset NO_COLOR
unset PROCESS_DEAD
+unset SUMMARY_ONLY
+unset RED
+unset GREEN
+unset YELLOW
+unset BLUE
+unset NC
+unset RESET
-while [ "$1" = "-s" -o "$1" = "-d" ]; do
+if [ -z "$TERM" ]; then export TERM=vt220; fi
- if [ "$1" = "-s" ]; then
- SUMMARY_ONLY=1
- fi
+while [ "$1" = "-d" -o "$1" = "-m" -o "$1" = "-n" -o "$1" = "-s" ]; do
if [ "$1" = "-d" ]; then
PROCESS_DEAD=1
fi
+ if [ "$1" = "-m" ]; then
+ MINIMAL_ONLY=1
+ fi
+
+ if [ "$1" = "-n" ]; then
+ NO_COLOR=1
+ fi
+
+ if [ "$1" = "-s" ]; then
+ SUMMARY_ONLY=1
+ fi
+
shift
done
DIR="$1"
-if [ "$DIR" = "" ]; then
+if [ "$DIR" = "" -o "$DIR" = "-h" -o "$DIR" = "--help" ]; then
- echo "Usage: $0 [-s] [-d] afl_output_directory" 1>&2
+ echo "Usage: $0 [-d] [-m] [-n] [-s] afl_output_directory" 1>&2
echo 1>&2
echo Options: 1>&2
- echo " -s - skip details and output summary results only" 1>&2
echo " -d - include dead fuzzer stats" 1>&2
+ echo " -m - just show minimal stats" 1>&2
+ echo " -n - no color output" 1>&2
+ echo " -s - skip details and output summary results only" 1>&2
echo 1>&2
exit 1
@@ -72,12 +94,14 @@ fi
BC=`which bc 2>/dev/null`
-RED=`tput setaf 9 1 1 2>/dev/null`
-GREEN=`tput setaf 2 1 1 2>/dev/null`
-BLUE=`tput setaf 4 1 1 2>/dev/null`
-YELLOW=`tput setaf 11 1 1 2>/dev/null`
-NC=`tput sgr0`
-RESET="$NC"
+if [ -z "$NO_COLOR" ]; then
+ RED=`tput setaf 9 1 1 2>/dev/null`
+ GREEN=`tput setaf 2 1 1 2>/dev/null`
+ BLUE=`tput setaf 4 1 1 2>/dev/null`
+ YELLOW=`tput setaf 11 1 1 2>/dev/null`
+ NC=`tput sgr0`
+ RESET="$NC"
+fi
CUR_TIME=`date +%s`
@@ -235,14 +259,21 @@ for i in `find . -maxdepth 2 -iname fuzzer_stats | sort`; do
echo " last_find : $FMT_FIND"
echo " last_crash : $FMT_CRASH"
- echo " last_hang : $FMT_HANG"
- echo " cycles_wo_finds : $FMT_CWOP"
+ if [ -z "$MINIMAL_ONLY" ]; then
+ echo " last_hang : $FMT_HANG"
+ echo " cycles_wo_finds : $FMT_CWOP"
+ fi
echo " coverage : $COVERAGE%"
- CPU_USAGE=$(ps aux | grep $fuzzer_pid | grep -v grep | awk '{print $3}')
- MEM_USAGE=$(ps aux | grep $fuzzer_pid | grep -v grep | awk '{print $4}')
+ if [ -z "$MINIMAL_ONLY" ]; then
+
+ CPU_USAGE=$(ps aux | grep $fuzzer_pid | grep -v grep | awk '{print $3}')
+ MEM_USAGE=$(ps aux | grep $fuzzer_pid | grep -v grep | awk '{print $4}')
+
+ echo " cpu usage $CPU_USAGE%, memory usage $MEM_USAGE%"
+
+ fi
- echo " cpu usage $CPU_USAGE%, memory usage $MEM_USAGE%"
echo " cycles $((cycles_done + 1)), lifetime speed $EXEC_SEC execs/sec, items $cur_item/$corpus_count (${PATH_PERC}%)"
if [ "$saved_crashes" = "0" ]; then
@@ -302,21 +333,27 @@ if [ ! "$DEAD_CNT" = "0" ]; then
fi
echo " Total run time : $FMT_TIME"
-echo " Total execs : $FMT_EXECS"
-echo " Cumulative speed : $TOTAL_EPS execs/sec"
+if [ -z "$MINIMAL_ONLY" ]; then
+ echo " Total execs : $FMT_EXECS"
+ echo " Cumulative speed : $TOTAL_EPS execs/sec"
+fi
if [ "$ALIVE_CNT" -gt "0" ]; then
echo " Average speed : $((TOTAL_EPS / ALIVE_CNT)) execs/sec"
fi
-echo " Pending items : $TOTAL_PFAV faves, $TOTAL_PENDING total"
+if [ -z "$MINIMAL_ONLY" ]; then
+ echo " Pending items : $TOTAL_PFAV faves, $TOTAL_PENDING total"
+fi
-if [ "$ALIVE_CNT" -gt "1" ]; then
+if [ "$ALIVE_CNT" -gt "1" -o -n "$MINIMAL_ONLY" ]; then
echo " Pending per fuzzer : $((TOTAL_PFAV/ALIVE_CNT)) faves, $((TOTAL_PENDING/ALIVE_CNT)) total (on average)"
fi
echo " Coverage reached : ${TOTAL_COVERAGE}%"
echo " Crashes saved : $TOTAL_CRASHES"
-echo " Hangs saved : $TOTAL_HANGS"
-echo "Cycles without finds : $TOTAL_WCOP"
+if [ -z "$MINIMAL_ONLY" ]; then
+ echo " Hangs saved : $TOTAL_HANGS"
+ echo "Cycles without finds : $TOTAL_WCOP"
+fi
echo " Time without finds : $TOTAL_LAST_FIND"
echo
diff --git a/docs/Changelog.md b/docs/Changelog.md
index dfb5afa1..fa9099c0 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -7,7 +7,10 @@
- afl-fuzz:
- added `AFL_FINAL_SYNC` which forces a final fuzzer sync (also for `-F`)
before terminating.
- - afl-whatsup: now also shows coverage reached
+ - afl-whatsup:
+ - now also shows coverage reached
+ - option -m shows only very relevant stats
+ - option -n will not use color in the output
- added benchmark/benchmark.sh if you want to see how good your fuzzing
speed is in comparison to other setups.
--
cgit 1.4.1
From 19d0c6a4c5015368ff610418994b2dc8f3f66117 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 23 Aug 2023 17:35:24 +0200
Subject: afl-whatsup startup detection
---
afl-whatsup | 63 ++++++++++++++++++++++++++++++++++++++++++++++++-------
docs/Changelog.md | 1 +
2 files changed, 56 insertions(+), 8 deletions(-)
(limited to 'docs')
diff --git a/afl-whatsup b/afl-whatsup
index bbb73e47..ebd1ce61 100755
--- a/afl-whatsup
+++ b/afl-whatsup
@@ -100,6 +100,7 @@ if [ -d queue ]; then
fi
BC=`which bc 2>/dev/null`
+FUSER=`which fuser 2>/dev/null`
if [ -z "$NO_COLOR" ]; then
RED=`tput setaf 9 1 1 2>/dev/null`
@@ -116,6 +117,7 @@ TMP=`mktemp -t .afl-whatsup-XXXXXXXX` || TMP=`mktemp -p /data/local/tmp .afl-wha
ALIVE_CNT=0
DEAD_CNT=0
+START_CNT=0
TOTAL_TIME=0
TOTAL_EXECS=0
@@ -177,6 +179,7 @@ for i in `find . -maxdepth 2 -iname fuzzer_stats | sort`; do
sed 's/^command_line.*$/_skip:1/;s/[ ]*:[ ]*/="/;s/$/"/' "$i" >"$TMP"
. "$TMP"
DIR=$(dirname "$i")
+ DIRECTORY=$DIR
DIR=${DIR##*/}
RUN_UNIX=$run_time
RUN_DAYS=$((RUN_UNIX / 60 / 60 / 24))
@@ -204,19 +207,59 @@ for i in `find . -maxdepth 2 -iname fuzzer_stats | sort`; do
if ! kill -0 "$fuzzer_pid" 2>/dev/null; then
- if [ "$SUMMARY_ONLY" = "" ]; then
+ IS_STARTING=
+ IS_DEAD=
- echo " Instance is dead or running remotely, skipping."
- echo
+ if [ -e "$i" ] && [ -e "$DIRECTORY/fuzzer_setup" ] && [ -n "$FUSER" ]; then
+
+ if [ "$i" -ot "$DIRECTORY/fuzzer_setup" ]; then
+
+ # fuzzer_setup is newer than fuzzer_stats, maybe the instance is starting?
+ TMP_PID=`fuser -v "$DIRECTORY" 2>&1 | grep afl-fuzz`
+
+ if [ -n "$TMP_PID" ]; then
+
+ if [ "$SUMMARY_ONLY" = "" ]; then
+
+ echo " Instance is still starting up, skipping."
+ echo
+
+ fi
+
+ START_CNT=$((START_CNT + 1))
+ last_find=0
+ IS_STARTING=1
+
+ if [ "$PROCESS_DEAD" = "" ]; then
+
+ continue
+
+ fi
+
+ fi
+
+ fi
fi
- DEAD_CNT=$((DEAD_CNT + 1))
- last_find=0
+ if [ -z "$IS_STARTING" ]; then
+
+ if [ "$SUMMARY_ONLY" = "" ]; then
+
+ echo " Instance is dead or running remotely, skipping."
+ echo
+
+ fi
- if [ "$PROCESS_DEAD" = "" ]; then
+ DEAD_CNT=$((DEAD_CNT + 1))
+ IS_DEAD=1
+ last_find=0
- continue
+ if [ "$PROCESS_DEAD" = "" ]; then
+
+ continue
+
+ fi
fi
@@ -326,7 +369,7 @@ if [ "$PROCESS_DEAD" = "" ]; then
else
TXT="included in stats"
- ALIVE_CNT=$(($ALIVE_CNT - $DEAD_CNT))
+ ALIVE_CNT=$(($ALIVE_CNT - $DEAD_CNT - $START_CNT))
fi
@@ -338,6 +381,10 @@ fi
echo " Fuzzers alive : $ALIVE_CNT"
+if [ ! "$START_CNT" = "0" ]; then
+ echo " Starting up : $START_CNT ($TXT)"
+fi
+
if [ ! "$DEAD_CNT" = "0" ]; then
echo " Dead or remote : $DEAD_CNT ($TXT)"
fi
diff --git a/docs/Changelog.md b/docs/Changelog.md
index fa9099c0..961b2940 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -8,6 +8,7 @@
- added `AFL_FINAL_SYNC` which forces a final fuzzer sync (also for `-F`)
before terminating.
- afl-whatsup:
+ - detect instanced that are starting up and show them as such as not dead
- now also shows coverage reached
- option -m shows only very relevant stats
- option -n will not use color in the output
--
cgit 1.4.1
From 549e5dd9269238ac43ff482d439f7f671946185c Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 23 Aug 2023 18:02:33 +0200
Subject: AFL_IGNORE_SEED_PROBLEMS
---
docs/Changelog.md | 2 ++
docs/env_variables.md | 3 +++
include/afl-fuzz.h | 7 +++----
include/envs.h | 1 +
src/afl-fuzz-init.c | 53 +++++++++++++++++++++++++++++++++++++++------------
src/afl-fuzz-state.c | 7 +++++++
src/afl-fuzz.c | 2 ++
7 files changed, 59 insertions(+), 16 deletions(-)
(limited to 'docs')
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 961b2940..87c01f21 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -7,6 +7,8 @@
- afl-fuzz:
- added `AFL_FINAL_SYNC` which forces a final fuzzer sync (also for `-F`)
before terminating.
+ - added AFL_IGNORE_SEED_PROBLEMS to skip over seeds that time out instead
+ of exiting with an error message
- afl-whatsup:
- detect instanced that are starting up and show them as such as not dead
- now also shows coverage reached
diff --git a/docs/env_variables.md b/docs/env_variables.md
index 2ce274d3..3bb4e844 100644
--- a/docs/env_variables.md
+++ b/docs/env_variables.md
@@ -327,6 +327,9 @@ checks or alter some of the more exotic semantics of the tool:
(`-i in`). This is an important feature to set when resuming a fuzzing
session.
+ - `AFL_IGNORE_SEED_PROBLEMS` will skip over crashes and timeouts in the seeds
+ instead of exiting.
+
- Setting `AFL_CRASH_EXITCODE` sets the exit code AFL++ treats as crash. For
example, if `AFL_CRASH_EXITCODE='-1'` is set, each input resulting in a `-1`
return code (i.e. `exit(-1)` got called), will be treated as if a crash had
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 3dfd2b2c..d02e852e 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -1,4 +1,3 @@
-
/*
american fuzzy lop++ - fuzzer header
------------------------------------
@@ -175,10 +174,10 @@ struct queue_entry {
stats_skipped, /* stats: how often skipped */
stats_finds, /* stats: # of saved finds */
stats_crashes, /* stats: # of saved crashes */
- stats_tmouts, /* stats: # of saved timeouts */
+ stats_tmouts, /* stats: # of saved timeouts */
#endif
fuzz_level, /* Number of fuzzing iterations */
- n_fuzz_entry; /* offset in n_fuzz */
+ n_fuzz_entry; /* offset in n_fuzz */
u64 exec_us, /* Execution time (us) */
handicap, /* Number of queue cycles behind */
@@ -402,7 +401,7 @@ typedef struct afl_env_vars {
afl_keep_timeouts, afl_no_crash_readme, afl_ignore_timeouts,
afl_no_startup_calibration, afl_no_warn_instability,
afl_post_process_keep_original, afl_crashing_seeds_as_new_crash,
- afl_final_sync;
+ afl_final_sync, afl_ignore_seed_problems;
u8 *afl_tmpdir, *afl_custom_mutator_library, *afl_python_module, *afl_path,
*afl_hang_tmout, *afl_forksrv_init_tmout, *afl_preload,
diff --git a/include/envs.h b/include/envs.h
index 3f5a9e1c..4259d6dd 100644
--- a/include/envs.h
+++ b/include/envs.h
@@ -113,6 +113,7 @@ static char *afl_environment_variables[] = {
"AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES",
"AFL_IGNORE_PROBLEMS",
"AFL_IGNORE_PROBLEMS_COVERAGE",
+ "AFL_IGNORE_SEED_PROBLEMS",
"AFL_IGNORE_TIMEOUTS",
"AFL_IGNORE_UNKNOWN_ENVS",
"AFL_IMPORT_FIRST",
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index 4c09fab7..9fc0cc57 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -951,19 +951,47 @@ void perform_dry_run(afl_state_t *afl) {
} else {
- SAYF("\n" cLRD "[-] " cRST
- "The program took more than %u ms to process one of the initial "
- "test cases.\n"
- " This is bad news; raising the limit with the -t option is "
- "possible, but\n"
- " will probably make the fuzzing process extremely slow.\n\n"
+ static int say_once = 0;
+
+ if (!say_once) {
+
+ SAYF(
+ "\n" cLRD "[-] " cRST
+ "The program took more than %u ms to process one of the "
+ "initial "
+ "test cases.\n"
+ " This is bad news; raising the limit with the -t option is "
+ "possible, but\n"
+ " will probably make the fuzzing process extremely slow.\n\n"
+
+ " If this test case is just a fluke, the other option is to "
+ "just avoid it\n"
+ " altogether, and find one that is less of a CPU hog.\n",
+ afl->fsrv.exec_tmout);
+
+ if (!afl->afl_env.afl_ignore_seed_problems) {
+
+ FATAL("Test case '%s' results in a timeout", fn);
+
+ }
+
+ say_once = 1;
+
+ }
+
+ if (!q->was_fuzzed) {
- " If this test case is just a fluke, the other option is to "
- "just avoid it\n"
- " altogether, and find one that is less of a CPU hog.\n",
- afl->fsrv.exec_tmout);
+ q->was_fuzzed = 1;
+ --afl->pending_not_fuzzed;
+ --afl->active_items;
- FATAL("Test case '%s' results in a timeout", fn);
+ }
+
+ q->disabled = 1;
+ q->perf_score = 0;
+
+ WARNF("Test case '%s' results in a timeout, skipping", fn);
+ break;
}
@@ -2270,7 +2298,8 @@ void check_crash_handling(void) {
reporting the awful way. */
#if !TARGET_OS_IPHONE
- if (system("launchctl list 2>/dev/null | grep -q '\\.ReportCrash\\>'")) return;
+ if (system("launchctl list 2>/dev/null | grep -q '\\.ReportCrash\\>'"))
+ return;
SAYF(
"\n" cLRD "[-] " cRST
diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c
index 97e00415..db82536d 100644
--- a/src/afl-fuzz-state.c
+++ b/src/afl-fuzz-state.c
@@ -316,6 +316,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
afl->afl_env.afl_ignore_problems =
get_afl_env(afl_environment_variables[i]) ? 1 : 0;
+ } else if (!strncmp(env, "AFL_IGNORE_SEED_PROBLEMS",
+
+ afl_environment_variable_len)) {
+
+ afl->afl_env.afl_ignore_seed_problems =
+ get_afl_env(afl_environment_variables[i]) ? 1 : 0;
+
} else if (!strncmp(env, "AFL_IGNORE_TIMEOUTS",
afl_environment_variable_len)) {
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 43834172..08960ac6 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -275,6 +275,8 @@ static void usage(u8 *argv0, int more_help) {
"AFL_IGNORE_PROBLEMS: do not abort fuzzing if an incorrect setup is detected\n"
"AFL_IGNORE_PROBLEMS_COVERAGE: if set in addition to AFL_IGNORE_PROBLEMS - also\n"
" ignore those libs for coverage\n"
+ "AFL_IGNORE_SEED_PROBLEMS: skip over crashes and timeouts in the seeds instead of\n"
+ " exiting\n"
"AFL_IGNORE_TIMEOUTS: do not process or save any timeouts\n"
"AFL_IGNORE_UNKNOWN_ENVS: don't warn on unknown env vars\n"
"AFL_IMPORT_FIRST: sync and import test cases from other fuzzer instances first\n"
--
cgit 1.4.1
From c60431247e971881bc159a84e5505dfec7adcf6d Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 29 Aug 2023 16:38:31 +0200
Subject: update docs
---
docs/fuzzing_in_depth.md | 4 ++--
src/afl-fuzz.c | 1 +
2 files changed, 3 insertions(+), 2 deletions(-)
(limited to 'docs')
diff --git a/docs/fuzzing_in_depth.md b/docs/fuzzing_in_depth.md
index f75ca5dc..5a5acbb2 100644
--- a/docs/fuzzing_in_depth.md
+++ b/docs/fuzzing_in_depth.md
@@ -616,7 +616,7 @@ For every secondary fuzzer there should be a variation, e.g.:
be one of them! (Although this is not really recommended.)
All other secondaries should be used like this:
-* a quarter to a third with the MOpt mutator enabled: `-L 0`
+* 10-20% with the MOpt mutator enabled: `-L 0`
* run with a different power schedule, recommended are: `fast` (default),
`explore`, `coe`, `lin`, `quad`, `exploit`, and `rare` which you can set with
the `-p` option, e.g., `-p explore`. See the
@@ -940,7 +940,7 @@ too long for your overall available fuzz run time.
* 65% for `AFL_DISABLE_TRIM`
* 50% for `AFL_KEEP_TIMEOUTS`
* 50% use a dictionary generated by `AFL_LLVM_DICT2FILE` + `AFL_LLVM_DICT2FILE_NO_MAIN=1`
- * 40% use MOpt (`-L 0`)
+ * 10% use MOpt (`-L 0`)
* 40% for `AFL_EXPAND_HAVOC_NOW`
* 20% for old queue processing (`-Z`)
* for CMPLOG targets, 70% for `-l 2`, 10% for `-l 3`, 20% for `-l 2AT`
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 8b9c1e50..90c255e3 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -176,6 +176,7 @@ static void usage(u8 *argv0, int more_help) {
" pacemaker mode (minutes of no new finds). 0 = "
"immediately,\n"
" -1 = immediately and together with normal mutation.\n"
+ " Note: this option is usually not very effective\n"
" -c program - enable CmpLog by specifying a binary compiled for "
"it.\n"
" if using QEMU/FRIDA or the fuzzing target is "
--
cgit 1.4.1
From 1604351368c26a1dd91c43c054fb466b8093e86e Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 31 Aug 2023 14:45:03 +0200
Subject: changelog
---
docs/Changelog.md | 2 ++
1 file changed, 2 insertions(+)
(limited to 'docs')
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 87c01f21..8d9a0aa8 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -14,6 +14,8 @@
- now also shows coverage reached
- option -m shows only very relevant stats
- option -n will not use color in the output
+ - frida_mode:
+ - fixes support for large map offsets
- added benchmark/benchmark.sh if you want to see how good your fuzzing
speed is in comparison to other setups.
--
cgit 1.4.1
From 9307ef4b7caa96754d0449361d48b5a98ef73d8f Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 4 Sep 2023 09:11:47 +0200
Subject: fix string transform laf
---
docs/Changelog.md | 2 ++
instrumentation/compare-transform-pass.so.cc | 4 ----
2 files changed, 2 insertions(+), 4 deletions(-)
(limited to 'docs')
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 8d9a0aa8..bccc6748 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -14,6 +14,8 @@
- now also shows coverage reached
- option -m shows only very relevant stats
- option -n will not use color in the output
+ - instrumentation:
+ - fix for a few string compare transform functions for LAF
- frida_mode:
- fixes support for large map offsets
- added benchmark/benchmark.sh if you want to see how good your fuzzing
diff --git a/instrumentation/compare-transform-pass.so.cc b/instrumentation/compare-transform-pass.so.cc
index b0bbd39a..5a5415d7 100644
--- a/instrumentation/compare-transform-pass.so.cc
+++ b/instrumentation/compare-transform-pass.so.cc
@@ -228,7 +228,6 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
isStrcmp &=
(!FuncName.compare("strcmp") || !FuncName.compare("xmlStrcmp") ||
!FuncName.compare("xmlStrEqual") ||
- !FuncName.compare("g_strcmp0") ||
!FuncName.compare("curl_strequal") ||
!FuncName.compare("strcsequal") ||
!FuncName.compare("g_strcmp0"));
@@ -239,7 +238,6 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
!FuncName.compare("memcmp_const_time") ||
!FuncName.compare("memcmpct"));
isStrncmp &= (!FuncName.compare("strncmp") ||
- !FuncName.compare("xmlStrncmp") ||
!FuncName.compare("curl_strnequal") ||
!FuncName.compare("xmlStrncmp"));
isStrcasecmp &= (!FuncName.compare("strcasecmp") ||
@@ -508,10 +506,8 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
isCaseInsensitive = true;
if (!Callee->getName().compare("xmlStrEqual") ||
- !Callee->getName().compare("g_strcmp0") ||
!Callee->getName().compare("curl_strequal") ||
!Callee->getName().compare("strcsequal") ||
- !Callee->getName().compare("xmlStrncmp") ||
!Callee->getName().compare("curl_strnequal"))
success_is_one = true;
--
cgit 1.4.1
From 19c387a824d8e5c34b2babb20bab1e47fa152649 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 12 Sep 2023 09:54:05 +0200
Subject: update multicore recommendation
---
docs/fuzzing_in_depth.md | 38 +++++++++++++++++++++++---------------
1 file changed, 23 insertions(+), 15 deletions(-)
(limited to 'docs')
diff --git a/docs/fuzzing_in_depth.md b/docs/fuzzing_in_depth.md
index 5a5acbb2..6a217641 100644
--- a/docs/fuzzing_in_depth.md
+++ b/docs/fuzzing_in_depth.md
@@ -599,32 +599,40 @@ during fuzzing) and their number, a value between 50-500MB is recommended. You
can set the cache size (in MB) by setting the environment variable
`AFL_TESTCACHE_SIZE`.
-There should be one main fuzzer (`-M main-$HOSTNAME` option) and as many
-secondary fuzzers (e.g., `-S variant1`) as you have cores that you use. Every
-`-M`/`-S` entry needs a unique name (that can be whatever), however, the same
-`-o` output directory location has to be used for all instances.
+There should be one main fuzzer (`-M main-$HOSTNAME` option - set also
+`AFL_FINAL_SYNC=1`) and as many secondary fuzzers (e.g., `-S variant1`) as you
+have cores that you use. Every `-M`/`-S` entry needs a unique name (that can be
+whatever), however, the same `-o` output directory location has to be used for
+all instances.
For every secondary fuzzer there should be a variation, e.g.:
-* one should fuzz the target that was compiled differently: with sanitizers
- activated (`export AFL_USE_ASAN=1 ; export AFL_USE_UBSAN=1 ; export
- AFL_USE_CFISAN=1`)
+* one should fuzz the target that was compiled with sanitizers activated
+ (`export AFL_USE_ASAN=1 ; export AFL_USE_UBSAN=1 ; export AFL_USE_CFISAN=1`)
* one or two should fuzz the target with CMPLOG/redqueen (see above), at least
- one cmplog instance should follow transformations (`-l AT`)
+ one cmplog instance should follow transformations (`-l 2AT`)
* one to three fuzzers should fuzz a target compiled with laf-intel/COMPCOV (see
above). Important note: If you run more than one laf-intel/COMPCOV fuzzer and
you want them to share their intermediate results, the main fuzzer (`-M`) must
- be one of them! (Although this is not really recommended.)
-
-All other secondaries should be used like this:
-* 10-20% with the MOpt mutator enabled: `-L 0`
-* run with a different power schedule, recommended are: `fast` (default),
+ be one of them (although this is not really recommended).
+
+The other secondaries should be run like this:
+* 10% with the MOpt mutator enabled: `-L 0`
+* 10% should use the old queue cycling with `-Z`
+* 50-70% should run with `AFL_DISABLE_TRIM`
+* 40% should run with `-P explore` and 20% with `-P exploit`
+* If you use `-a` then set 30% of the instances to not use `-a`; if you did
+ not set `-a` (why??), then set 30% to `-a ascii` and 30% to `-a binary`.
+* run each with a different power schedule, recommended are: `fast` (default),
`explore`, `coe`, `lin`, `quad`, `exploit`, and `rare` which you can set with
the `-p` option, e.g., `-p explore`. See the
[FAQ](FAQ.md#what-are-power-schedules) for details.
-* a few instances should use the old queue cycling with `-Z`
+
+It can be useful to set `AFL_IGNORE_SEED_PROBLEMS=1` to skip over seeds that
+crash or timeout during startup.
Also, it is recommended to set `export AFL_IMPORT_FIRST=1` to load test cases
-from other fuzzers in the campaign first.
+from other fuzzers in the campaign first. But note that can slow down the start
+of the first fuzz by quite a lot of you have many fuzzers and/or many seeds.
If you have a large corpus, a corpus from a previous run or are fuzzing in a CI,
then also set `export AFL_CMPLOG_ONLY_NEW=1` and `export AFL_FAST_CAL=1`.
--
cgit 1.4.1
From 3b835b7c8b2f73be6d5972951d049cef66c24abd Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 12 Sep 2023 16:05:56 +0200
Subject: increase sync length
---
docs/Changelog.md | 1 +
src/afl-fuzz.c | 4 ++--
2 files changed, 3 insertions(+), 2 deletions(-)
(limited to 'docs')
diff --git a/docs/Changelog.md b/docs/Changelog.md
index bccc6748..dfbadea3 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -9,6 +9,7 @@
before terminating.
- added AFL_IGNORE_SEED_PROBLEMS to skip over seeds that time out instead
of exiting with an error message
+ - allow -S/-M naming up to 50 characters (from 24)
- afl-whatsup:
- detect instanced that are starting up and show them as such as not dead
- now also shows coverage reached
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index a3d5e300..f659395e 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -1492,9 +1492,9 @@ int main(int argc, char **argv_orig, char **envp) {
if (afl->sync_id) {
- if (strlen(afl->sync_id) > 24) {
+ if (strlen(afl->sync_id) > 50) {
- FATAL("sync_id max length is 24 characters");
+ FATAL("sync_id max length is 50 characters");
}
--
cgit 1.4.1
From 0b6e74eeb099ac045932e5d3603af899268b48d0 Mon Sep 17 00:00:00 2001
From: Thomas Rooijakkers
Date: Wed, 13 Sep 2023 15:49:04 +0200
Subject: Add support for UTF-8 line rendering
---
GNUmakefile | 5 ++++
docs/INSTALL.md | 1 +
include/debug.h | 81 ++++++++++++++++++++++++++++++++++++---------------------
3 files changed, 57 insertions(+), 30 deletions(-)
(limited to 'docs')
diff --git a/GNUmakefile b/GNUmakefile
index 88816e85..4a234c51 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -45,6 +45,10 @@ ifdef NO_SPLICING
override CFLAGS_OPT += -DNO_SPLICING
endif
+ifdef UTF
+ override CFLAGS_OPT += -DFANCY_BOXES_UTF
+endif
+
ifdef ASAN_BUILD
$(info Compiling ASAN version of binaries)
override CFLAGS += $(ASAN_CFLAGS)
@@ -391,6 +395,7 @@ help:
@echo INTROSPECTION - compile afl-fuzz with mutation introspection
@echo NO_PYTHON - disable python support
@echo NO_SPLICING - disables splicing mutation in afl-fuzz, not recommended for normal fuzzing
+ @echo UTF - use UTF-8 for line rendering in status screen
@echo NO_NYX - disable building nyx mode dependencies
@echo "NO_CORESIGHT - disable building coresight (arm64 only)"
@echo NO_UNICORN_ARM64 - disable building unicorn on arm64
diff --git a/docs/INSTALL.md b/docs/INSTALL.md
index 9005a7eb..7c04d7d8 100644
--- a/docs/INSTALL.md
+++ b/docs/INSTALL.md
@@ -87,6 +87,7 @@ These build options exist:
* INTROSPECTION - compile afl-fuzz with mutation introspection
* NO_PYTHON - disable python support
* NO_SPLICING - disables splicing mutation in afl-fuzz, not recommended for normal fuzzing
+* UTF - use UTF-8 for line rendering in status screen
* NO_NYX - disable building nyx mode dependencies
* NO_CORESIGHT - disable building coresight (arm64 only)
* NO_UNICORN_ARM64 - disable building unicorn on arm64
diff --git a/include/debug.h b/include/debug.h
index cd621a72..a9179329 100644
--- a/include/debug.h
+++ b/include/debug.h
@@ -116,42 +116,63 @@
* Box drawing sequences *
*************************/
-#ifdef FANCY_BOXES
-
- #define SET_G1 "\x1b)0" /* Set G1 for box drawing */
- #define RESET_G1 "\x1b)B" /* Reset G1 to ASCII */
- #define bSTART "\x0e" /* Enter G1 drawing mode */
- #define bSTOP "\x0f" /* Leave G1 drawing mode */
- #define bH "q" /* Horizontal line */
- #define bV "x" /* Vertical line */
- #define bLT "l" /* Left top corner */
- #define bRT "k" /* Right top corner */
- #define bLB "m" /* Left bottom corner */
- #define bRB "j" /* Right bottom corner */
- #define bX "n" /* Cross */
- #define bVR "t" /* Vertical, branch right */
- #define bVL "u" /* Vertical, branch left */
- #define bHT "v" /* Horizontal, branch top */
- #define bHB "w" /* Horizontal, branch bottom */
-
-#else
+#ifdef FANCY_BOXES_UTF
#define SET_G1 ""
#define RESET_G1 ""
#define bSTART ""
#define bSTOP ""
- #define bH "-"
- #define bV "|"
- #define bLT "+"
- #define bRT "+"
- #define bLB "+"
- #define bRB "+"
- #define bX "+"
- #define bVR "+"
- #define bVL "+"
- #define bHT "+"
- #define bHB "+"
+ #define bH "\u2500" /* Horizontal line */
+ #define bV "\u2502" /* Vertical line */
+ #define bLT "\u250c" /* Left top corner */
+ #define bRT "\u2510" /* Right top corner */
+ #define bLB "\u2514" /* Left bottom corner */
+ #define bRB "\u2518" /* Right bottom corner */
+ #define bX "\u253c" /* Cross */
+ #define bVR "\u251c" /* Vertical, branch right */
+ #define bVL "\u2524" /* Vertical, branch left */
+ #define bHT "\u2534" /* Horizontal, branch top */
+ #define bHB "\u252c" /* Horizontal, branch bottom */
+
+#else
+ #ifdef FANCY_BOXES
+
+ #define SET_G1 "\x1b)0" /* Set G1 for box drawing */
+ #define RESET_G1 "\x1b)B" /* Reset G1 to ASCII */
+ #define bSTART "\x0e" /* Enter G1 drawing mode */
+ #define bSTOP "\x0f" /* Leave G1 drawing mode */
+ #define bH "q" /* Horizontal line */
+ #define bV "x" /* Vertical line */
+ #define bLT "l" /* Left top corner */
+ #define bRT "k" /* Right top corner */
+ #define bLB "m" /* Left bottom corner */
+ #define bRB "j" /* Right bottom corner */
+ #define bX "n" /* Cross */
+ #define bVR "t" /* Vertical, branch right */
+ #define bVL "u" /* Vertical, branch left */
+ #define bHT "v" /* Horizontal, branch top */
+ #define bHB "w" /* Horizontal, branch bottom */
+
+ #else
+
+ #define SET_G1 ""
+ #define RESET_G1 ""
+ #define bSTART ""
+ #define bSTOP ""
+ #define bH "-"
+ #define bV "|"
+ #define bLT "+"
+ #define bRT "+"
+ #define bLB "+"
+ #define bRB "+"
+ #define bX "+"
+ #define bVR "+"
+ #define bVL "+"
+ #define bHT "+"
+ #define bHB "+"
+
+ #endif
#endif /* ^FANCY_BOXES */
/***********************
--
cgit 1.4.1
From 54f01481571ba3a7c05a5e37b9f5021c1304834e Mon Sep 17 00:00:00 2001
From: Thomas Rooijakkers
Date: Tue, 19 Sep 2023 13:31:29 +0200
Subject: UTF-8 line rendering for status screen as default
---
GNUmakefile | 6 +++---
docs/INSTALL.md | 2 +-
include/debug.h | 64 ++++++++++++++++++++++++++++-----------------------------
3 files changed, 36 insertions(+), 36 deletions(-)
(limited to 'docs')
diff --git a/GNUmakefile b/GNUmakefile
index 4a234c51..fadf20bd 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -45,8 +45,8 @@ ifdef NO_SPLICING
override CFLAGS_OPT += -DNO_SPLICING
endif
-ifdef UTF
- override CFLAGS_OPT += -DFANCY_BOXES_UTF
+ifdef NO_UTF
+ override CFLAGS_OPT += -DFANCY_BOXES_NO_UTF
endif
ifdef ASAN_BUILD
@@ -395,7 +395,7 @@ help:
@echo INTROSPECTION - compile afl-fuzz with mutation introspection
@echo NO_PYTHON - disable python support
@echo NO_SPLICING - disables splicing mutation in afl-fuzz, not recommended for normal fuzzing
- @echo UTF - use UTF-8 for line rendering in status screen
+ @echo NO_UTF - do not use UTF-8 for line rendering in status screen (fallback to G1 box drawing, of vanilla AFL)
@echo NO_NYX - disable building nyx mode dependencies
@echo "NO_CORESIGHT - disable building coresight (arm64 only)"
@echo NO_UNICORN_ARM64 - disable building unicorn on arm64
diff --git a/docs/INSTALL.md b/docs/INSTALL.md
index 7c04d7d8..41f512ed 100644
--- a/docs/INSTALL.md
+++ b/docs/INSTALL.md
@@ -87,7 +87,7 @@ These build options exist:
* INTROSPECTION - compile afl-fuzz with mutation introspection
* NO_PYTHON - disable python support
* NO_SPLICING - disables splicing mutation in afl-fuzz, not recommended for normal fuzzing
-* UTF - use UTF-8 for line rendering in status screen
+* NO_UTF - do not use UTF-8 for line rendering in status screen (fallback to G1 box drawing, of vanilla AFL)
* NO_NYX - disable building nyx mode dependencies
* NO_CORESIGHT - disable building coresight (arm64 only)
* NO_UNICORN_ARM64 - disable building unicorn on arm64
diff --git a/include/debug.h b/include/debug.h
index a9179329..234d8fc4 100644
--- a/include/debug.h
+++ b/include/debug.h
@@ -116,43 +116,43 @@
* Box drawing sequences *
*************************/
-#ifdef FANCY_BOXES_UTF
-
- #define SET_G1 ""
- #define RESET_G1 ""
- #define bSTART ""
- #define bSTOP ""
- #define bH "\u2500" /* Horizontal line */
- #define bV "\u2502" /* Vertical line */
- #define bLT "\u250c" /* Left top corner */
- #define bRT "\u2510" /* Right top corner */
- #define bLB "\u2514" /* Left bottom corner */
- #define bRB "\u2518" /* Right bottom corner */
- #define bX "\u253c" /* Cross */
- #define bVR "\u251c" /* Vertical, branch right */
- #define bVL "\u2524" /* Vertical, branch left */
- #define bHT "\u2534" /* Horizontal, branch top */
- #define bHB "\u252c" /* Horizontal, branch bottom */
+#ifdef FANCY_BOXES_NO_UTF
+
+ #define SET_G1 "\x1b)0" /* Set G1 for box drawing */
+ #define RESET_G1 "\x1b)B" /* Reset G1 to ASCII */
+ #define bSTART "\x0e" /* Enter G1 drawing mode */
+ #define bSTOP "\x0f" /* Leave G1 drawing mode */
+ #define bH "q" /* Horizontal line */
+ #define bV "x" /* Vertical line */
+ #define bLT "l" /* Left top corner */
+ #define bRT "k" /* Right top corner */
+ #define bLB "m" /* Left bottom corner */
+ #define bRB "j" /* Right bottom corner */
+ #define bX "n" /* Cross */
+ #define bVR "t" /* Vertical, branch right */
+ #define bVL "u" /* Vertical, branch left */
+ #define bHT "v" /* Horizontal, branch top */
+ #define bHB "w" /* Horizontal, branch bottom */
#else
#ifdef FANCY_BOXES
- #define SET_G1 "\x1b)0" /* Set G1 for box drawing */
- #define RESET_G1 "\x1b)B" /* Reset G1 to ASCII */
- #define bSTART "\x0e" /* Enter G1 drawing mode */
- #define bSTOP "\x0f" /* Leave G1 drawing mode */
- #define bH "q" /* Horizontal line */
- #define bV "x" /* Vertical line */
- #define bLT "l" /* Left top corner */
- #define bRT "k" /* Right top corner */
- #define bLB "m" /* Left bottom corner */
- #define bRB "j" /* Right bottom corner */
- #define bX "n" /* Cross */
- #define bVR "t" /* Vertical, branch right */
- #define bVL "u" /* Vertical, branch left */
- #define bHT "v" /* Horizontal, branch top */
- #define bHB "w" /* Horizontal, branch bottom */
+ #define SET_G1 ""
+ #define RESET_G1 ""
+ #define bSTART ""
+ #define bSTOP ""
+ #define bH "\u2500" /* Horizontal line */
+ #define bV "\u2502" /* Vertical line */
+ #define bLT "\u250c" /* Left top corner */
+ #define bRT "\u2510" /* Right top corner */
+ #define bLB "\u2514" /* Left bottom corner */
+ #define bRB "\u2518" /* Right bottom corner */
+ #define bX "\u253c" /* Cross */
+ #define bVR "\u251c" /* Vertical, branch right */
+ #define bVL "\u2524" /* Vertical, branch left */
+ #define bHT "\u2534" /* Horizontal, branch top */
+ #define bHB "\u252c" /* Horizontal, branch bottom */
#else
--
cgit 1.4.1
From 6b73dee7da4e4e8bd227a9cb156c7a683d124682 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sat, 30 Sep 2023 12:42:40 +0200
Subject: add afl-addseeds tool
---
GNUmakefile | 2 +-
afl-addseeds | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
docs/Changelog.md | 1 +
src/afl-fuzz.c | 6 ++++++
4 files changed, 62 insertions(+), 1 deletion(-)
create mode 100755 afl-addseeds
(limited to 'docs')
diff --git a/GNUmakefile b/GNUmakefile
index fadf20bd..5fd37147 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -32,7 +32,7 @@ VERSION = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f
# PROGS intentionally omit afl-as, which gets installed elsewhere.
PROGS = afl-fuzz afl-showmap afl-tmin afl-gotcpu afl-analyze
-SH_PROGS = afl-plot afl-cmin afl-cmin.bash afl-whatsup afl-system-config afl-persistent-config afl-cc
+SH_PROGS = afl-plot afl-cmin afl-cmin.bash afl-whatsup afl-addseeds afl-system-config afl-persistent-config afl-cc
MANPAGES=$(foreach p, $(PROGS) $(SH_PROGS), $(p).8) afl-as.8
ASAN_OPTIONS=detect_leaks=0
diff --git a/afl-addseeds b/afl-addseeds
new file mode 100755
index 00000000..bb2843a8
--- /dev/null
+++ b/afl-addseeds
@@ -0,0 +1,54 @@
+#!/bin/sh
+
+test -z "$1" -o "$1" = "-h" -o "$1" = "--help" && {
+ echo Syntax: afl-addseeds -o afl-out-dir [-i seed_file_or_dir] seed_file_or_seed_dir seed_file_or_seed_dir ...
+ echo
+ echo Options:
+ echo " -o afl-out-dir the output directory being used in the fuzzing campaign"
+ echo " -i seed_file_or_dir file or directory of files to add"
+ echo
+ echo Adds new seeds to an existing AFL++ fuzzing campaign.
+ exit 0
+}
+
+for TOOL in find ls; do
+ X=`which $TOOL`
+ test -n "$X" || { echo "Error: required tool '$TOOL' not found."; exit 1; }
+done
+
+TEST=`printf %06d 123 2>/dev/null`
+test "$TEST" = "000123" || { echo "Error: required tool 'printf' not found."; exit 1; }
+
+OUT=
+NEXT=
+for i in $*; do
+ test -n "$NEXT" && { OUT=$i ; NEXT=""; }
+ test "$i" = "-o" && { NEXT=1; }
+done
+
+test -d "$OUT" || { echo Error: $OUT is not an existing directory; exit 1; }
+OK=`ls $OUT/*/fuzzer_stats 2>/dev/null`
+test -n "$OK" || { echo "Error: $OUT is not an 'afl-fuzz -o ... ' output directory" ; exit 1; }
+
+OUTDIR=$OUT/addseeds/queue
+mkdir -p "$OUTDIR" 2>/dev/null
+test -d "$OUTDIR" || { echo Error: could not create $OUTDIR ; exit 1 ; }
+
+echo Adding seeds ...
+NEXTID=0
+for i in $*; do
+ test -z "$i" -o "$i" = "$OUT" -o "$i" = "-i" -o "$i" = "-o" || {
+ find "$i" -type f | while read FILE; do
+ N=xxx
+ while [ -n "$N" ]; do
+ ID=$NEXTID
+ N=`ls "$OUTDIR/id:$(printf %06d $ID),"* 2>/dev/null`
+ NEXTID=$(($NEXTID + 1))
+ done
+ FN=`echo "$FILE" | sed 's/.*\///'`
+ cp -v "$FILE" "$OUTDIR/id:$(printf %06d $ID),time:0,execs:0,orig:$FN"
+ done
+ }
+done
+
+echo Done.
diff --git a/docs/Changelog.md b/docs/Changelog.md
index dfbadea3..101d380b 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -19,6 +19,7 @@
- fix for a few string compare transform functions for LAF
- frida_mode:
- fixes support for large map offsets
+ - added new tool afl-addseeds that adds new seeds to a running campaign
- added benchmark/benchmark.sh if you want to see how good your fuzzing
speed is in comparison to other setups.
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 8574b9b3..0a6755d7 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -1346,6 +1346,12 @@ int main(int argc, char **argv_orig, char **envp) {
}
+ if (strcmp(afl->sync_id, "addseeds") == 0) {
+
+ FATAL("-M/-S name 'addseeds' is a reserved name, choose something else");
+
+ }
+
if (afl->is_main_node == 1 && afl->schedule != FAST &&
afl->schedule != EXPLORE) {
--
cgit 1.4.1
From cf458a7d25dc3448b94ffe08d3d89531fc8d4818 Mon Sep 17 00:00:00 2001
From: Jesse Schwartzentruber
Date: Thu, 19 Oct 2023 17:14:31 -0400
Subject: Add an env to afl-clang-fast to disable setting rpath if LLVM path
isn't recognized
---
docs/env_variables.md | 6 ++++++
include/envs.h | 1 +
src/afl-cc.c | 27 ++++++++++++++++-----------
3 files changed, 23 insertions(+), 11 deletions(-)
(limited to 'docs')
diff --git a/docs/env_variables.md b/docs/env_variables.md
index 3bb4e844..a7636511 100644
--- a/docs/env_variables.md
+++ b/docs/env_variables.md
@@ -135,6 +135,12 @@ subset of the settings discussed in section 1, with the exception of:
- `TMPDIR` and `AFL_KEEP_ASSEMBLY`, since no temporary assembly files are
created.
+ - LLVM modes compiling C++ will normally set rpath in the binary if LLVM is
+ not in a usual location (/usr or /lib). Setting `AFL_LLVM_NO_RPATH=1`
+ disables this behaviour in case it isn't desired. For example, the compiling
+ toolchain might be in a custom location, but the target machine has LLVM
+ runtime libs in the search path.
+
Then there are a few specific features that are only available in
instrumentation mode:
diff --git a/include/envs.h b/include/envs.h
index 734b1707..93e49e34 100644
--- a/include/envs.h
+++ b/include/envs.h
@@ -162,6 +162,7 @@ static char *afl_environment_variables[] = {
"AFL_LLVM_MAP_DYNAMIC",
"AFL_LLVM_NGRAM_SIZE",
"AFL_NGRAM_SIZE",
+ "AFL_LLVM_NO_RPATH",
"AFL_LLVM_NOT_ZERO",
"AFL_LLVM_INSTRUMENT_FILE",
"AFL_LLVM_THREADSAFE_INST",
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 037a5c30..5f8f278f 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -1144,19 +1144,22 @@ static void edit_params(u32 argc, char **argv, char **envp) {
if (!have_pic) { cc_params[cc_par_cnt++] = "-fPIC"; }
- // in case LLVM is installed not via a package manager or "make install"
- // e.g. compiled download or compiled from github then its ./lib directory
- // might not be in the search path. Add it if so.
- u8 *libdir = strdup(LLVM_LIBDIR);
- if (plusplus_mode && strlen(libdir) && strncmp(libdir, "/usr", 4) &&
- strncmp(libdir, "/lib", 4)) {
+ if (!getenv("AFL_LLVM_NO_RPATH")) {
+ // in case LLVM is installed not via a package manager or "make install"
+ // e.g. compiled download or compiled from github then its ./lib directory
+ // might not be in the search path. Add it if so.
+ u8 *libdir = strdup(LLVM_LIBDIR);
+ if (plusplus_mode && strlen(libdir) && strncmp(libdir, "/usr", 4) &&
+ strncmp(libdir, "/lib", 4)) {
- cc_params[cc_par_cnt++] = "-Wl,-rpath";
- cc_params[cc_par_cnt++] = libdir;
+ cc_params[cc_par_cnt++] = "-Wl,-rpath";
+ cc_params[cc_par_cnt++] = libdir;
- } else {
+ } else {
- free(libdir);
+ free(libdir);
+
+ }
}
@@ -2289,7 +2292,9 @@ int main(int argc, char **argv, char **envp) {
" AFL_LLVM_CTX: use full context sensitive coverage (for "
"CLASSIC)\n"
" AFL_LLVM_NGRAM_SIZE: use ngram prev_loc count coverage (for "
- "CLASSIC)\n");
+ "CLASSIC)\n"
+ " AFL_LLVM_NO_RPATH: disable rpath setting for custom LLVM "
+ "locations\n");
#ifdef AFL_CLANG_FLTO
if (have_lto)
--
cgit 1.4.1
From 2230f88887e3e8d1793fdb98f9cd12d3449ba791 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 3 Nov 2023 11:19:14 +0100
Subject: add --help/--version/...
---
afl-persistent-config | 7 ++++++-
afl-system-config | 6 +++++-
docs/Changelog.md | 2 ++
instrumentation/afl-compiler-rt.o.c | 24 ++++++++++++++----------
src/afl-fuzz.c | 18 ++++++++++++++++--
5 files changed, 43 insertions(+), 14 deletions(-)
(limited to 'docs')
diff --git a/afl-persistent-config b/afl-persistent-config
index 3abcb866..d78db286 100755
--- a/afl-persistent-config
+++ b/afl-persistent-config
@@ -2,7 +2,7 @@
# written by jhertz
#
-test "$1" = "-h" -o "$1" = "-hh" && {
+test "$1" = "-h" -o "$1" = "-hh" -o "$1" = "--help" && {
echo 'afl-persistent-config'
echo
echo $0
@@ -17,6 +17,11 @@ test "$1" = "-h" -o "$1" = "-hh" && {
exit 0
}
+if [ $# -ne 0 ]; then
+ echo "ERROR: Unknown option(s): $@"
+ exit 1
+fi
+
echo
echo "WARNING: This scripts makes permanent configuration changes to the system to"
echo " increase the performance for fuzzing. As a result, the system also"
diff --git a/afl-system-config b/afl-system-config
index e64857eb..c633e4e8 100755
--- a/afl-system-config
+++ b/afl-system-config
@@ -1,5 +1,5 @@
#!/bin/sh
-test "$1" = "-h" -o "$1" = "-hh" && {
+test "$1" = "-h" -o "$1" = "-hh" -o "$1" = "--help" && {
echo 'afl-system-config by Marc Heuse '
echo
echo $0
@@ -13,6 +13,10 @@ test "$1" = "-h" -o "$1" = "-hh" && {
echo configuration options.
exit 0
}
+if [ $# -ne 0 ]; then
+ echo "ERROR: Unknown option(s): $@"
+ exit 1
+fi
DONE=
PLATFORM=`uname -s`
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 101d380b..bf1a7d87 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -10,6 +10,8 @@
- added AFL_IGNORE_SEED_PROBLEMS to skip over seeds that time out instead
of exiting with an error message
- allow -S/-M naming up to 50 characters (from 24)
+ - added scale support to CMPLOG (-l S)
+ - added --version and --help command line parameters
- afl-whatsup:
- detect instanced that are starting up and show them as such as not dead
- now also shows coverage reached
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index c3197c8a..d6b4d6b4 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -872,7 +872,7 @@ static void __afl_start_snapshots(void) {
if (__afl_debug) {
- fprintf(stderr, "target forkserver recv: %08x\n", was_killed);
+ fprintf(stderr, "DEBUG: target forkserver recv: %08x\n", was_killed);
}
@@ -1139,7 +1139,7 @@ static void __afl_start_forkserver(void) {
if (__afl_debug) {
- fprintf(stderr, "target forkserver recv: %08x\n", was_killed);
+ fprintf(stderr, "DEBUG: target forkserver recv: %08x\n", was_killed);
}
@@ -1472,6 +1472,7 @@ __attribute__((constructor(1))) void __afl_auto_second(void) {
__afl_debug = 1;
fprintf(stderr, "DEBUG: debug enabled\n");
+ fprintf(stderr, "DEBUG: AFL++ afl-compiler-rt" VERSION "\n");
}
@@ -1700,11 +1701,12 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
if (__afl_debug) {
- fprintf(stderr,
- "Running __sanitizer_cov_trace_pc_guard_init: %p-%p (%lu edges) "
- "after_fs=%u\n",
- start, stop, (unsigned long)(stop - start),
- __afl_already_initialized_forkserver);
+ fprintf(
+ stderr,
+ "DEBUG: Running __sanitizer_cov_trace_pc_guard_init: %p-%p (%lu edges) "
+ "after_fs=%u\n",
+ start, stop, (unsigned long)(stop - start),
+ __afl_already_initialized_forkserver);
}
@@ -1802,7 +1804,8 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
u8 ignore_dso_after_fs = !!getenv("AFL_IGNORE_PROBLEMS_COVERAGE");
if (__afl_debug && ignore_dso_after_fs) {
- fprintf(stderr, "Ignoring coverage from dynamically loaded code\n");
+ fprintf(stderr,
+ "DEBUG: Ignoring coverage from dynamically loaded code\n");
}
@@ -1872,7 +1875,8 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
if (__afl_debug) {
fprintf(stderr,
- "Done __sanitizer_cov_trace_pc_guard_init: __afl_final_loc = %u\n",
+ "DEBUG: Done __sanitizer_cov_trace_pc_guard_init: __afl_final_loc "
+ "= %u\n",
__afl_final_loc);
}
@@ -1883,7 +1887,7 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
if (__afl_debug) {
- fprintf(stderr, "Reinit shm necessary (+%u)\n",
+ fprintf(stderr, "DEBUG: Reinit shm necessary (+%u)\n",
__afl_final_loc - __afl_map_size);
}
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 2538f4a4..6a8a6aae 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -486,6 +486,22 @@ int main(int argc, char **argv_orig, char **envp) {
struct timeval tv;
struct timezone tz;
+ doc_path = access(DOC_PATH, F_OK) != 0 ? (u8 *)"docs" : (u8 *)DOC_PATH;
+
+ if (argc > 1 && strcmp(argv_orig[1], "--version") == 0) {
+
+ printf("afl-fuzz" VERSION "\n");
+ exit(0);
+
+ }
+
+ if (argc > 1 && strcmp(argv_orig[1], "--help") == 0) {
+
+ usage(argv_orig[0], 1);
+ exit(0);
+
+ }
+
#if defined USE_COLOR && defined ALWAYS_COLORED
if (getenv("AFL_NO_COLOR") || getenv("AFL_NO_COLOUR")) {
@@ -515,8 +531,6 @@ int main(int argc, char **argv_orig, char **envp) {
SAYF(cCYA "afl-fuzz" VERSION cRST
" based on afl by Michal Zalewski and a large online community\n");
- doc_path = access(DOC_PATH, F_OK) != 0 ? (u8 *)"docs" : (u8 *)DOC_PATH;
-
gettimeofday(&tv, &tz);
rand_set_seed(afl, tv.tv_sec ^ tv.tv_usec ^ getpid());
--
cgit 1.4.1
From ac0ad563480e3bf1fb69349e960b7957fffe75df Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 7 Nov 2023 10:31:09 +0100
Subject: fix dictionary and cmin
---
afl-cmin | 32 +++++++++----------
afl-cmin.bash | 86 ++++++++++++++++++++++++++++++---------------------
docs/Changelog.md | 2 ++
src/afl-fuzz-extras.c | 5 +--
4 files changed, 70 insertions(+), 55 deletions(-)
(limited to 'docs')
diff --git a/afl-cmin b/afl-cmin
index 23532b63..566f157d 100755
--- a/afl-cmin
+++ b/afl-cmin
@@ -259,22 +259,20 @@ BEGIN {
# Do a sanity check to discourage the use of /tmp, since we can't really
# handle this safely from an awk script.
- #if (!ENVIRON["AFL_ALLOW_TMP"]) {
- # dirlist[0] = in_dir
- # dirlist[1] = target_bin
- # dirlist[2] = out_dir
- # dirlist[3] = stdin_file
- # "pwd" | getline dirlist[4] # current directory
- # for (dirind in dirlist) {
- # dir = dirlist[dirind]
- #
- # if (dir ~ /^(\/var)?\/tmp/) {
- # print "[-] Error: do not use this script in /tmp or /var/tmp." > "/dev/stderr"
- # exit 1
- # }
- # }
- # delete dirlist
- #}
+ if (!ENVIRON["AFL_ALLOW_TMP"]) {
+ dirlist[0] = in_dir
+ dirlist[1] = target_bin
+ dirlist[2] = out_dir
+ dirlist[3] = stdin_file
+ "pwd" | getline dirlist[4] # current directory
+ for (dirind in dirlist) {
+ dir = dirlist[dirind]
+ if (dir ~ /^(\/var)?\/tmp/) {
+ print "[-] Warning: do not use this script in /tmp or /var/tmp for security reasons." > "/dev/stderr"
+ }
+ }
+ delete dirlist
+ }
if (threads && stdin_file) {
print "[-] Error: -T and -f cannot be used together." > "/dev/stderr"
@@ -430,7 +428,7 @@ BEGIN {
} else {
stat_format = "-f '%z %N'" # *BSD, MacOS
}
- cmdline = "(cd "in_dir" && find . \\( ! -name \".*\" -a -type d \\) -o -type f -exec stat "stat_format" \\{\\} + | sort -k1n -k2r)"
+ cmdline = "(cd "in_dir" && find . \\( ! -name \".*\" -a -type d \\) -o -type f -exec stat "stat_format" \\{\\} + | sort -k1n -k2r) | grep -Ev '^0'"
#cmdline = "ls "in_dir" | (cd "in_dir" && xargs stat "stat_format" 2>/dev/null) | sort -k1n -k2r"
#cmdline = "(cd "in_dir" && stat "stat_format" *) | sort -k1n -k2r"
#cmdline = "(cd "in_dir" && ls | xargs stat "stat_format" ) | sort -k1n -k2r"
diff --git a/afl-cmin.bash b/afl-cmin.bash
index b326bee8..fda48fb4 100755
--- a/afl-cmin.bash
+++ b/afl-cmin.bash
@@ -167,29 +167,28 @@ fi
# Do a sanity check to discourage the use of /tmp, since we can't really
# handle this safely from a shell script.
-#if [ "$AFL_ALLOW_TMP" = "" ]; then
-#
-# echo "$IN_DIR" | grep -qE '^(/var)?/tmp/'
-# T1="$?"
-#
-# echo "$TARGET_BIN" | grep -qE '^(/var)?/tmp/'
-# T2="$?"
-#
-# echo "$OUT_DIR" | grep -qE '^(/var)?/tmp/'
-# T3="$?"
-#
-# echo "$STDIN_FILE" | grep -qE '^(/var)?/tmp/'
-# T4="$?"
-#
-# echo "$PWD" | grep -qE '^(/var)?/tmp/'
-# T5="$?"
-#
-# if [ "$T1" = "0" -o "$T2" = "0" -o "$T3" = "0" -o "$T4" = "0" -o "$T5" = "0" ]; then
-# echo "[-] Error: do not use this script in /tmp or /var/tmp." 1>&2
-# exit 1
-# fi
-#
-#fi
+if [ "$AFL_ALLOW_TMP" = "" ]; then
+
+ echo "$IN_DIR" | grep -qE '^(/var)?/tmp/'
+ T1="$?"
+
+ echo "$TARGET_BIN" | grep -qE '^(/var)?/tmp/'
+ T2="$?"
+
+ echo "$OUT_DIR" | grep -qE '^(/var)?/tmp/'
+ T3="$?"
+
+ echo "$STDIN_FILE" | grep -qE '^(/var)?/tmp/'
+ T4="$?"
+
+ echo "$PWD" | grep -qE '^(/var)?/tmp/'
+ T5="$?"
+
+ if [ "$T1" = "0" -o "$T2" = "0" -o "$T3" = "0" -o "$T4" = "0" -o "$T5" = "0" ]; then
+ echo "[-] Warning: do not use this script in /tmp or /var/tmp for security reasons." 1>&2
+ fi
+
+fi
# If @@ is specified, but there's no -f, let's come up with a temporary input
# file name.
@@ -423,10 +422,14 @@ if [ "$THREADS" = "" ]; then
ls "$IN_DIR" | while read -r fn; do
- CUR=$((CUR+1))
- printf "\\r Processing file $CUR/$IN_COUNT... "
+ if [ -s "$IN_DIR/$fn" ]; then
- "$SHOWMAP" -m "$MEM_LIMIT" -t "$TIMEOUT" -o "$TRACE_DIR/$fn" -Z $EXTRA_PAR -- "$@" <"$IN_DIR/$fn"
+ CUR=$((CUR+1))
+ printf "\\r Processing file $CUR/$IN_COUNT... "
+
+ "$SHOWMAP" -m "$MEM_LIMIT" -t "$TIMEOUT" -o "$TRACE_DIR/$fn" -Z $EXTRA_PAR -- "$@" <"$IN_DIR/$fn"
+
+ fi
done
@@ -434,11 +437,15 @@ if [ "$THREADS" = "" ]; then
ls "$IN_DIR" | while read -r fn; do
- CUR=$((CUR+1))
- printf "\\r Processing file $CUR/$IN_COUNT... "
+ if [ -s "$IN_DIR/$fn" ]; then
+
+ CUR=$((CUR+1))
+ printf "\\r Processing file $CUR/$IN_COUNT... "
+
+ cp "$IN_DIR/$fn" "$STDIN_FILE"
+ "$SHOWMAP" -m "$MEM_LIMIT" -t "$TIMEOUT" -o "$TRACE_DIR/$fn" -Z $EXTRA_PAR -H "$STDIN_FILE" -- "$@" extras =
afl_realloc((void **)&afl->extras,
(afl->extras_cnt + 1) * sizeof(struct extra_data));
+ char *hexdigits = "0123456789abcdef";
+
if (unlikely(!afl->extras)) { PFATAL("alloc"); }
wptr = afl->extras[afl->extras_cnt].data = ck_alloc(rptr - lptr);
@@ -184,13 +186,12 @@ void load_extras_file(afl_state_t *afl, u8 *fname, u32 *min_len, u32 *max_len,
while (*lptr) {
- char *hexdigits = "0123456789abcdef";
-
switch (*lptr) {
case 1 ... 31:
case 128 ... 255:
WARNF("Non-printable characters in line %u.", cur_line);
+ ++lptr;
continue;
break;
--
cgit 1.4.1
From 6f8696c3149a08d93c9b61db97f7b23cc6578274 Mon Sep 17 00:00:00 2001
From: Manuel Carrasco
Date: Thu, 9 Nov 2023 13:46:41 +0000
Subject: Fix possible doc inconsistency for custom mutator's queue_get
function.
---
docs/custom_mutators.md | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
(limited to 'docs')
diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md
index c5a64622..1c4ab2cf 100644
--- a/docs/custom_mutators.md
+++ b/docs/custom_mutators.md
@@ -125,8 +125,9 @@ def deinit(): # optional for Python
- `queue_get` (optional):
- This method determines whether the custom fuzzer should fuzz the current
- queue entry or not
+ This method determines whether AFL++ should fuzz the current
+ queue entry or not: all defined custom mutators as well as
+ all AFL++'s mutators.
- `fuzz_count` (optional):
--
cgit 1.4.1
From 5681267bbc901941e6056390abfe6aad43b45775 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 20 Nov 2023 09:32:00 +0100
Subject: nits
---
docs/Changelog.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'docs')
diff --git a/docs/Changelog.md b/docs/Changelog.md
index c74a9ad7..1e2a4765 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -24,7 +24,7 @@
- fixes support for large map offsets
- afl-cmin/afl-cmin.bash: prevent unneeded file errors
- added new tool afl-addseeds that adds new seeds to a running campaign
- - added benchmark/benchmark.sh if you want to see how good your fuzzing
+ - added benchmark/benchmark.py if you want to see how good your fuzzing
speed is in comparison to other setups.
--
cgit 1.4.1
From d17e0b32f454319a117782bf7a8e4824213321df Mon Sep 17 00:00:00 2001
From: Carlo Maragno
Date: Thu, 23 Nov 2023 00:05:56 +0100
Subject: Fix typo in docker pull command, add exampe to mount current dir as
volume (#1914)
---
docs/INSTALL.md | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
(limited to 'docs')
diff --git a/docs/INSTALL.md b/docs/INSTALL.md
index 41f512ed..4f029f5d 100644
--- a/docs/INSTALL.md
+++ b/docs/INSTALL.md
@@ -7,10 +7,17 @@ You can use the [Dockerfile](../Dockerfile) or just pull directly from the
Docker Hub (for x86_64 and arm64):
```shell
-docker pull aflplusplus/aflplusplus:
+docker pull aflplusplus/aflplusplus:latest
docker run -ti -v /location/of/your/target:/src aflplusplus/aflplusplus
```
+Or for convinince to run in the current directory:
+
+```shell
+docker pull aflplusplus/aflplusplus:latest
+docker run -ti -v $(pwd):/src aflplusplus/aflplusplus
+```
+
This image is automatically generated when a push to the stable branch happens.
You will find your target source code in `/src` in the container.
--
cgit 1.4.1
From dd9a04c901c79fe2f3f078de6cc0777e3a5d96df Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 28 Nov 2023 09:14:29 +0100
Subject: code format
---
docs/Changelog.md | 1 +
src/afl-fuzz-run.c | 9 +++++++--
2 files changed, 8 insertions(+), 2 deletions(-)
(limited to 'docs')
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 1e2a4765..f7842d59 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -13,6 +13,7 @@
- added scale support to CMPLOG (-l S)
- added --version and --help command line parameters
- fixed endless loop when reading malformed dictionaries
+ - new custom mutator function: post_run - thanks to yangzao!
- afl-whatsup:
- detect instanced that are starting up and show them as such as not dead
- now also shows coverage reached
diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c
index b6d5df95..34a5ff81 100644
--- a/src/afl-fuzz-run.c
+++ b/src/afl-fuzz-run.c
@@ -62,12 +62,16 @@ fuzz_run_target(afl_state_t *afl, afl_forkserver_t *fsrv, u32 timeout) {
/* If post_run() function is defined in custom mutator, the function will be
called each time after AFL++ executes the target program. */
-
+
if (unlikely(afl->custom_mutators_count)) {
LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
- if (el->afl_custom_post_run) { el->afl_custom_post_run(el->data); }
+ if (unlikely(el->afl_custom_post_run)) {
+
+ el->afl_custom_post_run(el->data);
+
+ }
});
@@ -1123,3 +1127,4 @@ common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
return 0;
}
+
--
cgit 1.4.1
From 74f8ca6b468b6d89e8d588e3835486be48184893 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 28 Nov 2023 10:26:37 +0100
Subject: improve cmplog
---
docs/Changelog.md | 4 ++-
instrumentation/afl-compiler-rt.o.c | 10 ++++++--
instrumentation/cmplog-instructions-pass.cc | 38 +++++++++++++++--------------
src/afl-fuzz-redqueen.c | 4 +++
4 files changed, 35 insertions(+), 21 deletions(-)
(limited to 'docs')
diff --git a/docs/Changelog.md b/docs/Changelog.md
index f7842d59..b2e9fbf6 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -10,7 +10,9 @@
- added AFL_IGNORE_SEED_PROBLEMS to skip over seeds that time out instead
of exiting with an error message
- allow -S/-M naming up to 50 characters (from 24)
- - added scale support to CMPLOG (-l S)
+ - CMPLOG:
+ - added scale support (-l S)
+ - skip unhelpful insertions (u8)
- added --version and --help command line parameters
- fixed endless loop when reading malformed dictionaries
- new custom mutator function: post_run - thanks to yangzao!
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index 8ce8bca1..106892e2 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -1910,6 +1910,10 @@ void __cmplog_ins_hook1(uint8_t arg1, uint8_t arg2, uint8_t attr) {
// fprintf(stderr, "hook1 arg0=%02x arg1=%02x attr=%u\n",
// (u8) arg1, (u8) arg2, attr);
+ return;
+
+ /*
+
if (unlikely(!__afl_cmp_map || arg1 == arg2)) return;
uintptr_t k = (uintptr_t)__builtin_return_address(0);
@@ -1936,6 +1940,8 @@ void __cmplog_ins_hook1(uint8_t arg1, uint8_t arg2, uint8_t attr) {
__afl_cmp_map->log[k][hits].v0 = arg1;
__afl_cmp_map->log[k][hits].v1 = arg2;
+ */
+
}
void __cmplog_ins_hook2(uint16_t arg1, uint16_t arg2, uint8_t attr) {
@@ -2142,13 +2148,13 @@ void __cmplog_ins_hook16(uint128_t arg1, uint128_t arg2, uint8_t attr) {
void __sanitizer_cov_trace_cmp1(uint8_t arg1, uint8_t arg2) {
- __cmplog_ins_hook1(arg1, arg2, 0);
+ //__cmplog_ins_hook1(arg1, arg2, 0);
}
void __sanitizer_cov_trace_const_cmp1(uint8_t arg1, uint8_t arg2) {
- __cmplog_ins_hook1(arg1, arg2, 0);
+ //__cmplog_ins_hook1(arg1, arg2, 0);
}
diff --git a/instrumentation/cmplog-instructions-pass.cc b/instrumentation/cmplog-instructions-pass.cc
index 9cd1dc59..8be8c294 100644
--- a/instrumentation/cmplog-instructions-pass.cc
+++ b/instrumentation/cmplog-instructions-pass.cc
@@ -165,23 +165,25 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
IntegerType *Int64Ty = IntegerType::getInt64Ty(C);
IntegerType *Int128Ty = IntegerType::getInt128Ty(C);
-#if LLVM_VERSION_MAJOR >= 9
- FunctionCallee
-#else
- Constant *
-#endif
- c1 = M.getOrInsertFunction("__cmplog_ins_hook1", VoidTy, Int8Ty, Int8Ty,
- Int8Ty
-#if LLVM_VERSION_MAJOR < 5
- ,
- NULL
-#endif
- );
-#if LLVM_VERSION_MAJOR >= 9
- FunctionCallee cmplogHookIns1 = c1;
-#else
- Function *cmplogHookIns1 = cast(c1);
-#endif
+ /*
+ #if LLVM_VERSION_MAJOR >= 9
+ FunctionCallee
+ #else
+ Constant *
+ #endif
+ c1 = M.getOrInsertFunction("__cmplog_ins_hook1", VoidTy, Int8Ty, Int8Ty,
+ Int8Ty
+ #if LLVM_VERSION_MAJOR < 5
+ ,
+ NULL
+ #endif
+ );
+ #if LLVM_VERSION_MAJOR >= 9
+ FunctionCallee cmplogHookIns1 = c1;
+ #else
+ Function *cmplogHookIns1 = cast(c1);
+ #endif
+ */
#if LLVM_VERSION_MAJOR >= 9
FunctionCallee
@@ -619,7 +621,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
switch (cast_size) {
case 8:
- IRB.CreateCall(cmplogHookIns1, args);
+ // IRB.CreateCall(cmplogHookIns1, args);
break;
case 16:
IRB.CreateCall(cmplogHookIns2, args);
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index 13f164f5..c0ea5005 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -1906,6 +1906,8 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
#endif
+ if (hshape < 2) { return 0; }
+
for (i = 0; i < loggeds; ++i) {
struct cmp_operands *o = &afl->shm.cmp_map->log[key][i];
@@ -2698,6 +2700,8 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
hshape = SHAPE_BYTES(h->shape);
+ if (hshape < 2) { return 0; }
+
if (h->hits > CMP_MAP_RTN_H) {
loggeds = CMP_MAP_RTN_H;
--
cgit 1.4.1
From 638273e4f80ba89ada8a4428a6211ee6b59d964a Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 5 Dec 2023 17:38:32 +0100
Subject: nits
---
docs/INSTALL.md | 7 -------
1 file changed, 7 deletions(-)
(limited to 'docs')
diff --git a/docs/INSTALL.md b/docs/INSTALL.md
index 4f029f5d..1379df0a 100644
--- a/docs/INSTALL.md
+++ b/docs/INSTALL.md
@@ -11,13 +11,6 @@ docker pull aflplusplus/aflplusplus:latest
docker run -ti -v /location/of/your/target:/src aflplusplus/aflplusplus
```
-Or for convinince to run in the current directory:
-
-```shell
-docker pull aflplusplus/aflplusplus:latest
-docker run -ti -v $(pwd):/src aflplusplus/aflplusplus
-```
-
This image is automatically generated when a push to the stable branch happens.
You will find your target source code in `/src` in the container.
--
cgit 1.4.1
From a576f7aef42d190f969030a3efde7032d1425833 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 12 Dec 2023 09:34:04 +0100
Subject: in-depth blog post
---
docs/afl-fuzz_approach.md | 4 ++++
docs/tutorials.md | 5 ++++-
2 files changed, 8 insertions(+), 1 deletion(-)
(limited to 'docs')
diff --git a/docs/afl-fuzz_approach.md b/docs/afl-fuzz_approach.md
index 7d18b178..9ea06325 100644
--- a/docs/afl-fuzz_approach.md
+++ b/docs/afl-fuzz_approach.md
@@ -5,6 +5,10 @@ instrumentation-guided genetic algorithm. It uses a modified form of edge
coverage to effortlessly pick up subtle, local-scale changes to program control
flow.
+Note: If you are interested in a more current up-to-date deep dive how AFL++
+works then we commend this blog post:
+[https://blog.ritsec.club/posts/afl-under-hood/](https://blog.ritsec.club/posts/afl-under-hood/)
+
Simplifying a bit, the overall algorithm can be summed up as:
1) Load user-supplied initial test cases into the queue.
diff --git a/docs/tutorials.md b/docs/tutorials.md
index a5ee3322..0a09f6dc 100644
--- a/docs/tutorials.md
+++ b/docs/tutorials.md
@@ -21,7 +21,7 @@ training, then we can highly recommend the following:
* [https://github.com/antonio-morales/Fuzzing101](https://github.com/antonio-morales/Fuzzing101)
-Here is a good forkflow description (and tutorial) for qemu_mode:
+Here is a good workflow description (and tutorial) for qemu_mode:
* [https://airbus-seclab.github.io/AFLplusplus-blogpost/](https://airbus-seclab.github.io/AFLplusplus-blogpost/)
@@ -41,6 +41,9 @@ structure is), these links have you covered (some are outdated though):
* Superion for AFL++:
[https://github.com/adrian-rt/superion-mutator](https://github.com/adrian-rt/superion-mutator)
+For a very in-depth explanation on how AFL++ works check out:
+[https://blog.ritsec.club/posts/afl-under-hood/](https://blog.ritsec.club/posts/afl-under-hood/)
+
## Video Tutorials
* [Install AFL++ Ubuntu](https://www.youtube.com/watch?v=5dCvhkbi3RA)
--
cgit 1.4.1
From ae9cdb34e4fdc10c7c2d1c775238a7501fda288a Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 14 Dec 2023 16:04:00 +0100
Subject: AFL_FUZZER_LOOPCOUNT
---
docs/Changelog.md | 1 +
utils/aflpp_driver/aflpp_driver.c | 7 +++++++
2 files changed, 8 insertions(+)
(limited to 'docs')
diff --git a/docs/Changelog.md b/docs/Changelog.md
index b2e9fbf6..7faa0ab3 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -25,6 +25,7 @@
- fix for a few string compare transform functions for LAF
- frida_mode:
- fixes support for large map offsets
+ - support for AFL_FUZZER_LOOPCOUNT for afl.rs and LLVMFuzzerTestOneInput
- afl-cmin/afl-cmin.bash: prevent unneeded file errors
- added new tool afl-addseeds that adds new seeds to a running campaign
- added benchmark/benchmark.py if you want to see how good your fuzzing
diff --git a/utils/aflpp_driver/aflpp_driver.c b/utils/aflpp_driver/aflpp_driver.c
index dab7fd95..9ffb2383 100644
--- a/utils/aflpp_driver/aflpp_driver.c
+++ b/utils/aflpp_driver/aflpp_driver.c
@@ -292,6 +292,7 @@ __attribute__((weak)) int main(int argc, char **argv) {
"afl-fuzz will run N iterations before re-spawning the process "
"(default: "
"INT_MAX)\n"
+ "You can also use AFL_FUZZER_LOOPCOUNT to set N\n"
"For stdin input processing, pass '-' as single command line option.\n"
"For file input processing, pass '@@' as single command line option.\n"
"To use with afl-cmin or afl-cmin.bash pass '-' as single command line "
@@ -379,6 +380,12 @@ __attribute__((weak)) int LLVMFuzzerRunDriver(
}
+ if (getenv("AFL_FUZZER_LOOPCOUNT")) {
+
+ N = atoi(getenv("AFL_FUZZER_LOOPCOUNT"));
+
+ }
+
assert(N > 0);
__afl_manual_init();
--
cgit 1.4.1
From 37505928bcec63a08fe50cdebdbf7b9b28b952d0 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 15 Dec 2023 09:23:30 +0100
Subject: fix 2 mutation bugs
---
docs/Changelog.md | 3 +++
include/afl-mutations.h | 16 ++++++++--------
2 files changed, 11 insertions(+), 8 deletions(-)
(limited to 'docs')
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 7faa0ab3..0d75782d 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -5,6 +5,7 @@
### Version ++4.09a (dev)
- afl-fuzz:
+ - fixed the new mutation implementation for two bugs
- added `AFL_FINAL_SYNC` which forces a final fuzzer sync (also for `-F`)
before terminating.
- added AFL_IGNORE_SEED_PROBLEMS to skip over seeds that time out instead
@@ -23,6 +24,8 @@
- option -n will not use color in the output
- instrumentation:
- fix for a few string compare transform functions for LAF
+ - we are instrumenting __cxx internal functions again. this might break
+ a few targets, please report if so.
- frida_mode:
- fixes support for large map offsets
- support for AFL_FUZZER_LOOPCOUNT for afl.rs and LLVMFuzzerTestOneInput
diff --git a/include/afl-mutations.h b/include/afl-mutations.h
index d709b90d..6338c93c 100644
--- a/include/afl-mutations.h
+++ b/include/afl-mutations.h
@@ -2456,14 +2456,14 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
}
- char buf[20];
- snprintf(buf, sizeof(buf), "%" PRId64, val);
+ char numbuf[32];
+ snprintf(numbuf, sizeof(buf), "%" PRId64, val);
u32 old_len = off2 - off;
- u32 new_len = strlen(buf);
+ u32 new_len = strlen(numbuf);
if (old_len == new_len) {
- memcpy(buf + off, buf, new_len);
+ memcpy(buf + off, numbuf, new_len);
} else {
@@ -2473,7 +2473,7 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
/* Inserted part */
- memcpy(tmp_buf + off, buf, new_len);
+ memcpy(tmp_buf + off, numbuf, new_len);
/* Tail */
memcpy(tmp_buf + off + new_len, buf + off2, len - off2);
@@ -2509,9 +2509,9 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
}
u64 val = rand_next(afl);
- char buf[20];
- snprintf(buf, sizeof(buf), "%llu", val);
- memcpy(buf + pos, buf, len);
+ char numbuf[32];
+ snprintf(numbuf, sizeof(numbuf), "%llu", val);
+ memcpy(buf + pos, numbuf, len);
break;
--
cgit 1.4.1
From 8a7705aedbb759dd8ff331d47a99cc6bbc17902b Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 15 Dec 2023 09:28:39 +0100
Subject: v4.09c release
---
README.md | 4 ++--
docs/Changelog.md | 2 +-
include/config.h | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
(limited to 'docs')
diff --git a/README.md b/README.md
index 322ebcf2..a09147c5 100644
--- a/README.md
+++ b/README.md
@@ -2,9 +2,9 @@
-Release version: [4.08c](https://github.com/AFLplusplus/AFLplusplus/releases)
+Release version: [4.09c](https://github.com/AFLplusplus/AFLplusplus/releases)
-GitHub version: 4.09a
+GitHub version: 4.09c
Repository:
[https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 0d75782d..2dfcb482 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -3,7 +3,7 @@
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.09a (dev)
+### Version ++4.09c (release)
- afl-fuzz:
- fixed the new mutation implementation for two bugs
- added `AFL_FINAL_SYNC` which forces a final fuzzer sync (also for `-F`)
diff --git a/include/config.h b/include/config.h
index 988e536e..b346d7b4 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.09a"
+#define VERSION "++4.09c"
/******************************************************
* *
--
cgit 1.4.1
From ca0c9f6d1797bac121996c3b2ac50423f6e67b8f Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 15 Dec 2023 09:44:02 +0100
Subject: v4.10a init
---
README.md | 2 +-
docs/Changelog.md | 5 ++++-
include/config.h | 2 +-
3 files changed, 6 insertions(+), 3 deletions(-)
(limited to 'docs')
diff --git a/README.md b/README.md
index a09147c5..fd48cb14 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
Release version: [4.09c](https://github.com/AFLplusplus/AFLplusplus/releases)
-GitHub version: 4.09c
+GitHub version: 4.10a
Repository:
[https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 2dfcb482..2ac87f47 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -3,6 +3,10 @@
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.10a (dev)
+ - ...
+
+
### Version ++4.09c (release)
- afl-fuzz:
- fixed the new mutation implementation for two bugs
@@ -34,7 +38,6 @@
- added benchmark/benchmark.py if you want to see how good your fuzzing
speed is in comparison to other setups.
-
### Version ++4.08c (release)
- afl-fuzz:
- new mutation engine: mutations that favor discovery more paths are
diff --git a/include/config.h b/include/config.h
index b346d7b4..63340650 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.09c"
+#define VERSION "++4.10a"
/******************************************************
* *
--
cgit 1.4.1
From 353ae3682a02634abae0b6590dfb47b762cf6bfa Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 15 Dec 2023 10:24:12 +0100
Subject: switch to explore powerschedule as default
---
docs/Changelog.md | 3 ++-
src/afl-fuzz-state.c | 3 +--
src/afl-fuzz.c | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
(limited to 'docs')
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 2ac87f47..150ce6c7 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -4,7 +4,8 @@
release of the tool. See README.md for the general instruction manual.
### Version ++4.10a (dev)
- - ...
+ - default power schedule is now EXPLORE, due a fix in fast schedules
+ explore is slightly better now.
### Version ++4.09c (release)
diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c
index db82536d..7d6fdfb9 100644
--- a/src/afl-fuzz-state.c
+++ b/src/afl-fuzz-state.c
@@ -89,9 +89,8 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) {
afl->w_end = 0.3;
afl->g_max = 5000;
afl->period_pilot_tmp = 5000.0;
- afl->schedule = FAST; /* Power schedule (default: FAST) */
+ afl->schedule = EXPLORE; /* Power schedule (default: EXPLORE)*/
afl->havoc_max_mult = HAVOC_MAX_MULT;
-
afl->clear_screen = 1; /* Window resized? */
afl->havoc_div = 1; /* Cycle count divisor for havoc */
afl->stage_name = "init"; /* Name of the current fuzz stage */
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index becad351..dd990e71 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -138,7 +138,7 @@ static void usage(u8 *argv0, int more_help) {
"to\n"
" exploit mode, and back on new coverage (default: %u)\n"
" -p schedule - power schedules compute a seed's performance score:\n"
- " fast(default), explore, exploit, seek, rare, mmopt, "
+ " explore(default), fast, exploit, seek, rare, mmopt, "
"coe, lin\n"
" quad -- see docs/FAQ.md for more information\n"
" -f file - location read by the fuzzed program (default: stdin "
--
cgit 1.4.1
From 806a76afaeb1e1c99847df95af4181b3d1b48a91 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 19 Dec 2023 11:15:33 +0100
Subject: fix bad fix for MUT_STRATEGY_ARRAY_SIZE
---
docs/Changelog.md | 7 +++++--
include/afl-mutations.h | 3 ++-
2 files changed, 7 insertions(+), 3 deletions(-)
(limited to 'docs')
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 150ce6c7..133e460b 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -4,8 +4,11 @@
release of the tool. See README.md for the general instruction manual.
### Version ++4.10a (dev)
- - default power schedule is now EXPLORE, due a fix in fast schedules
- explore is slightly better now.
+ - afl-fuzz:
+ - default power schedule is now EXPLORE, due a fix in fast schedules
+ explore is slightly better now.
+ - fixed minor issues in the mutation engine, thanks to @futhewo for
+ reporting!
### Version ++4.09c (release)
diff --git a/include/afl-mutations.h b/include/afl-mutations.h
index dcc62d0b..75e66484 100644
--- a/include/afl-mutations.h
+++ b/include/afl-mutations.h
@@ -32,7 +32,7 @@
#include
#include "afl-fuzz.h"
-#define MUT_STRATEGY_ARRAY_SIZE 255
+#define MUT_STRATEGY_ARRAY_SIZE 256
enum {
@@ -1082,6 +1082,7 @@ u32 mutation_strategy_exploration_binary[MUT_STRATEGY_ARRAY_SIZE] = {
MUT_CLONE_COPY,
MUT_CLONE_COPY,
MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
MUT_CLONE_FIXED,
MUT_CLONE_FIXED,
MUT_CLONE_FIXED,
--
cgit 1.4.1
From 86d76b52acb945c662ba6d2f8ff44cf036a12161 Mon Sep 17 00:00:00 2001
From: Bet4 <0xbet4@gmail.com>
Date: Thu, 21 Dec 2023 23:48:43 +0800
Subject: Improve binary-only related docs
---
docs/fuzzing_binary-only_targets.md | 8 +-------
frida_mode/src/main.c | 4 ++--
frida_mode/src/ranges.c | 2 +-
3 files changed, 4 insertions(+), 10 deletions(-)
(limited to 'docs')
diff --git a/docs/fuzzing_binary-only_targets.md b/docs/fuzzing_binary-only_targets.md
index 9d9d6bb6..a151bce4 100644
--- a/docs/fuzzing_binary-only_targets.md
+++ b/docs/fuzzing_binary-only_targets.md
@@ -94,8 +94,7 @@ For more information, see
In FRIDA mode, you can fuzz binary-only targets as easily as with QEMU mode.
FRIDA mode is most of the times slightly faster than QEMU mode. It is also
-newer, lacks COMPCOV, and has the advantage that it works on MacOS (both intel
-and M1).
+newer, and has the advantage that it works on MacOS (both intel and M1).
To build FRIDA mode:
@@ -113,10 +112,6 @@ The mode is approximately 2-5x slower than compile-time instrumentation, and is
less conducive to parallelization. But for binary-only fuzzing, it gives a huge
speed improvement if it is possible to use.
-If you want to fuzz a binary-only library, then you can fuzz it with frida-gum
-via frida_mode/. You will have to write a harness to call the target function in
-the library, use afl-frida.c as a template.
-
You can also perform remote fuzzing with frida, e.g., if you want to fuzz on
iPhone or Android devices, for this you can use
[https://github.com/ttdennis/fpicker/](https://github.com/ttdennis/fpicker/) as
@@ -302,7 +297,6 @@ some are very hard to set up...
* S2E: [https://github.com/S2E](https://github.com/S2E)
* TinyInst:
[https://github.com/googleprojectzero/TinyInst](https://github.com/googleprojectzero/TinyInst)
- (Mac/Windows only)
* ... please send me any missing that are good
## Closing words
diff --git a/frida_mode/src/main.c b/frida_mode/src/main.c
index bd7b1351..9daf067b 100644
--- a/frida_mode/src/main.c
+++ b/frida_mode/src/main.c
@@ -166,7 +166,7 @@ static void afl_print_env(void) {
if (fd < 0) {
- FWARNF("Failed to open /proc/self/cmdline, errno: (%d)", errno);
+ FWARNF("Failed to open /proc/self/environ, errno: (%d)", errno);
return;
}
@@ -174,7 +174,7 @@ static void afl_print_env(void) {
ssize_t bytes_read = read(fd, buffer, PROC_MAX - 1);
if (bytes_read < 0) {
- FFATAL("Failed to read /proc/self/cmdline, errno: (%d)", errno);
+ FFATAL("Failed to read /proc/self/environ, errno: (%d)", errno);
}
diff --git a/frida_mode/src/ranges.c b/frida_mode/src/ranges.c
index e9fc3b4e..269ba59b 100644
--- a/frida_mode/src/ranges.c
+++ b/frida_mode/src/ranges.c
@@ -653,7 +653,7 @@ void ranges_init(void) {
/*
* After step 4 we have the total ranges to be instrumented, we now subtract
* that either from the original ranges of the modules or from the whole
- * memory if AFL_INST_NO_DYNAMIC_LOAD to configure the stalker.
+ * memory if AFL_FRIDA_INST_NO_DYNAMIC_LOAD to configure the stalker.
*/
if (ranges_inst_dynamic_load) {
--
cgit 1.4.1
From daaefcddc063b356018c29027494a00bcfc3e240 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sun, 24 Dec 2023 10:35:02 +0100
Subject: code format
---
docs/Changelog.md | 2 ++
instrumentation/SanitizerCoverageLTO.so.cc | 48 +++++++++++++++-------------
instrumentation/afl-llvm-dict2file.so.cc | 33 ++++++++++---------
instrumentation/cmplog-routines-pass.cc | 15 +++++----
instrumentation/compare-transform-pass.so.cc | 30 +++++++++--------
5 files changed, 70 insertions(+), 58 deletions(-)
(limited to 'docs')
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 133e460b..c8f04217 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -9,6 +9,8 @@
explore is slightly better now.
- fixed minor issues in the mutation engine, thanks to @futhewo for
reporting!
+ - instrumentation:
+ - LLVM 18 support, thanks to @devnexen!
### Version ++4.09c (release)
diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc
index 8365cf65..68423029 100644
--- a/instrumentation/SanitizerCoverageLTO.so.cc
+++ b/instrumentation/SanitizerCoverageLTO.so.cc
@@ -692,33 +692,37 @@ bool ModuleSanitizerCoverageLTO::instrumentModule(
* prototype */
FunctionType *FT = Callee->getFunctionType();
- isStrcmp &= FT->getNumParams() == 2 &&
- FT->getReturnType()->isIntegerTy(32) &&
- FT->getParamType(0) == FT->getParamType(1) &&
- FT->getParamType(0) ==
- IntegerType::getInt8Ty(M.getContext())->getPointerTo(0);
- isStrcasecmp &= FT->getNumParams() == 2 &&
- FT->getReturnType()->isIntegerTy(32) &&
- FT->getParamType(0) == FT->getParamType(1) &&
- FT->getParamType(0) ==
- IntegerType::getInt8Ty(M.getContext())->getPointerTo(0);
+ isStrcmp &=
+ FT->getNumParams() == 2 &&
+ FT->getReturnType()->isIntegerTy(32) &&
+ FT->getParamType(0) == FT->getParamType(1) &&
+ FT->getParamType(0) ==
+ IntegerType::getInt8Ty(M.getContext())->getPointerTo(0);
+ isStrcasecmp &=
+ FT->getNumParams() == 2 &&
+ FT->getReturnType()->isIntegerTy(32) &&
+ FT->getParamType(0) == FT->getParamType(1) &&
+ FT->getParamType(0) ==
+ IntegerType::getInt8Ty(M.getContext())->getPointerTo(0);
isMemcmp &= FT->getNumParams() == 3 &&
FT->getReturnType()->isIntegerTy(32) &&
FT->getParamType(0)->isPointerTy() &&
FT->getParamType(1)->isPointerTy() &&
FT->getParamType(2)->isIntegerTy();
- isStrncmp &= FT->getNumParams() == 3 &&
- FT->getReturnType()->isIntegerTy(32) &&
- FT->getParamType(0) == FT->getParamType(1) &&
- FT->getParamType(0) ==
- IntegerType::getInt8Ty(M.getContext())->getPointerTo(0) &&
- FT->getParamType(2)->isIntegerTy();
- isStrncasecmp &= FT->getNumParams() == 3 &&
- FT->getReturnType()->isIntegerTy(32) &&
- FT->getParamType(0) == FT->getParamType(1) &&
- FT->getParamType(0) ==
- IntegerType::getInt8Ty(M.getContext())->getPointerTo(0) &&
- FT->getParamType(2)->isIntegerTy();
+ isStrncmp &=
+ FT->getNumParams() == 3 &&
+ FT->getReturnType()->isIntegerTy(32) &&
+ FT->getParamType(0) == FT->getParamType(1) &&
+ FT->getParamType(0) ==
+ IntegerType::getInt8Ty(M.getContext())->getPointerTo(0) &&
+ FT->getParamType(2)->isIntegerTy();
+ isStrncasecmp &=
+ FT->getNumParams() == 3 &&
+ FT->getReturnType()->isIntegerTy(32) &&
+ FT->getParamType(0) == FT->getParamType(1) &&
+ FT->getParamType(0) ==
+ IntegerType::getInt8Ty(M.getContext())->getPointerTo(0) &&
+ FT->getParamType(2)->isIntegerTy();
isStdString &= FT->getNumParams() >= 2 &&
FT->getParamType(0)->isPointerTy() &&
FT->getParamType(1)->isPointerTy();
diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc
index 3a5b99f8..c60f3e06 100644
--- a/instrumentation/afl-llvm-dict2file.so.cc
+++ b/instrumentation/afl-llvm-dict2file.so.cc
@@ -433,32 +433,35 @@ bool AFLdict2filePass::runOnModule(Module &M) {
isStrstr &=
FT->getNumParams() == 2 &&
FT->getParamType(0) == FT->getParamType(1) &&
- FT->getParamType(0) == IntegerType::getInt8Ty(M.getContext())->getPointerTo(0);
+ FT->getParamType(0) ==
+ IntegerType::getInt8Ty(M.getContext())->getPointerTo(0);
isStrcmp &=
FT->getNumParams() == 2 && FT->getReturnType()->isIntegerTy(32) &&
FT->getParamType(0) == FT->getParamType(1) &&
- FT->getParamType(0) == IntegerType::getInt8Ty(M.getContext())->getPointerTo(0);
+ FT->getParamType(0) ==
+ IntegerType::getInt8Ty(M.getContext())->getPointerTo(0);
isStrcasecmp &=
FT->getNumParams() == 2 && FT->getReturnType()->isIntegerTy(32) &&
FT->getParamType(0) == FT->getParamType(1) &&
- FT->getParamType(0) == IntegerType::getInt8Ty(M.getContext())->getPointerTo(0);
+ FT->getParamType(0) ==
+ IntegerType::getInt8Ty(M.getContext())->getPointerTo(0);
isMemcmp &= FT->getNumParams() == 3 &&
FT->getReturnType()->isIntegerTy(32) &&
FT->getParamType(0)->isPointerTy() &&
FT->getParamType(1)->isPointerTy() &&
FT->getParamType(2)->isIntegerTy();
- isStrncmp &= FT->getNumParams() == 3 &&
- FT->getReturnType()->isIntegerTy(32) &&
- FT->getParamType(0) == FT->getParamType(1) &&
- FT->getParamType(0) ==
- IntegerType::getInt8Ty(M.getContext())->getPointerTo(0) &&
- FT->getParamType(2)->isIntegerTy();
- isStrncasecmp &= FT->getNumParams() == 3 &&
- FT->getReturnType()->isIntegerTy(32) &&
- FT->getParamType(0) == FT->getParamType(1) &&
- FT->getParamType(0) ==
- IntegerType::getInt8Ty(M.getContext())->getPointerTo(0) &&
- FT->getParamType(2)->isIntegerTy();
+ isStrncmp &=
+ FT->getNumParams() == 3 && FT->getReturnType()->isIntegerTy(32) &&
+ FT->getParamType(0) == FT->getParamType(1) &&
+ FT->getParamType(0) ==
+ IntegerType::getInt8Ty(M.getContext())->getPointerTo(0) &&
+ FT->getParamType(2)->isIntegerTy();
+ isStrncasecmp &=
+ FT->getNumParams() == 3 && FT->getReturnType()->isIntegerTy(32) &&
+ FT->getParamType(0) == FT->getParamType(1) &&
+ FT->getParamType(0) ==
+ IntegerType::getInt8Ty(M.getContext())->getPointerTo(0) &&
+ FT->getParamType(2)->isIntegerTy();
isStdString &= FT->getNumParams() >= 2 &&
FT->getParamType(0)->isPointerTy() &&
FT->getParamType(1)->isPointerTy();
diff --git a/instrumentation/cmplog-routines-pass.cc b/instrumentation/cmplog-routines-pass.cc
index 9272be62..b27e06e0 100644
--- a/instrumentation/cmplog-routines-pass.cc
+++ b/instrumentation/cmplog-routines-pass.cc
@@ -385,7 +385,8 @@ bool CmpLogRoutines::hookRtns(Module &M) {
isStrcmp &=
FT->getNumParams() == 2 && FT->getReturnType()->isIntegerTy(32) &&
FT->getParamType(0) == FT->getParamType(1) &&
- FT->getParamType(0) == IntegerType::getInt8Ty(M.getContext())->getPointerTo(0);
+ FT->getParamType(0) ==
+ IntegerType::getInt8Ty(M.getContext())->getPointerTo(0);
bool isStrncmp = (!FuncName.compare("strncmp") ||
!FuncName.compare("xmlStrncmp") ||
@@ -398,12 +399,12 @@ bool CmpLogRoutines::hookRtns(Module &M) {
!FuncName.compare("g_ascii_strncasecmp") ||
!FuncName.compare("Curl_strncasecompare") ||
!FuncName.compare("g_strncasecmp"));
- isStrncmp &= FT->getNumParams() == 3 &&
- FT->getReturnType()->isIntegerTy(32) &&
- FT->getParamType(0) == FT->getParamType(1) &&
- FT->getParamType(0) ==
- IntegerType::getInt8Ty(M.getContext())->getPointerTo(0) &&
- FT->getParamType(2)->isIntegerTy();
+ isStrncmp &=
+ FT->getNumParams() == 3 && FT->getReturnType()->isIntegerTy(32) &&
+ FT->getParamType(0) == FT->getParamType(1) &&
+ FT->getParamType(0) ==
+ IntegerType::getInt8Ty(M.getContext())->getPointerTo(0) &&
+ FT->getParamType(2)->isIntegerTy();
bool isGccStdStringStdString =
Callee->getName().find("__is_charIT_EE7__value") !=
diff --git a/instrumentation/compare-transform-pass.so.cc b/instrumentation/compare-transform-pass.so.cc
index 5c707914..b0d6355a 100644
--- a/instrumentation/compare-transform-pass.so.cc
+++ b/instrumentation/compare-transform-pass.so.cc
@@ -271,28 +271,30 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
isStrcmp &=
FT->getNumParams() == 2 && FT->getReturnType()->isIntegerTy(32) &&
FT->getParamType(0) == FT->getParamType(1) &&
- FT->getParamType(0) == IntegerType::getInt8Ty(M.getContext())->getPointerTo(0);
+ FT->getParamType(0) ==
+ IntegerType::getInt8Ty(M.getContext())->getPointerTo(0);
isStrcasecmp &=
FT->getNumParams() == 2 && FT->getReturnType()->isIntegerTy(32) &&
FT->getParamType(0) == FT->getParamType(1) &&
- FT->getParamType(0) == IntegerType::getInt8Ty(M.getContext())->getPointerTo(0);
+ FT->getParamType(0) ==
+ IntegerType::getInt8Ty(M.getContext())->getPointerTo(0);
isMemcmp &= FT->getNumParams() == 3 &&
FT->getReturnType()->isIntegerTy(32) &&
FT->getParamType(0)->isPointerTy() &&
FT->getParamType(1)->isPointerTy() &&
FT->getParamType(2)->isIntegerTy();
- isStrncmp &= FT->getNumParams() == 3 &&
- FT->getReturnType()->isIntegerTy(32) &&
- FT->getParamType(0) == FT->getParamType(1) &&
- FT->getParamType(0) ==
- IntegerType::getInt8Ty(M.getContext())->getPointerTo(0) &&
- FT->getParamType(2)->isIntegerTy();
- isStrncasecmp &= FT->getNumParams() == 3 &&
- FT->getReturnType()->isIntegerTy(32) &&
- FT->getParamType(0) == FT->getParamType(1) &&
- FT->getParamType(0) ==
- IntegerType::getInt8Ty(M.getContext())->getPointerTo(0) &&
- FT->getParamType(2)->isIntegerTy();
+ isStrncmp &=
+ FT->getNumParams() == 3 && FT->getReturnType()->isIntegerTy(32) &&
+ FT->getParamType(0) == FT->getParamType(1) &&
+ FT->getParamType(0) ==
+ IntegerType::getInt8Ty(M.getContext())->getPointerTo(0) &&
+ FT->getParamType(2)->isIntegerTy();
+ isStrncasecmp &=
+ FT->getNumParams() == 3 && FT->getReturnType()->isIntegerTy(32) &&
+ FT->getParamType(0) == FT->getParamType(1) &&
+ FT->getParamType(0) ==
+ IntegerType::getInt8Ty(M.getContext())->getPointerTo(0) &&
+ FT->getParamType(2)->isIntegerTy();
if (!isStrcmp && !isMemcmp && !isStrncmp && !isStrcasecmp &&
!isStrncasecmp && !isIntMemcpy)
--
cgit 1.4.1
From a9e6998b829e58eab670c79fca8913ba8c5f684d Mon Sep 17 00:00:00 2001
From: Xeonacid
Date: Mon, 25 Dec 2023 13:50:32 +0800
Subject: Fix custom_send link
Add a leading '/' to walk in the repo root instead of current dir.
---
docs/custom_mutators.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'docs')
diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md
index 1c4ab2cf..71547f8b 100644
--- a/docs/custom_mutators.md
+++ b/docs/custom_mutators.md
@@ -198,7 +198,7 @@ def deinit(): # optional for Python
This method can be used if you want to send data to the target yourself,
e.g. via IPC. This replaces some usage of utils/afl_proxy but requires
that you start the target with afl-fuzz.
- Example: [custom_mutators/examples/custom_send.c](custom_mutators/examples/custom_send.c)
+ Example: [custom_mutators/examples/custom_send.c](/custom_mutators/examples/custom_send.c)
- `queue_new_entry` (optional):
@@ -377,4 +377,4 @@ See [example.c](../custom_mutators/examples/example.c) and
- [bruce30262/libprotobuf-mutator_fuzzing_learning](https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/tree/master/4_libprotobuf_aflpp_custom_mutator)
- [thebabush/afl-libprotobuf-mutator](https://github.com/thebabush/afl-libprotobuf-mutator)
- [XML Fuzzing@NullCon 2017](https://www.agarri.fr/docs/XML_Fuzzing-NullCon2017-PUBLIC.pdf)
- - [A bug detected by AFL + XML-aware mutators](https://bugs.chromium.org/p/chromium/issues/detail?id=930663)
\ No newline at end of file
+ - [A bug detected by AFL + XML-aware mutators](https://bugs.chromium.org/p/chromium/issues/detail?id=930663)
--
cgit 1.4.1
From c3197dfeb736f3018124529eb184827eafe3a2d9 Mon Sep 17 00:00:00 2001
From: Xeonacid
Date: Mon, 25 Dec 2023 18:30:46 +0800
Subject: Use ../ instead
---
docs/custom_mutators.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'docs')
diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md
index 71547f8b..ce0a42dc 100644
--- a/docs/custom_mutators.md
+++ b/docs/custom_mutators.md
@@ -198,7 +198,7 @@ def deinit(): # optional for Python
This method can be used if you want to send data to the target yourself,
e.g. via IPC. This replaces some usage of utils/afl_proxy but requires
that you start the target with afl-fuzz.
- Example: [custom_mutators/examples/custom_send.c](/custom_mutators/examples/custom_send.c)
+ Example: [custom_mutators/examples/custom_send.c](../custom_mutators/examples/custom_send.c)
- `queue_new_entry` (optional):
--
cgit 1.4.1
From 98a2a334de15ed08d82c76bfa97d1f22c81f9a7d Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 27 Dec 2023 13:58:25 +0100
Subject: inject docs
---
docs/env_variables.md | 13 +++++++++++++
src/afl-cc.c | 4 ++++
2 files changed, 17 insertions(+)
(limited to 'docs')
diff --git a/docs/env_variables.md b/docs/env_variables.md
index a7636511..a972b6da 100644
--- a/docs/env_variables.md
+++ b/docs/env_variables.md
@@ -196,6 +196,19 @@ in the specified file.
For more information, see
[instrumentation/README.instrument_list.md](../instrumentation/README.instrument_list.md).
+#### INJECTIONS
+
+This feature is able to find simple injection vulnerabilities in insecure
+calls to mysql/mariadb/nosql/postgresql/ldap and XSS in libxml2.
+
+ - Setting `AFL_LLVM_INJECTIONS_ALL` will enable all injection hooking
+
+ - Setting `AFL_LLVM_INJECTIONS_SQL` will enable SQL injection hooking
+
+ - Setting `AFL_LLVM_INJECTIONS_LDAP` will enable LDAP injection hooking
+
+ - Setting `AFL_LLVM_INJECTIONS_XSS` will enable XSS injection hooking
+
#### LAF-INTEL
This great feature will split compares into series of single byte comparisons to
diff --git a/src/afl-cc.c b/src/afl-cc.c
index a46facc7..54c733c9 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -2295,6 +2295,10 @@ int main(int argc, char **argv, char **envp) {
"comparisons\n"
" AFL_LLVM_DICT2FILE_NO_MAIN: skip parsing main() for the "
"dictionary\n"
+ " AFL_LLVM_INJECTIONS_ALL: enables all injections hooking\n"
+ " AFL_LLVM_INJECTIONS_SQL: enables SQL injections hooking\n"
+ " AFL_LLVM_INJECTIONS_LDAP: enables LDAP injections hooking\n"
+ " AFL_LLVM_INJECTIONS_XSS: enables XSS injections hooking\n"
" AFL_LLVM_LAF_ALL: enables all LAF splits/transforms\n"
" AFL_LLVM_LAF_SPLIT_COMPARES: enable cascaded comparisons\n"
" AFL_LLVM_LAF_SPLIT_COMPARES_BITW: size limit (default 8)\n"
--
cgit 1.4.1
From 88cbaeb3e14de3ee5960ca78564e41741e7bd85b Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 29 Dec 2023 10:03:02 +0100
Subject: LLVM 17 bug workaround
---
TODO.md | 9 +++
docs/Changelog.md | 5 ++
instrumentation/SanitizerCoveragePCGUARD.so.cc | 1 +
instrumentation/split-compares-pass.so.cc | 77 ++++++++++++++++----------
4 files changed, 63 insertions(+), 29 deletions(-)
(limited to 'docs')
diff --git a/TODO.md b/TODO.md
index 9e9a2366..8d746d50 100644
--- a/TODO.md
+++ b/TODO.md
@@ -10,6 +10,15 @@
- when trimming then perform crash detection
- either -L0 and/or -p mmopt results in zero new coverage
+afl-clang-fast -Iapps -I. -Iinclude -Iapps/include -pthread -m64 -fsanitize=address -fno-omit-frame-pointer -g -Wa,--noexecstack -Qunused-arguments -fno-inline-functions -g -pthread -Wno-unused-command-line-argument -O3 -fno-sanitize=alignment -DOPENSSL_BUILDING_OPENSSL -DPEDANTIC -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -MMD -MF apps/openssl-bin-speed.d.tmp -MT apps/openssl-bin-speed.o -c -o apps/openssl-bin-speed.o apps/speed.c
+afl-cc++4.10a by Michal Zalewski, Laszlo Szekeres, Marc Heuse - mode: LLVM-PCGUARD
+Split-compare-newpass by laf.intel@gmail.com, extended by heiko@hexco.de (splitting icmp to 8 bit)
+Split-floatingpoint-compare-pass: 2 FP comparisons split
+724 comparisons found
+SanitizerCoveragePCGUARD++4.10a
+[+] Instrumented 7356 locations with no collisions (non-hardened mode) of which are 99 handled and 7 unhandled selects.
+
+
## Should
<<<<<<< Updated upstream
diff --git a/docs/Changelog.md b/docs/Changelog.md
index c8f04217..178d0f8a 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -11,6 +11,11 @@
reporting!
- instrumentation:
- LLVM 18 support, thanks to @devnexen!
+ - compcov/LAF-intel:
+ - floating point splitting bug fix by @hexcoder
+ - due a bug in LLVM 17 integer splitting is disabled!
+ - when splitting floats was selected, integers were always split as well,
+ fixed to require AFL_LLVM_LAF_SPLIT_COMPARES as it should
### Version ++4.09c (release)
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index 1c019d26..aae04bb1 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -952,6 +952,7 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
#endif
{
+ // fprintf(stderr, "UNHANDLED: %u\n", t->getTypeID());
unhandled++;
continue;
diff --git a/instrumentation/split-compares-pass.so.cc b/instrumentation/split-compares-pass.so.cc
index cbe8b743..144025fb 100644
--- a/instrumentation/split-compares-pass.so.cc
+++ b/instrumentation/split-compares-pass.so.cc
@@ -1707,12 +1707,6 @@ bool SplitComparesTransform::runOnModule(Module &M) {
#endif
- char *bitw_env = getenv("AFL_LLVM_LAF_SPLIT_COMPARES_BITW");
- if (!bitw_env) bitw_env = getenv("LAF_SPLIT_COMPARES_BITW");
- if (bitw_env) { target_bitwidth = atoi(bitw_env); }
-
- enableFPSplit = getenv("AFL_LLVM_LAF_SPLIT_FLOATS") != NULL;
-
if ((isatty(2) && getenv("AFL_QUIET") == NULL) ||
getenv("AFL_DEBUG") != NULL) {
@@ -1728,6 +1722,27 @@ bool SplitComparesTransform::runOnModule(Module &M) {
}
+ char *bitw_env = getenv("AFL_LLVM_LAF_SPLIT_COMPARES_BITW");
+ if (!bitw_env) bitw_env = getenv("LAF_SPLIT_COMPARES_BITW");
+ if (bitw_env) { target_bitwidth = atoi(bitw_env); }
+
+ if (getenv("AFL_LLVM_LAF_SPLIT_FLOATS")) { enableFPSplit = true; }
+
+ bool split_comp = false;
+
+ if (getenv("AFL_LLVM_LAF_SPLIT_COMPARES")) {
+
+#if LLVM_MAJOR == 17
+ if (!be_quiet)
+ fprintf(stderr,
+ "WARNING: AFL++ splitting integer comparisons is disabled in "
+ "LLVM 17 due bugs, switch to 16 or 18!\n");
+#else
+ split_comp = true;
+#endif
+
+ }
+
#if LLVM_MAJOR >= 11
auto PA = PreservedAnalyses::all();
#endif
@@ -1746,36 +1761,40 @@ bool SplitComparesTransform::runOnModule(Module &M) {
}
- std::vector worklist;
- /* iterate over all functions, bbs and instruction search for all integer
- * compare instructions. Save them into the worklist for later. */
- for (auto &F : M) {
+ if (split_comp) {
- if (!isInInstrumentList(&F, MNAME)) continue;
+ std::vector worklist;
+ /* iterate over all functions, bbs and instruction search for all integer
+ * compare instructions. Save them into the worklist for later. */
+ for (auto &F : M) {
- for (auto &BB : F) {
+ if (!isInInstrumentList(&F, MNAME)) continue;
- for (auto &IN : BB) {
+ for (auto &BB : F) {
- if (auto CI = dyn_cast(&IN)) {
+ for (auto &IN : BB) {
- auto op0 = CI->getOperand(0);
- auto op1 = CI->getOperand(1);
- if (!op0 || !op1) {
+ if (auto CI = dyn_cast(&IN)) {
+
+ auto op0 = CI->getOperand(0);
+ auto op1 = CI->getOperand(1);
+ if (!op0 || !op1) {
#if LLVM_MAJOR >= 11
- return PA;
+ return PA;
#else
- return false;
+ return false;
#endif
- }
+ }
- auto iTy1 = dyn_cast(op0->getType());
- if (iTy1 && isa(op1->getType())) {
+ auto iTy1 = dyn_cast(op0->getType());
+ if (iTy1 && isa(op1->getType())) {
- unsigned bitw = iTy1->getBitWidth();
- if (isSupportedBitWidth(bitw)) { worklist.push_back(CI); }
+ unsigned bitw = iTy1->getBitWidth();
+ if (isSupportedBitWidth(bitw)) { worklist.push_back(CI); }
+
+ }
}
@@ -1785,13 +1804,13 @@ bool SplitComparesTransform::runOnModule(Module &M) {
}
- }
+ // now that we have a list of all integer comparisons we can start replacing
+ // them with the splitted alternatives.
+ for (auto CI : worklist) {
- // now that we have a list of all integer comparisons we can start replacing
- // them with the splitted alternatives.
- for (auto CI : worklist) {
+ simplifyAndSplit(CI, M);
- simplifyAndSplit(CI, M);
+ }
}
--
cgit 1.4.1
From 5f492da71793e75e145e13d4c0dd9506bac2d60c Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sat, 30 Dec 2023 11:00:28 +0100
Subject: update changelog
---
docs/Changelog.md | 2 ++
1 file changed, 2 insertions(+)
(limited to 'docs')
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 178d0f8a..adc81d64 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -11,6 +11,8 @@
reporting!
- instrumentation:
- LLVM 18 support, thanks to @devnexen!
+ - Injection (SQL, LDAP, XSS) feature now available, see
+ `instrumentation/README.injections.md` how to activate/use/expand.
- compcov/LAF-intel:
- floating point splitting bug fix by @hexcoder
- due a bug in LLVM 17 integer splitting is disabled!
--
cgit 1.4.1
From ee7d69b8175f31f2efb2b3bf15f2bbb29f61aa14 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 4 Jan 2024 15:44:28 +0100
Subject: changelog
---
docs/Changelog.md | 6 +-
include/envs.h | 319 ++++++++++++++----------------------------------------
2 files changed, 88 insertions(+), 237 deletions(-)
(limited to 'docs')
diff --git a/docs/Changelog.md b/docs/Changelog.md
index adc81d64..69a369e3 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -9,15 +9,17 @@
explore is slightly better now.
- fixed minor issues in the mutation engine, thanks to @futhewo for
reporting!
+ - afl-cc:
+ - large rewrite by @SonicStark which fixes a few corner cases, thanks!
- instrumentation:
- LLVM 18 support, thanks to @devnexen!
- Injection (SQL, LDAP, XSS) feature now available, see
`instrumentation/README.injections.md` how to activate/use/expand.
- compcov/LAF-intel:
- floating point splitting bug fix by @hexcoder
- - due a bug in LLVM 17 integer splitting is disabled!
+ - due a bug in LLVM 17 integer splitting is disabled there!
- when splitting floats was selected, integers were always split as well,
- fixed to require AFL_LLVM_LAF_SPLIT_COMPARES as it should
+ fixed to require AFL_LLVM_LAF_SPLIT_COMPARES or _ALL as it should
### Version ++4.09c (release)
diff --git a/include/envs.h b/include/envs.h
index aa5c658e..0f645d23 100644
--- a/include/envs.h
+++ b/include/envs.h
@@ -16,255 +16,104 @@ static char *afl_environment_deprecated[] = {
static char *afl_environment_variables[] = {
- "AFL_ALIGNED_ALLOC",
- "AFL_ALLOW_TMP",
- "AFL_ANALYZE_HEX",
- "AFL_AS",
- "AFL_AUTORESUME",
- "AFL_AS_FORCE_INSTRUMENT",
- "AFL_BENCH_JUST_ONE",
- "AFL_BENCH_UNTIL_CRASH",
- "AFL_CAL_FAST",
- "AFL_CC",
- "AFL_CC_COMPILER",
- "AFL_CMIN_ALLOW_ANY",
- "AFL_CMIN_CRASHES_ONLY",
- "AFL_CMPLOG_ONLY_NEW",
- "AFL_CODE_END",
- "AFL_CODE_START",
- "AFL_COMPCOV_BINNAME",
- "AFL_COMPCOV_LEVEL",
- "AFL_CRASH_EXITCODE",
- "AFL_CRASHING_SEEDS_AS_NEW_CRASH",
- "AFL_CUSTOM_MUTATOR_LIBRARY",
- "AFL_CUSTOM_MUTATOR_ONLY",
- "AFL_CUSTOM_INFO_PROGRAM",
- "AFL_CUSTOM_INFO_PROGRAM_ARGV",
- "AFL_CUSTOM_INFO_PROGRAM_INPUT",
- "AFL_CUSTOM_INFO_OUT",
- "AFL_CXX",
- "AFL_CYCLE_SCHEDULES",
- "AFL_DEBUG",
- "AFL_DEBUG_CHILD",
- "AFL_DEBUG_GDB",
- "AFL_DEBUG_UNICORN",
- "AFL_DISABLE_TRIM",
- "AFL_DISABLE_LLVM_INSTRUMENTATION",
- "AFL_DONT_OPTIMIZE",
- "AFL_DRIVER_STDERR_DUPLICATE_FILENAME",
- "AFL_DUMB_FORKSRV",
- "AFL_EARLY_FORKSERVER",
- "AFL_ENTRYPOINT",
- "AFL_EXIT_WHEN_DONE",
- "AFL_EXIT_ON_TIME",
- "AFL_EXIT_ON_SEED_ISSUES",
- "AFL_FAST_CAL",
- "AFL_FINAL_SYNC",
- "AFL_FORCE_UI",
- "AFL_FRIDA_DEBUG_MAPS",
- "AFL_FRIDA_DRIVER_NO_HOOK",
- "AFL_FRIDA_EXCLUDE_RANGES",
- "AFL_FRIDA_INST_CACHE_SIZE",
- "AFL_FRIDA_INST_COVERAGE_ABSOLUTE",
- "AFL_FRIDA_INST_COVERAGE_FILE",
- "AFL_FRIDA_INST_DEBUG_FILE",
- "AFL_FRIDA_INST_INSN",
- "AFL_FRIDA_INST_JIT",
- "AFL_FRIDA_INST_NO_CACHE",
- "AFL_FRIDA_INST_NO_DYNAMIC_LOAD",
- "AFL_FRIDA_INST_NO_OPTIMIZE",
- "AFL_FRIDA_INST_NO_PREFETCH",
- "AFL_FRIDA_INST_NO_PREFETCH_BACKPATCH",
+ "AFL_ALIGNED_ALLOC", "AFL_ALLOW_TMP", "AFL_ANALYZE_HEX", "AFL_AS",
+ "AFL_AUTORESUME", "AFL_AS_FORCE_INSTRUMENT", "AFL_BENCH_JUST_ONE",
+ "AFL_BENCH_UNTIL_CRASH", "AFL_CAL_FAST", "AFL_CC", "AFL_CC_COMPILER",
+ "AFL_CMIN_ALLOW_ANY", "AFL_CMIN_CRASHES_ONLY", "AFL_CMPLOG_ONLY_NEW",
+ "AFL_CODE_END", "AFL_CODE_START", "AFL_COMPCOV_BINNAME",
+ "AFL_COMPCOV_LEVEL", "AFL_CRASH_EXITCODE",
+ "AFL_CRASHING_SEEDS_AS_NEW_CRASH", "AFL_CUSTOM_MUTATOR_LIBRARY",
+ "AFL_CUSTOM_MUTATOR_ONLY", "AFL_CUSTOM_INFO_PROGRAM",
+ "AFL_CUSTOM_INFO_PROGRAM_ARGV", "AFL_CUSTOM_INFO_PROGRAM_INPUT",
+ "AFL_CUSTOM_INFO_OUT", "AFL_CXX", "AFL_CYCLE_SCHEDULES", "AFL_DEBUG",
+ "AFL_DEBUG_CHILD", "AFL_DEBUG_GDB", "AFL_DEBUG_UNICORN", "AFL_DISABLE_TRIM",
+ "AFL_DISABLE_LLVM_INSTRUMENTATION", "AFL_DONT_OPTIMIZE",
+ "AFL_DRIVER_STDERR_DUPLICATE_FILENAME", "AFL_DUMB_FORKSRV",
+ "AFL_EARLY_FORKSERVER", "AFL_ENTRYPOINT", "AFL_EXIT_WHEN_DONE",
+ "AFL_EXIT_ON_TIME", "AFL_EXIT_ON_SEED_ISSUES", "AFL_FAST_CAL",
+ "AFL_FINAL_SYNC", "AFL_FORCE_UI", "AFL_FRIDA_DEBUG_MAPS",
+ "AFL_FRIDA_DRIVER_NO_HOOK", "AFL_FRIDA_EXCLUDE_RANGES",
+ "AFL_FRIDA_INST_CACHE_SIZE", "AFL_FRIDA_INST_COVERAGE_ABSOLUTE",
+ "AFL_FRIDA_INST_COVERAGE_FILE", "AFL_FRIDA_INST_DEBUG_FILE",
+ "AFL_FRIDA_INST_INSN", "AFL_FRIDA_INST_JIT", "AFL_FRIDA_INST_NO_CACHE",
+ "AFL_FRIDA_INST_NO_DYNAMIC_LOAD", "AFL_FRIDA_INST_NO_OPTIMIZE",
+ "AFL_FRIDA_INST_NO_PREFETCH", "AFL_FRIDA_INST_NO_PREFETCH_BACKPATCH",
"AFL_FRIDA_INST_NO_SUPPRESS"
"AFL_FRIDA_INST_RANGES",
- "AFL_FRIDA_INST_REGS_FILE",
- "AFL_FRIDA_INST_SEED",
- "AFL_FRIDA_INST_TRACE",
- "AFL_FRIDA_INST_TRACE_UNIQUE",
- "AFL_FRIDA_INST_UNSTABLE_COVERAGE_FILE",
- "AFL_FRIDA_JS_SCRIPT",
- "AFL_FRIDA_OUTPUT_STDOUT",
- "AFL_FRIDA_OUTPUT_STDERR",
- "AFL_FRIDA_PERSISTENT_ADDR",
- "AFL_FRIDA_PERSISTENT_CNT",
- "AFL_FRIDA_PERSISTENT_DEBUG",
- "AFL_FRIDA_PERSISTENT_HOOK",
- "AFL_FRIDA_PERSISTENT_RET",
- "AFL_FRIDA_STALKER_ADJACENT_BLOCKS",
- "AFL_FRIDA_STALKER_IC_ENTRIES",
- "AFL_FRIDA_STALKER_NO_BACKPATCH",
- "AFL_FRIDA_STATS_FILE",
- "AFL_FRIDA_STATS_INTERVAL",
- "AFL_FRIDA_TRACEABLE",
+ "AFL_FRIDA_INST_REGS_FILE", "AFL_FRIDA_INST_SEED", "AFL_FRIDA_INST_TRACE",
+ "AFL_FRIDA_INST_TRACE_UNIQUE", "AFL_FRIDA_INST_UNSTABLE_COVERAGE_FILE",
+ "AFL_FRIDA_JS_SCRIPT", "AFL_FRIDA_OUTPUT_STDOUT", "AFL_FRIDA_OUTPUT_STDERR",
+ "AFL_FRIDA_PERSISTENT_ADDR", "AFL_FRIDA_PERSISTENT_CNT",
+ "AFL_FRIDA_PERSISTENT_DEBUG", "AFL_FRIDA_PERSISTENT_HOOK",
+ "AFL_FRIDA_PERSISTENT_RET", "AFL_FRIDA_STALKER_ADJACENT_BLOCKS",
+ "AFL_FRIDA_STALKER_IC_ENTRIES", "AFL_FRIDA_STALKER_NO_BACKPATCH",
+ "AFL_FRIDA_STATS_FILE", "AFL_FRIDA_STATS_INTERVAL", "AFL_FRIDA_TRACEABLE",
"AFL_FRIDA_VERBOSE",
"AFL_FUZZER_ARGS", // oss-fuzz
- "AFL_FUZZER_STATS_UPDATE_INTERVAL",
- "AFL_GDB",
- "AFL_GCC_ALLOWLIST",
- "AFL_GCC_DENYLIST",
- "AFL_GCC_BLOCKLIST",
- "AFL_GCC_INSTRUMENT_FILE",
- "AFL_GCC_OUT_OF_LINE",
- "AFL_GCC_SKIP_NEVERZERO",
- "AFL_GCJ",
- "AFL_HANG_TMOUT",
- "AFL_FORKSRV_INIT_TMOUT",
- "AFL_HARDEN",
- "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES",
- "AFL_IGNORE_PROBLEMS",
- "AFL_IGNORE_PROBLEMS_COVERAGE",
- "AFL_IGNORE_SEED_PROBLEMS",
- "AFL_IGNORE_TIMEOUTS",
- "AFL_IGNORE_UNKNOWN_ENVS",
- "AFL_IMPORT_FIRST",
- "AFL_INPUT_LEN_MIN",
- "AFL_INPUT_LEN_MAX",
- "AFL_INST_LIBS",
- "AFL_INST_RATIO",
- "AFL_KEEP_TIMEOUTS",
- "AFL_KILL_SIGNAL",
- "AFL_FORK_SERVER_KILL_SIGNAL",
- "AFL_KEEP_TRACES",
- "AFL_KEEP_ASSEMBLY",
- "AFL_LD_HARD_FAIL",
- "AFL_LD_LIMIT_MB",
- "AFL_LD_NO_CALLOC_OVER",
- "AFL_LD_PASSTHROUGH",
- "AFL_REAL_LD",
- "AFL_LD_PRELOAD",
- "AFL_LD_VERBOSE",
- "AFL_LLVM_ALLOWLIST",
- "AFL_LLVM_DENYLIST",
- "AFL_LLVM_BLOCKLIST",
- "AFL_CMPLOG",
- "AFL_LLVM_CMPLOG",
- "AFL_GCC_CMPLOG",
- "AFL_LLVM_INSTRIM",
- "AFL_LLVM_CALLER",
- "AFL_LLVM_CTX",
- "AFL_LLVM_CTX_K",
- "AFL_LLVM_DICT2FILE",
- "AFL_LLVM_DICT2FILE_NO_MAIN",
- "AFL_LLVM_DOCUMENT_IDS",
- "AFL_LLVM_INSTRIM_LOOPHEAD",
- "AFL_LLVM_INSTRUMENT",
- "AFL_LLVM_LTO_AUTODICTIONARY",
- "AFL_LLVM_AUTODICTIONARY",
+ "AFL_FUZZER_STATS_UPDATE_INTERVAL", "AFL_GDB", "AFL_GCC_ALLOWLIST",
+ "AFL_GCC_DENYLIST", "AFL_GCC_BLOCKLIST", "AFL_GCC_INSTRUMENT_FILE",
+ "AFL_GCC_OUT_OF_LINE", "AFL_GCC_SKIP_NEVERZERO", "AFL_GCJ",
+ "AFL_HANG_TMOUT", "AFL_FORKSRV_INIT_TMOUT", "AFL_HARDEN",
+ "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES", "AFL_IGNORE_PROBLEMS",
+ "AFL_IGNORE_PROBLEMS_COVERAGE", "AFL_IGNORE_SEED_PROBLEMS",
+ "AFL_IGNORE_TIMEOUTS", "AFL_IGNORE_UNKNOWN_ENVS", "AFL_IMPORT_FIRST",
+ "AFL_INPUT_LEN_MIN", "AFL_INPUT_LEN_MAX", "AFL_INST_LIBS", "AFL_INST_RATIO",
+ "AFL_KEEP_TIMEOUTS", "AFL_KILL_SIGNAL", "AFL_FORK_SERVER_KILL_SIGNAL",
+ "AFL_KEEP_TRACES", "AFL_KEEP_ASSEMBLY", "AFL_LD_HARD_FAIL",
+ "AFL_LD_LIMIT_MB", "AFL_LD_NO_CALLOC_OVER", "AFL_LD_PASSTHROUGH",
+ "AFL_REAL_LD", "AFL_LD_PRELOAD", "AFL_LD_VERBOSE", "AFL_LLVM_ALLOWLIST",
+ "AFL_LLVM_DENYLIST", "AFL_LLVM_BLOCKLIST", "AFL_CMPLOG", "AFL_LLVM_CMPLOG",
+ "AFL_GCC_CMPLOG", "AFL_LLVM_INSTRIM", "AFL_LLVM_CALLER", "AFL_LLVM_CTX",
+ "AFL_LLVM_CTX_K", "AFL_LLVM_DICT2FILE", "AFL_LLVM_DICT2FILE_NO_MAIN",
+ "AFL_LLVM_DOCUMENT_IDS", "AFL_LLVM_INSTRIM_LOOPHEAD", "AFL_LLVM_INSTRUMENT",
+ "AFL_LLVM_LTO_AUTODICTIONARY", "AFL_LLVM_AUTODICTIONARY",
"AFL_LLVM_SKIPSINGLEBLOCK",
// Marker: ADD_TO_INJECTIONS
- "AFL_LLVM_INJECTIONS_ALL",
- "AFL_LLVM_INJECTIONS_SQL",
- "AFL_LLVM_INJECTIONS_LDAP",
- "AFL_LLVM_INJECTIONS_XSS",
- "AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK",
- "AFL_LLVM_LAF_SPLIT_COMPARES",
- "AFL_LLVM_LAF_SPLIT_COMPARES_BITW",
- "AFL_LLVM_LAF_SPLIT_FLOATS",
- "AFL_LLVM_LAF_SPLIT_SWITCHES",
- "AFL_LLVM_LAF_ALL",
- "AFL_LLVM_LAF_TRANSFORM_COMPARES",
- "AFL_LLVM_MAP_ADDR",
- "AFL_LLVM_MAP_DYNAMIC",
- "AFL_LLVM_NGRAM_SIZE",
- "AFL_NGRAM_SIZE",
- "AFL_LLVM_NO_RPATH",
- "AFL_LLVM_NOT_ZERO",
- "AFL_LLVM_INSTRUMENT_FILE",
- "AFL_LLVM_THREADSAFE_INST",
- "AFL_LLVM_SKIP_NEVERZERO",
- "AFL_NO_AFFINITY",
- "AFL_TRY_AFFINITY",
- "AFL_LLVM_LTO_DONTWRITEID",
+ "AFL_LLVM_INJECTIONS_ALL", "AFL_LLVM_INJECTIONS_SQL",
+ "AFL_LLVM_INJECTIONS_LDAP", "AFL_LLVM_INJECTIONS_XSS",
+ "AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK", "AFL_LLVM_LAF_SPLIT_COMPARES",
+ "AFL_LLVM_LAF_SPLIT_COMPARES_BITW", "AFL_LLVM_LAF_SPLIT_FLOATS",
+ "AFL_LLVM_LAF_SPLIT_SWITCHES", "AFL_LLVM_LAF_ALL",
+ "AFL_LLVM_LAF_TRANSFORM_COMPARES", "AFL_LLVM_MAP_ADDR",
+ "AFL_LLVM_MAP_DYNAMIC", "AFL_LLVM_NGRAM_SIZE", "AFL_NGRAM_SIZE",
+ "AFL_LLVM_NO_RPATH", "AFL_LLVM_NOT_ZERO", "AFL_LLVM_INSTRUMENT_FILE",
+ "AFL_LLVM_THREADSAFE_INST", "AFL_LLVM_SKIP_NEVERZERO", "AFL_NO_AFFINITY",
+ "AFL_TRY_AFFINITY", "AFL_LLVM_LTO_DONTWRITEID",
"AFL_LLVM_LTO_SKIPINIT"
"AFL_LLVM_LTO_STARTID",
- "AFL_FUZZER_LOOPCOUNT",
- "AFL_NO_ARITH",
- "AFL_NO_AUTODICT",
- "AFL_NO_BUILTIN",
+ "AFL_FUZZER_LOOPCOUNT", "AFL_NO_ARITH", "AFL_NO_AUTODICT", "AFL_NO_BUILTIN",
#if defined USE_COLOR && !defined ALWAYS_COLORED
- "AFL_NO_COLOR",
- "AFL_NO_COLOUR",
+ "AFL_NO_COLOR", "AFL_NO_COLOUR",
#endif
"AFL_NO_CPU_RED",
"AFL_NO_CFG_FUZZING", // afl.rs rust crate option
- "AFL_NO_CRASH_README",
- "AFL_NO_FORKSRV",
- "AFL_NO_UI",
- "AFL_NO_PYTHON",
- "AFL_NO_STARTUP_CALIBRATION",
- "AFL_NO_WARN_INSTABILITY",
- "AFL_UNTRACER_FILE",
- "AFL_LLVM_USE_TRACE_PC",
- "AFL_MAP_SIZE",
- "AFL_MAPSIZE",
+ "AFL_NO_CRASH_README", "AFL_NO_FORKSRV", "AFL_NO_UI", "AFL_NO_PYTHON",
+ "AFL_NO_STARTUP_CALIBRATION", "AFL_NO_WARN_INSTABILITY",
+ "AFL_UNTRACER_FILE", "AFL_LLVM_USE_TRACE_PC", "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_NYX_AUX_SIZE",
- "AFL_NYX_DISABLE_SNAPSHOT_MODE",
- "AFL_NYX_LOG",
- "AFL_NYX_REUSE_SNAPSHOT",
- "AFL_PASSTHROUGH",
- "AFL_PATH",
- "AFL_PERFORMANCE_FILE",
- "AFL_PERSISTENT_RECORD",
- "AFL_POST_PROCESS_KEEP_ORIGINAL",
- "AFL_PRELOAD",
- "AFL_TARGET_ENV",
- "AFL_PYTHON_MODULE",
- "AFL_QEMU_CUSTOM_BIN",
- "AFL_QEMU_COMPCOV",
- "AFL_QEMU_COMPCOV_DEBUG",
- "AFL_QEMU_DEBUG_MAPS",
- "AFL_QEMU_DISABLE_CACHE",
- "AFL_QEMU_DRIVER_NO_HOOK",
- "AFL_QEMU_FORCE_DFL",
- "AFL_QEMU_PERSISTENT_ADDR",
- "AFL_QEMU_PERSISTENT_CNT",
- "AFL_QEMU_PERSISTENT_GPR",
- "AFL_QEMU_PERSISTENT_HOOK",
- "AFL_QEMU_PERSISTENT_MEM",
- "AFL_QEMU_PERSISTENT_RET",
- "AFL_QEMU_PERSISTENT_RETADDR_OFFSET",
- "AFL_QEMU_PERSISTENT_EXITS",
- "AFL_QEMU_INST_RANGES",
- "AFL_QEMU_EXCLUDE_RANGES",
- "AFL_QEMU_SNAPSHOT",
- "AFL_QEMU_TRACK_UNSTABLE",
- "AFL_QUIET",
- "AFL_RANDOM_ALLOC_CANARY",
- "AFL_REAL_PATH",
- "AFL_SHUFFLE_QUEUE",
- "AFL_SKIP_BIN_CHECK",
- "AFL_SKIP_CPUFREQ",
- "AFL_SKIP_CRASHES",
- "AFL_SKIP_OSSFUZZ",
- "AFL_STATSD",
- "AFL_STATSD_HOST",
- "AFL_STATSD_PORT",
- "AFL_STATSD_TAGS_FLAVOR",
- "AFL_SYNC_TIME",
- "AFL_TESTCACHE_SIZE",
- "AFL_TESTCACHE_ENTRIES",
- "AFL_TMIN_EXACT",
- "AFL_TMPDIR",
- "AFL_TOKEN_FILE",
- "AFL_TRACE_PC",
- "AFL_USE_ASAN",
- "AFL_USE_MSAN",
- "AFL_USE_TRACE_PC",
- "AFL_USE_UBSAN",
- "AFL_USE_TSAN",
- "AFL_USE_CFISAN",
- "AFL_USE_LSAN",
- "AFL_WINE_PATH",
- "AFL_NO_SNAPSHOT",
- "AFL_EXPAND_HAVOC_NOW",
- "AFL_USE_FASAN",
- "AFL_USE_QASAN",
- "AFL_PRINT_FILENAMES",
- "AFL_PIZZA_MODE",
- NULL
+ "AFL_NOOPT", "AFL_NYX_AUX_SIZE", "AFL_NYX_DISABLE_SNAPSHOT_MODE",
+ "AFL_NYX_LOG", "AFL_NYX_REUSE_SNAPSHOT", "AFL_PASSTHROUGH", "AFL_PATH",
+ "AFL_PERFORMANCE_FILE", "AFL_PERSISTENT_RECORD",
+ "AFL_POST_PROCESS_KEEP_ORIGINAL", "AFL_PRELOAD", "AFL_TARGET_ENV",
+ "AFL_PYTHON_MODULE", "AFL_QEMU_CUSTOM_BIN", "AFL_QEMU_COMPCOV",
+ "AFL_QEMU_COMPCOV_DEBUG", "AFL_QEMU_DEBUG_MAPS", "AFL_QEMU_DISABLE_CACHE",
+ "AFL_QEMU_DRIVER_NO_HOOK", "AFL_QEMU_FORCE_DFL", "AFL_QEMU_PERSISTENT_ADDR",
+ "AFL_QEMU_PERSISTENT_CNT", "AFL_QEMU_PERSISTENT_GPR",
+ "AFL_QEMU_PERSISTENT_HOOK", "AFL_QEMU_PERSISTENT_MEM",
+ "AFL_QEMU_PERSISTENT_RET", "AFL_QEMU_PERSISTENT_RETADDR_OFFSET",
+ "AFL_QEMU_PERSISTENT_EXITS", "AFL_QEMU_INST_RANGES",
+ "AFL_QEMU_EXCLUDE_RANGES", "AFL_QEMU_SNAPSHOT", "AFL_QEMU_TRACK_UNSTABLE",
+ "AFL_QUIET", "AFL_RANDOM_ALLOC_CANARY", "AFL_REAL_PATH",
+ "AFL_SHUFFLE_QUEUE", "AFL_SKIP_BIN_CHECK", "AFL_SKIP_CPUFREQ",
+ "AFL_SKIP_CRASHES", "AFL_SKIP_OSSFUZZ", "AFL_STATSD", "AFL_STATSD_HOST",
+ "AFL_STATSD_PORT", "AFL_STATSD_TAGS_FLAVOR", "AFL_SYNC_TIME",
+ "AFL_TESTCACHE_SIZE", "AFL_TESTCACHE_ENTRIES", "AFL_TMIN_EXACT",
+ "AFL_TMPDIR", "AFL_TOKEN_FILE", "AFL_TRACE_PC", "AFL_USE_ASAN",
+ "AFL_USE_MSAN", "AFL_USE_TRACE_PC", "AFL_USE_UBSAN", "AFL_USE_TSAN",
+ "AFL_USE_CFISAN", "AFL_USE_LSAN", "AFL_WINE_PATH", "AFL_NO_SNAPSHOT",
+ "AFL_EXPAND_HAVOC_NOW", "AFL_USE_FASAN", "AFL_USE_QASAN",
+ "AFL_PRINT_FILENAMES", "AFL_PIZZA_MODE", NULL
};
--
cgit 1.4.1
From db65dc5a0b5174f6eb22befee6dbc703092ff168 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 9 Jan 2024 16:50:57 +0100
Subject: lto llvm 12+
---
GNUmakefile.llvm | 6 +++---
docs/Changelog.md | 1 +
2 files changed, 4 insertions(+), 3 deletions(-)
(limited to 'docs')
diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm
index c704d772..7437130d 100644
--- a/GNUmakefile.llvm
+++ b/GNUmakefile.llvm
@@ -51,7 +51,7 @@ LLVM_TOO_OLD = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^[1-9]
LLVM_NEW_API = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[0-9]' && echo 1 || echo 0 )
LLVM_NEWER_API = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[6-9]' && echo 1 || echo 0 )
LLVM_13_OK = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[3-9]' && echo 1 || echo 0 )
-LLVM_HAVE_LTO = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[1-9]' && echo 1 || echo 0 )
+LLVM_HAVE_LTO = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[2-9]' && echo 1 || echo 0 )
LLVM_BINDIR = $(shell $(LLVM_CONFIG) --bindir 2>/dev/null)
LLVM_LIBDIR = $(shell $(LLVM_CONFIG) --libdir 2>/dev/null)
LLVM_STDCXX = gnu++11
@@ -95,12 +95,12 @@ ifeq "$(LLVM_NEWER_API)" "1"
endif
ifeq "$(LLVM_HAVE_LTO)" "1"
- $(info [+] llvm_mode detected llvm 11+, enabling afl-lto LTO implementation)
+ $(info [+] llvm_mode detected llvm 12+, enabling afl-lto LTO implementation)
LLVM_LTO = 1
endif
ifeq "$(LLVM_LTO)" "0"
- $(info [+] llvm_mode detected llvm < 11, afl-lto LTO will not be build.)
+ $(info [+] llvm_mode detected llvm < 12, afl-lto LTO will not be build.)
endif
ifeq "$(LLVM_APPLE_XCODE)" "1"
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 69a369e3..7d388134 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -11,6 +11,7 @@
reporting!
- afl-cc:
- large rewrite by @SonicStark which fixes a few corner cases, thanks!
+ - LTO mode now requires llvm 12+
- instrumentation:
- LLVM 18 support, thanks to @devnexen!
- Injection (SQL, LDAP, XSS) feature now available, see
--
cgit 1.4.1
From f75778adfb0fbea570a94b43eff801eb6d996f79 Mon Sep 17 00:00:00 2001
From: Xeonacid
Date: Thu, 11 Jan 2024 15:42:51 +0800
Subject: docs(custom_mutators): fix missing ':' (#1953)
---
docs/custom_mutators.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'docs')
diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md
index ce0a42dc..73e3c802 100644
--- a/docs/custom_mutators.md
+++ b/docs/custom_mutators.md
@@ -73,7 +73,7 @@ def init(seed):
def fuzz_count(buf):
return cnt
-def splice_optout()
+def splice_optout():
pass
def fuzz(buf, add_buf, max_size):
--
cgit 1.4.1
From 68d883d4285b7adedb2cd87a034c28a76ce2aa8c Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 12 Jan 2024 15:44:45 +0100
Subject: changelog
---
docs/Changelog.md | 4 ++++
1 file changed, 4 insertions(+)
(limited to 'docs')
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 7d388134..76470bde 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -21,6 +21,10 @@
- due a bug in LLVM 17 integer splitting is disabled there!
- when splitting floats was selected, integers were always split as well,
fixed to require AFL_LLVM_LAF_SPLIT_COMPARES or _ALL as it should
+ - qemu_mode:
+ - plugins are now activated by default and a new module is included that
+ produces drcov compatible traces for lighthouse/lightkeeper/...
+ thanks to @JRomainG to submitting!
### Version ++4.09c (release)
--
cgit 1.4.1
From 04219f98575847e9846b4ecf0de40dd92cd9d56c Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 18 Jan 2024 09:28:56 +0100
Subject: update grammar mutator
---
custom_mutators/grammar_mutator/GRAMMAR_VERSION | 2 +-
custom_mutators/grammar_mutator/grammar_mutator | 2 +-
docs/Changelog.md | 1 +
3 files changed, 3 insertions(+), 2 deletions(-)
(limited to 'docs')
diff --git a/custom_mutators/grammar_mutator/GRAMMAR_VERSION b/custom_mutators/grammar_mutator/GRAMMAR_VERSION
index 4c291bf8..2568c6a5 100644
--- a/custom_mutators/grammar_mutator/GRAMMAR_VERSION
+++ b/custom_mutators/grammar_mutator/GRAMMAR_VERSION
@@ -1 +1 @@
-9716f1092737be0f18e59a449070687a31c5f41e
+ff4e5a2
diff --git a/custom_mutators/grammar_mutator/grammar_mutator b/custom_mutators/grammar_mutator/grammar_mutator
index 9716f109..ff4e5a26 160000
--- a/custom_mutators/grammar_mutator/grammar_mutator
+++ b/custom_mutators/grammar_mutator/grammar_mutator
@@ -1 +1 @@
-Subproject commit 9716f1092737be0f18e59a449070687a31c5f41e
+Subproject commit ff4e5a265daf5d88c4a636fb6a2c22b1d733db09
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 76470bde..c681c4e1 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -25,6 +25,7 @@
- plugins are now activated by default and a new module is included that
produces drcov compatible traces for lighthouse/lightkeeper/...
thanks to @JRomainG to submitting!
+ - updated the custom grammar mutator
### Version ++4.09c (release)
--
cgit 1.4.1
From 0c054f520eda67b7bb15f95ca58c028e9b68131f Mon Sep 17 00:00:00 2001
From: van Hauser
Date: Thu, 18 Jan 2024 16:17:48 +0100
Subject: push to stable (#1960)
* Output afl-clang-fast stuffs only if necessary (#1912)
* afl-cc header
* afl-cc common declarations
- Add afl-cc-state.c
- Strip includes, find_object, debug/be_quiet/have_*/callname setting from afl-cc.c
- Use debugf_args in main
- Modify execvp stuffs to fit new aflcc struct
* afl-cc show usage
* afl-cc mode selecting
1. compiler_mode by callname in argv[0]
2. compiler_mode by env "AFL_CC_COMPILER"
3. compiler_mode/instrument_mode by command line options "--afl-..."
4. instrument_mode/compiler_mode by various env vars including "AFL_LLVM_INSTRUMENT"
5. final checking steps
6. print "... - mode: %s-%s\n"
7. determine real argv[0] according to compiler_mode
* afl-cc macro defs
* afl-cc linking behaviors
* afl-cc fsanitize behaviors
* afl-cc misc
* afl-cc body update
* afl-cc all-in-one
formated with custom-format.py
* nits
---------
Co-authored-by: vanhauser-thc
* changelog
* update grammar mutator
* lto llvm 12+
* docs(custom_mutators): fix missing ':' (#1953)
* Fix broken LTO mode and response file support (#1948)
* Strip `-Wl,-no-undefined` during compilation (#1952)
Make the compiler wrapper stripping `-Wl,-no-undefined` in addition to `-Wl,--no-undefined`.
Both versions of the flag are accepted by clang and, therefore, used by building systems in the wild (e.g., samba will not build without this fix).
* Remove dead code in write_to_testcase (#1955)
The custom_mutators_count check in if case is duplicate with if condition.
The else case is custom_mutators_count == 0, neither custom_mutator_list iteration nor sent check needed.
Signed-off-by: Xeonacid
* update qemuafl
* WIP: Add ability to generate drcov trace using QEMU backend (#1956)
* Document new drcov QEMU plugin
* Add link to lightkeeper for QEMU drcov file loading
---------
Co-authored-by: Jean-Romain Garnier
* code format
* changelog
* sleep on uid != 0 afl-system-config
* fix segv about skip_next, warn on unsupported cases of linking options (#1958)
* todos
* ensure afl-cc only allows available compiler modes
* update grammar mutator
* disable aslr on apple
* fix for arm64
---------
Signed-off-by: Xeonacid
Co-authored-by: Sonic <50692172+SonicStark@users.noreply.github.com>
Co-authored-by: Xeonacid
Co-authored-by: Nils Bars
Co-authored-by: Jean-Romain Garnier <7504819+JRomainG@users.noreply.github.com>
Co-authored-by: Jean-Romain Garnier
---
GNUmakefile.llvm | 6 +-
afl-persistent-config | 8 +
afl-system-config | 1 +
docs/Changelog.md | 12 +-
docs/custom_mutators.md | 2 +-
include/envs.h | 319 +---
qemu_mode/QEMUAFL_VERSION | 2 +-
qemu_mode/README.md | 33 +-
qemu_mode/build_qemu_support.sh | 4 +-
qemu_mode/qemuafl | 2 +-
src/afl-cc.c | 3378 +++++++++++++++++++++++----------------
src/afl-fuzz-run.c | 41 +-
src/afl-fuzz.c | 4 +
13 files changed, 2118 insertions(+), 1694 deletions(-)
(limited to 'docs')
diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm
index c704d772..7437130d 100644
--- a/GNUmakefile.llvm
+++ b/GNUmakefile.llvm
@@ -51,7 +51,7 @@ LLVM_TOO_OLD = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^[1-9]
LLVM_NEW_API = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[0-9]' && echo 1 || echo 0 )
LLVM_NEWER_API = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[6-9]' && echo 1 || echo 0 )
LLVM_13_OK = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[3-9]' && echo 1 || echo 0 )
-LLVM_HAVE_LTO = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[1-9]' && echo 1 || echo 0 )
+LLVM_HAVE_LTO = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[2-9]' && echo 1 || echo 0 )
LLVM_BINDIR = $(shell $(LLVM_CONFIG) --bindir 2>/dev/null)
LLVM_LIBDIR = $(shell $(LLVM_CONFIG) --libdir 2>/dev/null)
LLVM_STDCXX = gnu++11
@@ -95,12 +95,12 @@ ifeq "$(LLVM_NEWER_API)" "1"
endif
ifeq "$(LLVM_HAVE_LTO)" "1"
- $(info [+] llvm_mode detected llvm 11+, enabling afl-lto LTO implementation)
+ $(info [+] llvm_mode detected llvm 12+, enabling afl-lto LTO implementation)
LLVM_LTO = 1
endif
ifeq "$(LLVM_LTO)" "0"
- $(info [+] llvm_mode detected llvm < 11, afl-lto LTO will not be build.)
+ $(info [+] llvm_mode detected llvm < 12, afl-lto LTO will not be build.)
endif
ifeq "$(LLVM_APPLE_XCODE)" "1"
diff --git a/afl-persistent-config b/afl-persistent-config
index d78db286..26be9d9f 100755
--- a/afl-persistent-config
+++ b/afl-persistent-config
@@ -38,6 +38,7 @@ fi
echo
PLATFORM=`uname -s`
+ARCH=`uname -m`
# check that we're on Mac
if [[ "$PLATFORM" = "Darwin" ]] ; then
@@ -87,6 +88,13 @@ if [[ "$PLATFORM" = "Darwin" ]] ; then
EOF
+ if [[ "$ARCH" = "x86_64" ]]; then
+ echo "Disabling ASLR system wide"
+ nvram boot-args="no_aslr=1"
+ else
+ echo NOTICE: on ARM64 we do not know currently how to disable system wide ASLR, please report if you know how.
+ fi
+
echo
echo "Reboot and enjoy your fuzzing"
exit 0
diff --git a/afl-system-config b/afl-system-config
index c633e4e8..7e2cb688 100755
--- a/afl-system-config
+++ b/afl-system-config
@@ -25,6 +25,7 @@ echo "WARNING: this reduces the security of the system!"
echo
if [ '!' "$EUID" = 0 ] && [ '!' `id -u` = 0 ] ; then
echo "Warning: you need to be root to run this!"
+ sleep 1
# we do not exit as other mechanisms exist that allows to do this than
# being root. let the errors speak for themselves.
fi
diff --git a/docs/Changelog.md b/docs/Changelog.md
index adc81d64..c681c4e1 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -9,15 +9,23 @@
explore is slightly better now.
- fixed minor issues in the mutation engine, thanks to @futhewo for
reporting!
+ - afl-cc:
+ - large rewrite by @SonicStark which fixes a few corner cases, thanks!
+ - LTO mode now requires llvm 12+
- instrumentation:
- LLVM 18 support, thanks to @devnexen!
- Injection (SQL, LDAP, XSS) feature now available, see
`instrumentation/README.injections.md` how to activate/use/expand.
- compcov/LAF-intel:
- floating point splitting bug fix by @hexcoder
- - due a bug in LLVM 17 integer splitting is disabled!
+ - due a bug in LLVM 17 integer splitting is disabled there!
- when splitting floats was selected, integers were always split as well,
- fixed to require AFL_LLVM_LAF_SPLIT_COMPARES as it should
+ fixed to require AFL_LLVM_LAF_SPLIT_COMPARES or _ALL as it should
+ - qemu_mode:
+ - plugins are now activated by default and a new module is included that
+ produces drcov compatible traces for lighthouse/lightkeeper/...
+ thanks to @JRomainG to submitting!
+ - updated the custom grammar mutator
### Version ++4.09c (release)
diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md
index ce0a42dc..73e3c802 100644
--- a/docs/custom_mutators.md
+++ b/docs/custom_mutators.md
@@ -73,7 +73,7 @@ def init(seed):
def fuzz_count(buf):
return cnt
-def splice_optout()
+def splice_optout():
pass
def fuzz(buf, add_buf, max_size):
diff --git a/include/envs.h b/include/envs.h
index aa5c658e..0f645d23 100644
--- a/include/envs.h
+++ b/include/envs.h
@@ -16,255 +16,104 @@ static char *afl_environment_deprecated[] = {
static char *afl_environment_variables[] = {
- "AFL_ALIGNED_ALLOC",
- "AFL_ALLOW_TMP",
- "AFL_ANALYZE_HEX",
- "AFL_AS",
- "AFL_AUTORESUME",
- "AFL_AS_FORCE_INSTRUMENT",
- "AFL_BENCH_JUST_ONE",
- "AFL_BENCH_UNTIL_CRASH",
- "AFL_CAL_FAST",
- "AFL_CC",
- "AFL_CC_COMPILER",
- "AFL_CMIN_ALLOW_ANY",
- "AFL_CMIN_CRASHES_ONLY",
- "AFL_CMPLOG_ONLY_NEW",
- "AFL_CODE_END",
- "AFL_CODE_START",
- "AFL_COMPCOV_BINNAME",
- "AFL_COMPCOV_LEVEL",
- "AFL_CRASH_EXITCODE",
- "AFL_CRASHING_SEEDS_AS_NEW_CRASH",
- "AFL_CUSTOM_MUTATOR_LIBRARY",
- "AFL_CUSTOM_MUTATOR_ONLY",
- "AFL_CUSTOM_INFO_PROGRAM",
- "AFL_CUSTOM_INFO_PROGRAM_ARGV",
- "AFL_CUSTOM_INFO_PROGRAM_INPUT",
- "AFL_CUSTOM_INFO_OUT",
- "AFL_CXX",
- "AFL_CYCLE_SCHEDULES",
- "AFL_DEBUG",
- "AFL_DEBUG_CHILD",
- "AFL_DEBUG_GDB",
- "AFL_DEBUG_UNICORN",
- "AFL_DISABLE_TRIM",
- "AFL_DISABLE_LLVM_INSTRUMENTATION",
- "AFL_DONT_OPTIMIZE",
- "AFL_DRIVER_STDERR_DUPLICATE_FILENAME",
- "AFL_DUMB_FORKSRV",
- "AFL_EARLY_FORKSERVER",
- "AFL_ENTRYPOINT",
- "AFL_EXIT_WHEN_DONE",
- "AFL_EXIT_ON_TIME",
- "AFL_EXIT_ON_SEED_ISSUES",
- "AFL_FAST_CAL",
- "AFL_FINAL_SYNC",
- "AFL_FORCE_UI",
- "AFL_FRIDA_DEBUG_MAPS",
- "AFL_FRIDA_DRIVER_NO_HOOK",
- "AFL_FRIDA_EXCLUDE_RANGES",
- "AFL_FRIDA_INST_CACHE_SIZE",
- "AFL_FRIDA_INST_COVERAGE_ABSOLUTE",
- "AFL_FRIDA_INST_COVERAGE_FILE",
- "AFL_FRIDA_INST_DEBUG_FILE",
- "AFL_FRIDA_INST_INSN",
- "AFL_FRIDA_INST_JIT",
- "AFL_FRIDA_INST_NO_CACHE",
- "AFL_FRIDA_INST_NO_DYNAMIC_LOAD",
- "AFL_FRIDA_INST_NO_OPTIMIZE",
- "AFL_FRIDA_INST_NO_PREFETCH",
- "AFL_FRIDA_INST_NO_PREFETCH_BACKPATCH",
+ "AFL_ALIGNED_ALLOC", "AFL_ALLOW_TMP", "AFL_ANALYZE_HEX", "AFL_AS",
+ "AFL_AUTORESUME", "AFL_AS_FORCE_INSTRUMENT", "AFL_BENCH_JUST_ONE",
+ "AFL_BENCH_UNTIL_CRASH", "AFL_CAL_FAST", "AFL_CC", "AFL_CC_COMPILER",
+ "AFL_CMIN_ALLOW_ANY", "AFL_CMIN_CRASHES_ONLY", "AFL_CMPLOG_ONLY_NEW",
+ "AFL_CODE_END", "AFL_CODE_START", "AFL_COMPCOV_BINNAME",
+ "AFL_COMPCOV_LEVEL", "AFL_CRASH_EXITCODE",
+ "AFL_CRASHING_SEEDS_AS_NEW_CRASH", "AFL_CUSTOM_MUTATOR_LIBRARY",
+ "AFL_CUSTOM_MUTATOR_ONLY", "AFL_CUSTOM_INFO_PROGRAM",
+ "AFL_CUSTOM_INFO_PROGRAM_ARGV", "AFL_CUSTOM_INFO_PROGRAM_INPUT",
+ "AFL_CUSTOM_INFO_OUT", "AFL_CXX", "AFL_CYCLE_SCHEDULES", "AFL_DEBUG",
+ "AFL_DEBUG_CHILD", "AFL_DEBUG_GDB", "AFL_DEBUG_UNICORN", "AFL_DISABLE_TRIM",
+ "AFL_DISABLE_LLVM_INSTRUMENTATION", "AFL_DONT_OPTIMIZE",
+ "AFL_DRIVER_STDERR_DUPLICATE_FILENAME", "AFL_DUMB_FORKSRV",
+ "AFL_EARLY_FORKSERVER", "AFL_ENTRYPOINT", "AFL_EXIT_WHEN_DONE",
+ "AFL_EXIT_ON_TIME", "AFL_EXIT_ON_SEED_ISSUES", "AFL_FAST_CAL",
+ "AFL_FINAL_SYNC", "AFL_FORCE_UI", "AFL_FRIDA_DEBUG_MAPS",
+ "AFL_FRIDA_DRIVER_NO_HOOK", "AFL_FRIDA_EXCLUDE_RANGES",
+ "AFL_FRIDA_INST_CACHE_SIZE", "AFL_FRIDA_INST_COVERAGE_ABSOLUTE",
+ "AFL_FRIDA_INST_COVERAGE_FILE", "AFL_FRIDA_INST_DEBUG_FILE",
+ "AFL_FRIDA_INST_INSN", "AFL_FRIDA_INST_JIT", "AFL_FRIDA_INST_NO_CACHE",
+ "AFL_FRIDA_INST_NO_DYNAMIC_LOAD", "AFL_FRIDA_INST_NO_OPTIMIZE",
+ "AFL_FRIDA_INST_NO_PREFETCH", "AFL_FRIDA_INST_NO_PREFETCH_BACKPATCH",
"AFL_FRIDA_INST_NO_SUPPRESS"
"AFL_FRIDA_INST_RANGES",
- "AFL_FRIDA_INST_REGS_FILE",
- "AFL_FRIDA_INST_SEED",
- "AFL_FRIDA_INST_TRACE",
- "AFL_FRIDA_INST_TRACE_UNIQUE",
- "AFL_FRIDA_INST_UNSTABLE_COVERAGE_FILE",
- "AFL_FRIDA_JS_SCRIPT",
- "AFL_FRIDA_OUTPUT_STDOUT",
- "AFL_FRIDA_OUTPUT_STDERR",
- "AFL_FRIDA_PERSISTENT_ADDR",
- "AFL_FRIDA_PERSISTENT_CNT",
- "AFL_FRIDA_PERSISTENT_DEBUG",
- "AFL_FRIDA_PERSISTENT_HOOK",
- "AFL_FRIDA_PERSISTENT_RET",
- "AFL_FRIDA_STALKER_ADJACENT_BLOCKS",
- "AFL_FRIDA_STALKER_IC_ENTRIES",
- "AFL_FRIDA_STALKER_NO_BACKPATCH",
- "AFL_FRIDA_STATS_FILE",
- "AFL_FRIDA_STATS_INTERVAL",
- "AFL_FRIDA_TRACEABLE",
+ "AFL_FRIDA_INST_REGS_FILE", "AFL_FRIDA_INST_SEED", "AFL_FRIDA_INST_TRACE",
+ "AFL_FRIDA_INST_TRACE_UNIQUE", "AFL_FRIDA_INST_UNSTABLE_COVERAGE_FILE",
+ "AFL_FRIDA_JS_SCRIPT", "AFL_FRIDA_OUTPUT_STDOUT", "AFL_FRIDA_OUTPUT_STDERR",
+ "AFL_FRIDA_PERSISTENT_ADDR", "AFL_FRIDA_PERSISTENT_CNT",
+ "AFL_FRIDA_PERSISTENT_DEBUG", "AFL_FRIDA_PERSISTENT_HOOK",
+ "AFL_FRIDA_PERSISTENT_RET", "AFL_FRIDA_STALKER_ADJACENT_BLOCKS",
+ "AFL_FRIDA_STALKER_IC_ENTRIES", "AFL_FRIDA_STALKER_NO_BACKPATCH",
+ "AFL_FRIDA_STATS_FILE", "AFL_FRIDA_STATS_INTERVAL", "AFL_FRIDA_TRACEABLE",
"AFL_FRIDA_VERBOSE",
"AFL_FUZZER_ARGS", // oss-fuzz
- "AFL_FUZZER_STATS_UPDATE_INTERVAL",
- "AFL_GDB",
- "AFL_GCC_ALLOWLIST",
- "AFL_GCC_DENYLIST",
- "AFL_GCC_BLOCKLIST",
- "AFL_GCC_INSTRUMENT_FILE",
- "AFL_GCC_OUT_OF_LINE",
- "AFL_GCC_SKIP_NEVERZERO",
- "AFL_GCJ",
- "AFL_HANG_TMOUT",
- "AFL_FORKSRV_INIT_TMOUT",
- "AFL_HARDEN",
- "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES",
- "AFL_IGNORE_PROBLEMS",
- "AFL_IGNORE_PROBLEMS_COVERAGE",
- "AFL_IGNORE_SEED_PROBLEMS",
- "AFL_IGNORE_TIMEOUTS",
- "AFL_IGNORE_UNKNOWN_ENVS",
- "AFL_IMPORT_FIRST",
- "AFL_INPUT_LEN_MIN",
- "AFL_INPUT_LEN_MAX",
- "AFL_INST_LIBS",
- "AFL_INST_RATIO",
- "AFL_KEEP_TIMEOUTS",
- "AFL_KILL_SIGNAL",
- "AFL_FORK_SERVER_KILL_SIGNAL",
- "AFL_KEEP_TRACES",
- "AFL_KEEP_ASSEMBLY",
- "AFL_LD_HARD_FAIL",
- "AFL_LD_LIMIT_MB",
- "AFL_LD_NO_CALLOC_OVER",
- "AFL_LD_PASSTHROUGH",
- "AFL_REAL_LD",
- "AFL_LD_PRELOAD",
- "AFL_LD_VERBOSE",
- "AFL_LLVM_ALLOWLIST",
- "AFL_LLVM_DENYLIST",
- "AFL_LLVM_BLOCKLIST",
- "AFL_CMPLOG",
- "AFL_LLVM_CMPLOG",
- "AFL_GCC_CMPLOG",
- "AFL_LLVM_INSTRIM",
- "AFL_LLVM_CALLER",
- "AFL_LLVM_CTX",
- "AFL_LLVM_CTX_K",
- "AFL_LLVM_DICT2FILE",
- "AFL_LLVM_DICT2FILE_NO_MAIN",
- "AFL_LLVM_DOCUMENT_IDS",
- "AFL_LLVM_INSTRIM_LOOPHEAD",
- "AFL_LLVM_INSTRUMENT",
- "AFL_LLVM_LTO_AUTODICTIONARY",
- "AFL_LLVM_AUTODICTIONARY",
+ "AFL_FUZZER_STATS_UPDATE_INTERVAL", "AFL_GDB", "AFL_GCC_ALLOWLIST",
+ "AFL_GCC_DENYLIST", "AFL_GCC_BLOCKLIST", "AFL_GCC_INSTRUMENT_FILE",
+ "AFL_GCC_OUT_OF_LINE", "AFL_GCC_SKIP_NEVERZERO", "AFL_GCJ",
+ "AFL_HANG_TMOUT", "AFL_FORKSRV_INIT_TMOUT", "AFL_HARDEN",
+ "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES", "AFL_IGNORE_PROBLEMS",
+ "AFL_IGNORE_PROBLEMS_COVERAGE", "AFL_IGNORE_SEED_PROBLEMS",
+ "AFL_IGNORE_TIMEOUTS", "AFL_IGNORE_UNKNOWN_ENVS", "AFL_IMPORT_FIRST",
+ "AFL_INPUT_LEN_MIN", "AFL_INPUT_LEN_MAX", "AFL_INST_LIBS", "AFL_INST_RATIO",
+ "AFL_KEEP_TIMEOUTS", "AFL_KILL_SIGNAL", "AFL_FORK_SERVER_KILL_SIGNAL",
+ "AFL_KEEP_TRACES", "AFL_KEEP_ASSEMBLY", "AFL_LD_HARD_FAIL",
+ "AFL_LD_LIMIT_MB", "AFL_LD_NO_CALLOC_OVER", "AFL_LD_PASSTHROUGH",
+ "AFL_REAL_LD", "AFL_LD_PRELOAD", "AFL_LD_VERBOSE", "AFL_LLVM_ALLOWLIST",
+ "AFL_LLVM_DENYLIST", "AFL_LLVM_BLOCKLIST", "AFL_CMPLOG", "AFL_LLVM_CMPLOG",
+ "AFL_GCC_CMPLOG", "AFL_LLVM_INSTRIM", "AFL_LLVM_CALLER", "AFL_LLVM_CTX",
+ "AFL_LLVM_CTX_K", "AFL_LLVM_DICT2FILE", "AFL_LLVM_DICT2FILE_NO_MAIN",
+ "AFL_LLVM_DOCUMENT_IDS", "AFL_LLVM_INSTRIM_LOOPHEAD", "AFL_LLVM_INSTRUMENT",
+ "AFL_LLVM_LTO_AUTODICTIONARY", "AFL_LLVM_AUTODICTIONARY",
"AFL_LLVM_SKIPSINGLEBLOCK",
// Marker: ADD_TO_INJECTIONS
- "AFL_LLVM_INJECTIONS_ALL",
- "AFL_LLVM_INJECTIONS_SQL",
- "AFL_LLVM_INJECTIONS_LDAP",
- "AFL_LLVM_INJECTIONS_XSS",
- "AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK",
- "AFL_LLVM_LAF_SPLIT_COMPARES",
- "AFL_LLVM_LAF_SPLIT_COMPARES_BITW",
- "AFL_LLVM_LAF_SPLIT_FLOATS",
- "AFL_LLVM_LAF_SPLIT_SWITCHES",
- "AFL_LLVM_LAF_ALL",
- "AFL_LLVM_LAF_TRANSFORM_COMPARES",
- "AFL_LLVM_MAP_ADDR",
- "AFL_LLVM_MAP_DYNAMIC",
- "AFL_LLVM_NGRAM_SIZE",
- "AFL_NGRAM_SIZE",
- "AFL_LLVM_NO_RPATH",
- "AFL_LLVM_NOT_ZERO",
- "AFL_LLVM_INSTRUMENT_FILE",
- "AFL_LLVM_THREADSAFE_INST",
- "AFL_LLVM_SKIP_NEVERZERO",
- "AFL_NO_AFFINITY",
- "AFL_TRY_AFFINITY",
- "AFL_LLVM_LTO_DONTWRITEID",
+ "AFL_LLVM_INJECTIONS_ALL", "AFL_LLVM_INJECTIONS_SQL",
+ "AFL_LLVM_INJECTIONS_LDAP", "AFL_LLVM_INJECTIONS_XSS",
+ "AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK", "AFL_LLVM_LAF_SPLIT_COMPARES",
+ "AFL_LLVM_LAF_SPLIT_COMPARES_BITW", "AFL_LLVM_LAF_SPLIT_FLOATS",
+ "AFL_LLVM_LAF_SPLIT_SWITCHES", "AFL_LLVM_LAF_ALL",
+ "AFL_LLVM_LAF_TRANSFORM_COMPARES", "AFL_LLVM_MAP_ADDR",
+ "AFL_LLVM_MAP_DYNAMIC", "AFL_LLVM_NGRAM_SIZE", "AFL_NGRAM_SIZE",
+ "AFL_LLVM_NO_RPATH", "AFL_LLVM_NOT_ZERO", "AFL_LLVM_INSTRUMENT_FILE",
+ "AFL_LLVM_THREADSAFE_INST", "AFL_LLVM_SKIP_NEVERZERO", "AFL_NO_AFFINITY",
+ "AFL_TRY_AFFINITY", "AFL_LLVM_LTO_DONTWRITEID",
"AFL_LLVM_LTO_SKIPINIT"
"AFL_LLVM_LTO_STARTID",
- "AFL_FUZZER_LOOPCOUNT",
- "AFL_NO_ARITH",
- "AFL_NO_AUTODICT",
- "AFL_NO_BUILTIN",
+ "AFL_FUZZER_LOOPCOUNT", "AFL_NO_ARITH", "AFL_NO_AUTODICT", "AFL_NO_BUILTIN",
#if defined USE_COLOR && !defined ALWAYS_COLORED
- "AFL_NO_COLOR",
- "AFL_NO_COLOUR",
+ "AFL_NO_COLOR", "AFL_NO_COLOUR",
#endif
"AFL_NO_CPU_RED",
"AFL_NO_CFG_FUZZING", // afl.rs rust crate option
- "AFL_NO_CRASH_README",
- "AFL_NO_FORKSRV",
- "AFL_NO_UI",
- "AFL_NO_PYTHON",
- "AFL_NO_STARTUP_CALIBRATION",
- "AFL_NO_WARN_INSTABILITY",
- "AFL_UNTRACER_FILE",
- "AFL_LLVM_USE_TRACE_PC",
- "AFL_MAP_SIZE",
- "AFL_MAPSIZE",
+ "AFL_NO_CRASH_README", "AFL_NO_FORKSRV", "AFL_NO_UI", "AFL_NO_PYTHON",
+ "AFL_NO_STARTUP_CALIBRATION", "AFL_NO_WARN_INSTABILITY",
+ "AFL_UNTRACER_FILE", "AFL_LLVM_USE_TRACE_PC", "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_NYX_AUX_SIZE",
- "AFL_NYX_DISABLE_SNAPSHOT_MODE",
- "AFL_NYX_LOG",
- "AFL_NYX_REUSE_SNAPSHOT",
- "AFL_PASSTHROUGH",
- "AFL_PATH",
- "AFL_PERFORMANCE_FILE",
- "AFL_PERSISTENT_RECORD",
- "AFL_POST_PROCESS_KEEP_ORIGINAL",
- "AFL_PRELOAD",
- "AFL_TARGET_ENV",
- "AFL_PYTHON_MODULE",
- "AFL_QEMU_CUSTOM_BIN",
- "AFL_QEMU_COMPCOV",
- "AFL_QEMU_COMPCOV_DEBUG",
- "AFL_QEMU_DEBUG_MAPS",
- "AFL_QEMU_DISABLE_CACHE",
- "AFL_QEMU_DRIVER_NO_HOOK",
- "AFL_QEMU_FORCE_DFL",
- "AFL_QEMU_PERSISTENT_ADDR",
- "AFL_QEMU_PERSISTENT_CNT",
- "AFL_QEMU_PERSISTENT_GPR",
- "AFL_QEMU_PERSISTENT_HOOK",
- "AFL_QEMU_PERSISTENT_MEM",
- "AFL_QEMU_PERSISTENT_RET",
- "AFL_QEMU_PERSISTENT_RETADDR_OFFSET",
- "AFL_QEMU_PERSISTENT_EXITS",
- "AFL_QEMU_INST_RANGES",
- "AFL_QEMU_EXCLUDE_RANGES",
- "AFL_QEMU_SNAPSHOT",
- "AFL_QEMU_TRACK_UNSTABLE",
- "AFL_QUIET",
- "AFL_RANDOM_ALLOC_CANARY",
- "AFL_REAL_PATH",
- "AFL_SHUFFLE_QUEUE",
- "AFL_SKIP_BIN_CHECK",
- "AFL_SKIP_CPUFREQ",
- "AFL_SKIP_CRASHES",
- "AFL_SKIP_OSSFUZZ",
- "AFL_STATSD",
- "AFL_STATSD_HOST",
- "AFL_STATSD_PORT",
- "AFL_STATSD_TAGS_FLAVOR",
- "AFL_SYNC_TIME",
- "AFL_TESTCACHE_SIZE",
- "AFL_TESTCACHE_ENTRIES",
- "AFL_TMIN_EXACT",
- "AFL_TMPDIR",
- "AFL_TOKEN_FILE",
- "AFL_TRACE_PC",
- "AFL_USE_ASAN",
- "AFL_USE_MSAN",
- "AFL_USE_TRACE_PC",
- "AFL_USE_UBSAN",
- "AFL_USE_TSAN",
- "AFL_USE_CFISAN",
- "AFL_USE_LSAN",
- "AFL_WINE_PATH",
- "AFL_NO_SNAPSHOT",
- "AFL_EXPAND_HAVOC_NOW",
- "AFL_USE_FASAN",
- "AFL_USE_QASAN",
- "AFL_PRINT_FILENAMES",
- "AFL_PIZZA_MODE",
- NULL
+ "AFL_NOOPT", "AFL_NYX_AUX_SIZE", "AFL_NYX_DISABLE_SNAPSHOT_MODE",
+ "AFL_NYX_LOG", "AFL_NYX_REUSE_SNAPSHOT", "AFL_PASSTHROUGH", "AFL_PATH",
+ "AFL_PERFORMANCE_FILE", "AFL_PERSISTENT_RECORD",
+ "AFL_POST_PROCESS_KEEP_ORIGINAL", "AFL_PRELOAD", "AFL_TARGET_ENV",
+ "AFL_PYTHON_MODULE", "AFL_QEMU_CUSTOM_BIN", "AFL_QEMU_COMPCOV",
+ "AFL_QEMU_COMPCOV_DEBUG", "AFL_QEMU_DEBUG_MAPS", "AFL_QEMU_DISABLE_CACHE",
+ "AFL_QEMU_DRIVER_NO_HOOK", "AFL_QEMU_FORCE_DFL", "AFL_QEMU_PERSISTENT_ADDR",
+ "AFL_QEMU_PERSISTENT_CNT", "AFL_QEMU_PERSISTENT_GPR",
+ "AFL_QEMU_PERSISTENT_HOOK", "AFL_QEMU_PERSISTENT_MEM",
+ "AFL_QEMU_PERSISTENT_RET", "AFL_QEMU_PERSISTENT_RETADDR_OFFSET",
+ "AFL_QEMU_PERSISTENT_EXITS", "AFL_QEMU_INST_RANGES",
+ "AFL_QEMU_EXCLUDE_RANGES", "AFL_QEMU_SNAPSHOT", "AFL_QEMU_TRACK_UNSTABLE",
+ "AFL_QUIET", "AFL_RANDOM_ALLOC_CANARY", "AFL_REAL_PATH",
+ "AFL_SHUFFLE_QUEUE", "AFL_SKIP_BIN_CHECK", "AFL_SKIP_CPUFREQ",
+ "AFL_SKIP_CRASHES", "AFL_SKIP_OSSFUZZ", "AFL_STATSD", "AFL_STATSD_HOST",
+ "AFL_STATSD_PORT", "AFL_STATSD_TAGS_FLAVOR", "AFL_SYNC_TIME",
+ "AFL_TESTCACHE_SIZE", "AFL_TESTCACHE_ENTRIES", "AFL_TMIN_EXACT",
+ "AFL_TMPDIR", "AFL_TOKEN_FILE", "AFL_TRACE_PC", "AFL_USE_ASAN",
+ "AFL_USE_MSAN", "AFL_USE_TRACE_PC", "AFL_USE_UBSAN", "AFL_USE_TSAN",
+ "AFL_USE_CFISAN", "AFL_USE_LSAN", "AFL_WINE_PATH", "AFL_NO_SNAPSHOT",
+ "AFL_EXPAND_HAVOC_NOW", "AFL_USE_FASAN", "AFL_USE_QASAN",
+ "AFL_PRINT_FILENAMES", "AFL_PIZZA_MODE", NULL
};
diff --git a/qemu_mode/QEMUAFL_VERSION b/qemu_mode/QEMUAFL_VERSION
index 44ea5345..b4e764b7 100644
--- a/qemu_mode/QEMUAFL_VERSION
+++ b/qemu_mode/QEMUAFL_VERSION
@@ -1 +1 @@
-a1321713c7
+e63c9af193
diff --git a/qemu_mode/README.md b/qemu_mode/README.md
index 92038737..b78eb297 100644
--- a/qemu_mode/README.md
+++ b/qemu_mode/README.md
@@ -193,12 +193,39 @@ Comparative measurements of execution speed or instrumentation coverage will be
fairly meaningless if the optimization levels or instrumentation scopes don't
match.
-## 12) Other features
+## 12) Coverage information
+
+Coverage information about a run of a target binary can be obtained using a
+dedicated QEMU user mode plugin enabled at runtime: the `drcov.c` plugin
+collects coverage information from the target binary and writes it in the Drcov
+format. This file can then be loaded using tools such as
+[lighthouse](https://github.com/gaasedelen/lighthouse),
+[lightkeeper](https://github.com/WorksButNotTested/lightkeeper) or
+[Cartographer](https://github.com/nccgroup/Cartographer).
+
+To compile the QEMU TCG plugins, run the following command from the `qemuafl`
+directory:
+
+```
+make plugins
+```
+
+Plugins can be loaded using either the `QEMU_PLUGIN` environment variable or
+using the `-plugin` option. For example:
+
+```
+afl-qemu-trace -plugin qemuafl/build/contrib/plugins/libdrcov.so,arg=filename=/tmp/target.drcov.trace
+```
+
+This would execute the target binary with the provided arguments and, once done,
+would write coverage information at `/tmp/target.drcov.trace`.
+
+## 13) Other features
With `AFL_QEMU_FORCE_DFL`, you force QEMU to ignore the registered signal
handlers of the target.
-## 13) Gotchas, feedback, bugs
+## 14) Gotchas, feedback, bugs
If you need to fix up checksums or do other cleanups on mutated test cases, see
`afl_custom_post_process` in custom_mutators/examples/example.c for a viable
@@ -217,7 +244,7 @@ program may be utilizing. In particular, it does not appear to have full support
for AVX2/FMA3. Using binaries for older CPUs or recompiling them with
`-march=core2`, can help.
-## 14) Alternatives: static rewriting
+## 15) Alternatives: static rewriting
Statically rewriting binaries just once, instead of attempting to translate them
at run time, can be a faster alternative. That said, static rewriting is fraught
diff --git a/qemu_mode/build_qemu_support.sh b/qemu_mode/build_qemu_support.sh
index f59cba78..3f8a88f2 100755
--- a/qemu_mode/build_qemu_support.sh
+++ b/qemu_mode/build_qemu_support.sh
@@ -132,7 +132,10 @@ echo "Building for CPU target $CPU_TARGET"
# --enable-pie seems to give a couple of exec's a second performance
# improvement, much to my surprise. Not sure how universal this is..
+# --enable-plugins allows loading TCG plugins at runtime, for example to obtain
+# coverage information, and does not seem to negatively impact performance
QEMU_CONF_FLAGS=" \
+ --enable-plugins \
--audio-drv-list= \
--disable-blobs \
--disable-bochs \
@@ -162,7 +165,6 @@ QEMU_CONF_FLAGS=" \
--disable-numa \
--disable-opengl \
--disable-parallels \
- --disable-plugins \
--disable-qcow1 \
--disable-qed \
--disable-rbd \
diff --git a/qemu_mode/qemuafl b/qemu_mode/qemuafl
index b0abbe2e..e63c9af1 160000
--- a/qemu_mode/qemuafl
+++ b/qemu_mode/qemuafl
@@ -1 +1 @@
-Subproject commit b0abbe2e74ed74ff6ff25b5ea3110d27ba978001
+Subproject commit e63c9af1937c13163cd1bc8bc276101441cbe70a
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 54c733c9..192c5423 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -47,23 +47,22 @@
#define LLVM_MINOR 0
#endif
-static u8 *obj_path; /* Path to runtime libraries */
-static u8 **cc_params; /* Parameters passed to the real CC */
-static u32 cc_par_cnt = 1; /* Param count, including argv0 */
-static u8 clang_mode; /* Invoked as afl-clang*? */
-static u8 llvm_fullpath[PATH_MAX];
-static u8 instrument_mode, instrument_opt_mode, ngram_size, ctx_k, lto_mode;
-static u8 compiler_mode, plusplus_mode, have_instr_env = 0, need_aflpplib = 0;
-static u8 have_gcc, have_llvm, have_gcc_plugin, have_lto, have_instr_list = 0;
-static u8 *lto_flag = AFL_CLANG_FLTO, *argvnull;
-static u8 debug;
-static u8 cwd[4096];
-static u8 cmplog_mode;
-u8 use_stdin; /* dummy */
-static int passthrough;
-// static u8 *march_opt = CFLAGS_OPT;
-
-enum {
+#ifndef MAX_PARAMS_NUM
+ #define MAX_PARAMS_NUM 2048
+#endif
+
+/* Global declarations */
+
+typedef enum {
+
+ PARAM_MISS, // not matched
+ PARAM_SCAN, // scan only
+ PARAM_KEEP, // kept as-is
+ PARAM_DROP, // ignored
+
+} param_st;
+
+typedef enum {
INSTRUMENT_DEFAULT = 0,
INSTRUMENT_CLASSIC = 1,
@@ -80,7 +79,20 @@ enum {
INSTRUMENT_OPT_CTX_K = 64,
INSTRUMENT_OPT_CODECOV = 128,
-};
+} instrument_mode_id;
+
+typedef enum {
+
+ UNSET = 0,
+ LTO = 1,
+ LLVM = 2,
+ GCC_PLUGIN = 3,
+ GCC = 4,
+ CLANG = 5
+
+} compiler_mode_id;
+
+static u8 cwd[4096];
char instrument_mode_string[18][18] = {
@@ -105,17 +117,6 @@ char instrument_mode_string[18][18] = {
};
-enum {
-
- UNSET = 0,
- LTO = 1,
- LLVM = 2,
- GCC_PLUGIN = 3,
- GCC = 4,
- CLANG = 5
-
-};
-
char compiler_mode_string[7][12] = {
"AUTOSELECT", "LLVM-LTO", "LLVM", "GCC_PLUGIN",
@@ -123,6 +124,18 @@ char compiler_mode_string[7][12] = {
};
+u8 *instrument_mode_2str(instrument_mode_id i) {
+
+ return instrument_mode_string[i];
+
+}
+
+u8 *compiler_mode_2str(compiler_mode_id i) {
+
+ return compiler_mode_string[i];
+
+}
+
u8 *getthecwd() {
if (getcwd(cwd, sizeof(cwd)) == NULL) {
@@ -136,26 +149,228 @@ u8 *getthecwd() {
}
-/* Try to find a specific runtime we need, returns NULL on fail. */
+typedef struct aflcc_state {
+
+ u8 **cc_params; /* Parameters passed to the real CC */
+ u32 cc_par_cnt; /* Param count, including argv0 */
+
+ u8 *argv0; /* Original argv0 (by strdup) */
+ u8 *callname; /* Executable file argv0 indicated */
+
+ u8 debug;
+
+ u8 compiler_mode, plusplus_mode, lto_mode;
+
+ u8 *lto_flag;
+
+ u8 instrument_mode, instrument_opt_mode, ngram_size, ctx_k;
+
+ u8 cmplog_mode;
+
+ u8 have_instr_env, have_gcc, have_clang, have_llvm, have_gcc_plugin, have_lto,
+ have_optimized_pcguard, have_instr_list;
+
+ u8 fortify_set, asan_set, x_set, bit_mode, preprocessor_only, have_unroll,
+ have_o, have_pic, have_c, shared_linking, partial_linking, non_dash;
+
+ // u8 *march_opt;
+ u8 need_aflpplib;
+ int passthrough;
+
+ u8 use_stdin; /* dummy */
+ u8 *argvnull; /* dummy */
+
+} aflcc_state_t;
+
+void aflcc_state_init(aflcc_state_t *, u8 *argv0);
+
+/* Try to find a specific runtime we need, the path to obj would be
+ allocated and returned. Otherwise it returns NULL on fail. */
+u8 *find_object(aflcc_state_t *, u8 *obj);
+
+void find_built_deps(aflcc_state_t *);
+
+static inline void limit_params(aflcc_state_t *aflcc, u32 add) {
+
+ if (aflcc->cc_par_cnt + add >= MAX_PARAMS_NUM)
+ FATAL("Too many command line parameters, please increase MAX_PARAMS_NUM.");
+
+}
+
+static inline void insert_param(aflcc_state_t *aflcc, u8 *param) {
+
+ aflcc->cc_params[aflcc->cc_par_cnt++] = param;
+
+}
+
+static inline void insert_object(aflcc_state_t *aflcc, u8 *obj, u8 *fmt,
+ u8 *msg) {
+
+ u8 *_obj_path = find_object(aflcc, obj);
+ if (!_obj_path) {
+
+ if (msg)
+ FATAL("%s", msg);
+ else
+ FATAL("Unable to find '%s'", obj);
+
+ } else {
+
+ if (fmt) {
+
+ u8 *_obj_path_fmt = alloc_printf(fmt, _obj_path);
+ ck_free(_obj_path);
+ aflcc->cc_params[aflcc->cc_par_cnt++] = _obj_path_fmt;
+
+ } else {
+
+ aflcc->cc_params[aflcc->cc_par_cnt++] = _obj_path;
+
+ }
+
+ }
+
+}
+
+static inline void load_llvm_pass(aflcc_state_t *aflcc, u8 *pass) {
+
+#if LLVM_MAJOR >= 11 /* use new pass manager */
+ #if LLVM_MAJOR < 16
+ insert_param(aflcc, "-fexperimental-new-pass-manager");
+ #endif
+ insert_object(aflcc, pass, "-fpass-plugin=%s", 0);
+#else
+ insert_param(aflcc, "-Xclang");
+ insert_param(aflcc, "-load");
+ insert_param(aflcc, "-Xclang");
+ insert_object(aflcc, pass, 0, 0);
+#endif
+
+}
+
+static inline void debugf_args(int argc, char **argv) {
+
+ DEBUGF("cd '%s';", getthecwd());
+ for (int i = 0; i < argc; i++)
+ SAYF(" '%s'", argv[i]);
+ SAYF("\n");
+ fflush(stdout);
+ fflush(stderr);
+
+}
+
+void compiler_mode_by_callname(aflcc_state_t *);
+void compiler_mode_by_environ(aflcc_state_t *);
+void compiler_mode_by_cmdline(aflcc_state_t *, int argc, char **argv);
+void instrument_mode_by_environ(aflcc_state_t *);
+void mode_final_checkout(aflcc_state_t *, int argc, char **argv);
+void mode_notification(aflcc_state_t *);
+
+void add_real_argv0(aflcc_state_t *);
+
+void add_defs_common(aflcc_state_t *);
+void add_defs_selective_instr(aflcc_state_t *);
+void add_defs_persistent_mode(aflcc_state_t *);
+void add_defs_fortify(aflcc_state_t *, u8);
+void add_defs_lsan_ctrl(aflcc_state_t *);
+
+param_st parse_fsanitize(aflcc_state_t *, u8 *, u8);
+void add_sanitizers(aflcc_state_t *, char **envp);
+void add_optimized_pcguard(aflcc_state_t *);
+void add_native_pcguard(aflcc_state_t *);
+
+void add_assembler(aflcc_state_t *);
+void add_gcc_plugin(aflcc_state_t *);
+
+param_st parse_misc_params(aflcc_state_t *, u8 *, u8);
+void add_misc_params(aflcc_state_t *);
+
+param_st parse_linking_params(aflcc_state_t *, u8 *, u8, u8 *skip_next,
+ char **argv);
+
+void add_lto_linker(aflcc_state_t *);
+void add_lto_passes(aflcc_state_t *);
+void add_runtime(aflcc_state_t *);
+
+/* Working state */
+
+void aflcc_state_init(aflcc_state_t *aflcc, u8 *argv0) {
+
+ // Default NULL/0 is a good start
+ memset(aflcc, 0, sizeof(aflcc_state_t));
+
+ aflcc->cc_params = ck_alloc(MAX_PARAMS_NUM * sizeof(u8 *));
+ aflcc->cc_par_cnt = 1;
+
+ aflcc->lto_flag = AFL_CLANG_FLTO;
+
+ // aflcc->march_opt = CFLAGS_OPT;
+
+ /* callname & if C++ mode */
+
+ aflcc->argv0 = ck_strdup(argv0);
+
+ char *cname = NULL;
+
+ if ((cname = strrchr(aflcc->argv0, '/')) != NULL) {
+
+ cname++;
+
+ } else {
+
+ cname = aflcc->argv0;
+
+ }
+
+ aflcc->callname = cname;
+
+ if (strlen(cname) > 2 && (strncmp(cname + strlen(cname) - 2, "++", 2) == 0 ||
+ strstr(cname, "-g++") != NULL)) {
+
+ aflcc->plusplus_mode = 1;
+
+ }
+
+ /* debug */
+
+ if (getenv("AFL_DEBUG")) {
+
+ aflcc->debug = 1;
+ if (strcmp(getenv("AFL_DEBUG"), "0") == 0) unsetenv("AFL_DEBUG");
+
+ } else if (getenv("AFL_QUIET")) {
+
+ be_quiet = 1;
+
+ }
+
+ if ((getenv("AFL_PASSTHROUGH") || getenv("AFL_NOOPT")) && (!aflcc->debug)) {
+
+ be_quiet = 1;
+
+ }
+
+}
/*
in find_object() we look here:
- 1. if obj_path is already set we look there first
- 2. then we check the $AFL_PATH environment variable location if set
- 3. next we check argv[0] if it has path information and use it
+ 1. firstly we check the $AFL_PATH environment variable location if set
+ 2. next we check argv[0] if it has path information and use it
a) we also check ../lib/afl
- 4. if 3. failed we check /proc (only Linux, Android, NetBSD, DragonFly, and
+ 3. if 2. failed we check /proc (only Linux, Android, NetBSD, DragonFly, and
FreeBSD with procfs)
a) and check here in ../lib/afl too
- 5. we look into the AFL_PATH define (usually /usr/local/lib/afl)
- 6. we finally try the current directory
+ 4. we look into the AFL_PATH define (usually /usr/local/lib/afl)
+ 5. we finally try the current directory
if all these attempts fail - we return NULL and the caller has to decide
- what to do.
+ what to do. Otherwise the path to obj would be allocated and returned.
*/
-static u8 *find_object(u8 *obj, u8 *argv0) {
+u8 *find_object(aflcc_state_t *aflcc, u8 *obj) {
+
+ u8 *argv0 = aflcc->argv0;
u8 *afl_path = getenv("AFL_PATH");
u8 *slash = NULL, *tmp;
@@ -164,14 +379,9 @@ static u8 *find_object(u8 *obj, u8 *argv0) {
tmp = alloc_printf("%s/%s", afl_path, obj);
- if (debug) DEBUGF("Trying %s\n", tmp);
-
- if (!access(tmp, R_OK)) {
-
- obj_path = afl_path;
- return tmp;
+ if (aflcc->debug) DEBUGF("Trying %s\n", tmp);
- }
+ if (!access(tmp, R_OK)) { return tmp; }
ck_free(tmp);
@@ -190,11 +400,11 @@ static u8 *find_object(u8 *obj, u8 *argv0) {
tmp = alloc_printf("%s/%s", dir, obj);
- if (debug) DEBUGF("Trying %s\n", tmp);
+ if (aflcc->debug) DEBUGF("Trying %s\n", tmp);
if (!access(tmp, R_OK)) {
- obj_path = dir;
+ ck_free(dir);
return tmp;
}
@@ -202,12 +412,10 @@ static u8 *find_object(u8 *obj, u8 *argv0) {
ck_free(tmp);
tmp = alloc_printf("%s/../lib/afl/%s", dir, obj);
- if (debug) DEBUGF("Trying %s\n", tmp);
+ if (aflcc->debug) DEBUGF("Trying %s\n", tmp);
if (!access(tmp, R_OK)) {
- u8 *dir2 = alloc_printf("%s/../lib/afl", dir);
- obj_path = dir2;
ck_free(dir);
return tmp;
@@ -247,26 +455,16 @@ static u8 *find_object(u8 *obj, u8 *argv0) {
*slash = 0;
tmp = alloc_printf("%s/%s", exepath, obj);
- if (!access(tmp, R_OK)) {
-
- u8 *dir = alloc_printf("%s", exepath);
- obj_path = dir;
- return tmp;
-
- }
+ if (!access(tmp, R_OK)) { return tmp; }
ck_free(tmp);
tmp = alloc_printf("%s/../lib/afl/%s", exepath, obj);
- if (debug) DEBUGF("Trying %s\n", tmp);
-
- if (!access(tmp, R_OK)) {
+ if (aflcc->debug) DEBUGF("Trying %s\n", tmp);
- u8 *dir = alloc_printf("%s/../lib/afl/", exepath);
- obj_path = dir;
- return tmp;
+ if (!access(tmp, R_OK)) { return tmp; }
- }
+ ck_free(tmp);
}
@@ -283,1843 +481,2036 @@ static u8 *find_object(u8 *obj, u8 *argv0) {
tmp = alloc_printf("%s/%s", AFL_PATH, obj);
- if (debug) DEBUGF("Trying %s\n", tmp);
+ if (aflcc->debug) DEBUGF("Trying %s\n", tmp);
- if (!access(tmp, R_OK)) {
-
- obj_path = AFL_PATH;
- return tmp;
-
- }
+ if (!access(tmp, R_OK)) { return tmp; }
ck_free(tmp);
-
tmp = alloc_printf("./%s", obj);
- if (debug) DEBUGF("Trying %s\n", tmp);
+ if (aflcc->debug) DEBUGF("Trying %s\n", tmp);
- if (!access(tmp, R_OK)) {
-
- obj_path = ".";
- return tmp;
-
- }
+ if (!access(tmp, R_OK)) { return tmp; }
ck_free(tmp);
- if (debug) DEBUGF("Trying ... giving up\n");
+ if (aflcc->debug) DEBUGF("Trying ... giving up\n");
return NULL;
}
-void parse_fsanitize(char *string) {
+void find_built_deps(aflcc_state_t *aflcc) {
- char *p, *ptr = string + strlen("-fsanitize=");
- char *new = malloc(strlen(string) + 1);
- char *tmp = malloc(strlen(ptr) + 1);
- u32 count = 0, len, ende = 0;
+ char *ptr = NULL;
- if (!new || !tmp) { FATAL("could not acquire memory"); }
- strcpy(new, "-fsanitize=");
+#if defined(__x86_64__)
+ if ((ptr = find_object(aflcc, "as")) != NULL) {
- do {
+ #ifndef __APPLE__
+ // on OSX clang masquerades as GCC
+ aflcc->have_gcc = 1;
+ #endif
+ aflcc->have_clang = 1;
+ ck_free(ptr);
- p = strchr(ptr, ',');
- if (!p) {
+ }
- p = ptr + strlen(ptr) + 1;
- ende = 1;
+#endif
- }
+ if ((ptr = find_object(aflcc, "SanitizerCoveragePCGUARD.so")) != NULL) {
- len = p - ptr;
- if (len) {
+ aflcc->have_optimized_pcguard = 1;
+ ck_free(ptr);
- strncpy(tmp, ptr, len);
- tmp[len] = 0;
- // fprintf(stderr, "Found: %s\n", tmp);
- ptr += len + 1;
- if (*tmp) {
+ }
- u32 copy = 1;
- if (!strcmp(tmp, "fuzzer")) {
+#if (LLVM_MAJOR >= 3)
- need_aflpplib = 1;
- copy = 0;
+ if ((ptr = find_object(aflcc, "SanitizerCoverageLTO.so")) != NULL) {
- } else if (!strncmp(tmp, "fuzzer", 6)) {
+ aflcc->have_lto = 1;
+ ck_free(ptr);
- copy = 0;
+ }
- }
+ if ((ptr = find_object(aflcc, "cmplog-routines-pass.so")) != NULL) {
- if (copy) {
+ aflcc->have_llvm = 1;
+ ck_free(ptr);
- if (count) { strcat(new, ","); }
- strcat(new, tmp);
- ++count;
+ }
- }
+#endif
- }
+#ifdef __ANDROID__
+ aflcc->have_llvm = 1;
+#endif
- } else {
+ if ((ptr = find_object(aflcc, "afl-gcc-pass.so")) != NULL) {
- ptr++; /*fprintf(stderr, "NO!\n"); */
+ aflcc->have_gcc_plugin = 1;
+ ck_free(ptr);
- }
+ }
- } while (!ende);
+#if !defined(__ANDROID__) && !defined(ANDROID)
+ ptr = find_object(aflcc, "afl-compiler-rt.o");
- strcpy(string, new);
- // fprintf(stderr, "string: %s\n", string);
- // fprintf(stderr, "new: %s\n", new);
+ if (!ptr) {
-}
+ FATAL(
+ "Unable to find 'afl-compiler-rt.o'. Please set the AFL_PATH "
+ "environment variable.");
-static u8 fortify_set = 0, asan_set = 0, x_set = 0, bit_mode = 0,
- shared_linking = 0, preprocessor_only = 0, have_unroll = 0,
- have_o = 0, have_pic = 0, have_c = 0, partial_linking = 0,
- non_dash = 0;
+ }
-#ifndef MAX_PARAMS_NUM
- #define MAX_PARAMS_NUM 2048
+ if (aflcc->debug) { DEBUGF("rt=%s\n", ptr); }
+
+ ck_free(ptr);
#endif
-static void process_params(u32 argc, char **argv) {
+}
- if (cc_par_cnt + argc >= MAX_PARAMS_NUM) {
+/* compiler_mode & instrument_mode selecting */
- FATAL("Too many command line parameters, please increase MAX_PARAMS_NUM.");
+void compiler_mode_by_callname(aflcc_state_t *aflcc) {
- }
+ if (strncmp(aflcc->callname, "afl-clang-fast", 14) == 0) {
- // reset
- have_instr_list = 0;
- have_c = 0;
+ /* afl-clang-fast is always created there by makefile
+ just like afl-clang, burdened with special purposes:
+ - If llvm-config is not available (i.e. LLVM_MAJOR is 0),
+ or too old, it falls back to LLVM-NATIVE mode and let
+ the actual compiler complain if doesn't work.
+ - Otherwise try default llvm instruments except LTO.
+ */
+#if (LLVM_MAJOR >= 3)
+ aflcc->compiler_mode = LLVM;
+#else
+ aflcc->compiler_mode = CLANG;
+#endif
- if (lto_mode && argc > 1) {
+ } else
- u32 idx;
- for (idx = 1; idx < argc; idx++) {
+#if (LLVM_MAJOR >= 3)
- if (!strncasecmp(argv[idx], "-fpic", 5)) { have_pic = 1; }
+ if (strncmp(aflcc->callname, "afl-clang-lto", 13) == 0 ||
- }
+ strncmp(aflcc->callname, "afl-lto", 7) == 0) {
- }
+ aflcc->compiler_mode = LTO;
- // for (u32 x = 0; x < argc; ++x) fprintf(stderr, "[%u] %s\n", x, argv[x]);
+ } else
- /* Process the argument list. */
+#endif
- u8 skip_next = 0;
- while (--argc) {
+ if (strncmp(aflcc->callname, "afl-gcc-fast", 12) == 0 ||
- u8 *cur = *(++argv);
+ strncmp(aflcc->callname, "afl-g++-fast", 12) == 0) {
- if (skip_next) {
+ aflcc->compiler_mode = GCC_PLUGIN;
- skip_next = 0;
- continue;
+#if defined(__x86_64__)
- }
+ } else if (strncmp(aflcc->callname, "afl-gcc", 7) == 0 ||
- if (cur[0] != '-') { non_dash = 1; }
- if (!strncmp(cur, "--afl", 5)) continue;
+ strncmp(aflcc->callname, "afl-g++", 7) == 0) {
- if (lto_mode && !strncmp(cur, "-flto=thin", 10)) {
+ aflcc->compiler_mode = GCC;
- FATAL(
- "afl-clang-lto cannot work with -flto=thin. Switch to -flto=full or "
- "use afl-clang-fast!");
+#endif
- }
+#if defined(__x86_64__)
- if (lto_mode && !strncmp(cur, "-fuse-ld=", 9)) continue;
- if (lto_mode && !strncmp(cur, "--ld-path=", 10)) continue;
- if (!strncmp(cur, "-fno-unroll", 11)) continue;
- if (strstr(cur, "afl-compiler-rt") || strstr(cur, "afl-llvm-rt")) continue;
- if (!strcmp(cur, "-Wl,-z,defs") || !strcmp(cur, "-Wl,--no-undefined") ||
- !strcmp(cur, "--no-undefined")) {
+ } else if (strcmp(aflcc->callname, "afl-clang") == 0 ||
- continue;
+ strcmp(aflcc->callname, "afl-clang++") == 0) {
- }
+ aflcc->compiler_mode = CLANG;
+
+#endif
- if (compiler_mode == GCC_PLUGIN && !strcmp(cur, "-pipe")) { continue; }
+ }
- if (!strcmp(cur, "-z") || !strcmp(cur, "-Wl,-z")) {
+}
- u8 *param = *(argv + 1);
- if (!strcmp(param, "defs") || !strcmp(param, "-Wl,defs")) {
+void compiler_mode_by_environ(aflcc_state_t *aflcc) {
- skip_next = 1;
- continue;
+ if (getenv("AFL_PASSTHROUGH") || getenv("AFL_NOOPT")) {
- }
+ aflcc->passthrough = 1;
- }
+ }
- if ((compiler_mode == GCC || compiler_mode == GCC_PLUGIN) &&
- !strncmp(cur, "-stdlib=", 8)) {
+ char *ptr = getenv("AFL_CC_COMPILER");
- if (!be_quiet) { WARNF("Found '%s' - stripping!", cur); }
- continue;
+ if (!ptr) { return; }
- }
+ if (aflcc->compiler_mode) {
- if (!strncmp(cur, "-fsanitize-coverage-", 20) && strstr(cur, "list=")) {
+ if (!be_quiet) {
- have_instr_list = 1;
+ WARNF(
+ "\"AFL_CC_COMPILER\" is set but a specific compiler was already "
+ "selected by command line parameter or symlink, ignoring the "
+ "environment variable!");
}
- if (!strncmp(cur, "-fsanitize=", strlen("-fsanitize=")) &&
- strchr(cur, ',')) {
+ } else {
- parse_fsanitize(cur);
- if (!cur || strlen(cur) <= strlen("-fsanitize=")) { continue; }
+ if (strncasecmp(ptr, "LTO", 3) == 0) {
- } else if ((!strncmp(cur, "-fsanitize=fuzzer-",
+ aflcc->compiler_mode = LTO;
- strlen("-fsanitize=fuzzer-")) ||
- !strncmp(cur, "-fsanitize-coverage",
- strlen("-fsanitize-coverage"))) &&
- (strncmp(cur, "sanitize-coverage-allow",
- strlen("sanitize-coverage-allow")) &&
- strncmp(cur, "sanitize-coverage-deny",
- strlen("sanitize-coverage-deny")) &&
- instrument_mode != INSTRUMENT_LLVMNATIVE)) {
+ } else if (strncasecmp(ptr, "LLVM", 4) == 0) {
- if (!be_quiet) { WARNF("Found '%s' - stripping!", cur); }
- continue;
+ aflcc->compiler_mode = LLVM;
- }
+ } else if (strncasecmp(ptr, "GCC_P", 5) == 0 ||
- if (need_aflpplib || !strcmp(cur, "-fsanitize=fuzzer")) {
+ strncasecmp(ptr, "GCC-P", 5) == 0 ||
+ strncasecmp(ptr, "GCCP", 4) == 0) {
- u8 *afllib = find_object("libAFLDriver.a", argv[0]);
+ aflcc->compiler_mode = GCC_PLUGIN;
- if (!be_quiet) {
+#if defined(__x86_64__)
- OKF("Found '-fsanitize=fuzzer', replacing with libAFLDriver.a");
+ } else if (strcasecmp(ptr, "GCC") == 0) {
- }
+ aflcc->compiler_mode = GCC;
- if (!afllib) {
+#endif
- if (!be_quiet) {
+#if defined(__x86_64__)
- WARNF(
- "Cannot find 'libAFLDriver.a' to replace '-fsanitize=fuzzer' in "
- "the flags - this will fail!");
+ } else if (strcasecmp(ptr, "CLANG") == 0) {
- }
+ aflcc->compiler_mode = CLANG;
- } else {
-
- cc_params[cc_par_cnt++] = afllib;
-
-#ifdef __APPLE__
- cc_params[cc_par_cnt++] = "-undefined";
- cc_params[cc_par_cnt++] = "dynamic_lookup";
#endif
- }
+ } else
- if (need_aflpplib) {
+ FATAL("Unknown AFL_CC_COMPILER mode: %s\n", ptr);
- need_aflpplib = 0;
+ }
- } else {
+}
- continue;
+// If it can be inferred, instrument_mode would also be set
+void compiler_mode_by_cmdline(aflcc_state_t *aflcc, int argc, char **argv) {
- }
+ char *ptr = NULL;
- }
+ for (int i = 1; i < argc; i++) {
- if (!strcmp(cur, "-m32")) bit_mode = 32;
- if (!strcmp(cur, "armv7a-linux-androideabi")) bit_mode = 32;
- if (!strcmp(cur, "-m64")) bit_mode = 64;
+ if (strncmp(argv[i], "--afl", 5) == 0) {
- if (!strcmp(cur, "-fsanitize=address") || !strcmp(cur, "-fsanitize=memory"))
- asan_set = 1;
+ if (!strcmp(argv[i], "--afl_noopt") || !strcmp(argv[i], "--afl-noopt")) {
- if (strstr(cur, "FORTIFY_SOURCE")) fortify_set = 1;
+ aflcc->passthrough = 1;
+ argv[i] = "-g"; // we have to overwrite it, -g is always good
+ continue;
- if (!strcmp(cur, "-x")) x_set = 1;
- if (!strcmp(cur, "-E")) preprocessor_only = 1;
- if (!strcmp(cur, "-shared")) shared_linking = 1;
- if (!strcmp(cur, "-dynamiclib")) shared_linking = 1;
- if (!strcmp(cur, "--target=wasm32-wasi")) passthrough = 1;
- if (!strcmp(cur, "-Wl,-r")) partial_linking = 1;
- if (!strcmp(cur, "-Wl,-i")) partial_linking = 1;
- if (!strcmp(cur, "-Wl,--relocatable")) partial_linking = 1;
- if (!strcmp(cur, "-r")) partial_linking = 1;
- if (!strcmp(cur, "--relocatable")) partial_linking = 1;
- if (!strcmp(cur, "-c")) have_c = 1;
+ }
- if (!strncmp(cur, "-O", 2)) have_o = 1;
- if (!strncmp(cur, "-funroll-loop", 13)) have_unroll = 1;
+ if (aflcc->compiler_mode && !be_quiet) {
- if (*cur == '@') {
+ WARNF(
+ "--afl-... compiler mode supersedes the AFL_CC_COMPILER and "
+ "symlink compiler selection!");
- // response file support.
- // we have two choices - move everything to the command line or
- // rewrite the response files to temporary files and delete them
- // afterwards. We choose the first for easiness.
- // We do *not* support quotes in the rsp files to cope with spaces in
- // filenames etc! If you need that then send a patch!
- u8 *filename = cur + 1;
- if (debug) { DEBUGF("response file=%s\n", filename); }
- FILE *f = fopen(filename, "r");
- struct stat st;
+ }
- // Check not found or empty? let the compiler complain if so.
- if (!f || fstat(fileno(f), &st) < 0 || st.st_size < 1) {
+ ptr = argv[i];
+ ptr += 5;
+ while (*ptr == '-')
+ ptr++;
- cc_params[cc_par_cnt++] = cur;
- continue;
+ if (strncasecmp(ptr, "LTO", 3) == 0) {
- }
+ aflcc->compiler_mode = LTO;
- u8 *tmpbuf = malloc(st.st_size + 2), *ptr;
- char **args = malloc(sizeof(char *) * (st.st_size >> 1));
- int count = 1, cont = 0, cont_act = 0;
+ } else if (strncasecmp(ptr, "LLVM", 4) == 0) {
- while (fgets(tmpbuf, st.st_size + 1, f)) {
+ aflcc->compiler_mode = LLVM;
- ptr = tmpbuf;
- // fprintf(stderr, "1: %s\n", ptr);
- // no leading whitespace
- while (isspace(*ptr)) {
+ } else if (strncasecmp(ptr, "PCGUARD", 7) == 0 ||
- ++ptr;
- cont_act = 0;
+ strncasecmp(ptr, "PC-GUARD", 8) == 0) {
- }
+ aflcc->compiler_mode = LLVM;
+ aflcc->instrument_mode = INSTRUMENT_PCGUARD;
- // no comments, no empty lines
- if (*ptr == '#' || *ptr == '\n' || !*ptr) { continue; }
- // remove LF
- if (ptr[strlen(ptr) - 1] == '\n') { ptr[strlen(ptr) - 1] = 0; }
- // remove CR
- if (*ptr && ptr[strlen(ptr) - 1] == '\r') { ptr[strlen(ptr) - 1] = 0; }
- // handle \ at end of line
- if (*ptr && ptr[strlen(ptr) - 1] == '\\') {
+ } else if (strcasecmp(ptr, "INSTRIM") == 0 ||
- cont = 1;
- ptr[strlen(ptr) - 1] = 0;
+ strcasecmp(ptr, "CFG") == 0) {
- }
+ FATAL(
+ "InsTrim instrumentation was removed. Use a modern LLVM and "
+ "PCGUARD (default in afl-cc).\n");
- // fprintf(stderr, "2: %s\n", ptr);
+ } else if (strcasecmp(ptr, "AFL") == 0 ||
- // remove whitespace at end
- while (*ptr && isspace(ptr[strlen(ptr) - 1])) {
+ strcasecmp(ptr, "CLASSIC") == 0) {
- ptr[strlen(ptr) - 1] = 0;
- cont = 0;
+ aflcc->compiler_mode = LLVM;
+ aflcc->instrument_mode = INSTRUMENT_CLASSIC;
- }
+ } else if (strcasecmp(ptr, "LLVMNATIVE") == 0 ||
- // fprintf(stderr, "3: %s\n", ptr);
- if (*ptr) {
+ strcasecmp(ptr, "NATIVE") == 0 ||
+ strcasecmp(ptr, "LLVM-NATIVE") == 0) {
- do {
+ aflcc->compiler_mode = LLVM;
+ aflcc->instrument_mode = INSTRUMENT_LLVMNATIVE;
- u8 *value = ptr;
- while (*ptr && !isspace(*ptr)) {
+ } else if (strncasecmp(ptr, "GCC_P", 5) == 0 ||
- ++ptr;
+ strncasecmp(ptr, "GCC-P", 5) == 0 ||
+ strncasecmp(ptr, "GCCP", 4) == 0) {
- }
+ aflcc->compiler_mode = GCC_PLUGIN;
- while (*ptr && isspace(*ptr)) {
+#if defined(__x86_64__)
- *ptr++ = 0;
+ } else if (strcasecmp(ptr, "GCC") == 0) {
- }
+ aflcc->compiler_mode = GCC;
- if (cont_act) {
+#endif
- u32 len = strlen(args[count - 1]) + strlen(value) + 1;
- u8 *tmp = malloc(len);
- snprintf(tmp, len, "%s%s", args[count - 1], value);
- free(args[count - 1]);
- args[count - 1] = tmp;
- cont_act = 0;
+#if defined(__x86_64__)
- } else {
+ } else if (strncasecmp(ptr, "CLANG", 5) == 0) {
- args[count++] = strdup(value);
+ aflcc->compiler_mode = CLANG;
- }
+#endif
- } while (*ptr);
+ } else
- }
+ FATAL("Unknown --afl-... compiler mode: %s\n", argv[i]);
- if (cont) {
+ }
- cont_act = 1;
- cont = 0;
+ }
- }
+}
- }
+static void instrument_mode_old_environ(aflcc_state_t *aflcc) {
- if (count) { process_params(count, args); }
+ if (getenv("AFL_LLVM_INSTRIM") || getenv("INSTRIM") ||
+ getenv("INSTRIM_LIB")) {
- // we cannot free args[]
- free(tmpbuf);
+ FATAL(
+ "InsTrim instrumentation was removed. Use a modern LLVM and PCGUARD "
+ "(default in afl-cc).\n");
- continue;
+ }
- }
+ if (getenv("USE_TRACE_PC") || getenv("AFL_USE_TRACE_PC") ||
+ getenv("AFL_LLVM_USE_TRACE_PC") || getenv("AFL_TRACE_PC")) {
- cc_params[cc_par_cnt++] = cur;
+ if (aflcc->instrument_mode == 0)
+ aflcc->instrument_mode = INSTRUMENT_PCGUARD;
+ else if (aflcc->instrument_mode != INSTRUMENT_PCGUARD)
+ FATAL("you cannot set AFL_LLVM_INSTRUMENT and AFL_TRACE_PC together");
}
-}
-
-/* Copy argv to cc_params, making the necessary edits. */
+ if (getenv("AFL_LLVM_CTX")) aflcc->instrument_opt_mode |= INSTRUMENT_OPT_CTX;
+ if (getenv("AFL_LLVM_CALLER"))
+ aflcc->instrument_opt_mode |= INSTRUMENT_OPT_CALLER;
-static void edit_params(u32 argc, char **argv, char **envp) {
+ if (getenv("AFL_LLVM_NGRAM_SIZE")) {
- cc_params = ck_alloc(MAX_PARAMS_NUM * sizeof(u8 *));
+ aflcc->instrument_opt_mode |= INSTRUMENT_OPT_NGRAM;
+ aflcc->ngram_size = atoi(getenv("AFL_LLVM_NGRAM_SIZE"));
+ if (aflcc->ngram_size < 2 || aflcc->ngram_size > NGRAM_SIZE_MAX)
+ FATAL(
+ "NGRAM instrumentation mode must be between 2 and NGRAM_SIZE_MAX "
+ "(%u)",
+ NGRAM_SIZE_MAX);
- for (u32 c = 1; c < argc; ++c) {
+ }
- if (!strcmp(argv[c], "-c")) have_c = 1;
- if (!strncmp(argv[c], "-fsanitize-coverage-", 20) &&
- strstr(argv[c], "list=")) {
+ if (getenv("AFL_LLVM_CTX_K")) {
- have_instr_list = 1;
+ aflcc->ctx_k = atoi(getenv("AFL_LLVM_CTX_K"));
+ if (aflcc->ctx_k < 1 || aflcc->ctx_k > CTX_MAX_K)
+ FATAL("K-CTX instrumentation mode must be between 1 and CTX_MAX_K (%u)",
+ CTX_MAX_K);
+ if (aflcc->ctx_k == 1) {
- }
+ setenv("AFL_LLVM_CALLER", "1", 1);
+ unsetenv("AFL_LLVM_CTX_K");
+ aflcc->instrument_opt_mode |= INSTRUMENT_OPT_CALLER;
- }
+ } else {
- if (lto_mode) {
+ aflcc->instrument_opt_mode |= INSTRUMENT_OPT_CTX_K;
- if (lto_flag[0] != '-')
- FATAL(
- "Using afl-clang-lto is not possible because Makefile magic did not "
- "identify the correct -flto flag");
- else
- compiler_mode = LTO;
+ }
}
- if (plusplus_mode) {
+}
- u8 *alt_cxx = getenv("AFL_CXX");
+// compiler_mode would also be set if depended by the instrument_mode
+static void instrument_mode_new_environ(aflcc_state_t *aflcc) {
- if (!alt_cxx) {
+ if (!getenv("AFL_LLVM_INSTRUMENT")) { return; }
- if (compiler_mode >= GCC_PLUGIN) {
+ u8 *ptr2 = strtok(getenv("AFL_LLVM_INSTRUMENT"), ":,;");
- if (compiler_mode == GCC) {
+ while (ptr2) {
- alt_cxx = clang_mode ? "clang++" : "g++";
+ if (strncasecmp(ptr2, "afl", strlen("afl")) == 0 ||
+ strncasecmp(ptr2, "classic", strlen("classic")) == 0) {
- } else if (compiler_mode == CLANG) {
+ if (aflcc->instrument_mode == INSTRUMENT_LTO) {
- alt_cxx = "clang++";
+ aflcc->instrument_mode = INSTRUMENT_CLASSIC;
+ aflcc->lto_mode = 1;
- } else {
+ } else if (!aflcc->instrument_mode ||
- alt_cxx = "g++";
+ aflcc->instrument_mode == INSTRUMENT_AFL) {
- }
+ aflcc->instrument_mode = INSTRUMENT_AFL;
} else {
- if (USE_BINDIR)
- snprintf(llvm_fullpath, sizeof(llvm_fullpath), "%s/clang++",
- LLVM_BINDIR);
- else
- snprintf(llvm_fullpath, sizeof(llvm_fullpath), CLANGPP_BIN);
- alt_cxx = llvm_fullpath;
+ FATAL("main instrumentation mode already set with %s",
+ instrument_mode_2str(aflcc->instrument_mode));
}
}
- cc_params[0] = alt_cxx;
+ if (strncasecmp(ptr2, "pc-guard", strlen("pc-guard")) == 0 ||
+ strncasecmp(ptr2, "pcguard", strlen("pcguard")) == 0) {
- } else {
+ if (!aflcc->instrument_mode ||
+ aflcc->instrument_mode == INSTRUMENT_PCGUARD)
- u8 *alt_cc = getenv("AFL_CC");
+ aflcc->instrument_mode = INSTRUMENT_PCGUARD;
- if (!alt_cc) {
+ else
+ FATAL("main instrumentation mode already set with %s",
+ instrument_mode_2str(aflcc->instrument_mode));
+
+ }
- if (compiler_mode >= GCC_PLUGIN) {
+ if (strncasecmp(ptr2, "llvmnative", strlen("llvmnative")) == 0 ||
+ strncasecmp(ptr2, "llvm-native", strlen("llvm-native")) == 0 ||
+ strncasecmp(ptr2, "native", strlen("native")) == 0) {
- if (compiler_mode == GCC) {
+ if (!aflcc->instrument_mode ||
+ aflcc->instrument_mode == INSTRUMENT_LLVMNATIVE)
- alt_cc = clang_mode ? "clang" : "gcc";
+ aflcc->instrument_mode = INSTRUMENT_LLVMNATIVE;
- } else if (compiler_mode == CLANG) {
+ else
+ FATAL("main instrumentation mode already set with %s",
+ instrument_mode_2str(aflcc->instrument_mode));
- alt_cc = "clang";
+ }
- } else {
+ if (strncasecmp(ptr2, "llvmcodecov", strlen("llvmcodecov")) == 0 ||
+ strncasecmp(ptr2, "llvm-codecov", strlen("llvm-codecov")) == 0) {
- alt_cc = "gcc";
+ if (!aflcc->instrument_mode ||
+ aflcc->instrument_mode == INSTRUMENT_LLVMNATIVE) {
- }
+ aflcc->instrument_mode = INSTRUMENT_LLVMNATIVE;
+ aflcc->instrument_opt_mode |= INSTRUMENT_OPT_CODECOV;
} else {
- if (USE_BINDIR)
- snprintf(llvm_fullpath, sizeof(llvm_fullpath), "%s/clang",
- LLVM_BINDIR);
- else
- snprintf(llvm_fullpath, sizeof(llvm_fullpath), "%s", CLANG_BIN);
- alt_cc = llvm_fullpath;
+ FATAL("main instrumentation mode already set with %s",
+ instrument_mode_2str(aflcc->instrument_mode));
}
}
- cc_params[0] = alt_cc;
+ if (strncasecmp(ptr2, "cfg", strlen("cfg")) == 0 ||
+ strncasecmp(ptr2, "instrim", strlen("instrim")) == 0) {
- }
+ FATAL(
+ "InsTrim instrumentation was removed. Use a modern LLVM and "
+ "PCGUARD (default in afl-cc).\n");
+
+ }
- if (compiler_mode == GCC || compiler_mode == CLANG) {
+ if (strncasecmp(ptr2, "lto", strlen("lto")) == 0) {
- cc_params[cc_par_cnt++] = "-B";
- cc_params[cc_par_cnt++] = obj_path;
+ aflcc->lto_mode = 1;
+ if (!aflcc->instrument_mode || aflcc->instrument_mode == INSTRUMENT_LTO)
- if (clang_mode || compiler_mode == CLANG) {
+ aflcc->instrument_mode = INSTRUMENT_LTO;
- cc_params[cc_par_cnt++] = "-no-integrated-as";
+ else
+ FATAL("main instrumentation mode already set with %s",
+ instrument_mode_2str(aflcc->instrument_mode));
}
- }
+#if defined(__x86_64__)
+ if (strcasecmp(ptr2, "gcc") == 0) {
- if (compiler_mode == GCC_PLUGIN) {
+ if (!aflcc->instrument_mode || aflcc->instrument_mode == INSTRUMENT_GCC)
- char *fplugin_arg;
+ aflcc->instrument_mode = INSTRUMENT_GCC;
- if (cmplog_mode) {
+ else if (aflcc->instrument_mode != INSTRUMENT_GCC)
+ FATAL("main instrumentation mode already set with %s",
+ instrument_mode_2str(aflcc->instrument_mode));
- fplugin_arg =
- alloc_printf("-fplugin=%s/afl-gcc-cmplog-pass.so", obj_path);
- cc_params[cc_par_cnt++] = fplugin_arg;
- fplugin_arg =
- alloc_printf("-fplugin=%s/afl-gcc-cmptrs-pass.so", obj_path);
- cc_params[cc_par_cnt++] = fplugin_arg;
+ aflcc->compiler_mode = GCC;
}
- fplugin_arg = alloc_printf("-fplugin=%s/afl-gcc-pass.so", obj_path);
- cc_params[cc_par_cnt++] = fplugin_arg;
- cc_params[cc_par_cnt++] = "-fno-if-conversion";
- cc_params[cc_par_cnt++] = "-fno-if-conversion2";
+#endif
- }
+#if defined(__x86_64__)
+ if (strcasecmp(ptr2, "clang") == 0) {
- if (compiler_mode == LLVM || compiler_mode == LTO) {
+ if (!aflcc->instrument_mode || aflcc->instrument_mode == INSTRUMENT_CLANG)
- cc_params[cc_par_cnt++] = "-Wno-unused-command-line-argument";
+ aflcc->instrument_mode = INSTRUMENT_CLANG;
- if (lto_mode && have_instr_env) {
+ else if (aflcc->instrument_mode != INSTRUMENT_CLANG)
+ FATAL("main instrumentation mode already set with %s",
+ instrument_mode_2str(aflcc->instrument_mode));
-#if LLVM_MAJOR >= 11 /* use new pass manager */
- #if LLVM_MAJOR < 16
- cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
- #endif
- cc_params[cc_par_cnt++] = alloc_printf(
- "-fpass-plugin=%s/afl-llvm-lto-instrumentlist.so", obj_path);
-#else
- cc_params[cc_par_cnt++] = "-Xclang";
- cc_params[cc_par_cnt++] = "-load";
- cc_params[cc_par_cnt++] = "-Xclang";
- cc_params[cc_par_cnt++] =
- alloc_printf("%s/afl-llvm-lto-instrumentlist.so", obj_path);
-#endif
+ aflcc->compiler_mode = CLANG;
}
- if (getenv("AFL_LLVM_DICT2FILE")) {
-
-#if LLVM_MAJOR >= 11 /* use new pass manager */
- #if LLVM_MAJOR < 16
- cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
- #endif
- cc_params[cc_par_cnt++] =
- alloc_printf("-fpass-plugin=%s/afl-llvm-dict2file.so", obj_path);
-#else
- cc_params[cc_par_cnt++] = "-Xclang";
- cc_params[cc_par_cnt++] = "-load";
- cc_params[cc_par_cnt++] = "-Xclang";
- cc_params[cc_par_cnt++] =
- alloc_printf("%s/afl-llvm-dict2file.so", obj_path);
#endif
- }
+ if (strncasecmp(ptr2, "ctx-", strlen("ctx-")) == 0 ||
+ strncasecmp(ptr2, "kctx-", strlen("c-ctx-")) == 0 ||
+ strncasecmp(ptr2, "k-ctx-", strlen("k-ctx-")) == 0) {
- // laf
- if (getenv("LAF_SPLIT_SWITCHES") || getenv("AFL_LLVM_LAF_SPLIT_SWITCHES")) {
+ u8 *ptr3 = ptr2;
+ while (*ptr3 && (*ptr3 < '0' || *ptr3 > '9'))
+ ptr3++;
-#if LLVM_MAJOR >= 11 /* use new pass manager */
- #if LLVM_MAJOR < 16
- cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
- #endif
- cc_params[cc_par_cnt++] =
- alloc_printf("-fpass-plugin=%s/split-switches-pass.so", obj_path);
-#else
- cc_params[cc_par_cnt++] = "-Xclang";
- cc_params[cc_par_cnt++] = "-load";
- cc_params[cc_par_cnt++] = "-Xclang";
- cc_params[cc_par_cnt++] =
- alloc_printf("%s/split-switches-pass.so", obj_path);
-#endif
+ if (!*ptr3) {
- }
+ if ((ptr3 = getenv("AFL_LLVM_CTX_K")) == NULL)
+ FATAL(
+ "you must set the K-CTX K with (e.g. for value 2) "
+ "AFL_LLVM_INSTRUMENT=ctx-2");
- if (getenv("LAF_TRANSFORM_COMPARES") ||
- getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES")) {
+ }
-#if LLVM_MAJOR >= 11 /* use new pass manager */
- #if LLVM_MAJOR < 16
- cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
- #endif
- cc_params[cc_par_cnt++] =
- alloc_printf("-fpass-plugin=%s/compare-transform-pass.so", obj_path);
-#else
- cc_params[cc_par_cnt++] = "-Xclang";
- cc_params[cc_par_cnt++] = "-load";
- cc_params[cc_par_cnt++] = "-Xclang";
- cc_params[cc_par_cnt++] =
- alloc_printf("%s/compare-transform-pass.so", obj_path);
-#endif
+ aflcc->ctx_k = atoi(ptr3);
+ if (aflcc->ctx_k < 1 || aflcc->ctx_k > CTX_MAX_K)
+ FATAL(
+ "K-CTX instrumentation option must be between 1 and CTX_MAX_K "
+ "(%u)",
+ CTX_MAX_K);
- }
+ if (aflcc->ctx_k == 1) {
- if (getenv("LAF_SPLIT_COMPARES") || getenv("AFL_LLVM_LAF_SPLIT_COMPARES") ||
- getenv("AFL_LLVM_LAF_SPLIT_FLOATS")) {
+ aflcc->instrument_opt_mode |= INSTRUMENT_OPT_CALLER;
+ setenv("AFL_LLVM_CALLER", "1", 1);
+ unsetenv("AFL_LLVM_CTX_K");
-#if LLVM_MAJOR >= 11 /* use new pass manager */
- #if LLVM_MAJOR < 16
- cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
- #endif
- cc_params[cc_par_cnt++] =
- alloc_printf("-fpass-plugin=%s/split-compares-pass.so", obj_path);
-#else
- cc_params[cc_par_cnt++] = "-Xclang";
- cc_params[cc_par_cnt++] = "-load";
- cc_params[cc_par_cnt++] = "-Xclang";
- cc_params[cc_par_cnt++] =
- alloc_printf("%s/split-compares-pass.so", obj_path);
-#endif
+ } else {
- }
+ aflcc->instrument_opt_mode |= (INSTRUMENT_OPT_CTX_K);
+ u8 *ptr4 = alloc_printf("%u", aflcc->ctx_k);
+ setenv("AFL_LLVM_CTX_K", ptr4, 1);
- // /laf
+ }
- unsetenv("AFL_LD");
- unsetenv("AFL_LD_CALLER");
+ }
- if (cmplog_mode) {
+ if (strcasecmp(ptr2, "ctx") == 0) {
- cc_params[cc_par_cnt++] = "-fno-inline";
+ aflcc->instrument_opt_mode |= INSTRUMENT_OPT_CTX;
+ setenv("AFL_LLVM_CTX", "1", 1);
-#if LLVM_MAJOR >= 11 /* use new pass manager */
- #if LLVM_MAJOR < 16
- cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
- #endif
- cc_params[cc_par_cnt++] =
- alloc_printf("-fpass-plugin=%s/cmplog-switches-pass.so", obj_path);
- #if LLVM_MAJOR < 16
- cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
- #endif
- cc_params[cc_par_cnt++] =
- alloc_printf("-fpass-plugin=%s/split-switches-pass.so", obj_path);
-#else
- cc_params[cc_par_cnt++] = "-Xclang";
- cc_params[cc_par_cnt++] = "-load";
- cc_params[cc_par_cnt++] = "-Xclang";
- cc_params[cc_par_cnt++] =
- alloc_printf("%s/cmplog-switches-pass.so", obj_path);
+ }
- // reuse split switches from laf
- cc_params[cc_par_cnt++] = "-Xclang";
- cc_params[cc_par_cnt++] = "-load";
- cc_params[cc_par_cnt++] = "-Xclang";
- cc_params[cc_par_cnt++] =
- alloc_printf("%s/split-switches-pass.so", obj_path);
-#endif
+ if (strncasecmp(ptr2, "caller", strlen("caller")) == 0) {
+
+ aflcc->instrument_opt_mode |= INSTRUMENT_OPT_CALLER;
+ setenv("AFL_LLVM_CALLER", "1", 1);
}
- // #if LLVM_MAJOR >= 13
- // // Use the old pass manager in LLVM 14 which the AFL++ passes still
- // use. cc_params[cc_par_cnt++] = "-flegacy-pass-manager";
- // #endif
+ if (strncasecmp(ptr2, "ngram", strlen("ngram")) == 0) {
- if (lto_mode && !have_c) {
+ u8 *ptr3 = ptr2 + strlen("ngram");
+ while (*ptr3 && (*ptr3 < '0' || *ptr3 > '9')) {
- u8 *ld_path = NULL;
- if (getenv("AFL_REAL_LD")) {
+ ptr3++;
- ld_path = strdup(getenv("AFL_REAL_LD"));
+ }
- } else {
+ if (!*ptr3) {
- ld_path = strdup(AFL_REAL_LD);
+ if ((ptr3 = getenv("AFL_LLVM_NGRAM_SIZE")) == NULL)
+ FATAL(
+ "you must set the NGRAM size with (e.g. for value 2) "
+ "AFL_LLVM_INSTRUMENT=ngram-2");
}
- if (!ld_path || !*ld_path) {
+ aflcc->ngram_size = atoi(ptr3);
- if (ld_path) {
+ if (aflcc->ngram_size < 2 || aflcc->ngram_size > NGRAM_SIZE_MAX) {
- // Freeing empty string
- free(ld_path);
+ FATAL(
+ "NGRAM instrumentation option must be between 2 and "
+ "NGRAM_SIZE_MAX (%u)",
+ NGRAM_SIZE_MAX);
- }
+ }
- ld_path = strdup("ld.lld");
+ aflcc->instrument_opt_mode |= (INSTRUMENT_OPT_NGRAM);
+ u8 *ptr4 = alloc_printf("%u", aflcc->ngram_size);
+ setenv("AFL_LLVM_NGRAM_SIZE", ptr4, 1);
- }
+ }
- if (!ld_path) { PFATAL("Could not allocate mem for ld_path"); }
-#if defined(AFL_CLANG_LDPATH) && LLVM_MAJOR >= 12
- cc_params[cc_par_cnt++] = alloc_printf("--ld-path=%s", ld_path);
-#else
- cc_params[cc_par_cnt++] = alloc_printf("-fuse-ld=%s", ld_path);
-#endif
- free(ld_path);
+ ptr2 = strtok(NULL, ":,;");
-#if defined(AFL_CLANG_LDPATH) && LLVM_MAJOR >= 15
- // The NewPM implementation only works fully since LLVM 15.
- cc_params[cc_par_cnt++] = alloc_printf(
- "-Wl,--load-pass-plugin=%s/SanitizerCoverageLTO.so", obj_path);
-#elif defined(AFL_CLANG_LDPATH) && LLVM_MAJOR >= 13
- cc_params[cc_par_cnt++] = "-Wl,--lto-legacy-pass-manager";
- cc_params[cc_par_cnt++] =
- alloc_printf("-Wl,-mllvm=-load=%s/SanitizerCoverageLTO.so", obj_path);
-#else
- cc_params[cc_par_cnt++] = "-fno-experimental-new-pass-manager";
- cc_params[cc_par_cnt++] =
- alloc_printf("-Wl,-mllvm=-load=%s/SanitizerCoverageLTO.so", obj_path);
-#endif
-
- cc_params[cc_par_cnt++] = "-Wl,--allow-multiple-definition";
- cc_params[cc_par_cnt++] = lto_flag;
-
- } else {
-
- if (instrument_mode == INSTRUMENT_PCGUARD) {
-
-#if LLVM_MAJOR >= 13
- #if defined __ANDROID__ || ANDROID
- cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard";
- instrument_mode = INSTRUMENT_LLVMNATIVE;
- #else
- if (have_instr_list) {
-
- if (!be_quiet)
- SAYF(
- "Using unoptimized trace-pc-guard, due usage of "
- "-fsanitize-coverage-allow/denylist, you can use "
- "AFL_LLVM_ALLOWLIST/AFL_LLMV_DENYLIST instead.\n");
- cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard";
- instrument_mode = INSTRUMENT_LLVMNATIVE;
-
- } else {
-
- #if LLVM_MAJOR >= 13 /* use new pass manager */
- #if LLVM_MAJOR < 16
- cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
- #endif
- cc_params[cc_par_cnt++] = alloc_printf(
- "-fpass-plugin=%s/SanitizerCoveragePCGUARD.so", obj_path);
- #else
- cc_params[cc_par_cnt++] = "-Xclang";
- cc_params[cc_par_cnt++] = "-load";
- cc_params[cc_par_cnt++] = "-Xclang";
- cc_params[cc_par_cnt++] =
- alloc_printf("%s/SanitizerCoveragePCGUARD.so", obj_path);
- #endif
-
- }
-
- #endif
-#else
- #if LLVM_MAJOR >= 4
- if (!be_quiet)
- SAYF(
- "Using unoptimized trace-pc-guard, upgrade to LLVM 13+ for "
- "enhanced version.\n");
- cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard";
- instrument_mode = INSTRUMENT_LLVMNATIVE;
- #else
- FATAL("pcguard instrumentation requires LLVM 4.0.1+");
- #endif
-#endif
-
- } else if (instrument_mode == INSTRUMENT_LLVMNATIVE) {
-
-#if LLVM_MAJOR >= 4
- if (instrument_opt_mode & INSTRUMENT_OPT_CODECOV) {
-
- #if LLVM_MAJOR >= 6
- cc_params[cc_par_cnt++] =
- "-fsanitize-coverage=trace-pc-guard,bb,no-prune,pc-table";
- #else
- FATAL("pcguard instrumentation with pc-table requires LLVM 6.0.1+");
- #endif
+ }
- } else {
+}
- cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard";
+void instrument_mode_by_environ(aflcc_state_t *aflcc) {
- }
+ if (getenv("AFL_LLVM_INSTRUMENT_FILE") || getenv("AFL_LLVM_WHITELIST") ||
+ getenv("AFL_LLVM_ALLOWLIST") || getenv("AFL_LLVM_DENYLIST") ||
+ getenv("AFL_LLVM_BLOCKLIST")) {
-#else
- FATAL("pcguard instrumentation requires LLVM 4.0.1+");
-#endif
+ aflcc->have_instr_env = 1;
- } else {
+ }
-#if LLVM_MAJOR >= 11 /* use new pass manager */
- #if LLVM_MAJOR < 16
- cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
- #endif
- cc_params[cc_par_cnt++] =
- alloc_printf("-fpass-plugin=%s/afl-llvm-pass.so", obj_path);
-#else
+ if (aflcc->have_instr_env && getenv("AFL_DONT_OPTIMIZE") && !be_quiet) {
- cc_params[cc_par_cnt++] = "-Xclang";
- cc_params[cc_par_cnt++] = "-load";
- cc_params[cc_par_cnt++] = "-Xclang";
- cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-pass.so", obj_path);
-#endif
+ WARNF(
+ "AFL_LLVM_ALLOWLIST/DENYLIST and AFL_DONT_OPTIMIZE cannot be combined "
+ "for file matching, only function matching!");
- }
+ }
- }
+ instrument_mode_old_environ(aflcc);
+ instrument_mode_new_environ(aflcc);
- if (cmplog_mode) {
+}
-#if LLVM_MAJOR >= 11
- #if LLVM_MAJOR < 16
- cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
- #endif
- cc_params[cc_par_cnt++] = alloc_printf(
- "-fpass-plugin=%s/cmplog-instructions-pass.so", obj_path);
- #if LLVM_MAJOR < 16
- cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
- #endif
- cc_params[cc_par_cnt++] =
- alloc_printf("-fpass-plugin=%s/cmplog-routines-pass.so", obj_path);
-#else
- cc_params[cc_par_cnt++] = "-Xclang";
- cc_params[cc_par_cnt++] = "-load";
- cc_params[cc_par_cnt++] = "-Xclang";
- cc_params[cc_par_cnt++] =
- alloc_printf("%s/cmplog-instructions-pass.so", obj_path);
-
- cc_params[cc_par_cnt++] = "-Xclang";
- cc_params[cc_par_cnt++] = "-load";
- cc_params[cc_par_cnt++] = "-Xclang";
- cc_params[cc_par_cnt++] =
- alloc_printf("%s/cmplog-routines-pass.so", obj_path);
-#endif
+static void instrument_opt_mode_exclude(aflcc_state_t *aflcc) {
- }
+ if ((aflcc->instrument_opt_mode & INSTRUMENT_OPT_CTX) &&
+ (aflcc->instrument_opt_mode & INSTRUMENT_OPT_CALLER)) {
- if (getenv("AFL_LLVM_INJECTIONS_ALL") ||
- getenv("AFL_LLVM_INJECTIONS_SQL") ||
- getenv("AFL_LLVM_INJECTIONS_LDAP") ||
- getenv("AFL_LLVM_INJECTIONS_XSS")) {
+ FATAL("you cannot set CTX and CALLER together");
-#if LLVM_MAJOR >= 11
- #if LLVM_MAJOR < 16
- cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
- #endif
- cc_params[cc_par_cnt++] =
- alloc_printf("-fpass-plugin=%s/injection-pass.so", obj_path);
-#else
- cc_params[cc_par_cnt++] = "-Xclang";
- cc_params[cc_par_cnt++] = "-load";
- cc_params[cc_par_cnt++] = "-Xclang";
- cc_params[cc_par_cnt++] = alloc_printf("%s/injection-pass.so", obj_path);
-#endif
+ }
- }
+ if ((aflcc->instrument_opt_mode & INSTRUMENT_OPT_CTX) &&
+ (aflcc->instrument_opt_mode & INSTRUMENT_OPT_CTX_K)) {
- // cc_params[cc_par_cnt++] = "-Qunused-arguments";
+ FATAL("you cannot set CTX and K-CTX together");
}
- /* Inspect the command line parameters. */
+ if ((aflcc->instrument_opt_mode & INSTRUMENT_OPT_CALLER) &&
+ (aflcc->instrument_opt_mode & INSTRUMENT_OPT_CTX_K)) {
- process_params(argc, argv);
+ FATAL("you cannot set CALLER and K-CTX together");
- if (!have_pic) {
+ }
- cc_params[cc_par_cnt++] = "-fPIC";
- have_pic = 1;
+ if (aflcc->instrument_opt_mode && aflcc->compiler_mode != LLVM)
+ FATAL("CTX, CALLER and NGRAM can only be used in LLVM mode");
- }
+ if (aflcc->instrument_opt_mode &&
+ aflcc->instrument_opt_mode != INSTRUMENT_OPT_CODECOV &&
+ aflcc->instrument_mode != INSTRUMENT_CLASSIC)
+ FATAL(
+ "CALLER, CTX and NGRAM instrumentation options can only be used with "
+ "the LLVM CLASSIC instrumentation mode.");
- if (compiler_mode != GCC_PLUGIN && compiler_mode != GCC &&
- !getenv("AFL_LLVM_NO_RPATH")) {
+}
- // in case LLVM is installed not via a package manager or "make install"
- // e.g. compiled download or compiled from github then its ./lib directory
- // might not be in the search path. Add it if so.
- const char *libdir = LLVM_LIBDIR;
- if (plusplus_mode && strlen(libdir) && strncmp(libdir, "/usr", 4) &&
- strncmp(libdir, "/lib", 4)) {
+void mode_final_checkout(aflcc_state_t *aflcc, int argc, char **argv) {
- u8 *libdir_opt = strdup("-Wl,-rpath=" LLVM_LIBDIR);
- cc_params[cc_par_cnt++] = libdir_opt;
+ if (aflcc->instrument_opt_mode &&
+ aflcc->instrument_mode == INSTRUMENT_DEFAULT &&
+ (aflcc->compiler_mode == LLVM || aflcc->compiler_mode == UNSET)) {
- }
+ aflcc->instrument_mode = INSTRUMENT_CLASSIC;
+ aflcc->compiler_mode = LLVM;
}
- if (getenv("AFL_HARDEN")) {
-
- cc_params[cc_par_cnt++] = "-fstack-protector-all";
+ if (!aflcc->compiler_mode) {
- if (!fortify_set) cc_params[cc_par_cnt++] = "-D_FORTIFY_SOURCE=2";
+ // lto is not a default because outside of afl-cc RANLIB and AR have to
+ // be set to LLVM versions so this would work
+ if (aflcc->have_llvm)
+ aflcc->compiler_mode = LLVM;
+ else if (aflcc->have_gcc_plugin)
+ aflcc->compiler_mode = GCC_PLUGIN;
+ else if (aflcc->have_gcc)
+ aflcc->compiler_mode = GCC;
+ else if (aflcc->have_clang)
+ aflcc->compiler_mode = CLANG;
+ else if (aflcc->have_lto)
+ aflcc->compiler_mode = LTO;
+ else
+ FATAL("no compiler mode available");
}
- if (!asan_set) {
+ switch (aflcc->compiler_mode) {
- if (getenv("AFL_USE_ASAN")) {
+ case GCC:
+ if (!aflcc->have_gcc) FATAL("afl-gcc not available on your platform!");
+ break;
+ case CLANG:
+ if (!aflcc->have_clang)
+ FATAL("afl-clang not available on your platform!");
+ break;
+ case LLVM:
+ if (!aflcc->have_llvm)
+ FATAL(
+ "LLVM mode is not available, please install LLVM 13+ and recompile "
+ "AFL++");
+ break;
+ case GCC_PLUGIN:
+ if (!aflcc->have_gcc_plugin)
+ FATAL(
+ "GCC_PLUGIN mode is not available, install gcc plugin support and "
+ "recompile AFL++");
+ break;
+ case LTO:
+ if (!aflcc->have_lto)
+ FATAL(
+ "LTO mode is not available, please install LLVM 13+ and lld of the "
+ "same version and recompile AFL++");
+ break;
+ default:
+ FATAL("no compiler mode available");
- if (getenv("AFL_USE_MSAN")) FATAL("ASAN and MSAN are mutually exclusive");
+ }
- if (getenv("AFL_HARDEN"))
- FATAL("ASAN and AFL_HARDEN are mutually exclusive");
+ if (aflcc->compiler_mode == GCC) { aflcc->instrument_mode = INSTRUMENT_GCC; }
- cc_params[cc_par_cnt++] = "-U_FORTIFY_SOURCE";
- cc_params[cc_par_cnt++] = "-fsanitize=address";
+ if (aflcc->compiler_mode == CLANG) {
- } else if (getenv("AFL_USE_MSAN")) {
+ /* if our PCGUARD implementation is not available then silently switch to
+ native LLVM PCGUARD. Or classic asm instrument is explicitly preferred. */
+ if (!aflcc->have_optimized_pcguard &&
+ (aflcc->instrument_mode == INSTRUMENT_DEFAULT ||
+ aflcc->instrument_mode == INSTRUMENT_PCGUARD)) {
- if (getenv("AFL_USE_ASAN")) FATAL("ASAN and MSAN are mutually exclusive");
+ aflcc->instrument_mode = INSTRUMENT_LLVMNATIVE;
- if (getenv("AFL_HARDEN"))
- FATAL("MSAN and AFL_HARDEN are mutually exclusive");
+ } else {
- cc_params[cc_par_cnt++] = "-U_FORTIFY_SOURCE";
- cc_params[cc_par_cnt++] = "-fsanitize=memory";
+ aflcc->instrument_mode = INSTRUMENT_CLANG;
+ setenv(CLANG_ENV_VAR, "1", 1); // used by afl-as
}
}
- if (getenv("AFL_USE_UBSAN")) {
+ if (aflcc->compiler_mode == LTO) {
- cc_params[cc_par_cnt++] = "-fsanitize=undefined";
- cc_params[cc_par_cnt++] = "-fsanitize-undefined-trap-on-error";
- cc_params[cc_par_cnt++] = "-fno-sanitize-recover=all";
- cc_params[cc_par_cnt++] = "-fno-omit-frame-pointer";
+ if (aflcc->instrument_mode == 0 ||
+ aflcc->instrument_mode == INSTRUMENT_LTO ||
+ aflcc->instrument_mode == INSTRUMENT_CFG ||
+ aflcc->instrument_mode == INSTRUMENT_PCGUARD) {
- }
+ aflcc->lto_mode = 1;
+ // force CFG
+ // if (!aflcc->instrument_mode) {
- if (getenv("AFL_USE_TSAN")) {
+ aflcc->instrument_mode = INSTRUMENT_PCGUARD;
- cc_params[cc_par_cnt++] = "-fsanitize=thread";
- cc_params[cc_par_cnt++] = "-fno-omit-frame-pointer";
+ // }
- }
+ } else if (aflcc->instrument_mode == INSTRUMENT_CLASSIC) {
- if (getenv("AFL_USE_LSAN")) {
+ aflcc->lto_mode = 1;
- cc_params[cc_par_cnt++] = "-fsanitize=leak";
- cc_params[cc_par_cnt++] = "-includesanitizer/lsan_interface.h";
- cc_params[cc_par_cnt++] =
- "-D__AFL_LEAK_CHECK()={if(__lsan_do_recoverable_leak_check() > 0) "
- "_exit(23); }";
- cc_params[cc_par_cnt++] = "-D__AFL_LSAN_OFF()=__lsan_disable();";
- cc_params[cc_par_cnt++] = "-D__AFL_LSAN_ON()=__lsan_enable();";
+ } else {
- }
+ if (!be_quiet) {
- if (getenv("AFL_USE_CFISAN")) {
+ WARNF("afl-clang-lto called with mode %s, using that mode instead",
+ instrument_mode_2str(aflcc->instrument_mode));
- if (compiler_mode == GCC_PLUGIN || compiler_mode == GCC) {
+ }
- cc_params[cc_par_cnt++] = "-fcf-protection=full";
+ }
- } else {
+ }
- if (!lto_mode) {
+ if (aflcc->instrument_mode == 0 && aflcc->compiler_mode < GCC_PLUGIN) {
- uint32_t i = 0, found = 0;
- while (envp[i] != NULL && !found)
- if (strncmp("-flto", envp[i++], 5) == 0) found = 1;
- if (!found) cc_params[cc_par_cnt++] = "-flto";
+#if LLVM_MAJOR >= 7
+ #if LLVM_MAJOR < 11 && (LLVM_MAJOR < 10 || LLVM_MINOR < 1)
+ if (aflcc->have_instr_env) {
- }
+ aflcc->instrument_mode = INSTRUMENT_AFL;
+ if (!be_quiet) {
- cc_params[cc_par_cnt++] = "-fsanitize=cfi";
- cc_params[cc_par_cnt++] = "-fvisibility=hidden";
+ WARNF(
+ "Switching to classic instrumentation because "
+ "AFL_LLVM_ALLOWLIST/DENYLIST does not work with PCGUARD < 10.0.1.");
- }
+ }
- }
+ } else
- if (!getenv("AFL_DONT_OPTIMIZE")) {
+ #endif
+ aflcc->instrument_mode = INSTRUMENT_PCGUARD;
- cc_params[cc_par_cnt++] = "-g";
- if (!have_o) cc_params[cc_par_cnt++] = "-O3";
- if (!have_unroll) cc_params[cc_par_cnt++] = "-funroll-loops";
- // if (strlen(march_opt) > 1 && march_opt[0] == '-')
- // cc_params[cc_par_cnt++] = march_opt;
+#else
+ aflcc->instrument_mode = INSTRUMENT_AFL;
+#endif
}
- if (getenv("AFL_NO_BUILTIN") || getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES") ||
- getenv("LAF_TRANSFORM_COMPARES") || getenv("AFL_LLVM_LAF_ALL") ||
- lto_mode) {
+ if (!aflcc->instrument_opt_mode && aflcc->lto_mode &&
+ aflcc->instrument_mode == INSTRUMENT_CFG) {
- cc_params[cc_par_cnt++] = "-fno-builtin-strcmp";
- cc_params[cc_par_cnt++] = "-fno-builtin-strncmp";
- cc_params[cc_par_cnt++] = "-fno-builtin-strcasecmp";
- cc_params[cc_par_cnt++] = "-fno-builtin-strncasecmp";
- cc_params[cc_par_cnt++] = "-fno-builtin-memcmp";
- cc_params[cc_par_cnt++] = "-fno-builtin-bcmp";
- cc_params[cc_par_cnt++] = "-fno-builtin-strstr";
- cc_params[cc_par_cnt++] = "-fno-builtin-strcasestr";
+ aflcc->instrument_mode = INSTRUMENT_PCGUARD;
}
-#if defined(USEMMAP) && !defined(__HAIKU__) && !__APPLE__
- if (!have_c) cc_params[cc_par_cnt++] = "-lrt";
+#ifndef AFL_CLANG_FLTO
+ if (aflcc->lto_mode)
+ FATAL(
+ "instrumentation mode LTO specified but LLVM support not available "
+ "(requires LLVM 11 or higher)");
#endif
- cc_params[cc_par_cnt++] = "-D__AFL_COMPILER=1";
- cc_params[cc_par_cnt++] = "-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION=1";
+ if (aflcc->lto_mode) {
- /* As documented in instrumentation/README.persistent_mode.md, deferred
- forkserver initialization and persistent mode are not available in afl-gcc
- and afl-clang. */
- if (compiler_mode != GCC && compiler_mode != CLANG) {
+ if (aflcc->lto_flag[0] != '-')
+ FATAL(
+ "Using afl-clang-lto is not possible because Makefile magic did not "
+ "identify the correct -flto flag");
+ else
+ aflcc->compiler_mode = LTO;
- cc_params[cc_par_cnt++] = "-D__AFL_HAVE_MANUAL_CONTROL=1";
+ }
- /* When the user tries to use persistent or deferred forkserver modes by
- appending a single line to the program, we want to reliably inject a
- signature into the binary (to be picked up by afl-fuzz) and we want
- to call a function from the runtime .o file. This is unnecessarily
- painful for three reasons:
+ if (getenv("AFL_LLVM_SKIP_NEVERZERO") && getenv("AFL_LLVM_NOT_ZERO"))
+ FATAL(
+ "AFL_LLVM_NOT_ZERO and AFL_LLVM_SKIP_NEVERZERO can not be set "
+ "together");
- 1) We need to convince the compiler not to optimize out the signature.
- This is done with __attribute__((used)).
+#if LLVM_MAJOR < 11 && (LLVM_MAJOR < 10 || LLVM_MINOR < 1)
- 2) We need to convince the linker, when called with -Wl,--gc-sections,
- not to do the same. This is done by forcing an assignment to a
- 'volatile' pointer.
+ if (aflcc->instrument_mode == INSTRUMENT_PCGUARD && aflcc->have_instr_env) {
- 3) We need to declare __afl_persistent_loop() in the global namespace,
- but doing this within a method in a class is hard - :: and extern "C"
- are forbidden and __attribute__((alias(...))) doesn't work. Hence the
- __asm__ aliasing trick.
+ FATAL(
+ "Instrumentation type PCGUARD does not support "
+ "AFL_LLVM_ALLOWLIST/DENYLIST! Use LLVM 10.0.1+ instead.");
- */
+ }
- cc_params[cc_par_cnt++] =
- "-D__AFL_FUZZ_INIT()="
- "int __afl_sharedmem_fuzzing = 1;"
- "extern unsigned int *__afl_fuzz_len;"
- "extern unsigned char *__afl_fuzz_ptr;"
- "unsigned char __afl_fuzz_alt[1048576];"
- "unsigned char *__afl_fuzz_alt_ptr = __afl_fuzz_alt;";
+#endif
- }
+ instrument_opt_mode_exclude(aflcc);
- if (plusplus_mode) {
+ u8 *ptr2;
- cc_params[cc_par_cnt++] =
- "-D__AFL_COVERAGE()=int __afl_selective_coverage = 1;"
- "extern \"C\" void __afl_coverage_discard();"
- "extern \"C\" void __afl_coverage_skip();"
- "extern \"C\" void __afl_coverage_on();"
- "extern \"C\" void __afl_coverage_off();";
+ if ((ptr2 = getenv("AFL_LLVM_DICT2FILE")) != NULL && *ptr2 != '/')
+ FATAL("AFL_LLVM_DICT2FILE must be set to an absolute file path");
- } else {
+ if (getenv("AFL_LLVM_LAF_ALL")) {
- cc_params[cc_par_cnt++] =
- "-D__AFL_COVERAGE()=int __afl_selective_coverage = 1;"
- "void __afl_coverage_discard();"
- "void __afl_coverage_skip();"
- "void __afl_coverage_on();"
- "void __afl_coverage_off();";
+ setenv("AFL_LLVM_LAF_SPLIT_SWITCHES", "1", 1);
+ setenv("AFL_LLVM_LAF_SPLIT_COMPARES", "1", 1);
+ setenv("AFL_LLVM_LAF_SPLIT_FLOATS", "1", 1);
+ setenv("AFL_LLVM_LAF_TRANSFORM_COMPARES", "1", 1);
}
- cc_params[cc_par_cnt++] =
- "-D__AFL_COVERAGE_START_OFF()=int __afl_selective_coverage_start_off = "
- "1;";
- cc_params[cc_par_cnt++] = "-D__AFL_COVERAGE_ON()=__afl_coverage_on()";
- cc_params[cc_par_cnt++] = "-D__AFL_COVERAGE_OFF()=__afl_coverage_off()";
- cc_params[cc_par_cnt++] =
- "-D__AFL_COVERAGE_DISCARD()=__afl_coverage_discard()";
- cc_params[cc_par_cnt++] = "-D__AFL_COVERAGE_SKIP()=__afl_coverage_skip()";
- cc_params[cc_par_cnt++] =
- "-D__AFL_FUZZ_TESTCASE_BUF=(__afl_fuzz_ptr ? __afl_fuzz_ptr : "
- "__afl_fuzz_alt_ptr)";
- cc_params[cc_par_cnt++] =
- "-D__AFL_FUZZ_TESTCASE_LEN=(__afl_fuzz_ptr ? *__afl_fuzz_len : "
- "(*__afl_fuzz_len = read(0, __afl_fuzz_alt_ptr, 1048576)) == 0xffffffff "
- "? 0 : *__afl_fuzz_len)";
+ aflcc->cmplog_mode = getenv("AFL_CMPLOG") || getenv("AFL_LLVM_CMPLOG") ||
+ getenv("AFL_GCC_CMPLOG");
- if (compiler_mode != GCC && compiler_mode != CLANG) {
+}
- cc_params[cc_par_cnt++] =
- "-D__AFL_LOOP(_A)="
- "({ static volatile const char *_B __attribute__((used,unused)); "
- " _B = (const char*)\"" PERSIST_SIG
- "\"; "
- "extern int __afl_connected;"
-#ifdef __APPLE__
- "__attribute__((visibility(\"default\"))) "
- "int _L(unsigned int) __asm__(\"___afl_persistent_loop\"); "
-#else
- "__attribute__((visibility(\"default\"))) "
- "int _L(unsigned int) __asm__(\"__afl_persistent_loop\"); "
-#endif /* ^__APPLE__ */
- // if afl is connected, we run _A times, else once.
- "_L(__afl_connected ? _A : 1); })";
-
- cc_params[cc_par_cnt++] =
- "-D__AFL_INIT()="
- "do { static volatile const char *_A __attribute__((used,unused)); "
- " _A = (const char*)\"" DEFER_SIG
- "\"; "
-#ifdef __APPLE__
- "__attribute__((visibility(\"default\"))) "
- "void _I(void) __asm__(\"___afl_manual_init\"); "
-#else
- "__attribute__((visibility(\"default\"))) "
- "void _I(void) __asm__(\"__afl_manual_init\"); "
-#endif /* ^__APPLE__ */
- "_I(); } while (0)";
+void mode_notification(aflcc_state_t *aflcc) {
- }
+ char *ptr2 = alloc_printf(" + NGRAM-%u", aflcc->ngram_size);
+ char *ptr3 = alloc_printf(" + K-CTX-%u", aflcc->ctx_k);
+
+ char *ptr1 = alloc_printf(
+ "%s%s%s%s%s", instrument_mode_2str(aflcc->instrument_mode),
+ (aflcc->instrument_opt_mode & INSTRUMENT_OPT_CTX) ? " + CTX" : "",
+ (aflcc->instrument_opt_mode & INSTRUMENT_OPT_CALLER) ? " + CALLER" : "",
+ (aflcc->instrument_opt_mode & INSTRUMENT_OPT_NGRAM) ? ptr2 : "",
+ (aflcc->instrument_opt_mode & INSTRUMENT_OPT_CTX_K) ? ptr3 : "");
- if (x_set) {
+ ck_free(ptr2);
+ ck_free(ptr3);
- cc_params[cc_par_cnt++] = "-x";
- cc_params[cc_par_cnt++] = "none";
+ if ((isatty(2) && !be_quiet) || aflcc->debug) {
+
+ SAYF(cCYA
+ "afl-cc" VERSION cRST
+ " by Michal Zalewski, Laszlo Szekeres, Marc Heuse - mode: %s-%s\n",
+ compiler_mode_2str(aflcc->compiler_mode), ptr1);
}
- // prevent unnecessary build errors
- if (compiler_mode != GCC_PLUGIN && compiler_mode != GCC) {
+ ck_free(ptr1);
+
+ if (!be_quiet &&
+ (aflcc->compiler_mode == GCC || aflcc->compiler_mode == CLANG)) {
- cc_params[cc_par_cnt++] = "-Wno-unused-command-line-argument";
+ WARNF(
+ "You are using outdated instrumentation, install LLVM and/or "
+ "gcc-plugin and use afl-clang-fast/afl-clang-lto/afl-gcc-fast "
+ "instead!");
}
- if (preprocessor_only || have_c || !non_dash) {
+}
- /* In the preprocessor_only case (-E), we are not actually compiling at
- all but requesting the compiler to output preprocessed sources only.
- We must not add the runtime in this case because the compiler will
- simply output its binary content back on stdout, breaking any build
- systems that rely on a separate source preprocessing step. */
- cc_params[cc_par_cnt] = NULL;
- return;
+void add_real_argv0(aflcc_state_t *aflcc) {
- }
+ static u8 llvm_fullpath[PATH_MAX];
-#ifndef __ANDROID__
+ if (aflcc->plusplus_mode) {
- if (compiler_mode != GCC && compiler_mode != CLANG) {
+ u8 *alt_cxx = getenv("AFL_CXX");
- switch (bit_mode) {
+ if (!alt_cxx) {
- case 0:
- if (!shared_linking && !partial_linking)
- cc_params[cc_par_cnt++] =
- alloc_printf("%s/afl-compiler-rt.o", obj_path);
- if (lto_mode)
- cc_params[cc_par_cnt++] =
- alloc_printf("%s/afl-llvm-rt-lto.o", obj_path);
- break;
+ if (aflcc->compiler_mode == GCC || aflcc->compiler_mode == GCC_PLUGIN) {
- case 32:
- if (!shared_linking && !partial_linking) {
+ alt_cxx = "g++";
- cc_params[cc_par_cnt++] =
- alloc_printf("%s/afl-compiler-rt-32.o", obj_path);
- if (access(cc_params[cc_par_cnt - 1], R_OK))
- FATAL("-m32 is not supported by your compiler");
+ } else if (aflcc->compiler_mode == CLANG) {
- }
+ alt_cxx = "clang++";
- if (lto_mode) {
+ } else {
- cc_params[cc_par_cnt++] =
- alloc_printf("%s/afl-llvm-rt-lto-32.o", obj_path);
- if (access(cc_params[cc_par_cnt - 1], R_OK))
- FATAL("-m32 is not supported by your compiler");
+ if (USE_BINDIR)
+ snprintf(llvm_fullpath, sizeof(llvm_fullpath), "%s/clang++",
+ LLVM_BINDIR);
+ else
+ snprintf(llvm_fullpath, sizeof(llvm_fullpath), CLANGPP_BIN);
+ alt_cxx = llvm_fullpath;
- }
+ }
- break;
+ }
- case 64:
- if (!shared_linking && !partial_linking) {
+ aflcc->cc_params[0] = alt_cxx;
- cc_params[cc_par_cnt++] =
- alloc_printf("%s/afl-compiler-rt-64.o", obj_path);
- if (access(cc_params[cc_par_cnt - 1], R_OK))
- FATAL("-m64 is not supported by your compiler");
+ } else {
- }
+ u8 *alt_cc = getenv("AFL_CC");
- if (lto_mode) {
+ if (!alt_cc) {
- cc_params[cc_par_cnt++] =
- alloc_printf("%s/afl-llvm-rt-lto-64.o", obj_path);
- if (access(cc_params[cc_par_cnt - 1], R_OK))
- FATAL("-m64 is not supported by your compiler");
+ if (aflcc->compiler_mode == GCC || aflcc->compiler_mode == GCC_PLUGIN) {
- }
+ alt_cc = "gcc";
- break;
+ } else if (aflcc->compiler_mode == CLANG) {
- }
+ alt_cc = "clang";
- #if !defined(__APPLE__) && !defined(__sun)
- if (!shared_linking && !partial_linking)
- cc_params[cc_par_cnt++] =
- alloc_printf("-Wl,--dynamic-list=%s/dynamic_list.txt", obj_path);
- #endif
+ } else {
- #if defined(__APPLE__)
- if (shared_linking || partial_linking) {
+ if (USE_BINDIR)
+ snprintf(llvm_fullpath, sizeof(llvm_fullpath), "%s/clang",
+ LLVM_BINDIR);
+ else
+ snprintf(llvm_fullpath, sizeof(llvm_fullpath), CLANG_BIN);
+ alt_cc = llvm_fullpath;
- cc_params[cc_par_cnt++] = "-Wl,-U";
- cc_params[cc_par_cnt++] = "-Wl,___afl_area_ptr";
- cc_params[cc_par_cnt++] = "-Wl,-U";
- cc_params[cc_par_cnt++] = "-Wl,___sanitizer_cov_trace_pc_guard_init";
+ }
}
- #endif
+ aflcc->cc_params[0] = alt_cc;
}
- #if defined(USEMMAP) && !defined(__HAIKU__) && !__APPLE__
- cc_params[cc_par_cnt++] = "-lrt";
- #endif
+}
-#endif
+/* Macro defs for the preprocessor */
- cc_params[cc_par_cnt] = NULL;
+void add_defs_common(aflcc_state_t *aflcc) {
+
+ insert_param(aflcc, "-D__AFL_COMPILER=1");
+ insert_param(aflcc, "-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION=1");
}
-/* Main entry point */
+/* See instrumentation/README.instrument_list.md#
+ 2-selective-instrumentation-with-_afl_coverage-directives */
+void add_defs_selective_instr(aflcc_state_t *aflcc) {
-int main(int argc, char **argv, char **envp) {
+ if (aflcc->plusplus_mode) {
- int i;
- char *callname = argv[0], *ptr = NULL;
+ insert_param(aflcc,
+ "-D__AFL_COVERAGE()=int __afl_selective_coverage = 1;"
+ "extern \"C\" void __afl_coverage_discard();"
+ "extern \"C\" void __afl_coverage_skip();"
+ "extern \"C\" void __afl_coverage_on();"
+ "extern \"C\" void __afl_coverage_off();");
- if (getenv("AFL_DEBUG")) {
+ } else {
- debug = 1;
- if (strcmp(getenv("AFL_DEBUG"), "0") == 0) unsetenv("AFL_DEBUG");
+ insert_param(aflcc,
+ "-D__AFL_COVERAGE()=int __afl_selective_coverage = 1;"
+ "void __afl_coverage_discard();"
+ "void __afl_coverage_skip();"
+ "void __afl_coverage_on();"
+ "void __afl_coverage_off();");
- } else if (getenv("AFL_QUIET"))
+ }
- be_quiet = 1;
+ insert_param(
+ aflcc,
+ "-D__AFL_COVERAGE_START_OFF()=int __afl_selective_coverage_start_off = "
+ "1;");
+ insert_param(aflcc, "-D__AFL_COVERAGE_ON()=__afl_coverage_on()");
+ insert_param(aflcc, "-D__AFL_COVERAGE_OFF()=__afl_coverage_off()");
+ insert_param(aflcc, "-D__AFL_COVERAGE_DISCARD()=__afl_coverage_discard()");
+ insert_param(aflcc, "-D__AFL_COVERAGE_SKIP()=__afl_coverage_skip()");
- if (getenv("AFL_LLVM_INSTRUMENT_FILE") || getenv("AFL_LLVM_WHITELIST") ||
- getenv("AFL_LLVM_ALLOWLIST") || getenv("AFL_LLVM_DENYLIST") ||
- getenv("AFL_LLVM_BLOCKLIST")) {
+}
- have_instr_env = 1;
+/* As documented in instrumentation/README.persistent_mode.md, deferred
+ forkserver initialization and persistent mode are not available in afl-gcc
+ and afl-clang. */
+void add_defs_persistent_mode(aflcc_state_t *aflcc) {
- }
+ if (aflcc->compiler_mode == GCC || aflcc->compiler_mode == CLANG) return;
- if (getenv("AFL_PASSTHROUGH") || getenv("AFL_NOOPT")) {
+ insert_param(aflcc, "-D__AFL_HAVE_MANUAL_CONTROL=1");
- passthrough = 1;
- if (!debug) { be_quiet = 1; }
+ /* When the user tries to use persistent or deferred forkserver modes by
+ appending a single line to the program, we want to reliably inject a
+ signature into the binary (to be picked up by afl-fuzz) and we want
+ to call a function from the runtime .o file. This is unnecessarily
+ painful for three reasons:
- }
+ 1) We need to convince the compiler not to optimize out the signature.
+ This is done with __attribute__((used)).
- if ((ptr = strrchr(callname, '/')) != NULL) callname = ptr + 1;
- argvnull = (u8 *)argv[0];
- check_environment_vars(envp);
+ 2) We need to convince the linker, when called with -Wl,--gc-sections,
+ not to do the same. This is done by forcing an assignment to a
+ 'volatile' pointer.
- if ((ptr = find_object("as", argv[0])) != NULL) {
+ 3) We need to declare __afl_persistent_loop() in the global namespace,
+ but doing this within a method in a class is hard - :: and extern "C"
+ are forbidden and __attribute__((alias(...))) doesn't work. Hence the
+ __asm__ aliasing trick.
- have_gcc = 1;
- ck_free(ptr);
+ */
- }
+ insert_param(aflcc,
+ "-D__AFL_FUZZ_INIT()="
+ "int __afl_sharedmem_fuzzing = 1;"
+ "extern unsigned int *__afl_fuzz_len;"
+ "extern unsigned char *__afl_fuzz_ptr;"
+ "unsigned char __afl_fuzz_alt[1048576];"
+ "unsigned char *__afl_fuzz_alt_ptr = __afl_fuzz_alt;");
-#if (LLVM_MAJOR >= 3)
+ insert_param(aflcc,
+ "-D__AFL_FUZZ_TESTCASE_BUF=(__afl_fuzz_ptr ? __afl_fuzz_ptr : "
+ "__afl_fuzz_alt_ptr)");
- if ((ptr = find_object("SanitizerCoverageLTO.so", argv[0])) != NULL) {
+ insert_param(
+ aflcc,
+ "-D__AFL_FUZZ_TESTCASE_LEN=(__afl_fuzz_ptr ? *__afl_fuzz_len : "
+ "(*__afl_fuzz_len = read(0, __afl_fuzz_alt_ptr, 1048576)) == 0xffffffff "
+ "? 0 : *__afl_fuzz_len)");
+
+ insert_param(
+ aflcc,
+ "-D__AFL_LOOP(_A)="
+ "({ static volatile const char *_B __attribute__((used,unused)); "
+ " _B = (const char*)\"" PERSIST_SIG
+ "\"; "
+ "extern int __afl_connected;"
+#ifdef __APPLE__
+ "__attribute__((visibility(\"default\"))) "
+ "int _L(unsigned int) __asm__(\"___afl_persistent_loop\"); "
+#else
+ "__attribute__((visibility(\"default\"))) "
+ "int _L(unsigned int) __asm__(\"__afl_persistent_loop\"); "
+#endif /* ^__APPLE__ */
+ // if afl is connected, we run _A times, else once.
+ "_L(__afl_connected ? _A : 1); })");
+
+ insert_param(
+ aflcc,
+ "-D__AFL_INIT()="
+ "do { static volatile const char *_A __attribute__((used,unused)); "
+ " _A = (const char*)\"" DEFER_SIG
+ "\"; "
+#ifdef __APPLE__
+ "__attribute__((visibility(\"default\"))) "
+ "void _I(void) __asm__(\"___afl_manual_init\"); "
+#else
+ "__attribute__((visibility(\"default\"))) "
+ "void _I(void) __asm__(\"__afl_manual_init\"); "
+#endif /* ^__APPLE__ */
+ "_I(); } while (0)");
- have_lto = 1;
- ck_free(ptr);
+}
- }
+/* Control _FORTIFY_SOURCE */
+void add_defs_fortify(aflcc_state_t *aflcc, u8 action) {
- if ((ptr = find_object("cmplog-routines-pass.so", argv[0])) != NULL) {
+ switch (action) {
- have_llvm = 1;
- ck_free(ptr);
+ case 1:
+ insert_param(aflcc, "-D_FORTIFY_SOURCE=1");
+ break;
- }
+ case 2:
+ insert_param(aflcc, "-D_FORTIFY_SOURCE=2");
+ break;
-#endif
+ default: // OFF
+ insert_param(aflcc, "-U_FORTIFY_SOURCE");
+ break;
-#ifdef __ANDROID__
- have_llvm = 1;
-#endif
+ }
- if ((ptr = find_object("afl-gcc-pass.so", argv[0])) != NULL) {
+}
- have_gcc_plugin = 1;
- ck_free(ptr);
+void add_defs_lsan_ctrl(aflcc_state_t *aflcc) {
- }
+ insert_param(aflcc, "-includesanitizer/lsan_interface.h");
+ insert_param(
+ aflcc,
+ "-D__AFL_LEAK_CHECK()={if(__lsan_do_recoverable_leak_check() > 0) "
+ "_exit(23); }");
+ insert_param(aflcc, "-D__AFL_LSAN_OFF()=__lsan_disable();");
+ insert_param(aflcc, "-D__AFL_LSAN_ON()=__lsan_enable();");
-#if (LLVM_MAJOR >= 3)
+}
- if (strncmp(callname, "afl-clang-fast", 14) == 0) {
+/* About fsanitize (including PCGUARD features) */
- compiler_mode = LLVM;
+/* For input "-fsanitize=...", it:
- } else if (strncmp(callname, "afl-clang-lto", 13) == 0 ||
+ 1. may have various OOB traps :) if ... doesn't contain ',' or
+ the input has bad syntax such as "-fsantiz=,"
+ 2. strips any fuzzer* in ... and writes back (may result in "-fsanitize=")
+ 3. rets 1 if exactly "fuzzer" found, otherwise rets 0
+*/
+static u8 fsanitize_fuzzer_comma(char *string) {
- strncmp(callname, "afl-lto", 7) == 0) {
+ u8 detect_single_fuzzer = 0;
- compiler_mode = LTO;
+ char *p, *ptr = string + strlen("-fsanitize=");
+ // ck_alloc will check alloc failure
+ char *new = ck_alloc(strlen(string) + 1);
+ char *tmp = ck_alloc(strlen(ptr) + 1);
+ u32 count = 0, len, ende = 0;
- } else
+ strcpy(new, "-fsanitize=");
-#endif
- if (strncmp(callname, "afl-gcc-fast", 12) == 0 ||
+ do {
- strncmp(callname, "afl-g++-fast", 12) == 0) {
+ p = strchr(ptr, ',');
+ if (!p) {
- compiler_mode = GCC_PLUGIN;
+ p = ptr + strlen(ptr) + 1;
+ ende = 1;
- } else if (strncmp(callname, "afl-gcc", 7) == 0 ||
+ }
- strncmp(callname, "afl-g++", 7) == 0) {
+ len = p - ptr;
+ if (len) {
- compiler_mode = GCC;
+ strncpy(tmp, ptr, len);
+ tmp[len] = 0;
+ // fprintf(stderr, "Found: %s\n", tmp);
+ ptr += len + 1;
+ if (*tmp) {
- } else if (strcmp(callname, "afl-clang") == 0 ||
+ u32 copy = 1;
+ if (!strcmp(tmp, "fuzzer")) {
- strcmp(callname, "afl-clang++") == 0) {
+ detect_single_fuzzer = 1;
+ copy = 0;
- compiler_mode = CLANG;
+ } else if (!strncmp(tmp, "fuzzer", 6)) {
- }
+ copy = 0;
- if ((ptr = getenv("AFL_CC_COMPILER"))) {
+ }
- if (compiler_mode) {
+ if (copy) {
- if (!be_quiet) {
+ if (count) { strcat(new, ","); }
+ strcat(new, tmp);
+ ++count;
- WARNF(
- "\"AFL_CC_COMPILER\" is set but a specific compiler was already "
- "selected by command line parameter or symlink, ignoring the "
- "environment variable!");
+ }
}
} else {
- if (strncasecmp(ptr, "LTO", 3) == 0) {
+ ptr++;
- compiler_mode = LTO;
+ }
- } else if (strncasecmp(ptr, "LLVM", 4) == 0) {
+ } while (!ende);
- compiler_mode = LLVM;
+ strcpy(string, new);
- } else if (strncasecmp(ptr, "GCC_P", 5) == 0 ||
+ ck_free(tmp);
+ ck_free(new);
- strncasecmp(ptr, "GCC-P", 5) == 0 ||
- strncasecmp(ptr, "GCCP", 4) == 0) {
+ return detect_single_fuzzer;
- compiler_mode = GCC_PLUGIN;
+}
- } else if (strcasecmp(ptr, "GCC") == 0) {
+param_st parse_fsanitize(aflcc_state_t *aflcc, u8 *cur_argv, u8 scan) {
- compiler_mode = GCC;
+ param_st final_ = PARAM_MISS;
- } else
+ if (!strncmp(cur_argv, "-fsanitize-coverage-", 20) &&
+ strstr(cur_argv, "list=")) {
+
+ if (scan) {
+
+ aflcc->have_instr_list = 1;
+ final_ = PARAM_SCAN;
+
+ } else {
- FATAL("Unknown AFL_CC_COMPILER mode: %s\n", ptr);
+ final_ = PARAM_KEEP; // may be set to DROP next
}
}
- if (strcmp(callname, "afl-clang") == 0 ||
- strcmp(callname, "afl-clang++") == 0) {
+ if (!strcmp(cur_argv, "-fsanitize=fuzzer")) {
- clang_mode = 1;
- compiler_mode = CLANG;
+ if (scan) {
- if (strcmp(callname, "afl-clang++") == 0) { plusplus_mode = 1; }
+ aflcc->need_aflpplib = 1;
+ final_ = PARAM_SCAN;
- }
+ } else {
- for (i = 1; i < argc; i++) {
+ final_ = PARAM_DROP;
- if (strncmp(argv[i], "--afl", 5) == 0) {
+ }
- if (!strcmp(argv[i], "--afl_noopt") || !strcmp(argv[i], "--afl-noopt")) {
+ } else if (!strncmp(cur_argv, "-fsanitize=", strlen("-fsanitize=")) &&
- passthrough = 1;
- argv[i] = "-g"; // we have to overwrite it, -g is always good
- continue;
+ strchr(cur_argv, ',') &&
+ !strstr(cur_argv, "=,")) { // avoid OOB errors
- }
+ if (scan) {
- if (compiler_mode && !be_quiet) {
+ u8 *cur_argv_ = ck_strdup(cur_argv);
- WARNF(
- "--afl-... compiler mode supersedes the AFL_CC_COMPILER and "
- "symlink compiler selection!");
+ if (fsanitize_fuzzer_comma(cur_argv_)) {
+
+ aflcc->need_aflpplib = 1;
+ final_ = PARAM_SCAN;
}
- ptr = argv[i];
- ptr += 5;
- while (*ptr == '-')
- ptr++;
+ ck_free(cur_argv_);
- if (strncasecmp(ptr, "LTO", 3) == 0) {
+ } else {
- compiler_mode = LTO;
+ fsanitize_fuzzer_comma(cur_argv);
+ if (!cur_argv || strlen(cur_argv) <= strlen("-fsanitize="))
+ final_ = PARAM_DROP; // this means it only has "fuzzer" previously.
- } else if (strncasecmp(ptr, "LLVM", 4) == 0) {
+ }
- compiler_mode = LLVM;
+ } else if ((!strncmp(cur_argv, "-fsanitize=fuzzer-",
- } else if (strncasecmp(ptr, "PCGUARD", 7) == 0 ||
+ strlen("-fsanitize=fuzzer-")) ||
+ !strncmp(cur_argv, "-fsanitize-coverage",
+ strlen("-fsanitize-coverage"))) &&
+ (strncmp(cur_argv, "sanitize-coverage-allow",
+ strlen("sanitize-coverage-allow")) &&
+ strncmp(cur_argv, "sanitize-coverage-deny",
+ strlen("sanitize-coverage-deny")) &&
+ aflcc->instrument_mode != INSTRUMENT_LLVMNATIVE)) {
- strncasecmp(ptr, "PC-GUARD", 8) == 0) {
+ if (scan) {
- compiler_mode = LLVM;
- instrument_mode = INSTRUMENT_PCGUARD;
+ final_ = PARAM_SCAN;
- } else if (strcasecmp(ptr, "INSTRIM") == 0 ||
+ } else {
- strcasecmp(ptr, "CFG") == 0) {
+ if (!be_quiet) { WARNF("Found '%s' - stripping!", cur_argv); }
+ final_ = PARAM_DROP;
- FATAL(
- "InsTrim instrumentation was removed. Use a modern LLVM and "
- "PCGUARD (default in afl-cc).\n");
+ }
- } else if (strcasecmp(ptr, "AFL") == 0 ||
+ }
- strcasecmp(ptr, "CLASSIC") == 0) {
+ if (!strcmp(cur_argv, "-fsanitize=address") ||
+ !strcmp(cur_argv, "-fsanitize=memory")) {
- compiler_mode = LLVM;
- instrument_mode = INSTRUMENT_CLASSIC;
+ if (scan) {
- } else if (strcasecmp(ptr, "LLVMNATIVE") == 0 ||
+ // "-fsanitize=undefined,address" may be un-treated, but it's OK.
+ aflcc->asan_set = 1;
+ final_ = PARAM_SCAN;
- strcasecmp(ptr, "NATIVE") == 0 ||
- strcasecmp(ptr, "LLVM-NATIVE") == 0) {
+ } else {
- compiler_mode = LLVM;
- instrument_mode = INSTRUMENT_LLVMNATIVE;
+ // It's impossible that final_ is PARAM_DROP before,
+ // so no checks are needed here.
+ final_ = PARAM_KEEP;
- } else if (strncasecmp(ptr, "GCC_P", 5) == 0 ||
+ }
- strncasecmp(ptr, "GCC-P", 5) == 0 ||
- strncasecmp(ptr, "GCCP", 4) == 0) {
+ }
- compiler_mode = GCC_PLUGIN;
+ if (final_ == PARAM_KEEP) insert_param(aflcc, cur_argv);
- } else if (strcasecmp(ptr, "GCC") == 0) {
+ return final_;
- compiler_mode = GCC;
+}
- } else if (strncasecmp(ptr, "CLANG", 5) == 0) {
+void add_sanitizers(aflcc_state_t *aflcc, char **envp) {
- compiler_mode = CLANG;
+ if (!aflcc->asan_set) {
- } else
+ if (getenv("AFL_USE_ASAN")) {
- FATAL("Unknown --afl-... compiler mode: %s\n", argv[i]);
+ if (getenv("AFL_USE_MSAN")) FATAL("ASAN and MSAN are mutually exclusive");
- }
+ if (getenv("AFL_HARDEN"))
+ FATAL("ASAN and AFL_HARDEN are mutually exclusive");
- }
+ add_defs_fortify(aflcc, 0);
+ insert_param(aflcc, "-fsanitize=address");
- if (strlen(callname) > 2 &&
- (strncmp(callname + strlen(callname) - 2, "++", 2) == 0 ||
- strstr(callname, "-g++") != NULL))
- plusplus_mode = 1;
+ } else if (getenv("AFL_USE_MSAN")) {
- if (getenv("USE_TRACE_PC") || getenv("AFL_USE_TRACE_PC") ||
- getenv("AFL_LLVM_USE_TRACE_PC") || getenv("AFL_TRACE_PC")) {
+ if (getenv("AFL_USE_ASAN")) FATAL("ASAN and MSAN are mutually exclusive");
- if (instrument_mode == 0)
- instrument_mode = INSTRUMENT_PCGUARD;
- else if (instrument_mode != INSTRUMENT_PCGUARD)
- FATAL("you cannot set AFL_LLVM_INSTRUMENT and AFL_TRACE_PC together");
+ if (getenv("AFL_HARDEN"))
+ FATAL("MSAN and AFL_HARDEN are mutually exclusive");
+
+ add_defs_fortify(aflcc, 0);
+ insert_param(aflcc, "-fsanitize=memory");
+
+ }
}
- if (have_instr_env && getenv("AFL_DONT_OPTIMIZE") && !be_quiet) {
+ if (getenv("AFL_USE_UBSAN")) {
- WARNF(
- "AFL_LLVM_ALLOWLIST/DENYLIST and AFL_DONT_OPTIMIZE cannot be combined "
- "for file matching, only function matching!");
+ insert_param(aflcc, "-fsanitize=undefined");
+ insert_param(aflcc, "-fsanitize-undefined-trap-on-error");
+ insert_param(aflcc, "-fno-sanitize-recover=all");
+ insert_param(aflcc, "-fno-omit-frame-pointer");
}
- if (getenv("AFL_LLVM_INSTRIM") || getenv("INSTRIM") ||
- getenv("INSTRIM_LIB")) {
+ if (getenv("AFL_USE_TSAN")) {
- FATAL(
- "InsTrim instrumentation was removed. Use a modern LLVM and PCGUARD "
- "(default in afl-cc).\n");
+ insert_param(aflcc, "-fsanitize=thread");
+ insert_param(aflcc, "-fno-omit-frame-pointer");
}
- if (getenv("AFL_LLVM_CTX")) instrument_opt_mode |= INSTRUMENT_OPT_CTX;
- if (getenv("AFL_LLVM_CALLER")) instrument_opt_mode |= INSTRUMENT_OPT_CALLER;
-
- if (getenv("AFL_LLVM_NGRAM_SIZE")) {
+ if (getenv("AFL_USE_LSAN")) {
- instrument_opt_mode |= INSTRUMENT_OPT_NGRAM;
- ngram_size = atoi(getenv("AFL_LLVM_NGRAM_SIZE"));
- if (ngram_size < 2 || ngram_size > NGRAM_SIZE_MAX)
- FATAL(
- "NGRAM instrumentation mode must be between 2 and NGRAM_SIZE_MAX "
- "(%u)",
- NGRAM_SIZE_MAX);
+ insert_param(aflcc, "-fsanitize=leak");
+ add_defs_lsan_ctrl(aflcc);
}
- if (getenv("AFL_LLVM_CTX_K")) {
+ if (getenv("AFL_USE_CFISAN")) {
- 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) {
+ if (aflcc->compiler_mode == GCC_PLUGIN || aflcc->compiler_mode == GCC) {
- setenv("AFL_LLVM_CALLER", "1", 1);
- unsetenv("AFL_LLVM_CTX_K");
- instrument_opt_mode |= INSTRUMENT_OPT_CALLER;
+ insert_param(aflcc, "-fcf-protection=full");
} else {
- instrument_opt_mode |= INSTRUMENT_OPT_CTX_K;
+ if (!aflcc->lto_mode) {
+
+ uint32_t i = 0, found = 0;
+ while (envp[i] != NULL && !found)
+ if (strncmp("-flto", envp[i++], 5) == 0) found = 1;
+ if (!found) insert_param(aflcc, "-flto");
+
+ }
+
+ insert_param(aflcc, "-fsanitize=cfi");
+ insert_param(aflcc, "-fvisibility=hidden");
}
}
- if (getenv("AFL_LLVM_INSTRUMENT")) {
+}
- u8 *ptr2 = strtok(getenv("AFL_LLVM_INSTRUMENT"), ":,;");
+void add_native_pcguard(aflcc_state_t *aflcc) {
- while (ptr2) {
+ /* If llvm-config doesn't figure out LLVM_MAJOR, just
+ go on anyway and let compiler complain if doesn't work. */
- if (strncasecmp(ptr2, "afl", strlen("afl")) == 0 ||
- strncasecmp(ptr2, "classic", strlen("classic")) == 0) {
+ if (aflcc->instrument_opt_mode & INSTRUMENT_OPT_CODECOV) {
- if (instrument_mode == INSTRUMENT_LTO) {
+#if LLVM_MAJOR > 0 && LLVM_MAJOR < 6
+ FATAL("pcguard instrumentation with pc-table requires LLVM 6.0.1+");
+#else
+ #if LLVM_MAJOR == 0
+ WARNF(
+ "pcguard instrumentation with pc-table requires LLVM 6.0.1+"
+ " otherwise the compiler will fail");
+ #endif
+ insert_param(aflcc,
+ "-fsanitize-coverage=trace-pc-guard,bb,no-prune,pc-table");
+#endif
- instrument_mode = INSTRUMENT_CLASSIC;
- lto_mode = 1;
+ } else {
- } else if (!instrument_mode || instrument_mode == INSTRUMENT_AFL) {
+#if LLVM_MAJOR > 0 && LLVM_MAJOR < 4
+ FATAL("pcguard instrumentation requires LLVM 4.0.1+");
+#else
+ #if LLVM_MAJOR == 0
+ WARNF(
+ "pcguard instrumentation requires LLVM 4.0.1+"
+ " otherwise the compiler will fail");
+ #endif
+ insert_param(aflcc, "-fsanitize-coverage=trace-pc-guard");
+#endif
- instrument_mode = INSTRUMENT_AFL;
+ }
- } else {
+}
- FATAL("main instrumentation mode already set with %s",
- instrument_mode_string[instrument_mode]);
+void add_optimized_pcguard(aflcc_state_t *aflcc) {
- }
+#if LLVM_MAJOR >= 13
+ #if defined __ANDROID__ || ANDROID
- }
+ insert_param(aflcc, "-fsanitize-coverage=trace-pc-guard");
+ aflcc->instrument_mode = INSTRUMENT_LLVMNATIVE;
- if (strncasecmp(ptr2, "pc-guard", strlen("pc-guard")) == 0 ||
- strncasecmp(ptr2, "pcguard", strlen("pcguard")) == 0) {
+ #else
- if (!instrument_mode || instrument_mode == INSTRUMENT_PCGUARD)
- instrument_mode = INSTRUMENT_PCGUARD;
- else
- FATAL("main instrumentation mode already set with %s",
- instrument_mode_string[instrument_mode]);
+ if (aflcc->have_instr_list) {
- }
+ if (!be_quiet)
+ SAYF(
+ "Using unoptimized trace-pc-guard, due usage of "
+ "-fsanitize-coverage-allow/denylist, you can use "
+ "AFL_LLVM_ALLOWLIST/AFL_LLMV_DENYLIST instead.\n");
- if (strncasecmp(ptr2, "llvmnative", strlen("llvmnative")) == 0 ||
- strncasecmp(ptr2, "llvm-native", strlen("llvm-native")) == 0 ||
- strncasecmp(ptr2, "native", strlen("native")) == 0) {
+ insert_param(aflcc, "-fsanitize-coverage=trace-pc-guard");
+ aflcc->instrument_mode = INSTRUMENT_LLVMNATIVE;
- if (!instrument_mode || instrument_mode == INSTRUMENT_LLVMNATIVE)
- instrument_mode = INSTRUMENT_LLVMNATIVE;
- else
- FATAL("main instrumentation mode already set with %s",
- instrument_mode_string[instrument_mode]);
+ } else {
- }
+ /* Since LLVM_MAJOR >= 13 we use new pass manager */
+ #if LLVM_MAJOR < 16
+ insert_param(aflcc, "-fexperimental-new-pass-manager");
+ #endif
+ insert_object(aflcc, "SanitizerCoveragePCGUARD.so", "-fpass-plugin=%s", 0);
- if (strncasecmp(ptr2, "llvmcodecov", strlen("llvmcodecov")) == 0 ||
- strncasecmp(ptr2, "llvm-codecov", strlen("llvm-codecov")) == 0) {
+ }
- if (!instrument_mode || instrument_mode == INSTRUMENT_LLVMNATIVE) {
+ #endif // defined __ANDROID__ || ANDROID
+#else // LLVM_MAJOR < 13
+ #if LLVM_MAJOR >= 4
- instrument_mode = INSTRUMENT_LLVMNATIVE;
- instrument_opt_mode |= INSTRUMENT_OPT_CODECOV;
+ if (!be_quiet)
+ SAYF(
+ "Using unoptimized trace-pc-guard, upgrade to LLVM 13+ for "
+ "enhanced version.\n");
+ insert_param(aflcc, "-fsanitize-coverage=trace-pc-guard");
+ aflcc->instrument_mode = INSTRUMENT_LLVMNATIVE;
- } else {
+ #else
- FATAL("main instrumentation mode already set with %s",
- instrument_mode_string[instrument_mode]);
+ FATAL("pcguard instrumentation requires LLVM 4.0.1+");
- }
+ #endif
+#endif
- }
+}
- if (strncasecmp(ptr2, "cfg", strlen("cfg")) == 0 ||
- strncasecmp(ptr2, "instrim", strlen("instrim")) == 0) {
+/* Linking behaviors */
- FATAL(
- "InsTrim instrumentation was removed. Use a modern LLVM and "
- "PCGUARD (default in afl-cc).\n");
+param_st parse_linking_params(aflcc_state_t *aflcc, u8 *cur_argv, u8 scan,
+ u8 *skip_next, char **argv) {
- }
+ if (aflcc->lto_mode && !strncmp(cur_argv, "-flto=thin", 10)) {
- if (strncasecmp(ptr2, "lto", strlen("lto")) == 0) {
+ FATAL(
+ "afl-clang-lto cannot work with -flto=thin. Switch to -flto=full or "
+ "use afl-clang-fast!");
- lto_mode = 1;
- if (!instrument_mode || instrument_mode == INSTRUMENT_LTO)
- instrument_mode = INSTRUMENT_LTO;
- else
- FATAL("main instrumentation mode already set with %s",
- instrument_mode_string[instrument_mode]);
+ }
- }
+ param_st final_ = PARAM_MISS;
- if (strcasecmp(ptr2, "gcc") == 0) {
+ if (!strcmp(cur_argv, "-shared") || !strcmp(cur_argv, "-dynamiclib")) {
- if (!instrument_mode || instrument_mode == INSTRUMENT_GCC)
- instrument_mode = INSTRUMENT_GCC;
- else if (instrument_mode != INSTRUMENT_GCC)
- FATAL("main instrumentation mode already set with %s",
- instrument_mode_string[instrument_mode]);
- compiler_mode = GCC;
+ if (scan) {
- }
+ aflcc->shared_linking = 1;
+ final_ = PARAM_SCAN;
- if (strcasecmp(ptr2, "clang") == 0) {
+ } else {
- if (!instrument_mode || instrument_mode == INSTRUMENT_CLANG)
- instrument_mode = INSTRUMENT_CLANG;
- else if (instrument_mode != INSTRUMENT_CLANG)
- FATAL("main instrumentation mode already set with %s",
- instrument_mode_string[instrument_mode]);
- compiler_mode = CLANG;
+ final_ = PARAM_KEEP;
- }
+ }
- if (strncasecmp(ptr2, "ctx-", strlen("ctx-")) == 0 ||
- strncasecmp(ptr2, "kctx-", strlen("c-ctx-")) == 0 ||
- strncasecmp(ptr2, "k-ctx-", strlen("k-ctx-")) == 0) {
+ } else if (!strcmp(cur_argv, "-Wl,-r") || !strcmp(cur_argv, "-Wl,-i") ||
- u8 *ptr3 = ptr2;
- while (*ptr3 && (*ptr3 < '0' || *ptr3 > '9'))
- ptr3++;
+ !strcmp(cur_argv, "-Wl,--relocatable") ||
+ !strcmp(cur_argv, "-r") || !strcmp(cur_argv, "--relocatable")) {
- if (!*ptr3) {
+ if (scan) {
- if ((ptr3 = getenv("AFL_LLVM_CTX_K")) == NULL)
- FATAL(
- "you must set the K-CTX K with (e.g. for value 2) "
- "AFL_LLVM_INSTRUMENT=ctx-2");
+ aflcc->partial_linking = 1;
+ final_ = PARAM_SCAN;
- }
+ } else {
- ctx_k = atoi(ptr3);
- if (ctx_k < 1 || ctx_k > CTX_MAX_K)
- FATAL(
- "K-CTX instrumentation option must be between 1 and CTX_MAX_K "
- "(%u)",
- CTX_MAX_K);
+ final_ = PARAM_KEEP;
- if (ctx_k == 1) {
+ }
- instrument_opt_mode |= INSTRUMENT_OPT_CALLER;
- setenv("AFL_LLVM_CALLER", "1", 1);
- unsetenv("AFL_LLVM_CTX_K");
+ } else if (!strncmp(cur_argv, "-fuse-ld=", 9) ||
- } else {
+ !strncmp(cur_argv, "--ld-path=", 10)) {
- instrument_opt_mode |= (INSTRUMENT_OPT_CTX_K);
- u8 *ptr4 = alloc_printf("%u", ctx_k);
- setenv("AFL_LLVM_CTX_K", ptr4, 1);
+ if (scan) {
- }
+ final_ = PARAM_SCAN;
- }
+ } else {
- if (strcasecmp(ptr2, "ctx") == 0) {
+ if (aflcc->lto_mode)
+ final_ = PARAM_DROP;
+ else
+ final_ = PARAM_KEEP;
- instrument_opt_mode |= INSTRUMENT_OPT_CTX;
- setenv("AFL_LLVM_CTX", "1", 1);
+ }
- }
+ } else if (!strcmp(cur_argv, "-Wl,-z,defs") ||
- if (strncasecmp(ptr2, "caller", strlen("caller")) == 0) {
+ !strcmp(cur_argv, "-Wl,--no-undefined") ||
+ !strcmp(cur_argv, "-Wl,-no-undefined") ||
+ !strcmp(cur_argv, "--no-undefined") ||
+ strstr(cur_argv, "afl-compiler-rt") ||
+ strstr(cur_argv, "afl-llvm-rt")) {
- instrument_opt_mode |= INSTRUMENT_OPT_CALLER;
- setenv("AFL_LLVM_CALLER", "1", 1);
+ if (scan) {
- }
+ final_ = PARAM_SCAN;
- if (strncasecmp(ptr2, "ngram", strlen("ngram")) == 0) {
+ } else {
- u8 *ptr3 = ptr2 + strlen("ngram");
- while (*ptr3 && (*ptr3 < '0' || *ptr3 > '9'))
- ptr3++;
+ final_ = PARAM_DROP;
- if (!*ptr3) {
+ }
- if ((ptr3 = getenv("AFL_LLVM_NGRAM_SIZE")) == NULL)
- FATAL(
- "you must set the NGRAM size with (e.g. for value 2) "
- "AFL_LLVM_INSTRUMENT=ngram-2");
+ } else if (!strcmp(cur_argv, "-z") || !strcmp(cur_argv, "-Wl,-z")) {
- }
+ u8 *param = *(argv + 1);
+ if (param && (!strcmp(param, "defs") || !strcmp(param, "-Wl,defs"))) {
- ngram_size = atoi(ptr3);
- if (ngram_size < 2 || ngram_size > NGRAM_SIZE_MAX)
- FATAL(
- "NGRAM instrumentation option must be between 2 and "
- "NGRAM_SIZE_MAX (%u)",
- NGRAM_SIZE_MAX);
- instrument_opt_mode |= (INSTRUMENT_OPT_NGRAM);
- u8 *ptr4 = alloc_printf("%u", ngram_size);
- setenv("AFL_LLVM_NGRAM_SIZE", ptr4, 1);
+ *skip_next = 1;
- }
+ if (scan) {
- ptr2 = strtok(NULL, ":,;");
+ final_ = PARAM_SCAN;
- }
+ } else {
- }
+ final_ = PARAM_DROP;
- if ((instrument_opt_mode & INSTRUMENT_OPT_CTX) &&
- (instrument_opt_mode & INSTRUMENT_OPT_CALLER)) {
+ }
- FATAL("you cannot set CTX and CALLER together");
+ }
}
- if ((instrument_opt_mode & INSTRUMENT_OPT_CTX) &&
- (instrument_opt_mode & INSTRUMENT_OPT_CTX_K)) {
+ // Try to warn user for some unsupported cases
+ if (scan && final_ == PARAM_MISS) {
- FATAL("you cannot set CTX and K-CTX together");
+ u8 *ptr_ = NULL;
- }
+ if (!strcmp(cur_argv, "-Xlinker") && (ptr_ = *(argv + 1))) {
- if ((instrument_opt_mode & INSTRUMENT_OPT_CALLER) &&
- (instrument_opt_mode & INSTRUMENT_OPT_CTX_K)) {
+ if (!strcmp(ptr_, "defs")) {
- FATAL("you cannot set CALLER and K-CTX together");
+ WARNF("'-Xlinker' 'defs' detected. This may result in a bad link.");
- }
+ } else if (strstr(ptr_, "-no-undefined")) {
- if (instrument_opt_mode && instrument_mode == INSTRUMENT_DEFAULT &&
- (compiler_mode == LLVM || compiler_mode == UNSET)) {
+ WARNF(
+ "'-Xlinker' '%s' detected. The latter option may be dropped and "
+ "result in a bad link.",
+ ptr_);
- instrument_mode = INSTRUMENT_CLASSIC;
- compiler_mode = LLVM;
+ }
- }
+ } else if (!strncmp(cur_argv, "-Wl,", 4) &&
- if (!compiler_mode) {
+ (u8 *)strrchr(cur_argv, ',') != (cur_argv + 3)) {
- // lto is not a default because outside of afl-cc RANLIB and AR have to
- // be set to LLVM versions so this would work
- if (have_llvm)
- compiler_mode = LLVM;
- else if (have_gcc_plugin)
- compiler_mode = GCC_PLUGIN;
- else if (have_gcc)
-#ifdef __APPLE__
- // on OSX clang masquerades as GCC
- compiler_mode = CLANG;
-#else
- compiler_mode = GCC;
-#endif
- else if (have_lto)
- compiler_mode = LTO;
- else
- FATAL("no compiler mode available");
+ ptr_ = cur_argv + 4;
- }
+ if (strstr(ptr_, "-shared") || strstr(ptr_, "-dynamiclib")) {
- /* if our PCGUARD implementation is not available then silently switch to
- native LLVM PCGUARD */
- if (compiler_mode == CLANG &&
- (instrument_mode == INSTRUMENT_DEFAULT ||
- instrument_mode == INSTRUMENT_PCGUARD) &&
- find_object("SanitizerCoveragePCGUARD.so", argv[0]) == NULL) {
+ WARNF(
+ "'%s': multiple link options after '-Wl,' may break shared "
+ "linking.",
+ ptr_);
- instrument_mode = INSTRUMENT_LLVMNATIVE;
+ }
- }
+ if (strstr(ptr_, "-r,") || strstr(ptr_, "-i,") || strstr(ptr_, ",-r") ||
+ strstr(ptr_, ",-i") || strstr(ptr_, "--relocatable")) {
- if (compiler_mode == GCC) {
+ WARNF(
+ "'%s': multiple link options after '-Wl,' may break partial "
+ "linking.",
+ ptr_);
- if (clang_mode) {
+ }
- instrument_mode = INSTRUMENT_CLANG;
+ if (strstr(ptr_, "defs") || strstr(ptr_, "no-undefined")) {
- } else {
+ WARNF(
+ "'%s': multiple link options after '-Wl,' may enable report "
+ "unresolved symbol references and result in a bad link.",
+ ptr_);
- instrument_mode = INSTRUMENT_GCC;
+ }
}
}
- if (compiler_mode == CLANG) {
+ if (final_ == PARAM_KEEP) insert_param(aflcc, cur_argv);
- instrument_mode = INSTRUMENT_CLANG;
- setenv(CLANG_ENV_VAR, "1", 1); // used by afl-as
+ return final_;
- }
+}
+
+void add_lto_linker(aflcc_state_t *aflcc) {
+
+ unsetenv("AFL_LD");
+ unsetenv("AFL_LD_CALLER");
+
+ u8 *ld_path = NULL;
+ if (getenv("AFL_REAL_LD")) {
+
+ ld_path = strdup(getenv("AFL_REAL_LD"));
+
+ } else {
+
+ ld_path = strdup(AFL_REAL_LD);
+
+ }
+
+ if (!ld_path || !*ld_path) {
+
+ if (ld_path) {
+
+ // Freeing empty string
+ free(ld_path);
+
+ }
+
+ ld_path = strdup("ld.lld");
+
+ }
+
+ if (!ld_path) { PFATAL("Could not allocate mem for ld_path"); }
+#if defined(AFL_CLANG_LDPATH) && LLVM_MAJOR >= 12
+ insert_param(aflcc, alloc_printf("--ld-path=%s", ld_path));
+#else
+ insert_param(aflcc, alloc_printf("-fuse-ld=%s", ld_path));
+#endif
+ free(ld_path);
+
+}
+
+void add_lto_passes(aflcc_state_t *aflcc) {
+
+#if defined(AFL_CLANG_LDPATH) && LLVM_MAJOR >= 15
+ // The NewPM implementation only works fully since LLVM 15.
+ insert_object(aflcc, "SanitizerCoverageLTO.so", "-Wl,--load-pass-plugin=%s",
+ 0);
+#elif defined(AFL_CLANG_LDPATH) && LLVM_MAJOR >= 13
+ insert_param(aflcc, "-Wl,--lto-legacy-pass-manager");
+ insert_object(aflcc, "SanitizerCoverageLTO.so", "-Wl,-mllvm=-load=%s", 0);
+#else
+ insert_param(aflcc, "-fno-experimental-new-pass-manager");
+ insert_object(aflcc, "SanitizerCoverageLTO.so", "-Wl,-mllvm=-load=%s", 0);
+#endif
+
+ insert_param(aflcc, "-Wl,--allow-multiple-definition");
+
+}
+
+static void add_aflpplib(aflcc_state_t *aflcc) {
+
+ if (!aflcc->need_aflpplib) return;
+
+ u8 *afllib = find_object(aflcc, "libAFLDriver.a");
+
+ if (!be_quiet) {
+
+ OKF("Found '-fsanitize=fuzzer', replacing with libAFLDriver.a");
+
+ }
+
+ if (!afllib) {
+
+ if (!be_quiet) {
+
+ WARNF(
+ "Cannot find 'libAFLDriver.a' to replace '-fsanitize=fuzzer' in "
+ "the flags - this will fail!");
+
+ }
+
+ } else {
+
+ insert_param(aflcc, afllib);
+
+#ifdef __APPLE__
+ insert_param(aflcc, "-Wl,-undefined");
+ insert_param(aflcc, "dynamic_lookup");
+#endif
+
+ }
+
+}
+
+void add_runtime(aflcc_state_t *aflcc) {
+
+ if (aflcc->preprocessor_only || aflcc->have_c || !aflcc->non_dash) {
+
+ /* In the preprocessor_only case (-E), we are not actually compiling at
+ all but requesting the compiler to output preprocessed sources only.
+ We must not add the runtime in this case because the compiler will
+ simply output its binary content back on stdout, breaking any build
+ systems that rely on a separate source preprocessing step. */
+ return;
+
+ }
+
+ if (aflcc->compiler_mode != GCC_PLUGIN && aflcc->compiler_mode != GCC &&
+ !getenv("AFL_LLVM_NO_RPATH")) {
+
+ // in case LLVM is installed not via a package manager or "make install"
+ // e.g. compiled download or compiled from github then its ./lib directory
+ // might not be in the search path. Add it if so.
+ const char *libdir = LLVM_LIBDIR;
+ if (aflcc->plusplus_mode && strlen(libdir) && strncmp(libdir, "/usr", 4) &&
+ strncmp(libdir, "/lib", 4)) {
+
+ u8 *libdir_opt = strdup("-Wl,-rpath=" LLVM_LIBDIR);
+ insert_param(aflcc, libdir_opt);
+
+ }
+
+ }
+
+#ifndef __ANDROID__
+
+ #define M32_ERR_MSG "-m32 is not supported by your compiler"
+ #define M64_ERR_MSG "-m64 is not supported by your compiler"
+
+ if (aflcc->compiler_mode != GCC && aflcc->compiler_mode != CLANG) {
+
+ switch (aflcc->bit_mode) {
+
+ case 0:
+ if (!aflcc->shared_linking && !aflcc->partial_linking)
+ insert_object(aflcc, "afl-compiler-rt.o", 0, 0);
+ if (aflcc->lto_mode) insert_object(aflcc, "afl-llvm-rt-lto.o", 0, 0);
+ break;
+
+ case 32:
+ if (!aflcc->shared_linking && !aflcc->partial_linking)
+ insert_object(aflcc, "afl-compiler-rt-32.o", 0, M32_ERR_MSG);
+ if (aflcc->lto_mode)
+ insert_object(aflcc, "afl-llvm-rt-lto-32.o", 0, M32_ERR_MSG);
+ break;
+
+ case 64:
+ if (!aflcc->shared_linking && !aflcc->partial_linking)
+ insert_object(aflcc, "afl-compiler-rt-64.o", 0, M64_ERR_MSG);
+ if (aflcc->lto_mode)
+ insert_object(aflcc, "afl-llvm-rt-lto-64.o", 0, M64_ERR_MSG);
+ break;
+
+ }
+
+ #if !defined(__APPLE__) && !defined(__sun)
+ if (!aflcc->shared_linking && !aflcc->partial_linking)
+ insert_object(aflcc, "dynamic_list.txt", "-Wl,--dynamic-list=%s", 0);
+ #endif
+
+ #if defined(__APPLE__)
+ if (aflcc->shared_linking || aflcc->partial_linking) {
+
+ insert_param(aflcc, "-Wl,-U");
+ insert_param(aflcc, "-Wl,___afl_area_ptr");
+ insert_param(aflcc, "-Wl,-U");
+ insert_param(aflcc, "-Wl,___sanitizer_cov_trace_pc_guard_init");
+
+ }
+
+ #endif
+
+ }
+
+#endif
+
+ add_aflpplib(aflcc);
+
+#if defined(USEMMAP) && !defined(__HAIKU__) && !__APPLE__
+ insert_param(aflcc, "-Wl,-lrt");
+#endif
+
+}
+
+/* Misc */
+
+void add_assembler(aflcc_state_t *aflcc) {
+
+ u8 *afl_as = find_object(aflcc, "as");
+
+ if (!afl_as) FATAL("Cannot find 'as' (symlink to 'afl-as').");
+
+ u8 *slash = strrchr(afl_as, '/');
+ if (slash) *slash = 0;
+
+ insert_param(aflcc, "-B");
+ insert_param(aflcc, afl_as);
+
+ if (aflcc->compiler_mode == CLANG) insert_param(aflcc, "-no-integrated-as");
+
+}
+
+void add_gcc_plugin(aflcc_state_t *aflcc) {
+
+ if (aflcc->cmplog_mode) {
+
+ insert_object(aflcc, "afl-gcc-cmplog-pass.so", "-fplugin=%s", 0);
+ insert_object(aflcc, "afl-gcc-cmptrs-pass.so", "-fplugin=%s", 0);
+
+ }
+
+ insert_object(aflcc, "afl-gcc-pass.so", "-fplugin=%s", 0);
+
+ insert_param(aflcc, "-fno-if-conversion");
+ insert_param(aflcc, "-fno-if-conversion2");
+
+}
+
+void add_misc_params(aflcc_state_t *aflcc) {
+
+ if (getenv("AFL_NO_BUILTIN") || getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES") ||
+ getenv("AFL_LLVM_LAF_ALL") || getenv("AFL_LLVM_CMPLOG") ||
+ aflcc->lto_mode) {
+
+ insert_param(aflcc, "-fno-builtin-strcmp");
+ insert_param(aflcc, "-fno-builtin-strncmp");
+ insert_param(aflcc, "-fno-builtin-strcasecmp");
+ insert_param(aflcc, "-fno-builtin-strncasecmp");
+ insert_param(aflcc, "-fno-builtin-memcmp");
+ insert_param(aflcc, "-fno-builtin-bcmp");
+ insert_param(aflcc, "-fno-builtin-strstr");
+ insert_param(aflcc, "-fno-builtin-strcasestr");
+
+ }
+
+ if (!aflcc->have_pic) { insert_param(aflcc, "-fPIC"); }
+
+ if (getenv("AFL_HARDEN")) {
+
+ insert_param(aflcc, "-fstack-protector-all");
+
+ if (!aflcc->fortify_set) add_defs_fortify(aflcc, 2);
+
+ }
+
+ if (!getenv("AFL_DONT_OPTIMIZE")) {
+
+ insert_param(aflcc, "-g");
+ if (!aflcc->have_o) insert_param(aflcc, "-O3");
+ if (!aflcc->have_unroll) insert_param(aflcc, "-funroll-loops");
+ // if (strlen(aflcc->march_opt) > 1 && aflcc->march_opt[0] == '-')
+ // insert_param(aflcc, aflcc->march_opt);
+
+ }
+
+ if (aflcc->x_set) {
+
+ insert_param(aflcc, "-x");
+ insert_param(aflcc, "none");
+
+ }
+
+}
+
+param_st parse_misc_params(aflcc_state_t *aflcc, u8 *cur_argv, u8 scan) {
+
+ param_st final_ = PARAM_MISS;
+
+// MACRO START
+#define SCAN_KEEP(dst, src) \
+ do { \
+ \
+ if (scan) { \
+ \
+ dst = src; \
+ final_ = PARAM_SCAN; \
+ \
+ } else { \
+ \
+ final_ = PARAM_KEEP; \
+ \
+ } \
+ \
+ } while (0)
+
+ // MACRO END
+
+ if (!strncasecmp(cur_argv, "-fpic", 5)) {
+
+ SCAN_KEEP(aflcc->have_pic, 1);
+
+ } else if (!strcmp(cur_argv, "-m32") ||
+
+ !strcmp(cur_argv, "armv7a-linux-androideabi")) {
+
+ SCAN_KEEP(aflcc->bit_mode, 32);
+
+ } else if (!strcmp(cur_argv, "-m64")) {
+
+ SCAN_KEEP(aflcc->bit_mode, 64);
+
+ } else if (strstr(cur_argv, "FORTIFY_SOURCE")) {
+
+ SCAN_KEEP(aflcc->fortify_set, 1);
+
+ } else if (!strcmp(cur_argv, "-x")) {
+
+ SCAN_KEEP(aflcc->x_set, 1);
+
+ } else if (!strcmp(cur_argv, "-E")) {
+
+ SCAN_KEEP(aflcc->preprocessor_only, 1);
+
+ } else if (!strcmp(cur_argv, "--target=wasm32-wasi")) {
+
+ SCAN_KEEP(aflcc->passthrough, 1);
+
+ } else if (!strcmp(cur_argv, "-c")) {
+
+ SCAN_KEEP(aflcc->have_c, 1);
+
+ } else if (!strncmp(cur_argv, "-O", 2)) {
+
+ SCAN_KEEP(aflcc->have_o, 1);
+
+ } else if (!strncmp(cur_argv, "-funroll-loop", 13)) {
+
+ SCAN_KEEP(aflcc->have_unroll, 1);
+
+ } else if (!strncmp(cur_argv, "--afl", 5)) {
+
+ if (scan)
+ final_ = PARAM_SCAN;
+ else
+ final_ = PARAM_DROP;
+
+ } else if (!strncmp(cur_argv, "-fno-unroll", 11)) {
+
+ if (scan)
+ final_ = PARAM_SCAN;
+ else
+ final_ = PARAM_DROP;
+
+ } else if (!strcmp(cur_argv, "-pipe") && aflcc->compiler_mode == GCC_PLUGIN) {
+
+ if (scan)
+ final_ = PARAM_SCAN;
+ else
+ final_ = PARAM_DROP;
+
+ } else if (!strncmp(cur_argv, "-stdlib=", 8) &&
+
+ (aflcc->compiler_mode == GCC ||
+ aflcc->compiler_mode == GCC_PLUGIN)) {
+
+ if (scan) {
+
+ final_ = PARAM_SCAN;
+
+ } else {
+
+ if (!be_quiet) WARNF("Found '%s' - stripping!", cur_argv);
+ final_ = PARAM_DROP;
+
+ }
+
+ } else if (cur_argv[0] != '-') {
+
+ /* It's a weak, loose pattern, with very different purpose
+ than others. We handle it at last, cautiously and robustly. */
+
+ if (scan && cur_argv[0] != '@') // response file support
+ aflcc->non_dash = 1;
+
+ }
+
+#undef SCAN_KEEP
+
+ if (final_ == PARAM_KEEP) insert_param(aflcc, cur_argv);
+
+ return final_;
+
+}
+
+static void maybe_usage(aflcc_state_t *aflcc, int argc, char **argv) {
if (argc < 2 || strncmp(argv[1], "-h", 2) == 0) {
@@ -2168,16 +2559,22 @@ int main(int argc, char **argv, char **envp) {
" [GCC/CLANG] simple gcc/clang: %s%s\n"
" CLASSIC DEFAULT no no no no no "
"no\n\n",
- have_llvm ? "AVAILABLE" : "unavailable!",
- compiler_mode == LLVM ? " [SELECTED]" : "",
- have_llvm ? "AVAILABLE" : "unavailable!",
- have_llvm ? "AVAILABLE" : "unavailable!",
- have_lto ? "AVAILABLE" : "unavailable!",
- compiler_mode == LTO ? " [SELECTED]" : "",
- have_gcc_plugin ? "AVAILABLE" : "unavailable!",
- compiler_mode == GCC_PLUGIN ? " [SELECTED]" : "",
- have_gcc ? "AVAILABLE" : "unavailable!",
- (compiler_mode == GCC || compiler_mode == CLANG) ? " [SELECTED]" : "");
+ aflcc->have_llvm ? "AVAILABLE" : "unavailable!",
+ aflcc->compiler_mode == LLVM ? " [SELECTED]" : "",
+ aflcc->have_llvm ? "AVAILABLE" : "unavailable!",
+ aflcc->have_llvm ? "AVAILABLE" : "unavailable!",
+ aflcc->have_lto ? "AVAILABLE" : "unavailable!",
+ aflcc->compiler_mode == LTO ? " [SELECTED]" : "",
+ aflcc->have_gcc_plugin ? "AVAILABLE" : "unavailable!",
+ aflcc->compiler_mode == GCC_PLUGIN ? " [SELECTED]" : "",
+ aflcc->have_gcc && aflcc->have_clang
+ ? "AVAILABLE"
+ : (aflcc->have_gcc
+ ? "GCC ONLY "
+ : (aflcc->have_clang ? "CLANG ONLY" : "unavailable!")),
+ (aflcc->compiler_mode == GCC || aflcc->compiler_mode == CLANG)
+ ? " [SELECTED]"
+ : "");
SAYF(
"Modes:\n"
@@ -2266,7 +2663,7 @@ int main(int argc, char **argv, char **envp) {
" AFL_USE_TSAN: activate thread sanitizer\n"
" AFL_USE_LSAN: activate leak-checker sanitizer\n");
- if (have_gcc_plugin)
+ if (aflcc->have_gcc_plugin)
SAYF(
"\nGCC Plugin-specific environment variables:\n"
" AFL_GCC_CMPLOG: log operands of comparisons (RedQueen mutator)\n"
@@ -2282,7 +2679,7 @@ int main(int argc, char **argv, char **envp) {
#define COUNTER_BEHAVIOUR \
" AFL_LLVM_NOT_ZERO: use cycling trace counters that skip zero\n"
#endif
- if (have_llvm)
+ if (aflcc->have_llvm)
SAYF(
"\nLLVM/LTO/afl-clang-fast/afl-clang-lto specific environment "
"variables:\n"
@@ -2310,7 +2707,7 @@ int main(int argc, char **argv, char **envp) {
"instrument allow/\n"
" deny listing (selective instrumentation)\n");
- if (have_llvm)
+ if (aflcc->have_llvm)
SAYF(
" AFL_LLVM_CMPLOG: log operands of comparisons (RedQueen "
"mutator)\n"
@@ -2329,7 +2726,7 @@ int main(int argc, char **argv, char **envp) {
"locations\n");
#ifdef AFL_CLANG_FLTO
- if (have_lto)
+ if (aflcc->have_lto)
SAYF(
"\nLTO/afl-clang-lto specific environment variables:\n"
" AFL_LLVM_MAP_ADDR: use a fixed coverage map address (speed), "
@@ -2365,9 +2762,9 @@ int main(int argc, char **argv, char **envp) {
"targets.\n\n");
#if (LLVM_MAJOR >= 3)
- if (have_lto)
+ if (aflcc->have_lto)
SAYF("afl-cc LTO with ld=%s %s\n", AFL_REAL_LD, AFL_CLANG_FLTO);
- if (have_llvm)
+ if (aflcc->have_llvm)
SAYF("afl-cc LLVM version %d using the binary path \"%s\".\n", LLVM_MAJOR,
LLVM_BINDIR);
#endif
@@ -2406,205 +2803,356 @@ int main(int argc, char **argv, char **envp) {
}
- if (compiler_mode == LTO) {
+}
- if (instrument_mode == 0 || instrument_mode == INSTRUMENT_LTO ||
- instrument_mode == INSTRUMENT_CFG ||
- instrument_mode == INSTRUMENT_PCGUARD) {
+static void process_params(aflcc_state_t *aflcc, u8 scan, u32 argc,
+ char **argv) {
- lto_mode = 1;
- // force CFG
- // if (!instrument_mode) {
+ limit_params(aflcc, argc);
- instrument_mode = INSTRUMENT_PCGUARD;
- // ptr = instrument_mode_string[instrument_mode];
- // }
-
- } else if (instrument_mode == INSTRUMENT_CLASSIC) {
+ // for (u32 x = 0; x < argc; ++x) fprintf(stderr, "[%u] %s\n", x, argv[x]);
- lto_mode = 1;
+ /* Process the argument list. */
- } else {
+ u8 skip_next = 0;
+ while (--argc) {
- if (!be_quiet) {
+ u8 *cur = *(++argv);
- WARNF("afl-clang-lto called with mode %s, using that mode instead",
- instrument_mode_string[instrument_mode]);
+ if (skip_next > 0) {
- }
+ skip_next--;
+ continue;
}
- }
+ if (PARAM_MISS != parse_misc_params(aflcc, cur, scan)) continue;
- if (instrument_mode == 0 && compiler_mode < GCC_PLUGIN) {
+ if (PARAM_MISS != parse_fsanitize(aflcc, cur, scan)) continue;
-#if LLVM_MAJOR >= 7
- #if LLVM_MAJOR < 11 && (LLVM_MAJOR < 10 || LLVM_MINOR < 1)
- if (have_instr_env) {
+ if (PARAM_MISS != parse_linking_params(aflcc, cur, scan, &skip_next, argv))
+ continue;
- instrument_mode = INSTRUMENT_AFL;
- if (!be_quiet) {
+ if (*cur == '@') {
- WARNF(
- "Switching to classic instrumentation because "
- "AFL_LLVM_ALLOWLIST/DENYLIST does not work with PCGUARD < 10.0.1.");
+ // response file support.
+ // we have two choices - move everything to the command line or
+ // rewrite the response files to temporary files and delete them
+ // afterwards. We choose the first for easiness.
+ // We do *not* support quotes in the rsp files to cope with spaces in
+ // filenames etc! If you need that then send a patch!
+ u8 *filename = cur + 1;
+ if (aflcc->debug) { DEBUGF("response file=%s\n", filename); }
+ FILE *f = fopen(filename, "r");
+ struct stat st;
+
+ // Check not found or empty? let the compiler complain if so.
+ if (!f || fstat(fileno(f), &st) < 0 || st.st_size < 1) {
+
+ if (!scan) insert_param(aflcc, cur);
+ continue;
}
- } else
+ u8 *tmpbuf = malloc(st.st_size + 2), *ptr;
+ char **args = malloc(sizeof(char *) * (st.st_size >> 1));
+ int count = 1, cont = 0, cont_act = 0;
- #endif
- instrument_mode = INSTRUMENT_PCGUARD;
+ while (fgets(tmpbuf, st.st_size + 1, f)) {
-#else
- instrument_mode = INSTRUMENT_AFL;
-#endif
+ ptr = tmpbuf;
+ // fprintf(stderr, "1: %s\n", ptr);
+ // no leading whitespace
+ while (isspace(*ptr)) {
- }
+ ++ptr;
+ cont_act = 0;
- if (instrument_opt_mode && compiler_mode != LLVM)
- FATAL("CTX, CALLER and NGRAM can only be used in LLVM mode");
+ }
- if (!instrument_opt_mode) {
+ // no comments, no empty lines
+ if (*ptr == '#' || *ptr == '\n' || !*ptr) { continue; }
+ // remove LF
+ if (ptr[strlen(ptr) - 1] == '\n') { ptr[strlen(ptr) - 1] = 0; }
+ // remove CR
+ if (*ptr && ptr[strlen(ptr) - 1] == '\r') { ptr[strlen(ptr) - 1] = 0; }
+ // handle \ at end of line
+ if (*ptr && ptr[strlen(ptr) - 1] == '\\') {
- if (lto_mode && instrument_mode == INSTRUMENT_CFG)
- instrument_mode = INSTRUMENT_PCGUARD;
- ptr = instrument_mode_string[instrument_mode];
+ cont = 1;
+ ptr[strlen(ptr) - 1] = 0;
- } else {
+ }
- char *ptr2 = alloc_printf(" + NGRAM-%u", ngram_size);
- char *ptr3 = alloc_printf(" + K-CTX-%u", ctx_k);
+ // fprintf(stderr, "2: %s\n", ptr);
- ptr = alloc_printf(
- "%s%s%s%s%s", instrument_mode_string[instrument_mode],
- (instrument_opt_mode & INSTRUMENT_OPT_CTX) ? " + CTX" : "",
- (instrument_opt_mode & INSTRUMENT_OPT_CALLER) ? " + CALLER" : "",
- (instrument_opt_mode & INSTRUMENT_OPT_NGRAM) ? ptr2 : "",
- (instrument_opt_mode & INSTRUMENT_OPT_CTX_K) ? ptr3 : "");
+ // remove whitespace at end
+ while (*ptr && isspace(ptr[strlen(ptr) - 1])) {
- ck_free(ptr2);
- ck_free(ptr3);
+ ptr[strlen(ptr) - 1] = 0;
+ cont = 0;
- }
+ }
-#ifndef AFL_CLANG_FLTO
- if (lto_mode)
- FATAL(
- "instrumentation mode LTO specified but LLVM support not available "
- "(requires LLVM 11 or higher)");
-#endif
+ // fprintf(stderr, "3: %s\n", ptr);
+ if (*ptr) {
- if (instrument_opt_mode && instrument_opt_mode != INSTRUMENT_OPT_CODECOV &&
- instrument_mode != INSTRUMENT_CLASSIC)
- FATAL(
- "CALLER, CTX and NGRAM instrumentation options can only be used with "
- "the LLVM CLASSIC instrumentation mode.");
+ do {
- if (getenv("AFL_LLVM_SKIP_NEVERZERO") && getenv("AFL_LLVM_NOT_ZERO"))
- FATAL(
- "AFL_LLVM_NOT_ZERO and AFL_LLVM_SKIP_NEVERZERO can not be set "
- "together");
+ u8 *value = ptr;
+ while (*ptr && !isspace(*ptr)) {
-#if LLVM_MAJOR < 11 && (LLVM_MAJOR < 10 || LLVM_MINOR < 1)
- if (instrument_mode == INSTRUMENT_PCGUARD && have_instr_env) {
+ ++ptr;
- FATAL(
- "Instrumentation type PCGUARD does not support "
- "AFL_LLVM_ALLOWLIST/DENYLIST! Use LLVM 10.0.1+ instead.");
+ }
- }
+ while (*ptr && isspace(*ptr)) {
-#endif
+ *ptr++ = 0;
- u8 *ptr2;
+ }
- if ((ptr2 = getenv("AFL_LLVM_DICT2FILE")) != NULL && *ptr2 != '/')
- FATAL("AFL_LLVM_DICT2FILE must be set to an absolute file path");
+ if (cont_act) {
- if ((isatty(2) && !be_quiet) || debug) {
+ u32 len = strlen(args[count - 1]) + strlen(value) + 1;
+ u8 *tmp = malloc(len);
+ snprintf(tmp, len, "%s%s", args[count - 1], value);
+ free(args[count - 1]);
+ args[count - 1] = tmp;
+ cont_act = 0;
- SAYF(cCYA
- "afl-cc" VERSION cRST
- " by Michal Zalewski, Laszlo Szekeres, Marc Heuse - mode: %s-%s\n",
- compiler_mode_string[compiler_mode], ptr);
+ } else {
- }
+ args[count++] = strdup(value);
- if (!be_quiet && (compiler_mode == GCC || compiler_mode == CLANG)) {
+ }
- WARNF(
- "You are using outdated instrumentation, install LLVM and/or "
- "gcc-plugin and use afl-clang-fast/afl-clang-lto/afl-gcc-fast "
- "instead!");
+ } while (*ptr);
+
+ }
+
+ if (cont) {
+
+ cont_act = 1;
+ cont = 0;
+
+ }
+
+ }
+
+ if (count) { process_params(aflcc, scan, count, args); }
+
+ // we cannot free args[] unless we don't need
+ // to keep any reference in cc_params
+ if (scan) {
+
+ if (count) do {
+
+ free(args[--count]);
+
+ } while (count);
+
+ free(args);
+
+ }
+
+ free(tmpbuf);
+
+ continue;
+
+ }
+
+ if (!scan) insert_param(aflcc, cur);
}
- if (debug) {
+}
- DEBUGF("cd '%s';", getthecwd());
- for (i = 0; i < argc; i++)
- SAYF(" '%s'", argv[i]);
- SAYF("\n");
- fflush(stdout);
- fflush(stderr);
+/* Copy argv to cc_params, making the necessary edits. */
+
+static void edit_params(aflcc_state_t *aflcc, u32 argc, char **argv,
+ char **envp) {
+
+ add_real_argv0(aflcc);
+
+ // prevent unnecessary build errors
+ if (aflcc->compiler_mode != GCC_PLUGIN && aflcc->compiler_mode != GCC) {
+
+ insert_param(aflcc, "-Wno-unused-command-line-argument");
}
- if (getenv("AFL_LLVM_LAF_ALL")) {
+ if (aflcc->compiler_mode == GCC || aflcc->compiler_mode == CLANG) {
- setenv("AFL_LLVM_LAF_SPLIT_SWITCHES", "1", 1);
- setenv("AFL_LLVM_LAF_SPLIT_COMPARES", "1", 1);
- setenv("AFL_LLVM_LAF_SPLIT_FLOATS", "1", 1);
- setenv("AFL_LLVM_LAF_TRANSFORM_COMPARES", "1", 1);
+ add_assembler(aflcc);
}
- cmplog_mode = getenv("AFL_CMPLOG") || getenv("AFL_LLVM_CMPLOG") ||
- getenv("AFL_GCC_CMPLOG");
+ if (aflcc->compiler_mode == GCC_PLUGIN) { add_gcc_plugin(aflcc); }
-#if !defined(__ANDROID__) && !defined(ANDROID)
- ptr = find_object("afl-compiler-rt.o", argv[0]);
+ if (aflcc->compiler_mode == LLVM || aflcc->compiler_mode == LTO) {
- if (!ptr) {
+ if (aflcc->lto_mode && aflcc->have_instr_env) {
- FATAL(
- "Unable to find 'afl-compiler-rt.o'. Please set the AFL_PATH "
- "environment variable.");
+ load_llvm_pass(aflcc, "afl-llvm-lto-instrumentlist.so");
- }
+ }
- if (debug) { DEBUGF("rt=%s obj_path=%s\n", ptr, obj_path); }
+ if (getenv("AFL_LLVM_DICT2FILE")) {
- ck_free(ptr);
-#endif
+ load_llvm_pass(aflcc, "afl-llvm-dict2file.so");
- edit_params(argc, argv, envp);
+ }
- if (debug) {
+ // laf
+ if (getenv("LAF_SPLIT_SWITCHES") || getenv("AFL_LLVM_LAF_SPLIT_SWITCHES")) {
- DEBUGF("cd '%s';", getthecwd());
- for (i = 0; i < (s32)cc_par_cnt; i++)
- SAYF(" '%s'", cc_params[i]);
- SAYF("\n");
- fflush(stdout);
- fflush(stderr);
+ load_llvm_pass(aflcc, "split-switches-pass.so");
+
+ }
+
+ if (getenv("LAF_TRANSFORM_COMPARES") ||
+ getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES")) {
+
+ load_llvm_pass(aflcc, "compare-transform-pass.so");
+
+ }
+
+ if (getenv("LAF_SPLIT_COMPARES") || getenv("AFL_LLVM_LAF_SPLIT_COMPARES") ||
+ getenv("AFL_LLVM_LAF_SPLIT_FLOATS")) {
+
+ load_llvm_pass(aflcc, "split-compares-pass.so");
+
+ }
+
+ // /laf
+
+ if (aflcc->cmplog_mode) {
+
+ insert_param(aflcc, "-fno-inline");
+
+ load_llvm_pass(aflcc, "cmplog-switches-pass.so");
+ // reuse split switches from laf
+ load_llvm_pass(aflcc, "split-switches-pass.so");
+
+ }
+
+ // #if LLVM_MAJOR >= 13
+ // // Use the old pass manager in LLVM 14 which the AFL++ passes still
+ // use. insert_param(aflcc, "-flegacy-pass-manager");
+ // #endif
+
+ if (aflcc->lto_mode) {
+
+ insert_param(aflcc, aflcc->lto_flag);
+
+ if (!aflcc->have_c) {
+
+ add_lto_linker(aflcc);
+ add_lto_passes(aflcc);
+
+ }
+
+ } else {
+
+ if (aflcc->instrument_mode == INSTRUMENT_PCGUARD) {
+
+ add_optimized_pcguard(aflcc);
+
+ } else if (aflcc->instrument_mode == INSTRUMENT_LLVMNATIVE) {
+
+ add_native_pcguard(aflcc);
+
+ } else {
+
+ load_llvm_pass(aflcc, "afl-llvm-pass.so");
+
+ }
+
+ }
+
+ if (aflcc->cmplog_mode) {
+
+ load_llvm_pass(aflcc, "cmplog-instructions-pass.so");
+ load_llvm_pass(aflcc, "cmplog-routines-pass.so");
+
+ }
+
+ if (getenv("AFL_LLVM_INJECTIONS_ALL") ||
+ getenv("AFL_LLVM_INJECTIONS_SQL") ||
+ getenv("AFL_LLVM_INJECTIONS_LDAP") ||
+ getenv("AFL_LLVM_INJECTIONS_XSS")) {
+
+ load_llvm_pass(aflcc, "injection-pass.so");
+
+ }
+
+ // insert_param(aflcc, "-Qunused-arguments");
}
- if (passthrough) {
+ /* Inspect the command line parameters. */
+
+ process_params(aflcc, 0, argc, argv);
+
+ add_sanitizers(aflcc, envp);
+
+ add_misc_params(aflcc);
+
+ add_defs_common(aflcc);
+ add_defs_selective_instr(aflcc);
+ add_defs_persistent_mode(aflcc);
+
+ add_runtime(aflcc);
+
+ insert_param(aflcc, NULL);
+
+}
+
+/* Main entry point */
+
+int main(int argc, char **argv, char **envp) {
+
+ aflcc_state_t *aflcc = malloc(sizeof(aflcc_state_t));
+ aflcc_state_init(aflcc, (u8 *)argv[0]);
+
+ check_environment_vars(envp);
+
+ find_built_deps(aflcc);
+
+ compiler_mode_by_callname(aflcc);
+ compiler_mode_by_environ(aflcc);
+ compiler_mode_by_cmdline(aflcc, argc, argv);
+
+ instrument_mode_by_environ(aflcc);
+
+ mode_final_checkout(aflcc, argc, argv);
+
+ process_params(aflcc, 1, argc, argv);
+
+ maybe_usage(aflcc, argc, argv);
+
+ mode_notification(aflcc);
+
+ if (aflcc->debug) debugf_args(argc, argv);
+
+ edit_params(aflcc, argc, argv, envp);
+
+ if (aflcc->debug)
+ debugf_args((s32)aflcc->cc_par_cnt, (char **)aflcc->cc_params);
+
+ if (aflcc->passthrough) {
- argv[0] = cc_params[0];
- execvp(cc_params[0], (char **)argv);
+ argv[0] = aflcc->cc_params[0];
+ execvp(aflcc->cc_params[0], (char **)argv);
} else {
- execvp(cc_params[0], (char **)cc_params);
+ execvp(aflcc->cc_params[0], (char **)aflcc->cc_params);
}
- FATAL("Oops, failed to execute '%s' - check your PATH", cc_params[0]);
+ FATAL("Oops, failed to execute '%s' - check your PATH", aflcc->cc_params[0]);
return 0;
diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c
index 34a5ff81..1ee8ebe7 100644
--- a/src/afl-fuzz-run.c
+++ b/src/afl-fuzz-run.c
@@ -169,20 +169,16 @@ write_to_testcase(afl_state_t *afl, void **mem, u32 len, u32 fix) {
}
- if (unlikely(afl->custom_mutators_count)) {
-
- LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
-
- if (el->afl_custom_fuzz_send) {
+ LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
- el->afl_custom_fuzz_send(el->data, *mem, new_size);
- sent = 1;
+ if (el->afl_custom_fuzz_send) {
- }
+ el->afl_custom_fuzz_send(el->data, *mem, new_size);
+ sent = 1;
- });
+ }
- }
+ });
if (likely(!sent)) {
@@ -203,7 +199,7 @@ write_to_testcase(afl_state_t *afl, void **mem, u32 len, u32 fix) {
}
- } else {
+ } else { /* !afl->custom_mutators_count */
if (unlikely(len < afl->min_length && !fix)) {
@@ -215,27 +211,8 @@ write_to_testcase(afl_state_t *afl, void **mem, u32 len, u32 fix) {
}
- if (unlikely(afl->custom_mutators_count)) {
-
- LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
-
- if (el->afl_custom_fuzz_send) {
-
- el->afl_custom_fuzz_send(el->data, *mem, len);
- sent = 1;
-
- }
-
- });
-
- }
-
- if (likely(!sent)) {
-
- /* boring uncustom. */
- afl_fsrv_write_to_testcase(&afl->fsrv, *mem, len);
-
- }
+ /* boring uncustom. */
+ afl_fsrv_write_to_testcase(&afl->fsrv, *mem, len);
}
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 17949fd7..2d5787e8 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -1812,6 +1812,10 @@ int main(int argc, char **argv_orig, char **envp) {
check_cpu_governor(afl);
#endif
+ #ifdef __APPLE__
+ setenv("DYLD_NO_PIE", "1", 0);
+ #endif
+
if (getenv("LD_PRELOAD")) {
WARNF(
--
cgit 1.4.1
From a518c4d75c15e2e0cb8633361a0162eb70c7965b Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 19 Jan 2024 11:53:44 +0100
Subject: macos
---
afl-cmin | 6 ++++-
docs/Changelog.md | 1 +
test/test-basic.sh | 69 ++++++++++++++++++++++++++++++------------------------
test/test-llvm.sh | 28 +++++++++++++---------
4 files changed, 62 insertions(+), 42 deletions(-)
(limited to 'docs')
diff --git a/afl-cmin b/afl-cmin
index 566f157d..4aaf3953 100755
--- a/afl-cmin
+++ b/afl-cmin
@@ -1,11 +1,15 @@
#!/usr/bin/env sh
+SYS=$(uname -s)
+test "$SYS" = "Darwin" && {
+ echo Error: afl-cmin does not work on Apple currently. please use afl-cmin.bash instead.
+ exit 1
+}
export AFL_QUIET=1
export ASAN_OPTIONS=detect_leaks=0
THISPATH=`dirname ${0}`
export PATH="${THISPATH}:$PATH"
awk -f - -- ${@+"$@"} <<'EOF'
#!/usr/bin/awk -f
-
# awk script to minimize a test corpus of input files
#
# based on afl-cmin bash script written by Michal Zalewski
diff --git a/docs/Changelog.md b/docs/Changelog.md
index c681c4e1..ad0f7a5a 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -26,6 +26,7 @@
produces drcov compatible traces for lighthouse/lightkeeper/...
thanks to @JRomainG to submitting!
- updated the custom grammar mutator
+ - document afl-cmin does not work on macOS
### Version ++4.09c (release)
diff --git a/test/test-basic.sh b/test/test-basic.sh
index 61ad4b7c..7005d3ce 100755
--- a/test/test-basic.sh
+++ b/test/test-basic.sh
@@ -2,6 +2,7 @@
. ./test-pre.sh
+OS=$(uname -s)
AFL_GCC=afl-gcc
$ECHO "$BLUE[*] Testing: ${AFL_GCC}, afl-showmap, afl-fuzz, afl-cmin and afl-tmin"
@@ -61,7 +62,7 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc
}
# now we want to be sure that afl-fuzz is working
# make sure crash reporter is disabled on Mac OS X
- (test "$(uname -s)" = "Darwin" && test $(launchctl list 2>/dev/null | grep -q '\.ReportCrash$') && {
+ (test "$OS" = "Darwin" && test $(launchctl list 2>/dev/null | grep -q '\.ReportCrash$') && {
$ECHO "$RED[!] we cannot run afl-fuzz with enabled crash reporter. Run 'sudo sh afl-system-config'.$RESET"
true
}) || {
@@ -84,16 +85,20 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc
}
echo 000000000000000000000000 > in/in2
echo 111 > in/in3
- mkdir -p in2
- ../afl-cmin -m ${MEM_LIMIT} -i in -o in2 -- ./test-instr.plain >/dev/null 2>&1 # why is afl-forkserver writing to stderr?
- CNT=`ls in2/* 2>/dev/null | wc -l`
- case "$CNT" in
- *2) $ECHO "$GREEN[+] afl-cmin correctly minimized the number of testcases" ;;
- *) $ECHO "$RED[!] afl-cmin did not correctly minimize the number of testcases ($CNT)"
- CODE=1
- ;;
- esac
- rm -f in2/in*
+ test "$OS" = "Darwin" && {
+ $ECHO "$GREY[*] afl-cmin not available on macOS, cannot test afl-cmin"
+ } || {
+ mkdir -p in2
+ ../afl-cmin -m ${MEM_LIMIT} -i in -o in2 -- ./test-instr.plain >/dev/null 2>&1 # why is afl-forkserver writing to stderr?
+ CNT=`ls in2/* 2>/dev/null | wc -l`
+ case "$CNT" in
+ *2) $ECHO "$GREEN[+] afl-cmin correctly minimized the number of testcases" ;;
+ *) $ECHO "$RED[!] afl-cmin did not correctly minimize the number of testcases ($CNT)"
+ CODE=1
+ ;;
+ esac
+ rm -f in2/in*
+ }
export AFL_QUIET=1
if command -v bash >/dev/null ; then {
../afl-cmin.bash -m ${MEM_LIMIT} -i in -o in2 -- ./test-instr.plain >/dev/null
@@ -182,7 +187,7 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc
}
# now we want to be sure that afl-fuzz is working
# make sure crash reporter is disabled on Mac OS X
- (test "$(uname -s)" = "Darwin" && test $(launchctl list 2>/dev/null | grep -q '\.ReportCrash$') && {
+ (test "$OS" = "Darwin" && test $(launchctl list 2>/dev/null | grep -q '\.ReportCrash$') && {
$ECHO "$RED[!] we cannot run afl-fuzz with enabled crash reporter. Run 'sudo sh afl-system-config'.$RESET"
true
}) || {
@@ -204,25 +209,29 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc
}
}
echo 000000000000000000000000 > in/in2
- echo AAA > in/in3
- mkdir -p in2
- ../afl-cmin -m ${MEM_LIMIT} -i in -o in2 -- ./test-instr.plain >/dev/null 2>&1 # why is afl-forkserver writing to stderr?
- CNT=`ls in2/* 2>/dev/null | wc -l`
- case "$CNT" in
- *2) $ECHO "$GREEN[+] afl-cmin correctly minimized the number of testcases" ;;
- \ *1|1) { # allow leading whitecase for portability
- test -s in2/* && $ECHO "$YELLOW[?] afl-cmin did minimize to one testcase. This can be a bug or due compiler optimization."
- test -s in2/* || {
- $ECHO "$RED[!] afl-cmin did not correctly minimize the number of testcases ($CNT)"
- CODE=1
+ echo AAA > in/in2
+ test "$OS" = "Darwin" && {
+ $ECHO "$GREY[*] afl-cmin not available on macOS, cannot test afl-cmin"
+ } || {
+ mkdir -p in2
+ ../afl-cmin -m ${MEM_LIMIT} -i in -o in2 -- ./test-instr.plain >/dev/null 2>&1 # why is afl-forkserver writing to stderr?
+ CNT=`ls in2/* 2>/dev/null | wc -l`
+ case "$CNT" in
+ *2) $ECHO "$GREEN[+] afl-cmin correctly minimized the number of testcases" ;;
+ \ *1|1) { # allow leading whitecase for portability
+ test -s in2/* && $ECHO "$YELLOW[?] afl-cmin did minimize to one testcase. This can be a bug or due compiler optimization."
+ test -s in2/* || {
+ $ECHO "$RED[!] afl-cmin did not correctly minimize the number of testcases ($CNT)"
+ CODE=1
+ }
}
- }
- ;;
- *) $ECHO "$RED[!] afl-cmin did not correctly minimize the number of testcases ($CNT)"
- CODE=1
- ;;
- esac
- rm -f in2/in*
+ ;;
+ *) $ECHO "$RED[!] afl-cmin did not correctly minimize the number of testcases ($CNT)"
+ CODE=1
+ ;;
+ esac
+ rm -f in2/in*
+ }
export AFL_QUIET=1
if command -v bash >/dev/null ; then {
../afl-cmin.bash -m ${MEM_LIMIT} -i in -o in2 -- ./test-instr.plain >/dev/null
diff --git a/test/test-llvm.sh b/test/test-llvm.sh
index 95e43b1c..53bbd7b4 100755
--- a/test/test-llvm.sh
+++ b/test/test-llvm.sh
@@ -2,6 +2,8 @@
. ./test-pre.sh
+OS=$(uname -s)
+
$ECHO "$BLUE[*] Testing: llvm_mode, afl-showmap, afl-fuzz, afl-cmin and afl-tmin"
test -e ../afl-clang-fast -a -e ../split-switches-pass.so && {
../afl-clang-fast -o test-instr.plain ../test-instr.c > /dev/null 2>&1
@@ -123,7 +125,7 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && {
}
# now we want to be sure that afl-fuzz is working
# make sure crash reporter is disabled on Mac OS X
- (test "$(uname -s)" = "Darwin" && test $(launchctl list 2>/dev/null | grep -q '\.ReportCrash$') && {
+ (test "$OS" = "Darwin" && test $(launchctl list 2>/dev/null | grep -q '\.ReportCrash$') && {
$ECHO "$RED[!] we cannot run afl-fuzz with enabled crash reporter. Run 'sudo sh afl-system-config'.$RESET"
CODE=1
true
@@ -146,18 +148,22 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && {
}
}
test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc" || {
+ mkdir -p in2
echo 000000000000000000000000 > in/in2
echo 111 > in/in3
- mkdir -p in2
- ../afl-cmin -m ${MEM_LIMIT} -i in -o in2 -- ./test-instr.plain >/dev/null 2>&1 # why is afl-forkserver writing to stderr?
- CNT=`ls in2/* 2>/dev/null | wc -l`
- case "$CNT" in
- *2) $ECHO "$GREEN[+] afl-cmin correctly minimized the number of testcases" ;;
- *) $ECHO "$RED[!] afl-cmin did not correctly minimize the number of testcases ($CNT)"
- CODE=1
- ;;
- esac
- rm -f in2/in*
+ test "$OS" = "Darwin" && {
+ $ECHO "$GREY[*] afl-cmin not available on macOS, cannot test afl-cmin"
+ } || {
+ ../afl-cmin -m ${MEM_LIMIT} -i in -o in2 -- ./test-instr.plain >/dev/null 2>&1 # why is afl-forkserver writing to stderr?
+ CNT=`ls in2/* 2>/dev/null | wc -l`
+ case "$CNT" in
+ *2) $ECHO "$GREEN[+] afl-cmin correctly minimized the number of testcases" ;;
+ *) $ECHO "$RED[!] afl-cmin did not correctly minimize the number of testcases ($CNT)"
+ CODE=1
+ ;;
+ esac
+ rm -f in2/in*
+ }
export AFL_QUIET=1
if type bash >/dev/null ; then {
../afl-cmin.bash -m ${MEM_LIMIT} -i in -o in2 -- ./test-instr.plain >/dev/null
--
cgit 1.4.1
From 9cefc4d3d48f6bfddc63e29cf4256c8382fc59d7 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 22 Jan 2024 10:52:22 +0100
Subject: fix docs
---
docs/resources/1_instrument_target.drawio.svg | 2 +-
instrumentation/README.lto.md | 12 ++++++------
src/afl-fuzz.c | 2 +-
3 files changed, 8 insertions(+), 8 deletions(-)
(limited to 'docs')
diff --git a/docs/resources/1_instrument_target.drawio.svg b/docs/resources/1_instrument_target.drawio.svg
index af6ac397..c93fa2b8 100644
--- a/docs/resources/1_instrument_target.drawio.svg
+++ b/docs/resources/1_instrument_target.drawio.svg
@@ -1,4 +1,4 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/instrumentation/README.lto.md b/instrumentation/README.lto.md
index df59cc2a..bd479c26 100644
--- a/instrumentation/README.lto.md
+++ b/instrumentation/README.lto.md
@@ -2,7 +2,7 @@
## TL;DR:
-This version requires a LLVM 11 or newer.
+This version requires a LLVM 12 or newer.
1. Use afl-clang-lto/afl-clang-lto++ because the resulting binaries run
slightly faster and give better coverage.
@@ -10,7 +10,7 @@ This version requires a LLVM 11 or newer.
2. You can use it together with COMPCOV, COMPLOG and the instrument file
listing features.
-3. It only works with LLVM 11 or newer.
+3. It only works with LLVM 12 or newer.
4. AUTODICTIONARY feature (see below)
@@ -60,7 +60,7 @@ AUTODICTIONARY: 11 strings found
[+] Instrumented 12071 locations with no collisions (on average 1046 collisions would be in afl-gcc/afl-clang-fast) (non-hardened mode).
```
-## Getting LLVM 11+
+## Getting LLVM 12+
### Installing llvm
@@ -73,7 +73,7 @@ chmod +x llvm.sh
sudo ./llvm.sh 15 all
```
-LLVM 11 to 16 should be available in all current Linux repositories.
+LLVM 12 to 18 should be available in all current Linux repositories.
## How to build afl-clang-lto
@@ -277,7 +277,7 @@ AS=llvm-as ...
afl-clang-lto is still work in progress.
Known issues:
-* Anything that LLVM 11+ cannot compile, afl-clang-lto cannot compile either -
+* Anything that LLVM 12+ cannot compile, afl-clang-lto cannot compile either -
obviously.
* Anything that does not compile with LTO, afl-clang-lto cannot compile either -
obviously.
@@ -319,7 +319,7 @@ Still more problems came up though as this only works without bugs from LLVM 9
onwards, and with high optimization the link optimization ruins the instrumented
control flow graph.
-This is all now fixed with LLVM 11+. The llvm's own linker is now able to load
+This is all now fixed with LLVM 12+. The llvm's own linker is now able to load
passes and this bypasses all problems we had.
Happy end :)
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 2d5787e8..5aec072e 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -165,7 +165,7 @@ static void usage(u8 *argv0, int more_help) {
"\n"
"Mutator settings:\n"
- " -a - target input format, \"text\" or \"binary\" (default: "
+ " -a type - target input format, \"text\" or \"binary\" (default: "
"generic)\n"
" -g minlength - set min length of generated fuzz input (default: 1)\n"
" -G maxlength - set max length of generated fuzz input (default: "
--
cgit 1.4.1
From 33a129e00cbfcc0f979880270e01cbf58400c75a Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 22 Jan 2024 11:01:30 +0100
Subject: update changelog
---
docs/Changelog.md | 1 +
1 file changed, 1 insertion(+)
(limited to 'docs')
diff --git a/docs/Changelog.md b/docs/Changelog.md
index ad0f7a5a..9accb9da 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -25,6 +25,7 @@
- plugins are now activated by default and a new module is included that
produces drcov compatible traces for lighthouse/lightkeeper/...
thanks to @JRomainG to submitting!
+ - updated Nyx checkout (fixes a bug)
- updated the custom grammar mutator
- document afl-cmin does not work on macOS
--
cgit 1.4.1
From 1ffb1b6b2adaedbee7febc9f344c042fd25eae1a Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 26 Jan 2024 16:58:17 +0100
Subject: changelog
---
docs/Changelog.md | 3 +++
1 file changed, 3 insertions(+)
(limited to 'docs')
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 9accb9da..38dbba82 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -12,6 +12,7 @@
- afl-cc:
- large rewrite by @SonicStark which fixes a few corner cases, thanks!
- LTO mode now requires llvm 12+
+ - workaround for ASAN with gcc_plugin mode
- instrumentation:
- LLVM 18 support, thanks to @devnexen!
- Injection (SQL, LDAP, XSS) feature now available, see
@@ -21,6 +22,8 @@
- due a bug in LLVM 17 integer splitting is disabled there!
- when splitting floats was selected, integers were always split as well,
fixed to require AFL_LLVM_LAF_SPLIT_COMPARES or _ALL as it should
+ - dynamic instrumentation filtering for LLVM NATIVE, thanks @Mozilla!
+ see utils/dynamic_covfilter/README.md
- qemu_mode:
- plugins are now activated by default and a new module is included that
produces drcov compatible traces for lighthouse/lightkeeper/...
--
cgit 1.4.1
From ccad11f7eb04e8c0de76fec6fd4b6eab1e940319 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 31 Jan 2024 14:03:25 +0100
Subject: nyx build script updates
---
docs/Changelog.md | 6 ++---
nyx_mode/build_nyx_support.sh | 57 ++++++++++++++++++++++++++++++++++++-------
2 files changed, 51 insertions(+), 12 deletions(-)
(limited to 'docs')
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 38dbba82..720a0689 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -15,7 +15,7 @@
- workaround for ASAN with gcc_plugin mode
- instrumentation:
- LLVM 18 support, thanks to @devnexen!
- - Injection (SQL, LDAP, XSS) feature now available, see
+ - Injection (SQL, LDAP, XSS) fuzzing feature now available, see
`instrumentation/README.injections.md` how to activate/use/expand.
- compcov/LAF-intel:
- floating point splitting bug fix by @hexcoder
@@ -28,9 +28,9 @@
- plugins are now activated by default and a new module is included that
produces drcov compatible traces for lighthouse/lightkeeper/...
thanks to @JRomainG to submitting!
- - updated Nyx checkout (fixes a bug)
+ - updated Nyx checkout (fixes a bug) and some QOL
- updated the custom grammar mutator
- - document afl-cmin does not work on macOS
+ - document afl-cmin does not work on macOS (but afl-cmin.bash does)
### Version ++4.09c (release)
diff --git a/nyx_mode/build_nyx_support.sh b/nyx_mode/build_nyx_support.sh
index 581a8292..454d1e7b 100755
--- a/nyx_mode/build_nyx_support.sh
+++ b/nyx_mode/build_nyx_support.sh
@@ -28,6 +28,7 @@ echo "[*] Making sure all Nyx is checked out"
if git status 1>/dev/null 2>&1; then
+ set +e
git submodule init
echo "[*] initializing QEMU-Nyx submodule"
git submodule update ./QEMU-Nyx 2>/dev/null # ignore errors
@@ -35,6 +36,7 @@ if git status 1>/dev/null 2>&1; then
git submodule update ./packer 2>/dev/null # ignore errors
echo "[*] initializing libnyx submodule"
git submodule update ./libnyx 2>/dev/null # ignore errors
+ set -e
else
@@ -48,20 +50,57 @@ test -e packer/.git || { echo "[-] packer not checked out, please install git or
test -e libnyx/.git || { echo "[-] libnyx not checked out, please install git or check your internet connection." ; exit 1 ; }
test -e QEMU-Nyx/.git || { echo "[-] QEMU-Nyx not checked out, please install git or check your internet connection." ; exit 1 ; }
-echo "[*] checking packer init.cpio.gz ..."
-if [ ! -f "packer/linux_initramfs/init.cpio.gz" ]; then
- (cd packer/linux_initramfs/ && sh pack.sh)
+
+QEMU_NYX_VERSION="$(cat ./QEMU_NYX_VERSION)"
+cd "./QEMU-Nyx" || exit 1
+if [ -n "$NO_CHECKOUT" ]; then
+ echo "[*] Skipping checkout to $QEMU_NYX_VERSION"
+else
+ echo "[*] Checking out $QEMU_NYX_VERSION"
+ set +e
+ sh -c 'git stash' 1>/dev/null 2>/dev/null
+ git pull 1>/dev/null 2>/dev/null
+ git checkout "$QEMU_NYX_VERSION" || echo Warning: could not check out to commit $QEMU_NYX_VERSION
+ set -e
fi
+cd - > /dev/null
-echo "[*] Checking libnyx ..."
-if [ ! -f "libnyx/libnyx/target/release/liblibnyx.a" ]; then
- (cd libnyx/libnyx && cargo build --release)
+PACKER_VERSION="$(cat ./PACKER_VERSION)"
+cd "./packer" || exit 1
+if [ -n "$NO_CHECKOUT" ]; then
+ echo "[*] Skipping checkout to $PACKER_VERSION"
+else
+ echo "[*] Checking out $PACKER_VERSION"
+ set +e
+ sh -c 'git stash' 1>/dev/null 2>/dev/null
+ git pull 1>/dev/null 2>/dev/null
+ git checkout "$PACKER_VERSION" || echo Warning: could not check out to commit $PACKER_VERSION
+ set -e
fi
+cd - > /dev/null
-echo "[*] Checking QEMU-Nyx ..."
-if [ ! -f "QEMU-Nyx/x86_64-softmmu/qemu-system-x86_64" ]; then
- (cd QEMU-Nyx && ./compile_qemu_nyx.sh static)
+LIBNYX_VERSION="$(cat ./LIBNYX_VERSION)"
+cd "./libnyx/" || exit 1
+if [ -n "$NO_CHECKOUT" ]; then
+ echo "[*] Skipping checkout to $LIBNYX_VERSION"
+else
+ echo "[*] Checking out $LIBNYX_VERSION"
+ set +e
+ sh -c 'git stash' 1>/dev/null 2>/dev/null
+ git pull 1>/dev/null 2>/dev/null
+ git checkout "$LIBNYX_VERSION" || echo Warning: could not check out to commit $LIBNYX_VERSION
+ set -e
fi
+cd - > /dev/null
+
+echo "[*] checking packer init.cpio.gz ..."
+(cd packer/linux_initramfs/ && sh pack.sh)
+
+echo "[*] Checking libnyx ..."
+(cd libnyx/libnyx && cargo build --release)
+
+echo "[*] Checking QEMU-Nyx ..."
+(cd QEMU-Nyx && ./compile_qemu_nyx.sh static )
echo "[*] Checking libnyx.so ..."
cp libnyx/libnyx/target/release/liblibnyx.so ../libnyx.so
--
cgit 1.4.1
From eda770fd32b804e3ebd6a43738c0002f6118a463 Mon Sep 17 00:00:00 2001
From: van Hauser
Date: Thu, 1 Feb 2024 15:13:07 +0100
Subject: push to stable (#1967)
* Output afl-clang-fast stuffs only if necessary (#1912)
* afl-cc header
* afl-cc common declarations
- Add afl-cc-state.c
- Strip includes, find_object, debug/be_quiet/have_*/callname setting from afl-cc.c
- Use debugf_args in main
- Modify execvp stuffs to fit new aflcc struct
* afl-cc show usage
* afl-cc mode selecting
1. compiler_mode by callname in argv[0]
2. compiler_mode by env "AFL_CC_COMPILER"
3. compiler_mode/instrument_mode by command line options "--afl-..."
4. instrument_mode/compiler_mode by various env vars including "AFL_LLVM_INSTRUMENT"
5. final checking steps
6. print "... - mode: %s-%s\n"
7. determine real argv[0] according to compiler_mode
* afl-cc macro defs
* afl-cc linking behaviors
* afl-cc fsanitize behaviors
* afl-cc misc
* afl-cc body update
* afl-cc all-in-one
formated with custom-format.py
* nits
---------
Co-authored-by: vanhauser-thc
* changelog
* update grammar mutator
* lto llvm 12+
* docs(custom_mutators): fix missing ':' (#1953)
* Fix broken LTO mode and response file support (#1948)
* Strip `-Wl,-no-undefined` during compilation (#1952)
Make the compiler wrapper stripping `-Wl,-no-undefined` in addition to `-Wl,--no-undefined`.
Both versions of the flag are accepted by clang and, therefore, used by building systems in the wild (e.g., samba will not build without this fix).
* Remove dead code in write_to_testcase (#1955)
The custom_mutators_count check in if case is duplicate with if condition.
The else case is custom_mutators_count == 0, neither custom_mutator_list iteration nor sent check needed.
Signed-off-by: Xeonacid
* update qemuafl
* WIP: Add ability to generate drcov trace using QEMU backend (#1956)
* Document new drcov QEMU plugin
* Add link to lightkeeper for QEMU drcov file loading
---------
Co-authored-by: Jean-Romain Garnier
* code format
* changelog
* sleep on uid != 0 afl-system-config
* fix segv about skip_next, warn on unsupported cases of linking options (#1958)
* todos
* ensure afl-cc only allows available compiler modes
* update grammar mutator
* disable aslr on apple
* fix for arm64
* help selective instrumentation
* typos
* macos
* add compiler test script
* apple fixes
* bump nyx submodules (#1963)
* fix docs
* update changelog
* update grammar mutator
* improve compiler test script
* gcc asan workaround (#1966)
* fix github merge fuckup
* fix
* Fix afl-cc (#1968)
- Check if too many cmdline params here, each time before insert a new param.
- Check if it is "-fsanitize=..." before we do sth.
- Remove improper param_st transfer.
* Avoid adding llvmnative instrumentation when linking rust sanitizer runtime (#1969)
* Dynamic instrumentation filtering for LLVM native (#1971)
* Add two dynamic instrumentation filter methods to runtime
* Always use pc-table with native pcguard
* Add make_symbol_list.py and README
* changelog
* todos
* new forkserver check
* fix
* nyx test for CI
* improve nyx docs
* Fixes to afl-cc and documentation (#1974)
* Always compile with -ldl when building for CODE_COVERAGE
When building with CODE_COVERAGE, the afl runtime contains code that
calls `dladdr` which requires -ldl. Under most circumstances, clang
already adds this (e.g. when building with pc-table), but there are some
circumstances where it isn't added automatically.
* Add visibility declaration to __afl_connected
When building with hidden visibility, the use of __AFL_LOOP inside such
code can cause linker errors due to __afl_connected being declared
"hidden".
* Update docs to clarify that CODE_COVERAGE=1 is required for dynamic_covfilter
* nits
* nyx build script updates
* test error output
* debug ci
* debug ci
* Improve afl-cc (#1975)
* update response file support
- full support of rsp file
- fix some segv issues
* Improve afl-cc
- remove dead code about allow/denylist options of sancov
- missing `if (!aflcc->have_msan)`
- add docs for each function
- typo
* enable nyx
* debug ci
* debug ci
* debug ci
* debug ci
* debug ci
* debug ci
* debug ci
* debug ci
* fix ci
* clean test script
* NO_NYX
* NO_NYX
* fix ci
* debug ci
* fix ci
* finalize ci fix
---------
Signed-off-by: Xeonacid
Co-authored-by: Sonic <50692172+SonicStark@users.noreply.github.com>
Co-authored-by: Xeonacid
Co-authored-by: Nils Bars
Co-authored-by: Jean-Romain Garnier <7504819+JRomainG@users.noreply.github.com>
Co-authored-by: Jean-Romain Garnier
Co-authored-by: Sergej Schumilo
Co-authored-by: Christian Holler (:decoder)
---
.github/workflows/ci.yml | 10 +-
Dockerfile | 6 +-
GNUmakefile | 20 +-
TODO.md | 19 +-
afl-cmin | 6 +-
custom_mutators/grammar_mutator/GRAMMAR_VERSION | 2 +-
custom_mutators/grammar_mutator/grammar_mutator | 2 +-
docs/Changelog.md | 7 +-
docs/resources/1_instrument_target.drawio.svg | 2 +-
instrumentation/README.lto.md | 12 +-
instrumentation/SanitizerCoveragePCGUARD.so.cc | 7 +
instrumentation/afl-compiler-rt.o.c | 279 ++++++++-
instrumentation/afl-llvm-common.cc | 4 +-
nyx_mode/LIBNYX_VERSION | 2 +-
nyx_mode/QEMU-Nyx | 2 +-
nyx_mode/QEMU_NYX_VERSION | 2 +-
nyx_mode/README.md | 22 +-
nyx_mode/build_nyx_support.sh | 77 ++-
nyx_mode/libnyx | 2 +-
nyx_mode/update_ref.sh | 6 +-
src/afl-cc.c | 753 +++++++++++++++++-------
src/afl-forkserver.c | 6 +
src/afl-fuzz-init.c | 6 +
src/afl-fuzz.c | 11 +-
test/test-all.sh | 2 +
test/test-basic.sh | 69 ++-
test/test-compilers.sh | 7 +
test/test-llvm.sh | 28 +-
test/test-nyx-mode.sh | 79 +++
test/test-pre.sh | 2 +-
utils/dynamic_covfilter/README.md | 60 ++
utils/dynamic_covfilter/make_symbol_list.py | 73 +++
32 files changed, 1229 insertions(+), 356 deletions(-)
create mode 100755 test/test-compilers.sh
create mode 100755 test/test-nyx-mode.sh
create mode 100644 utils/dynamic_covfilter/README.md
create mode 100644 utils/dynamic_covfilter/make_symbol_list.py
(limited to 'docs')
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index fdf618b9..ed382fbb 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -20,20 +20,18 @@ jobs:
AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: 1
steps:
- uses: actions/checkout@v3
+ - name: update
+ run: sudo apt-get update && sudo apt-get upgrade -y
- name: debug
run: apt-cache search plugin-dev | grep gcc-; echo; apt-cache search clang-format- | grep clang-format-
- - name: update
- run: sudo apt-get update
- # && sudo apt-get upgrade -y
- name: install packages
- #run: sudo apt-get install -y -m -f --install-suggests build-essential git libtool libtool-bin automake bison libglib2.0-0 clang llvm-dev libc++-dev findutils libcmocka-dev python3-dev python3-setuptools ninja-build python3-pip
- run: sudo apt-get install -y -m -f build-essential git libtool libtool-bin automake flex bison libglib2.0-0 clang llvm-dev libc++-dev findutils libcmocka-dev python3-dev python3-setuptools ninja-build python3-pip
+ run: sudo apt-get install -y -m -f build-essential gcc-10 g++-10 git libtool libtool-bin automake flex bison libglib2.0-0 clang-12 llvm-12-dev libc++-dev findutils libcmocka-dev python3-dev python3-setuptools ninja-build python3-pip gcc-10-plugin-dev
- name: compiler installed
run: gcc -v; echo; clang -v
- name: install gcc plugin
run: sudo apt-get install -y -m -f --install-suggests $(readlink /usr/bin/gcc)-plugin-dev
- name: build afl++
- run: make distrib ASAN_BUILD=1 NO_NYX=1
+ run: export NO_NYX=1; export ASAN_BUILD=1; export LLVM_CONFIG=llvm-config-12; make ASAN_BUILD=1 NO_NYX=1 LLVM_CONFIG=llvm-config-12 distrib
- name: run tests
run: sudo -E ./afl-system-config; make tests
# macos:
diff --git a/Dockerfile b/Dockerfile
index e1616198..99998a61 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -16,8 +16,8 @@ ENV NO_CORESIGHT=1
ENV NO_NYX=1
### Only change these if you know what you are doing:
-# LLVM 15 does not look good so we stay at 14 to still have LTO
-ENV LLVM_VERSION=14
+# Current recommended LLVM version is 16
+ENV LLVM_VERSION=16
# GCC 12 is producing compile errors for some targets so we stay at GCC 11
ENV GCC_VERSION=11
@@ -88,7 +88,7 @@ ARG TEST_BUILD
RUN sed -i.bak 's/^ -/ /g' GNUmakefile && \
make clean && make distrib && \
- ([ "${TEST_BUILD}" ] || (make install && make clean)) && \
+ ([ "${TEST_BUILD}" ] || (make install)) && \
mv GNUmakefile.bak GNUmakefile
RUN echo "set encoding=utf-8" > /root/.vimrc && \
diff --git a/GNUmakefile b/GNUmakefile
index b67f9c15..283c57c2 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -66,6 +66,10 @@ ifdef MSAN_BUILD
override LDFLAGS += -fsanitize=memory
endif
+ifdef CODE_COVERAGE
+ override CFLAGS += -D__AFL_CODE_COVERAGE=1
+endif
+
ifeq "$(findstring android, $(shell $(CC) --version 2>/dev/null))" ""
ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -Werror -x c - -flto=full -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
CFLAGS_FLTO ?= -flto=full
@@ -395,7 +399,7 @@ help:
@echo INTROSPECTION - compile afl-fuzz with mutation introspection
@echo NO_PYTHON - disable python support
@echo NO_SPLICING - disables splicing mutation in afl-fuzz, not recommended for normal fuzzing
- @echo NO_UTF - do not use UTF-8 for line rendering in status screen (fallback to G1 box drawing, of vanilla AFL)
+ @echo "NO_UTF - do not use UTF-8 for line rendering in status screen (fallback to G1 box drawing, of vanilla AFL)"
@echo NO_NYX - disable building nyx mode dependencies
@echo "NO_CORESIGHT - disable building coresight (arm64 only)"
@echo NO_UNICORN_ARM64 - disable building unicorn on arm64
@@ -649,16 +653,16 @@ endif
# -$(MAKE) -C utils/plot_ui
-$(MAKE) -C frida_mode
ifneq "$(SYS)" "Darwin"
- ifeq "$(ARCH)" "aarch64"
- ifndef NO_CORESIGHT
+ifeq "$(ARCH)" "aarch64"
+ ifndef NO_CORESIGHT
-$(MAKE) -C coresight_mode
- endif
endif
- ifeq "$(SYS)" "Linux"
- ifndef NO_NYX
+endif
+ifeq "$(SYS)" "Linux"
+ifndef NO_NYX
-cd nyx_mode && ./build_nyx_support.sh
- endif
- endif
+endif
+endif
-cd qemu_mode && sh ./build_qemu_support.sh
ifeq "$(ARCH)" "aarch64"
ifndef NO_UNICORN_ARM64
diff --git a/TODO.md b/TODO.md
index 7cab71e8..f2e3963f 100644
--- a/TODO.md
+++ b/TODO.md
@@ -2,26 +2,21 @@
## Must
+ - UI revamp
+ - hardened_usercopy=0 page_alloc.shuffle=0
+ - add value_profile but only enable after 15 minutes without finds
+ - cmplog max len, cmplog max items envs?
- adapt MOpt to new mutation engine
- - Update afl->pending_not_fuzzed for MOpt
- - cmplog rtn sanity check on fixed length? + no length 1
+ - Update afl->pending_not_fuzzed for MOpt
+ - cmplog rtn sanity check on fixed length? currently we ignore the length
- afl-showmap -f support
- afl-fuzz multicore wrapper script
- when trimming then perform crash detection
- - either -L0 and/or -p mmopt results in zero new coverage
+ - problem: either -L0 and/or -p mmopt results in zero new coverage
## Should
-<<<<<<< Updated upstream
- - add value_profile but only enable after 15 minutes without finds?
-=======
- - afl-showmap -f support
- - afl-fuzz multicore wrapper script
- - UI revamp
- - hardened_usercopy=0 page_alloc.shuffle=0
- - add value_profile but only enable after 15 minutes without finds
->>>>>>> Stashed changes
- afl-crash-analysis
- support persistent and deferred fork server in afl-showmap?
- better autodetection of shifting runtime timeout values
diff --git a/afl-cmin b/afl-cmin
index 566f157d..4aaf3953 100755
--- a/afl-cmin
+++ b/afl-cmin
@@ -1,11 +1,15 @@
#!/usr/bin/env sh
+SYS=$(uname -s)
+test "$SYS" = "Darwin" && {
+ echo Error: afl-cmin does not work on Apple currently. please use afl-cmin.bash instead.
+ exit 1
+}
export AFL_QUIET=1
export ASAN_OPTIONS=detect_leaks=0
THISPATH=`dirname ${0}`
export PATH="${THISPATH}:$PATH"
awk -f - -- ${@+"$@"} <<'EOF'
#!/usr/bin/awk -f
-
# awk script to minimize a test corpus of input files
#
# based on afl-cmin bash script written by Michal Zalewski
diff --git a/custom_mutators/grammar_mutator/GRAMMAR_VERSION b/custom_mutators/grammar_mutator/GRAMMAR_VERSION
index 2568c6a5..3a019448 100644
--- a/custom_mutators/grammar_mutator/GRAMMAR_VERSION
+++ b/custom_mutators/grammar_mutator/GRAMMAR_VERSION
@@ -1 +1 @@
-ff4e5a2
+5ed4f8d
diff --git a/custom_mutators/grammar_mutator/grammar_mutator b/custom_mutators/grammar_mutator/grammar_mutator
index ff4e5a26..5ed4f8d6 160000
--- a/custom_mutators/grammar_mutator/grammar_mutator
+++ b/custom_mutators/grammar_mutator/grammar_mutator
@@ -1 +1 @@
-Subproject commit ff4e5a265daf5d88c4a636fb6a2c22b1d733db09
+Subproject commit 5ed4f8d6e6524df9670af6b411b13031833d67d2
diff --git a/docs/Changelog.md b/docs/Changelog.md
index c681c4e1..720a0689 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -12,20 +12,25 @@
- afl-cc:
- large rewrite by @SonicStark which fixes a few corner cases, thanks!
- LTO mode now requires llvm 12+
+ - workaround for ASAN with gcc_plugin mode
- instrumentation:
- LLVM 18 support, thanks to @devnexen!
- - Injection (SQL, LDAP, XSS) feature now available, see
+ - Injection (SQL, LDAP, XSS) fuzzing feature now available, see
`instrumentation/README.injections.md` how to activate/use/expand.
- compcov/LAF-intel:
- floating point splitting bug fix by @hexcoder
- due a bug in LLVM 17 integer splitting is disabled there!
- when splitting floats was selected, integers were always split as well,
fixed to require AFL_LLVM_LAF_SPLIT_COMPARES or _ALL as it should
+ - dynamic instrumentation filtering for LLVM NATIVE, thanks @Mozilla!
+ see utils/dynamic_covfilter/README.md
- qemu_mode:
- plugins are now activated by default and a new module is included that
produces drcov compatible traces for lighthouse/lightkeeper/...
thanks to @JRomainG to submitting!
+ - updated Nyx checkout (fixes a bug) and some QOL
- updated the custom grammar mutator
+ - document afl-cmin does not work on macOS (but afl-cmin.bash does)
### Version ++4.09c (release)
diff --git a/docs/resources/1_instrument_target.drawio.svg b/docs/resources/1_instrument_target.drawio.svg
index af6ac397..c93fa2b8 100644
--- a/docs/resources/1_instrument_target.drawio.svg
+++ b/docs/resources/1_instrument_target.drawio.svg
@@ -1,4 +1,4 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/instrumentation/README.lto.md b/instrumentation/README.lto.md
index df59cc2a..bd479c26 100644
--- a/instrumentation/README.lto.md
+++ b/instrumentation/README.lto.md
@@ -2,7 +2,7 @@
## TL;DR:
-This version requires a LLVM 11 or newer.
+This version requires a LLVM 12 or newer.
1. Use afl-clang-lto/afl-clang-lto++ because the resulting binaries run
slightly faster and give better coverage.
@@ -10,7 +10,7 @@ This version requires a LLVM 11 or newer.
2. You can use it together with COMPCOV, COMPLOG and the instrument file
listing features.
-3. It only works with LLVM 11 or newer.
+3. It only works with LLVM 12 or newer.
4. AUTODICTIONARY feature (see below)
@@ -60,7 +60,7 @@ AUTODICTIONARY: 11 strings found
[+] Instrumented 12071 locations with no collisions (on average 1046 collisions would be in afl-gcc/afl-clang-fast) (non-hardened mode).
```
-## Getting LLVM 11+
+## Getting LLVM 12+
### Installing llvm
@@ -73,7 +73,7 @@ chmod +x llvm.sh
sudo ./llvm.sh 15 all
```
-LLVM 11 to 16 should be available in all current Linux repositories.
+LLVM 12 to 18 should be available in all current Linux repositories.
## How to build afl-clang-lto
@@ -277,7 +277,7 @@ AS=llvm-as ...
afl-clang-lto is still work in progress.
Known issues:
-* Anything that LLVM 11+ cannot compile, afl-clang-lto cannot compile either -
+* Anything that LLVM 12+ cannot compile, afl-clang-lto cannot compile either -
obviously.
* Anything that does not compile with LTO, afl-clang-lto cannot compile either -
obviously.
@@ -319,7 +319,7 @@ Still more problems came up though as this only works without bugs from LLVM 9
onwards, and with high optimization the link optimization ruins the instrumented
control flow graph.
-This is all now fixed with LLVM 11+. The llvm's own linker is now able to load
+This is all now fixed with LLVM 12+. The llvm's own linker is now able to load
passes and this bypasses all problems we had.
Happy end :)
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index aae04bb1..f88ce126 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -627,6 +627,13 @@ void ModuleSanitizerCoverageAFL::instrumentFunction(
}
+ if (debug) {
+
+ fprintf(stderr, "SanitizerCoveragePCGUARD: instrumenting %s in %s\n",
+ F.getName().str().c_str(), F.getParent()->getName().str().c_str());
+
+ }
+
InjectCoverage(F, BlocksToInstrument, IsLeafFunc);
// InjectTraceForCmp(F, CmpTraceTargets);
// InjectTraceForSwitch(F, SwitchTraceTargets);
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index 39a762b6..8e55d6a0 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -22,6 +22,10 @@
#define __USE_GNU
#endif
#include
+
+__attribute__((weak)) void __sanitizer_symbolize_pc(void *, const char *fmt,
+ char *out_buf,
+ size_t out_buf_size);
#endif
#ifdef __ANDROID__
@@ -124,8 +128,8 @@ struct afl_module_info_t {
uintptr_t base_address;
// PC Guard start/stop
- u32 start;
- u32 stop;
+ u32 *start;
+ u32 *stop;
// PC Table begin/end
const uintptr_t *pcs_beg;
@@ -147,6 +151,18 @@ afl_module_info_t *__afl_module_info = NULL;
u32 __afl_pcmap_size = 0;
uintptr_t *__afl_pcmap_ptr = NULL;
+
+typedef struct {
+
+ uintptr_t start;
+ u32 len;
+
+} FilterPCEntry;
+
+u32 __afl_filter_pcs_size = 0;
+FilterPCEntry *__afl_filter_pcs = NULL;
+u8 *__afl_filter_pcs_module = NULL;
+
#endif // __AFL_CODE_COVERAGE
/* 1 if we are running in afl, and the forkserver was started, else 0 */
@@ -1587,15 +1603,116 @@ void __sanitizer_cov_trace_pc_guard(uint32_t *guard) {
}
#ifdef __AFL_CODE_COVERAGE
-void __sanitizer_cov_pcs_init(const uintptr_t *pcs_beg,
- const uintptr_t *pcs_end) {
+void afl_read_pc_filter_file(const char *filter_file) {
- if (__afl_debug) {
+ FILE *file;
+ char ch;
+
+ file = fopen(filter_file, "r");
+ if (file == NULL) {
+
+ perror("Error opening file");
+ return;
+
+ }
+
+ // Check how many PCs we expect to read
+ while ((ch = fgetc(file)) != EOF) {
+
+ if (ch == '\n') { __afl_filter_pcs_size++; }
+
+ }
+
+ // Rewind to actually read the PCs
+ fseek(file, 0, SEEK_SET);
+
+ __afl_filter_pcs = malloc(__afl_filter_pcs_size * sizeof(FilterPCEntry));
+ if (!__afl_filter_pcs) {
+
+ perror("Error allocating PC array");
+ return;
+
+ }
+
+ for (size_t i = 0; i < __afl_filter_pcs_size; i++) {
+
+ fscanf(file, "%lx", &(__afl_filter_pcs[i].start));
+ ch = fgetc(file); // Read tab
+ fscanf(file, "%u", &(__afl_filter_pcs[i].len));
+ ch = fgetc(file); // Read tab
+
+ if (!__afl_filter_pcs_module) {
+
+ // Read the module name and store it.
+ // TODO: We only support one module here right now although
+ // there is technically no reason to support multiple modules
+ // in one go.
+ size_t max_module_len = 255;
+ size_t i = 0;
+ __afl_filter_pcs_module = malloc(max_module_len);
+ while (i < max_module_len - 1 &&
+ (__afl_filter_pcs_module[i] = fgetc(file)) != '\t') {
+
+ ++i;
+
+ }
- fprintf(stderr, "DEBUG: __sanitizer_cov_pcs_init called\n");
+ __afl_filter_pcs_module[i] = '\0';
+ fprintf(stderr, "DEBUGXXX: Read module name %s\n",
+ __afl_filter_pcs_module);
+
+ }
+
+ while ((ch = fgetc(file)) != '\n' && ch != EOF)
+ ;
+
+ }
+
+ fclose(file);
+
+}
+
+u32 locate_in_pcs(uintptr_t needle, u32 *index) {
+
+ size_t lower_bound = 0;
+ size_t upper_bound = __afl_filter_pcs_size - 1;
+
+ while (lower_bound < __afl_filter_pcs_size && lower_bound <= upper_bound) {
+
+ size_t current_index = lower_bound + (upper_bound - lower_bound) / 2;
+
+ if (__afl_filter_pcs[current_index].start <= needle) {
+
+ if (__afl_filter_pcs[current_index].start +
+ __afl_filter_pcs[current_index].len >
+ needle) {
+
+ // Hit
+ *index = current_index;
+ return 1;
+
+ } else {
+
+ lower_bound = current_index + 1;
+
+ }
+
+ } else {
+
+ if (!current_index) { break; }
+ upper_bound = current_index - 1;
+
+ }
}
+ return 0;
+
+}
+
+void __sanitizer_cov_pcs_init(const uintptr_t *pcs_beg,
+ const uintptr_t *pcs_end) {
+
// If for whatever reason, we cannot get dlinfo here, then pc_guard_init also
// couldn't get it and we'd end up attributing to the wrong module.
Dl_info dlinfo;
@@ -1608,6 +1725,16 @@ void __sanitizer_cov_pcs_init(const uintptr_t *pcs_beg,
}
+ if (__afl_debug) {
+
+ fprintf(
+ stderr,
+ "DEBUG: (%u) __sanitizer_cov_pcs_init called for module %s with %ld "
+ "PCs\n",
+ getpid(), dlinfo.dli_fname, pcs_end - pcs_beg);
+
+ }
+
afl_module_info_t *last_module_info = __afl_module_info;
while (last_module_info && last_module_info->next) {
@@ -1623,34 +1750,78 @@ void __sanitizer_cov_pcs_init(const uintptr_t *pcs_beg,
}
+ if (strcmp(dlinfo.dli_fname, last_module_info->name)) {
+
+ // This can happen with modules being loaded after the forkserver
+ // where we decide to not track the module. In that case we must
+ // not track it here either.
+ fprintf(
+ stderr,
+ "WARNING: __sanitizer_cov_pcs_init module info mismatch: %s vs %s\n",
+ dlinfo.dli_fname, last_module_info->name);
+ return;
+
+ }
+
last_module_info->pcs_beg = pcs_beg;
last_module_info->pcs_end = pcs_end;
+ // This is a direct filter based on symbolizing inside the runtime.
+ // It should only be used with smaller binaries to avoid long startup
+ // times. Currently, this only supports a single token to scan for.
+ const char *pc_filter = getenv("AFL_PC_FILTER");
+
+ // This is a much faster PC filter based on pre-symbolized input data
+ // that is sorted for fast lookup through binary search. This method
+ // of filtering is suitable even for very large binaries.
+ const char *pc_filter_file = getenv("AFL_PC_FILTER_FILE");
+ if (pc_filter_file && !__afl_filter_pcs) {
+
+ afl_read_pc_filter_file(pc_filter_file);
+
+ }
+
// Now update the pcmap. If this is the last module coming in, after all
// pre-loaded code, then this will also map all of our delayed previous
// modules.
-
- if (!__afl_pcmap_ptr) { return; }
-
+ //
for (afl_module_info_t *mod_info = __afl_module_info; mod_info;
mod_info = mod_info->next) {
if (mod_info->mapped) { continue; }
+ if (!mod_info->start) {
+
+ fprintf(stderr,
+ "ERROR: __sanitizer_cov_pcs_init called with mod_info->start == "
+ "NULL (%s)\n",
+ mod_info->name);
+ abort();
+
+ }
+
PCTableEntry *start = (PCTableEntry *)(mod_info->pcs_beg);
PCTableEntry *end = (PCTableEntry *)(mod_info->pcs_end);
+ if (!*mod_info->stop) { continue; }
+
u32 in_module_index = 0;
while (start < end) {
- if (mod_info->start + in_module_index >= __afl_map_size) {
+ if (*mod_info->start + in_module_index >= __afl_map_size) {
- fprintf(stderr, "ERROR: __sanitizer_cov_pcs_init out of bounds?!\n");
+ fprintf(stderr,
+ "ERROR: __sanitizer_cov_pcs_init out of bounds?! Start: %u "
+ "Stop: %u Map Size: %u (%s)\n",
+ *mod_info->start, *mod_info->stop, __afl_map_size,
+ mod_info->name);
abort();
}
+ u32 orig_start_index = *mod_info->start;
+
uintptr_t PC = start->PC;
// This is what `GetPreviousInstructionPc` in sanitizer runtime does
@@ -1660,7 +1831,58 @@ void __sanitizer_cov_pcs_init(const uintptr_t *pcs_beg,
// Calculate relative offset in module
PC = PC - mod_info->base_address;
- __afl_pcmap_ptr[mod_info->start + in_module_index] = PC;
+ if (__afl_pcmap_ptr) {
+
+ __afl_pcmap_ptr[orig_start_index + in_module_index] = PC;
+
+ }
+
+ if (pc_filter) {
+
+ char PcDescr[1024];
+ // This function is a part of the sanitizer run-time.
+ // To use it, link with AddressSanitizer or other sanitizer.
+ __sanitizer_symbolize_pc((void *)start->PC, "%p %F %L", PcDescr,
+ sizeof(PcDescr));
+
+ if (strstr(PcDescr, pc_filter)) {
+
+ if (__afl_debug)
+ fprintf(
+ stderr,
+ "DEBUG: Selective instrumentation match: %s (PC %p Index %u)\n",
+ PcDescr, (void *)start->PC,
+ *(mod_info->start + in_module_index));
+ // No change to guard needed
+
+ } else {
+
+ // Null out the guard to disable this edge
+ *(mod_info->start + in_module_index) = 0;
+
+ }
+
+ }
+
+ if (__afl_filter_pcs && strstr(mod_info->name, __afl_filter_pcs_module)) {
+
+ u32 result_index;
+ if (locate_in_pcs(PC, &result_index)) {
+
+ if (__afl_debug)
+ fprintf(stderr,
+ "DEBUG: Selective instrumentation match: (PC %lx File "
+ "Index %u PC Index %u)\n",
+ PC, result_index, in_module_index);
+
+ } else {
+
+ // Null out the guard to disable this edge
+ *(mod_info->start + in_module_index) = 0;
+
+ }
+
+ }
start++;
in_module_index++;
@@ -1671,8 +1893,10 @@ void __sanitizer_cov_pcs_init(const uintptr_t *pcs_beg,
if (__afl_debug) {
- fprintf(stderr, "DEBUG: __sanitizer_cov_pcs_init initialized %u PCs\n",
- in_module_index);
+ fprintf(stderr,
+ "DEBUG: __sanitizer_cov_pcs_init successfully mapped %s with %u "
+ "PCs\n",
+ mod_info->name, in_module_index);
}
@@ -1706,9 +1930,9 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
fprintf(
stderr,
"DEBUG: Running __sanitizer_cov_trace_pc_guard_init: %p-%p (%lu edges) "
- "after_fs=%u\n",
+ "after_fs=%u *start=%u\n",
start, stop, (unsigned long)(stop - start),
- __afl_already_initialized_forkserver);
+ __afl_already_initialized_forkserver, *start);
}
@@ -1740,8 +1964,8 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
mod_info->id = last_module_info ? last_module_info->id + 1 : 0;
mod_info->name = strdup(dlinfo.dli_fname);
mod_info->base_address = (uintptr_t)dlinfo.dli_fbase;
- mod_info->start = 0;
- mod_info->stop = 0;
+ mod_info->start = NULL;
+ mod_info->stop = NULL;
mod_info->pcs_beg = NULL;
mod_info->pcs_end = NULL;
mod_info->mapped = 0;
@@ -1757,8 +1981,12 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
}
- fprintf(stderr, "[pcmap] Module: %s Base Address: %p\n", dlinfo.dli_fname,
- dlinfo.dli_fbase);
+ if (__afl_debug) {
+
+ fprintf(stderr, "[pcmap] Module: %s Base Address: %p\n",
+ dlinfo.dli_fname, dlinfo.dli_fbase);
+
+ }
}
@@ -1861,12 +2089,17 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
#ifdef __AFL_CODE_COVERAGE
if (mod_info) {
- mod_info->start = *orig_start;
- mod_info->stop = *(stop - 1);
+ if (!mod_info->start) {
+
+ mod_info->start = orig_start;
+ mod_info->stop = stop - 1;
+
+ }
+
if (__afl_debug) {
fprintf(stderr, "DEBUG: [pcmap] Start Index: %u Stop Index: %u\n",
- mod_info->start, mod_info->stop);
+ *(mod_info->start), *(mod_info->stop));
}
diff --git a/instrumentation/afl-llvm-common.cc b/instrumentation/afl-llvm-common.cc
index 96952bd6..8e9e7800 100644
--- a/instrumentation/afl-llvm-common.cc
+++ b/instrumentation/afl-llvm-common.cc
@@ -201,7 +201,7 @@ void initInstrumentList() {
if (debug)
DEBUGF("loaded allowlist with %zu file and %zu function entries\n",
- allowListFiles.size(), allowListFunctions.size());
+ allowListFiles.size() / 4, allowListFunctions.size() / 4);
}
@@ -276,7 +276,7 @@ void initInstrumentList() {
if (debug)
DEBUGF("loaded denylist with %zu file and %zu function entries\n",
- denyListFiles.size(), denyListFunctions.size());
+ denyListFiles.size() / 4, denyListFunctions.size() / 4);
}
diff --git a/nyx_mode/LIBNYX_VERSION b/nyx_mode/LIBNYX_VERSION
index da3939ad..9aae19be 100644
--- a/nyx_mode/LIBNYX_VERSION
+++ b/nyx_mode/LIBNYX_VERSION
@@ -1 +1 @@
-512058a
+6833d23
diff --git a/nyx_mode/QEMU-Nyx b/nyx_mode/QEMU-Nyx
index 02a6f2ae..1def26f8 160000
--- a/nyx_mode/QEMU-Nyx
+++ b/nyx_mode/QEMU-Nyx
@@ -1 +1 @@
-Subproject commit 02a6f2aed360cfe76bb3d788dafe517c350d74e5
+Subproject commit 1def26f83e83556d767754581fa52081ffb54b09
diff --git a/nyx_mode/QEMU_NYX_VERSION b/nyx_mode/QEMU_NYX_VERSION
index 4f58054c..cac32d41 100644
--- a/nyx_mode/QEMU_NYX_VERSION
+++ b/nyx_mode/QEMU_NYX_VERSION
@@ -1 +1 @@
-02a6f2aed3
+1def26f83e
diff --git a/nyx_mode/README.md b/nyx_mode/README.md
index aee9879e..7a2a8e6c 100644
--- a/nyx_mode/README.md
+++ b/nyx_mode/README.md
@@ -84,9 +84,17 @@ Then the final step: we generate the Nyx package configuration:
python3 nyx_mode/packer/packer/nyx_config_gen.py PACKAGE-DIRECTORY Kernel
```
-
## Fuzzing with Nyx mode
+Note that you need to load the kvm kernel modules for Nyx:
+```
+sudo modprobe -r kvm-intel
+sudo modprobe -r kvm
+sudo modprobe kvm enable_vmware_backdoor=y
+sudo modprobe kvm-intel
+cat /sys/module/kvm/parameters/enable_vmware_backdoor | grep -q Y && echi OK || echo KVM module problem
+```
+
All the hard parts are done, fuzzing with Nyx mode is easy - just supply the
`PACKAGE-DIRECTORY` as fuzzing target and specify the `-X` option to afl-fuzz:
@@ -94,16 +102,8 @@ All the hard parts are done, fuzzing with Nyx mode is easy - just supply the
afl-fuzz -i in -o out -X -- ./PACKAGE-DIRECTORY
```
-Most likely your first run will fail because the Linux modules have to be
-specially set up, but afl-fuzz will tell you this on startup and how to rectify
-the situation:
-
-```
-sudo modprobe -r kvm-intel # or kvm-amd for AMD processors
-sudo modprobe -r kvm
-sudo modprobe kvm enable_vmware_backdoor=y
-sudo modprobe kvm-intel # or kvm-amd for AMD processors
-```
+If you get a forkserver error upon starting then you did not load the Linux
+kvm kernel modules, see above.
If you want to fuzz in parallel (and you should!), then this has to be done in a
special way:
diff --git a/nyx_mode/build_nyx_support.sh b/nyx_mode/build_nyx_support.sh
index 581a8292..fda4ec12 100755
--- a/nyx_mode/build_nyx_support.sh
+++ b/nyx_mode/build_nyx_support.sh
@@ -9,6 +9,21 @@ echo
echo "[*] Performing basic sanity checks..."
+if [ "$CI" = "true" ]; then
+
+ echo "[-] Error: nyx_mode cannot be tested in the Github CI, skipping ..."
+ exit 0
+
+fi
+
+
+if [ -n "$NO_NYX" ]; then
+
+ echo "[-] Error: the NO_NYX environment variable is set, please unset."
+ exit 0
+
+fi
+
if [ ! "$(uname -s)" = "Linux" ]; then
echo "[-] Error: Nyx mode is only available on Linux."
@@ -23,11 +38,17 @@ if [ ! "$(uname -m)" = "x86_64" ]; then
fi
+cargo help > /dev/null 2>&1 || {
+ echo "[-] Error: Rust is not installed."
+ exit 0
+}
+
echo "[*] Making sure all Nyx is checked out"
if git status 1>/dev/null 2>&1; then
+ set +e
git submodule init
echo "[*] initializing QEMU-Nyx submodule"
git submodule update ./QEMU-Nyx 2>/dev/null # ignore errors
@@ -35,6 +56,7 @@ if git status 1>/dev/null 2>&1; then
git submodule update ./packer 2>/dev/null # ignore errors
echo "[*] initializing libnyx submodule"
git submodule update ./libnyx 2>/dev/null # ignore errors
+ set -e
else
@@ -48,20 +70,57 @@ test -e packer/.git || { echo "[-] packer not checked out, please install git or
test -e libnyx/.git || { echo "[-] libnyx not checked out, please install git or check your internet connection." ; exit 1 ; }
test -e QEMU-Nyx/.git || { echo "[-] QEMU-Nyx not checked out, please install git or check your internet connection." ; exit 1 ; }
-echo "[*] checking packer init.cpio.gz ..."
-if [ ! -f "packer/linux_initramfs/init.cpio.gz" ]; then
- (cd packer/linux_initramfs/ && sh pack.sh)
+
+QEMU_NYX_VERSION="$(cat ./QEMU_NYX_VERSION)"
+cd "./QEMU-Nyx" || exit 1
+if [ -n "$NO_CHECKOUT" ]; then
+ echo "[*] Skipping checkout to $QEMU_NYX_VERSION"
+else
+ echo "[*] Checking out $QEMU_NYX_VERSION"
+ set +e
+ sh -c 'git stash' 1>/dev/null 2>/dev/null
+ git pull 1>/dev/null 2>/dev/null
+ git checkout "$QEMU_NYX_VERSION" || echo Warning: could not check out to commit $QEMU_NYX_VERSION
+ set -e
fi
+cd - > /dev/null
-echo "[*] Checking libnyx ..."
-if [ ! -f "libnyx/libnyx/target/release/liblibnyx.a" ]; then
- (cd libnyx/libnyx && cargo build --release)
+PACKER_VERSION="$(cat ./PACKER_VERSION)"
+cd "./packer" || exit 1
+if [ -n "$NO_CHECKOUT" ]; then
+ echo "[*] Skipping checkout to $PACKER_VERSION"
+else
+ echo "[*] Checking out $PACKER_VERSION"
+ set +e
+ sh -c 'git stash' 1>/dev/null 2>/dev/null
+ git pull 1>/dev/null 2>/dev/null
+ git checkout "$PACKER_VERSION" || echo Warning: could not check out to commit $PACKER_VERSION
+ set -e
fi
+cd - > /dev/null
-echo "[*] Checking QEMU-Nyx ..."
-if [ ! -f "QEMU-Nyx/x86_64-softmmu/qemu-system-x86_64" ]; then
- (cd QEMU-Nyx && ./compile_qemu_nyx.sh static)
+LIBNYX_VERSION="$(cat ./LIBNYX_VERSION)"
+cd "./libnyx/" || exit 1
+if [ -n "$NO_CHECKOUT" ]; then
+ echo "[*] Skipping checkout to $LIBNYX_VERSION"
+else
+ echo "[*] Checking out $LIBNYX_VERSION"
+ set +e
+ sh -c 'git stash' 1>/dev/null 2>/dev/null
+ git pull 1>/dev/null 2>/dev/null
+ git checkout "$LIBNYX_VERSION" || echo Warning: could not check out to commit $LIBNYX_VERSION
+ set -e
fi
+cd - > /dev/null
+
+echo "[*] checking packer init.cpio.gz ..."
+(cd packer/linux_initramfs/ && sh pack.sh)
+
+echo "[*] Checking libnyx ..."
+(cd libnyx/libnyx && cargo build --release)
+
+echo "[*] Checking QEMU-Nyx ..."
+(cd QEMU-Nyx && ./compile_qemu_nyx.sh static )
echo "[*] Checking libnyx.so ..."
cp libnyx/libnyx/target/release/liblibnyx.so ../libnyx.so
diff --git a/nyx_mode/libnyx b/nyx_mode/libnyx
index 512058a6..6833d236 160000
--- a/nyx_mode/libnyx
+++ b/nyx_mode/libnyx
@@ -1 +1 @@
-Subproject commit 512058a68d58b1a90a4e3971b526a955559735bf
+Subproject commit 6833d236dfe785a8a23d8c8d79e74c99fa635004
diff --git a/nyx_mode/update_ref.sh b/nyx_mode/update_ref.sh
index 898a803f..146a1255 100755
--- a/nyx_mode/update_ref.sh
+++ b/nyx_mode/update_ref.sh
@@ -41,7 +41,7 @@ cd ..
rm "$UC_VERSION_FILE"
echo "$NEW_VERSION" > "$UC_VERSION_FILE"
-echo "Done. New XXX version is $NEW_VERSION."
+echo "Done. New libnyx version is $NEW_VERSION."
UC_VERSION_FILE='./PACKER_VERSION'
@@ -68,7 +68,7 @@ cd ..
rm "$UC_VERSION_FILE"
echo "$NEW_VERSION" > "$UC_VERSION_FILE"
-echo "Done. New XXX version is $NEW_VERSION."
+echo "Done. New packer version is $NEW_VERSION."
UC_VERSION_FILE='./QEMU_NYX_VERSION'
@@ -95,5 +95,5 @@ cd ..
rm "$UC_VERSION_FILE"
echo "$NEW_VERSION" > "$UC_VERSION_FILE"
-echo "Done. New XXX version is $NEW_VERSION."
+echo "Done. New QEMU-Nyx version is $NEW_VERSION."
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 192c5423..c300ddfc 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -51,7 +51,7 @@
#define MAX_PARAMS_NUM 2048
#endif
-/* Global declarations */
+/** Global declarations -----BEGIN----- **/
typedef enum {
@@ -170,8 +170,11 @@ typedef struct aflcc_state {
u8 have_instr_env, have_gcc, have_clang, have_llvm, have_gcc_plugin, have_lto,
have_optimized_pcguard, have_instr_list;
- u8 fortify_set, asan_set, x_set, bit_mode, preprocessor_only, have_unroll,
- have_o, have_pic, have_c, shared_linking, partial_linking, non_dash;
+ u8 fortify_set, x_set, bit_mode, preprocessor_only, have_unroll, have_o,
+ have_pic, have_c, shared_linking, partial_linking, non_dash, have_fp,
+ have_flto, have_hidden, have_fortify, have_fcf, have_staticasan,
+ have_rust_asanrt, have_asan, have_msan, have_ubsan, have_lsan, have_tsan,
+ have_cfisan;
// u8 *march_opt;
u8 need_aflpplib;
@@ -184,25 +187,27 @@ typedef struct aflcc_state {
void aflcc_state_init(aflcc_state_t *, u8 *argv0);
-/* Try to find a specific runtime we need, the path to obj would be
- allocated and returned. Otherwise it returns NULL on fail. */
u8 *find_object(aflcc_state_t *, u8 *obj);
void find_built_deps(aflcc_state_t *);
-static inline void limit_params(aflcc_state_t *aflcc, u32 add) {
+/* Insert param into the new argv, raise error if MAX_PARAMS_NUM exceeded. */
+static inline void insert_param(aflcc_state_t *aflcc, u8 *param) {
- if (aflcc->cc_par_cnt + add >= MAX_PARAMS_NUM)
+ if (unlikely(aflcc->cc_par_cnt + 1 >= MAX_PARAMS_NUM))
FATAL("Too many command line parameters, please increase MAX_PARAMS_NUM.");
-}
-
-static inline void insert_param(aflcc_state_t *aflcc, u8 *param) {
-
aflcc->cc_params[aflcc->cc_par_cnt++] = param;
}
+/*
+ Insert a param which contains path to the object file. It uses find_object to
+ get the path based on the name `obj`, and then uses a sprintf like method to
+ format it with `fmt`. If `fmt` is NULL, the inserted arg is same as the path.
+ If `msg` provided, it should be an error msg raised if the path can't be
+ found. `obj` must not be NULL.
+*/
static inline void insert_object(aflcc_state_t *aflcc, u8 *obj, u8 *fmt,
u8 *msg) {
@@ -232,6 +237,7 @@ static inline void insert_object(aflcc_state_t *aflcc, u8 *obj, u8 *fmt,
}
+/* Insert params into the new argv, make clang load the pass. */
static inline void load_llvm_pass(aflcc_state_t *aflcc, u8 *pass) {
#if LLVM_MAJOR >= 11 /* use new pass manager */
@@ -292,8 +298,12 @@ void add_lto_linker(aflcc_state_t *);
void add_lto_passes(aflcc_state_t *);
void add_runtime(aflcc_state_t *);
-/* Working state */
+/** Global declarations -----END----- **/
+/*
+ Init global state struct. We also extract the callname,
+ check debug options and if in C++ mode here.
+*/
void aflcc_state_init(aflcc_state_t *aflcc, u8 *argv0) {
// Default NULL/0 is a good start
@@ -353,7 +363,7 @@ void aflcc_state_init(aflcc_state_t *aflcc, u8 *argv0) {
}
/*
- in find_object() we look here:
+ Try to find a specific runtime we need, in here:
1. firstly we check the $AFL_PATH environment variable location if set
2. next we check argv[0] if it has path information and use it
@@ -367,7 +377,6 @@ void aflcc_state_init(aflcc_state_t *aflcc, u8 *argv0) {
if all these attempts fail - we return NULL and the caller has to decide
what to do. Otherwise the path to obj would be allocated and returned.
*/
-
u8 *find_object(aflcc_state_t *aflcc, u8 *obj) {
u8 *argv0 = aflcc->argv0;
@@ -500,6 +509,10 @@ u8 *find_object(aflcc_state_t *aflcc, u8 *obj) {
}
+/*
+ Deduce some info about compiler toolchains in current system,
+ from the building results of AFL++
+*/
void find_built_deps(aflcc_state_t *aflcc) {
char *ptr = NULL;
@@ -572,8 +585,9 @@ void find_built_deps(aflcc_state_t *aflcc) {
}
-/* compiler_mode & instrument_mode selecting */
+/** compiler_mode & instrument_mode selecting -----BEGIN----- **/
+/* Select compiler_mode by callname, such as "afl-clang-fast", etc. */
void compiler_mode_by_callname(aflcc_state_t *aflcc) {
if (strncmp(aflcc->callname, "afl-clang-fast", 14) == 0) {
@@ -611,30 +625,26 @@ void compiler_mode_by_callname(aflcc_state_t *aflcc) {
aflcc->compiler_mode = GCC_PLUGIN;
-#if defined(__x86_64__)
-
} else if (strncmp(aflcc->callname, "afl-gcc", 7) == 0 ||
strncmp(aflcc->callname, "afl-g++", 7) == 0) {
aflcc->compiler_mode = GCC;
-#endif
-
-#if defined(__x86_64__)
-
} else if (strcmp(aflcc->callname, "afl-clang") == 0 ||
strcmp(aflcc->callname, "afl-clang++") == 0) {
aflcc->compiler_mode = CLANG;
-#endif
-
}
}
+/*
+ Select compiler_mode by env AFL_CC_COMPILER. And passthrough mode can be
+ regarded as a special compiler_mode, so we check for it here, too.
+*/
void compiler_mode_by_environ(aflcc_state_t *aflcc) {
if (getenv("AFL_PASSTHROUGH") || getenv("AFL_NOOPT")) {
@@ -675,22 +685,14 @@ void compiler_mode_by_environ(aflcc_state_t *aflcc) {
aflcc->compiler_mode = GCC_PLUGIN;
-#if defined(__x86_64__)
-
} else if (strcasecmp(ptr, "GCC") == 0) {
aflcc->compiler_mode = GCC;
-#endif
-
-#if defined(__x86_64__)
-
} else if (strcasecmp(ptr, "CLANG") == 0) {
aflcc->compiler_mode = CLANG;
-#endif
-
} else
FATAL("Unknown AFL_CC_COMPILER mode: %s\n", ptr);
@@ -699,7 +701,13 @@ void compiler_mode_by_environ(aflcc_state_t *aflcc) {
}
-// If it can be inferred, instrument_mode would also be set
+/*
+ Select compiler_mode by command line options --afl-...
+ If it can be inferred, instrument_mode would also be set.
+ This can supersedes previous result based on callname
+ or AFL_CC_COMPILER. And "--afl_noopt"/"--afl-noopt" will
+ be overwritten by "-g".
+*/
void compiler_mode_by_cmdline(aflcc_state_t *aflcc, int argc, char **argv) {
char *ptr = NULL;
@@ -774,22 +782,14 @@ void compiler_mode_by_cmdline(aflcc_state_t *aflcc, int argc, char **argv) {
aflcc->compiler_mode = GCC_PLUGIN;
-#if defined(__x86_64__)
-
} else if (strcasecmp(ptr, "GCC") == 0) {
aflcc->compiler_mode = GCC;
-#endif
-
-#if defined(__x86_64__)
-
} else if (strncasecmp(ptr, "CLANG", 5) == 0) {
aflcc->compiler_mode = CLANG;
-#endif
-
} else
FATAL("Unknown --afl-... compiler mode: %s\n", argv[i]);
@@ -800,6 +800,12 @@ void compiler_mode_by_cmdline(aflcc_state_t *aflcc, int argc, char **argv) {
}
+/*
+ Select instrument_mode by those envs in old style:
+ - USE_TRACE_PC, AFL_USE_TRACE_PC, AFL_LLVM_USE_TRACE_PC, AFL_TRACE_PC
+ - AFL_LLVM_CALLER, AFL_LLVM_CTX, AFL_LLVM_CTX_K
+ - AFL_LLVM_NGRAM_SIZE
+*/
static void instrument_mode_old_environ(aflcc_state_t *aflcc) {
if (getenv("AFL_LLVM_INSTRIM") || getenv("INSTRIM") ||
@@ -859,7 +865,11 @@ static void instrument_mode_old_environ(aflcc_state_t *aflcc) {
}
-// compiler_mode would also be set if depended by the instrument_mode
+/*
+ Select instrument_mode by env 'AFL_LLVM_INSTRUMENT'.
+ Previous compiler_mode will be superseded, if required by some
+ values of instrument_mode.
+*/
static void instrument_mode_new_environ(aflcc_state_t *aflcc) {
if (!getenv("AFL_LLVM_INSTRUMENT")) { return; }
@@ -960,7 +970,6 @@ static void instrument_mode_new_environ(aflcc_state_t *aflcc) {
}
-#if defined(__x86_64__)
if (strcasecmp(ptr2, "gcc") == 0) {
if (!aflcc->instrument_mode || aflcc->instrument_mode == INSTRUMENT_GCC)
@@ -975,9 +984,6 @@ static void instrument_mode_new_environ(aflcc_state_t *aflcc) {
}
-#endif
-
-#if defined(__x86_64__)
if (strcasecmp(ptr2, "clang") == 0) {
if (!aflcc->instrument_mode || aflcc->instrument_mode == INSTRUMENT_CLANG)
@@ -992,8 +998,6 @@ static void instrument_mode_new_environ(aflcc_state_t *aflcc) {
}
-#endif
-
if (strncasecmp(ptr2, "ctx-", strlen("ctx-")) == 0 ||
strncasecmp(ptr2, "kctx-", strlen("c-ctx-")) == 0 ||
strncasecmp(ptr2, "k-ctx-", strlen("k-ctx-")) == 0) {
@@ -1089,6 +1093,11 @@ static void instrument_mode_new_environ(aflcc_state_t *aflcc) {
}
+/*
+ Select instrument_mode by envs, the top wrapper. We check
+ have_instr_env firstly, then call instrument_mode_old_environ
+ and instrument_mode_new_environ sequentially.
+*/
void instrument_mode_by_environ(aflcc_state_t *aflcc) {
if (getenv("AFL_LLVM_INSTRUMENT_FILE") || getenv("AFL_LLVM_WHITELIST") ||
@@ -1112,6 +1121,10 @@ void instrument_mode_by_environ(aflcc_state_t *aflcc) {
}
+/*
+ Workaround to ensure CALLER, CTX, K-CTX and NGRAM
+ instrumentation were used correctly.
+*/
static void instrument_opt_mode_exclude(aflcc_state_t *aflcc) {
if ((aflcc->instrument_opt_mode & INSTRUMENT_OPT_CTX) &&
@@ -1147,6 +1160,11 @@ static void instrument_opt_mode_exclude(aflcc_state_t *aflcc) {
}
+/*
+ Last step of compiler_mode & instrument_mode selecting.
+ We have a few of workarounds here, to check any corner cases,
+ prepare for a series of fallbacks, and raise warnings or errors.
+*/
void mode_final_checkout(aflcc_state_t *aflcc, int argc, char **argv) {
if (aflcc->instrument_opt_mode &&
@@ -1180,11 +1198,11 @@ void mode_final_checkout(aflcc_state_t *aflcc, int argc, char **argv) {
switch (aflcc->compiler_mode) {
case GCC:
- if (!aflcc->have_gcc) FATAL("afl-gcc not available on your platform!");
+ if (!aflcc->have_gcc) FATAL("afl-gcc is not available on your platform!");
break;
case CLANG:
if (!aflcc->have_clang)
- FATAL("afl-clang not available on your platform!");
+ FATAL("afl-clang is not available on your platform!");
break;
case LLVM:
if (!aflcc->have_llvm)
@@ -1351,6 +1369,10 @@ void mode_final_checkout(aflcc_state_t *aflcc, int argc, char **argv) {
}
+/*
+ Print welcome message on screen, giving brief notes about
+ compiler_mode and instrument_mode.
+*/
void mode_notification(aflcc_state_t *aflcc) {
char *ptr2 = alloc_printf(" + NGRAM-%u", aflcc->ngram_size);
@@ -1389,6 +1411,17 @@ void mode_notification(aflcc_state_t *aflcc) {
}
+/*
+ Set argv[0] required by execvp. It can be
+ - specified by env AFL_CXX
+ - g++ or clang++
+ - CLANGPP_BIN or LLVM_BINDIR/clang++
+ when in C++ mode, or
+ - specified by env AFL_CC
+ - gcc or clang
+ - CLANG_BIN or LLVM_BINDIR/clang
+ otherwise.
+*/
void add_real_argv0(aflcc_state_t *aflcc) {
static u8 llvm_fullpath[PATH_MAX];
@@ -1455,7 +1488,9 @@ void add_real_argv0(aflcc_state_t *aflcc) {
}
-/* Macro defs for the preprocessor */
+/** compiler_mode & instrument_mode selecting -----END----- **/
+
+/** Macro defs for the preprocessor -----BEGIN----- **/
void add_defs_common(aflcc_state_t *aflcc) {
@@ -1464,8 +1499,11 @@ void add_defs_common(aflcc_state_t *aflcc) {
}
-/* See instrumentation/README.instrument_list.md#
- 2-selective-instrumentation-with-_afl_coverage-directives */
+/*
+ __afl_coverage macro defs. See
+ instrumentation/README.instrument_list.md#
+ 2-selective-instrumentation-with-_afl_coverage-directives
+*/
void add_defs_selective_instr(aflcc_state_t *aflcc) {
if (aflcc->plusplus_mode) {
@@ -1499,9 +1537,11 @@ void add_defs_selective_instr(aflcc_state_t *aflcc) {
}
-/* As documented in instrumentation/README.persistent_mode.md, deferred
- forkserver initialization and persistent mode are not available in afl-gcc
- and afl-clang. */
+/*
+ Macro defs for persistent mode. As documented in
+ instrumentation/README.persistent_mode.md, deferred forkserver initialization
+ and persistent mode are not available in afl-gcc and afl-clang.
+*/
void add_defs_persistent_mode(aflcc_state_t *aflcc) {
if (aflcc->compiler_mode == GCC || aflcc->compiler_mode == CLANG) return;
@@ -1552,7 +1592,7 @@ void add_defs_persistent_mode(aflcc_state_t *aflcc) {
"({ static volatile const char *_B __attribute__((used,unused)); "
" _B = (const char*)\"" PERSIST_SIG
"\"; "
- "extern int __afl_connected;"
+ "extern __attribute__((visibility(\"default\"))) int __afl_connected;"
#ifdef __APPLE__
"__attribute__((visibility(\"default\"))) "
"int _L(unsigned int) __asm__(\"___afl_persistent_loop\"); "
@@ -1580,9 +1620,15 @@ void add_defs_persistent_mode(aflcc_state_t *aflcc) {
}
-/* Control _FORTIFY_SOURCE */
+/*
+ Control macro def of _FORTIFY_SOURCE. It will do nothing
+ if we detect this routine has been called previously, or
+ the macro already here in these existing args.
+*/
void add_defs_fortify(aflcc_state_t *aflcc, u8 action) {
+ if (aflcc->have_fortify) { return; }
+
switch (action) {
case 1:
@@ -1599,8 +1645,11 @@ void add_defs_fortify(aflcc_state_t *aflcc, u8 action) {
}
+ aflcc->have_fortify = 1;
+
}
+/* Macro defs of __AFL_LEAK_CHECK, __AFL_LSAN_ON and __AFL_LSAN_OFF */
void add_defs_lsan_ctrl(aflcc_state_t *aflcc) {
insert_param(aflcc, "-includesanitizer/lsan_interface.h");
@@ -1613,7 +1662,9 @@ void add_defs_lsan_ctrl(aflcc_state_t *aflcc) {
}
-/* About fsanitize (including PCGUARD features) */
+/** Macro defs for the preprocessor -----END----- **/
+
+/** About -fsanitize -----BEGIN----- **/
/* For input "-fsanitize=...", it:
@@ -1692,26 +1743,59 @@ static u8 fsanitize_fuzzer_comma(char *string) {
}
+/*
+ Parse and process possible -fsanitize related args, return PARAM_MISS
+ if nothing matched. We have 3 main tasks here for these args:
+ - Check which one of those sanitizers present here.
+ - Check if libfuzzer present. We need to block the request of enable
+ libfuzzer, and link harness with our libAFLDriver.a later.
+ - Check if SanCov allow/denylist options present. We need to try switching
+ to LLVMNATIVE instead of using our optimized PCGUARD anyway. If we
+ can't make it finally for various reasons, just drop these options.
+*/
param_st parse_fsanitize(aflcc_state_t *aflcc, u8 *cur_argv, u8 scan) {
param_st final_ = PARAM_MISS;
- if (!strncmp(cur_argv, "-fsanitize-coverage-", 20) &&
- strstr(cur_argv, "list=")) {
-
- if (scan) {
-
- aflcc->have_instr_list = 1;
- final_ = PARAM_SCAN;
+// MACRO START
+#define HAVE_SANITIZER_SCAN_KEEP(v, k) \
+ do { \
+ \
+ if (strstr(cur_argv, "=" STRINGIFY(k)) || \
+ strstr(cur_argv, "," STRINGIFY(k))) { \
+ \
+ if (scan) { \
+ \
+ aflcc->have_##v = 1; \
+ final_ = PARAM_SCAN; \
+ \
+ } else { \
+ \
+ final_ = PARAM_KEEP; \
+ \
+ } \
+ \
+ } \
+ \
+ } while (0)
- } else {
+ // MACRO END
- final_ = PARAM_KEEP; // may be set to DROP next
+ if (!strncmp(cur_argv, "-fsanitize=", strlen("-fsanitize="))) {
- }
+ HAVE_SANITIZER_SCAN_KEEP(asan, address);
+ HAVE_SANITIZER_SCAN_KEEP(msan, memory);
+ HAVE_SANITIZER_SCAN_KEEP(ubsan, undefined);
+ HAVE_SANITIZER_SCAN_KEEP(tsan, thread);
+ HAVE_SANITIZER_SCAN_KEEP(lsan, leak);
+ HAVE_SANITIZER_SCAN_KEEP(cfisan, cfi);
}
+#undef HAVE_SANITIZER_SCAN_KEEP
+
+ // We can't use a "else if" there, because some of the following
+ // matching rules overlap with those in the if-statement above.
if (!strcmp(cur_argv, "-fsanitize=fuzzer")) {
if (scan) {
@@ -1751,44 +1835,27 @@ param_st parse_fsanitize(aflcc_state_t *aflcc, u8 *cur_argv, u8 scan) {
}
- } else if ((!strncmp(cur_argv, "-fsanitize=fuzzer-",
+ } else if (!strncmp(cur_argv, "-fsanitize-coverage-", 20) &&
- strlen("-fsanitize=fuzzer-")) ||
- !strncmp(cur_argv, "-fsanitize-coverage",
- strlen("-fsanitize-coverage"))) &&
- (strncmp(cur_argv, "sanitize-coverage-allow",
- strlen("sanitize-coverage-allow")) &&
- strncmp(cur_argv, "sanitize-coverage-deny",
- strlen("sanitize-coverage-deny")) &&
- aflcc->instrument_mode != INSTRUMENT_LLVMNATIVE)) {
+ strstr(cur_argv, "list=")) {
if (scan) {
+ aflcc->have_instr_list = 1;
final_ = PARAM_SCAN;
} else {
- if (!be_quiet) { WARNF("Found '%s' - stripping!", cur_argv); }
- final_ = PARAM_DROP;
-
- }
+ if (aflcc->instrument_mode != INSTRUMENT_LLVMNATIVE) {
- }
-
- if (!strcmp(cur_argv, "-fsanitize=address") ||
- !strcmp(cur_argv, "-fsanitize=memory")) {
-
- if (scan) {
+ if (!be_quiet) { WARNF("Found '%s' - stripping!", cur_argv); }
+ final_ = PARAM_DROP;
- // "-fsanitize=undefined,address" may be un-treated, but it's OK.
- aflcc->asan_set = 1;
- final_ = PARAM_SCAN;
+ } else {
- } else {
+ final_ = PARAM_KEEP;
- // It's impossible that final_ is PARAM_DROP before,
- // so no checks are needed here.
- final_ = PARAM_KEEP;
+ }
}
@@ -1800,76 +1867,125 @@ param_st parse_fsanitize(aflcc_state_t *aflcc, u8 *cur_argv, u8 scan) {
}
+/*
+ Add params for sanitizers. Here we need to consider:
+ - Use static runtime for asan, as much as possible.
+ - ASAN, MSAN, AFL_HARDEN are mutually exclusive.
+ - Add options if not found there, on request of AFL_USE_ASAN, AFL_USE_MSAN,
+ etc.
+ - Update have_* so that functions called after this can have correct context.
+ However this also means any functions called before should NOT depend on
+ these have_*, otherwise they may not work as expected.
+*/
void add_sanitizers(aflcc_state_t *aflcc, char **envp) {
- if (!aflcc->asan_set) {
+ if (getenv("AFL_USE_ASAN") || aflcc->have_asan) {
+
+ if (getenv("AFL_USE_MSAN") || aflcc->have_msan)
+ FATAL("ASAN and MSAN are mutually exclusive");
- if (getenv("AFL_USE_ASAN")) {
+ if (getenv("AFL_HARDEN"))
+ FATAL("ASAN and AFL_HARDEN are mutually exclusive");
- if (getenv("AFL_USE_MSAN")) FATAL("ASAN and MSAN are mutually exclusive");
+ if (aflcc->compiler_mode == GCC_PLUGIN && !aflcc->have_staticasan) {
- if (getenv("AFL_HARDEN"))
- FATAL("ASAN and AFL_HARDEN are mutually exclusive");
+ insert_param(aflcc, "-static-libasan");
- add_defs_fortify(aflcc, 0);
- insert_param(aflcc, "-fsanitize=address");
+ }
- } else if (getenv("AFL_USE_MSAN")) {
+ add_defs_fortify(aflcc, 0);
+ if (!aflcc->have_asan) { insert_param(aflcc, "-fsanitize=address"); }
+ aflcc->have_asan = 1;
- if (getenv("AFL_USE_ASAN")) FATAL("ASAN and MSAN are mutually exclusive");
+ } else if (getenv("AFL_USE_MSAN") || aflcc->have_msan) {
- if (getenv("AFL_HARDEN"))
- FATAL("MSAN and AFL_HARDEN are mutually exclusive");
+ if (getenv("AFL_USE_ASAN") || aflcc->have_asan)
+ FATAL("ASAN and MSAN are mutually exclusive");
- add_defs_fortify(aflcc, 0);
- insert_param(aflcc, "-fsanitize=memory");
+ if (getenv("AFL_HARDEN"))
+ FATAL("MSAN and AFL_HARDEN are mutually exclusive");
- }
+ add_defs_fortify(aflcc, 0);
+ if (!aflcc->have_msan) { insert_param(aflcc, "-fsanitize=memory"); }
+ aflcc->have_msan = 1;
}
- if (getenv("AFL_USE_UBSAN")) {
+ if (getenv("AFL_USE_UBSAN") || aflcc->have_ubsan) {
+
+ if (!aflcc->have_ubsan) {
+
+ insert_param(aflcc, "-fsanitize=undefined");
+ insert_param(aflcc, "-fsanitize-undefined-trap-on-error");
+ insert_param(aflcc, "-fno-sanitize-recover=all");
+
+ }
+
+ if (!aflcc->have_fp) {
- insert_param(aflcc, "-fsanitize=undefined");
- insert_param(aflcc, "-fsanitize-undefined-trap-on-error");
- insert_param(aflcc, "-fno-sanitize-recover=all");
- insert_param(aflcc, "-fno-omit-frame-pointer");
+ insert_param(aflcc, "-fno-omit-frame-pointer");
+ aflcc->have_fp = 1;
+
+ }
+
+ aflcc->have_ubsan = 1;
}
- if (getenv("AFL_USE_TSAN")) {
+ if (getenv("AFL_USE_TSAN") || aflcc->have_tsan) {
+
+ if (!aflcc->have_fp) {
+
+ insert_param(aflcc, "-fno-omit-frame-pointer");
+ aflcc->have_fp = 1;
+
+ }
- insert_param(aflcc, "-fsanitize=thread");
- insert_param(aflcc, "-fno-omit-frame-pointer");
+ if (!aflcc->have_tsan) { insert_param(aflcc, "-fsanitize=thread"); }
+ aflcc->have_tsan = 1;
}
- if (getenv("AFL_USE_LSAN")) {
+ if (getenv("AFL_USE_LSAN") && !aflcc->have_lsan) {
insert_param(aflcc, "-fsanitize=leak");
add_defs_lsan_ctrl(aflcc);
+ aflcc->have_lsan = 1;
}
- if (getenv("AFL_USE_CFISAN")) {
+ if (getenv("AFL_USE_CFISAN") || aflcc->have_cfisan) {
if (aflcc->compiler_mode == GCC_PLUGIN || aflcc->compiler_mode == GCC) {
- insert_param(aflcc, "-fcf-protection=full");
+ if (!aflcc->have_fcf) { insert_param(aflcc, "-fcf-protection=full"); }
} else {
- if (!aflcc->lto_mode) {
+ if (!aflcc->lto_mode && !aflcc->have_flto) {
uint32_t i = 0, found = 0;
- while (envp[i] != NULL && !found)
+ while (envp[i] != NULL && !found) {
+
if (strncmp("-flto", envp[i++], 5) == 0) found = 1;
- if (!found) insert_param(aflcc, "-flto");
+
+ }
+
+ if (!found) { insert_param(aflcc, "-flto"); }
+ aflcc->have_flto = 1;
}
- insert_param(aflcc, "-fsanitize=cfi");
- insert_param(aflcc, "-fvisibility=hidden");
+ if (!aflcc->have_cfisan) { insert_param(aflcc, "-fsanitize=cfi"); }
+
+ if (!aflcc->have_hidden) {
+
+ insert_param(aflcc, "-fvisibility=hidden");
+ aflcc->have_hidden = 1;
+
+ }
+
+ aflcc->have_cfisan = 1;
}
@@ -1877,42 +1993,48 @@ void add_sanitizers(aflcc_state_t *aflcc, char **envp) {
}
+/* Add params to enable LLVM SanCov, the native PCGUARD */
void add_native_pcguard(aflcc_state_t *aflcc) {
+ /* If there is a rust ASan runtime on the command line, it is likely we're
+ * linking from rust and adding native flags requiring the sanitizer runtime
+ * will trigger native clang to add yet another runtime, causing linker
+ * errors. For now we shouldn't add instrumentation here, we're linking
+ * anyway.
+ */
+ if (aflcc->have_rust_asanrt) { return; }
+
/* If llvm-config doesn't figure out LLVM_MAJOR, just
go on anyway and let compiler complain if doesn't work. */
- if (aflcc->instrument_opt_mode & INSTRUMENT_OPT_CODECOV) {
-
#if LLVM_MAJOR > 0 && LLVM_MAJOR < 6
- FATAL("pcguard instrumentation with pc-table requires LLVM 6.0.1+");
+ FATAL("pcguard instrumentation with pc-table requires LLVM 6.0.1+");
#else
#if LLVM_MAJOR == 0
- WARNF(
- "pcguard instrumentation with pc-table requires LLVM 6.0.1+"
- " otherwise the compiler will fail");
+ WARNF(
+ "pcguard instrumentation with pc-table requires LLVM 6.0.1+"
+ " otherwise the compiler will fail");
#endif
+ if (aflcc->instrument_opt_mode & INSTRUMENT_OPT_CODECOV) {
+
insert_param(aflcc,
"-fsanitize-coverage=trace-pc-guard,bb,no-prune,pc-table");
-#endif
} else {
-#if LLVM_MAJOR > 0 && LLVM_MAJOR < 4
- FATAL("pcguard instrumentation requires LLVM 4.0.1+");
-#else
- #if LLVM_MAJOR == 0
- WARNF(
- "pcguard instrumentation requires LLVM 4.0.1+"
- " otherwise the compiler will fail");
- #endif
- insert_param(aflcc, "-fsanitize-coverage=trace-pc-guard");
-#endif
+ insert_param(aflcc, "-fsanitize-coverage=trace-pc-guard,pc-table");
}
+#endif
+
}
+/*
+ Add params to launch our optimized PCGUARD on request.
+ It will fallback to use the native PCGUARD in some cases. If so, plz
+ bear in mind that instrument_mode will be set to INSTRUMENT_LLVMNATIVE.
+*/
void add_optimized_pcguard(aflcc_state_t *aflcc) {
#if LLVM_MAJOR >= 13
@@ -1929,7 +2051,7 @@ void add_optimized_pcguard(aflcc_state_t *aflcc) {
SAYF(
"Using unoptimized trace-pc-guard, due usage of "
"-fsanitize-coverage-allow/denylist, you can use "
- "AFL_LLVM_ALLOWLIST/AFL_LLMV_DENYLIST instead.\n");
+ "AFL_LLVM_ALLOWLIST/AFL_LLVM_DENYLIST instead.\n");
insert_param(aflcc, "-fsanitize-coverage=trace-pc-guard");
aflcc->instrument_mode = INSTRUMENT_LLVMNATIVE;
@@ -1964,8 +2086,14 @@ void add_optimized_pcguard(aflcc_state_t *aflcc) {
}
-/* Linking behaviors */
+/** About -fsanitize -----END----- **/
+/** Linking behaviors -----BEGIN----- **/
+
+/*
+ Parse and process possible linking stage related args,
+ return PARAM_MISS if nothing matched.
+*/
param_st parse_linking_params(aflcc_state_t *aflcc, u8 *cur_argv, u8 scan,
u8 *skip_next, char **argv) {
@@ -2128,6 +2256,7 @@ param_st parse_linking_params(aflcc_state_t *aflcc, u8 *cur_argv, u8 scan,
}
+/* Add params to specify the linker used in LTO */
void add_lto_linker(aflcc_state_t *aflcc) {
unsetenv("AFL_LD");
@@ -2167,6 +2296,7 @@ void add_lto_linker(aflcc_state_t *aflcc) {
}
+/* Add params to launch SanitizerCoverageLTO.so when linking */
void add_lto_passes(aflcc_state_t *aflcc) {
#if defined(AFL_CLANG_LDPATH) && LLVM_MAJOR >= 15
@@ -2185,6 +2315,7 @@ void add_lto_passes(aflcc_state_t *aflcc) {
}
+/* Add params to link with libAFLDriver.a on request */
static void add_aflpplib(aflcc_state_t *aflcc) {
if (!aflcc->need_aflpplib) return;
@@ -2220,6 +2351,7 @@ static void add_aflpplib(aflcc_state_t *aflcc) {
}
+/* Add params to link with runtimes depended by our instrumentation */
void add_runtime(aflcc_state_t *aflcc) {
if (aflcc->preprocessor_only || aflcc->have_c || !aflcc->non_dash) {
@@ -2281,6 +2413,11 @@ void add_runtime(aflcc_state_t *aflcc) {
}
+ #if __AFL_CODE_COVERAGE
+ // Required for dladdr used in afl-compiler-rt.o
+ insert_param(aflcc, "-ldl");
+ #endif
+
#if !defined(__APPLE__) && !defined(__sun)
if (!aflcc->shared_linking && !aflcc->partial_linking)
insert_object(aflcc, "dynamic_list.txt", "-Wl,--dynamic-list=%s", 0);
@@ -2310,8 +2447,14 @@ void add_runtime(aflcc_state_t *aflcc) {
}
-/* Misc */
+/** Linking behaviors -----END----- **/
+/** Miscellaneous routines -----BEGIN----- **/
+
+/*
+ Add params to make compiler driver use our afl-as
+ as assembler, required by the vanilla instrumentation.
+*/
void add_assembler(aflcc_state_t *aflcc) {
u8 *afl_as = find_object(aflcc, "as");
@@ -2328,6 +2471,7 @@ void add_assembler(aflcc_state_t *aflcc) {
}
+/* Add params to launch the gcc plugins for instrumentation. */
void add_gcc_plugin(aflcc_state_t *aflcc) {
if (aflcc->cmplog_mode) {
@@ -2344,6 +2488,7 @@ void add_gcc_plugin(aflcc_state_t *aflcc) {
}
+/* Add some miscellaneous params required by our instrumentation. */
void add_misc_params(aflcc_state_t *aflcc) {
if (getenv("AFL_NO_BUILTIN") || getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES") ||
@@ -2390,6 +2535,10 @@ void add_misc_params(aflcc_state_t *aflcc) {
}
+/*
+ Parse and process a variety of args under our matching rules,
+ return PARAM_MISS if nothing matched.
+*/
param_st parse_misc_params(aflcc_state_t *aflcc, u8 *cur_argv, u8 scan) {
param_st final_ = PARAM_MISS;
@@ -2447,6 +2596,36 @@ param_st parse_misc_params(aflcc_state_t *aflcc, u8 *cur_argv, u8 scan) {
SCAN_KEEP(aflcc->have_c, 1);
+ } else if (!strcmp(cur_argv, "-static-libasan")) {
+
+ SCAN_KEEP(aflcc->have_staticasan, 1);
+
+ } else if (strstr(cur_argv, "librustc") && strstr(cur_argv, "_rt.asan.a")) {
+
+ SCAN_KEEP(aflcc->have_rust_asanrt, 1);
+
+ } else if (!strcmp(cur_argv, "-fno-omit-frame-pointer")) {
+
+ SCAN_KEEP(aflcc->have_fp, 1);
+
+ } else if (!strcmp(cur_argv, "-fvisibility=hidden")) {
+
+ SCAN_KEEP(aflcc->have_hidden, 1);
+
+ } else if (!strcmp(cur_argv, "-flto") || !strcmp(cur_argv, "-flto=full")) {
+
+ SCAN_KEEP(aflcc->have_flto, 1);
+
+ } else if (!strncmp(cur_argv, "-D_FORTIFY_SOURCE",
+
+ strlen("-D_FORTIFY_SOURCE"))) {
+
+ SCAN_KEEP(aflcc->have_fortify, 1);
+
+ } else if (!strncmp(cur_argv, "-fcf-protection", strlen("-fcf-protection"))) {
+
+ SCAN_KEEP(aflcc->have_cfisan, 1);
+
} else if (!strncmp(cur_argv, "-O", 2)) {
SCAN_KEEP(aflcc->have_o, 1);
@@ -2510,6 +2689,9 @@ param_st parse_misc_params(aflcc_state_t *aflcc, u8 *cur_argv, u8 scan) {
}
+/** Miscellaneous routines -----END----- **/
+
+/* Print help message on request */
static void maybe_usage(aflcc_state_t *aflcc, int argc, char **argv) {
if (argc < 2 || strncmp(argv[1], "-h", 2) == 0) {
@@ -2538,11 +2720,11 @@ static void maybe_usage(aflcc_state_t *aflcc, int argc, char **argv) {
"MODES: NCC PERSIST DICT LAF "
"CMPLOG SELECT\n"
" [LLVM] LLVM: %s%s\n"
- " PCGUARD %s yes yes module yes yes "
+ " PCGUARD %s yes yes module yes yes "
"yes\n"
- " NATIVE AVAILABLE no yes no no "
+ " NATIVE AVAILABLE no yes no no "
"part. yes\n"
- " CLASSIC %s no yes module yes yes "
+ " CLASSIC %s no yes module yes yes "
"yes\n"
" - NORMAL\n"
" - CALLER\n"
@@ -2805,11 +2987,27 @@ static void maybe_usage(aflcc_state_t *aflcc, int argc, char **argv) {
}
+/*
+ Process params passed to afl-cc.
+
+ We have two working modes, *scan* and *non-scan*. In scan mode,
+ the main task is to set some variables in aflcc according to current argv[i],
+ while in non-scan mode, is to choose keep or drop current argv[i].
+
+ We have several matching routines being called sequentially in the while-loop,
+ and each of them try to parse and match current argv[i] according to their own
+ rules. If one miss match, the next will then take over. In non-scan mode, each
+ argv[i] mis-matched by all the routines will be kept.
+
+ These routines are:
+ 1. parse_misc_params
+ 2. parse_fsanitize
+ 3. parse_linking_params
+ 4. `if (*cur == '@') {...}`, i.e., parse response files
+*/
static void process_params(aflcc_state_t *aflcc, u8 scan, u32 argc,
char **argv) {
- limit_params(aflcc, argc);
-
// for (u32 x = 0; x < argc; ++x) fprintf(stderr, "[%u] %s\n", x, argv[x]);
/* Process the argument list. */
@@ -2833,134 +3031,249 @@ static void process_params(aflcc_state_t *aflcc, u8 scan, u32 argc,
if (PARAM_MISS != parse_linking_params(aflcc, cur, scan, &skip_next, argv))
continue;
+ /* Response file support -----BEGIN-----
+ We have two choices - move everything to the command line or
+ rewrite the response files to temporary files and delete them
+ afterwards. We choose the first for easiness.
+ For clang, llvm::cl::ExpandResponseFiles does this, however it
+ only has C++ interface. And for gcc there is expandargv in libiberty,
+ written in C, but we can't simply copy-paste since its LGPL licensed.
+ So here we use an equivalent FSM as alternative, and try to be compatible
+ with the two above. See:
+ - https://gcc.gnu.org/onlinedocs/gcc/Overall-Options.html
+ - driver::expand_at_files in gcc.git/gcc/gcc.c
+ - expandargv in gcc.git/libiberty/argv.c
+ - llvm-project.git/clang/tools/driver/driver.cpp
+ - ExpandResponseFiles in
+ llvm-project.git/llvm/lib/Support/CommandLine.cpp
+ */
if (*cur == '@') {
- // response file support.
- // we have two choices - move everything to the command line or
- // rewrite the response files to temporary files and delete them
- // afterwards. We choose the first for easiness.
- // We do *not* support quotes in the rsp files to cope with spaces in
- // filenames etc! If you need that then send a patch!
u8 *filename = cur + 1;
if (aflcc->debug) { DEBUGF("response file=%s\n", filename); }
- FILE *f = fopen(filename, "r");
- struct stat st;
// Check not found or empty? let the compiler complain if so.
- if (!f || fstat(fileno(f), &st) < 0 || st.st_size < 1) {
+ FILE *f = fopen(filename, "r");
+ if (!f) {
if (!scan) insert_param(aflcc, cur);
continue;
}
- u8 *tmpbuf = malloc(st.st_size + 2), *ptr;
- char **args = malloc(sizeof(char *) * (st.st_size >> 1));
- int count = 1, cont = 0, cont_act = 0;
+ struct stat st;
+ if (fstat(fileno(f), &st) || !S_ISREG(st.st_mode) || st.st_size < 1) {
- while (fgets(tmpbuf, st.st_size + 1, f)) {
+ fclose(f);
+ if (!scan) insert_param(aflcc, cur);
+ continue;
- ptr = tmpbuf;
- // fprintf(stderr, "1: %s\n", ptr);
- // no leading whitespace
- while (isspace(*ptr)) {
+ }
- ++ptr;
- cont_act = 0;
+ // Limit the number of response files, the max value
+ // just keep consistent with expandargv. Only do this in
+ // scan mode, and not touch rsp_count anymore in the next.
+ static u32 rsp_count = 2000;
+ if (scan) {
- }
+ if (rsp_count == 0) FATAL("Too many response files provided!");
- // no comments, no empty lines
- if (*ptr == '#' || *ptr == '\n' || !*ptr) { continue; }
- // remove LF
- if (ptr[strlen(ptr) - 1] == '\n') { ptr[strlen(ptr) - 1] = 0; }
- // remove CR
- if (*ptr && ptr[strlen(ptr) - 1] == '\r') { ptr[strlen(ptr) - 1] = 0; }
- // handle \ at end of line
- if (*ptr && ptr[strlen(ptr) - 1] == '\\') {
+ --rsp_count;
- cont = 1;
- ptr[strlen(ptr) - 1] = 0;
+ }
- }
+ // argc, argv acquired from this rsp file. Note that
+ // process_params ignores argv[0], we need to put a const "" here.
+ u32 argc_read = 1;
+ char **argv_read = ck_alloc(sizeof(char *));
+ argv_read[0] = "";
+
+ char *arg_buf = NULL;
+ u64 arg_len = 0;
+
+ enum fsm_state {
+
+ fsm_whitespace, // whitespace seen so far
+ fsm_double_quote, // have unpaired double quote
+ fsm_single_quote, // have unpaired single quote
+ fsm_backslash, // a backslash is seen with no unpaired quote
+ fsm_normal // a normal char is seen
+
+ };
+
+ // Workaround to append c to arg buffer, and append the buffer to argv
+#define ARG_ALLOC(c) \
+ do { \
+ \
+ ++arg_len; \
+ arg_buf = ck_realloc(arg_buf, (arg_len + 1) * sizeof(char)); \
+ arg_buf[arg_len] = '\0'; \
+ arg_buf[arg_len - 1] = (char)c; \
+ \
+ } while (0)
+
+#define ARG_STORE() \
+ do { \
+ \
+ ++argc_read; \
+ argv_read = ck_realloc(argv_read, argc_read * sizeof(char *)); \
+ argv_read[argc_read - 1] = arg_buf; \
+ arg_buf = NULL; \
+ arg_len = 0; \
+ \
+ } while (0)
- // fprintf(stderr, "2: %s\n", ptr);
+ int cur_chr = (int)' '; // init as whitespace, as a good start :)
+ enum fsm_state state_ = fsm_whitespace;
- // remove whitespace at end
- while (*ptr && isspace(ptr[strlen(ptr) - 1])) {
+ while (cur_chr != EOF) {
- ptr[strlen(ptr) - 1] = 0;
- cont = 0;
+ switch (state_) {
- }
+ case fsm_whitespace:
- // fprintf(stderr, "3: %s\n", ptr);
- if (*ptr) {
+ if (arg_buf) {
+
+ ARG_STORE();
+ break;
+
+ }
- do {
+ if (isspace(cur_chr)) {
- u8 *value = ptr;
- while (*ptr && !isspace(*ptr)) {
+ cur_chr = fgetc(f);
- ++ptr;
+ } else if (cur_chr == (int)'\'') {
+
+ state_ = fsm_single_quote;
+ cur_chr = fgetc(f);
+
+ } else if (cur_chr == (int)'"') {
+
+ state_ = fsm_double_quote;
+ cur_chr = fgetc(f);
+
+ } else if (cur_chr == (int)'\\') {
+
+ state_ = fsm_backslash;
+ cur_chr = fgetc(f);
+
+ } else {
+
+ state_ = fsm_normal;
}
- while (*ptr && isspace(*ptr)) {
+ break;
+
+ case fsm_normal:
+
+ if (isspace(cur_chr)) {
+
+ state_ = fsm_whitespace;
+
+ } else if (cur_chr == (int)'\'') {
+
+ state_ = fsm_single_quote;
+ cur_chr = fgetc(f);
+
+ } else if (cur_chr == (int)'\"') {
- *ptr++ = 0;
+ state_ = fsm_double_quote;
+ cur_chr = fgetc(f);
+
+ } else if (cur_chr == (int)'\\') {
+
+ state_ = fsm_backslash;
+ cur_chr = fgetc(f);
+
+ } else {
+
+ ARG_ALLOC(cur_chr);
+ cur_chr = fgetc(f);
}
- if (cont_act) {
+ break;
+
+ case fsm_backslash:
+
+ ARG_ALLOC(cur_chr);
+ cur_chr = fgetc(f);
+ state_ = fsm_normal;
- u32 len = strlen(args[count - 1]) + strlen(value) + 1;
- u8 *tmp = malloc(len);
- snprintf(tmp, len, "%s%s", args[count - 1], value);
- free(args[count - 1]);
- args[count - 1] = tmp;
- cont_act = 0;
+ break;
+
+ case fsm_single_quote:
+
+ if (cur_chr == (int)'\\') {
+
+ cur_chr = fgetc(f);
+ if (cur_chr == EOF) break;
+ ARG_ALLOC(cur_chr);
+
+ } else if (cur_chr == (int)'\'') {
+
+ state_ = fsm_normal;
} else {
- args[count++] = strdup(value);
+ ARG_ALLOC(cur_chr);
}
- } while (*ptr);
+ cur_chr = fgetc(f);
+ break;
- }
+ case fsm_double_quote:
+
+ if (cur_chr == (int)'\\') {
- if (cont) {
+ cur_chr = fgetc(f);
+ if (cur_chr == EOF) break;
+ ARG_ALLOC(cur_chr);
- cont_act = 1;
- cont = 0;
+ } else if (cur_chr == (int)'"') {
+
+ state_ = fsm_normal;
+
+ } else {
+
+ ARG_ALLOC(cur_chr);
+
+ }
+
+ cur_chr = fgetc(f);
+ break;
+
+ default:
+ break;
}
}
- if (count) { process_params(aflcc, scan, count, args); }
+ if (arg_buf) { ARG_STORE(); } // save the pending arg after EOF
- // we cannot free args[] unless we don't need
- // to keep any reference in cc_params
- if (scan) {
+#undef ARG_ALLOC
+#undef ARG_STORE
- if (count) do {
+ if (argc_read > 1) { process_params(aflcc, scan, argc_read, argv_read); }
- free(args[--count]);
+ // We cannot free argv_read[] unless we don't need to keep any
+ // reference in cc_params. Never free argv[0], the const "".
+ if (scan) {
- } while (count);
+ while (argc_read > 1)
+ ck_free(argv_read[--argc_read]);
- free(args);
+ ck_free(argv_read);
}
- free(tmpbuf);
-
continue;
- }
+ } /* Response file support -----END----- */
if (!scan) insert_param(aflcc, cur);
@@ -2968,8 +3281,7 @@ static void process_params(aflcc_state_t *aflcc, u8 scan, u32 argc,
}
-/* Copy argv to cc_params, making the necessary edits. */
-
+/* Process each of the existing argv, also add a few new args. */
static void edit_params(aflcc_state_t *aflcc, u32 argc, char **argv,
char **envp) {
@@ -3110,7 +3422,6 @@ static void edit_params(aflcc_state_t *aflcc, u32 argc, char **argv,
}
/* Main entry point */
-
int main(int argc, char **argv, char **envp) {
aflcc_state_t *aflcc = malloc(sizeof(aflcc_state_t));
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index 3f9bfa72..214b4fe9 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -1017,6 +1017,12 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
if (rlen == 4) {
+ if (status >= 0x41464c00 && status <= 0x41464cff) {
+
+ FATAL("Target uses the new forkserver model, you need to switch to a newer afl-fuzz too!");
+
+ }
+
if (!be_quiet) { OKF("All right - fork server is up."); }
if (getenv("AFL_DEBUG")) {
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index 35932913..8ab44a3b 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -124,6 +124,9 @@ void bind_to_free_cpu(afl_state_t *afl) {
}
WARNF("Not binding to a CPU core (AFL_NO_AFFINITY set).");
+ #ifdef __linux__
+ if (afl->fsrv.nyx_mode) { afl->fsrv.nyx_bind_cpu_id = 0; }
+ #endif
return;
}
@@ -151,6 +154,9 @@ void bind_to_free_cpu(afl_state_t *afl) {
} else {
OKF("CPU binding request using -b %d successful.", afl->cpu_to_bind);
+ #ifdef __linux__
+ if (afl->fsrv.nyx_mode) { afl->fsrv.nyx_bind_cpu_id = afl->cpu_to_bind; }
+ #endif
}
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 2d5787e8..8cf6c735 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -165,7 +165,7 @@ static void usage(u8 *argv0, int more_help) {
"\n"
"Mutator settings:\n"
- " -a - target input format, \"text\" or \"binary\" (default: "
+ " -a type - target input format, \"text\" or \"binary\" (default: "
"generic)\n"
" -g minlength - set min length of generated fuzz input (default: 1)\n"
" -G maxlength - set max length of generated fuzz input (default: "
@@ -1915,6 +1915,15 @@ int main(int argc, char **argv_orig, char **envp) {
bind_to_free_cpu(afl);
#endif /* HAVE_AFFINITY */
+ #ifdef __linux__
+ if (afl->fsrv.nyx_mode && afl->fsrv.nyx_bind_cpu_id == 0xFFFFFFFF) {
+
+ afl->fsrv.nyx_bind_cpu_id = 0;
+
+ }
+
+ #endif
+
#ifdef __HAIKU__
/* Prioritizes performance over power saving */
set_scheduler_mode(SCHEDULER_MODE_LOW_LATENCY);
diff --git a/test/test-all.sh b/test/test-all.sh
index 3cb692ca..65cfb812 100755
--- a/test/test-all.sh
+++ b/test/test-all.sh
@@ -16,6 +16,8 @@
. ./test-frida-mode.sh
+. ./test-nyx-mode.sh
+
. ./test-unicorn-mode.sh
. ./test-custom-mutators.sh
diff --git a/test/test-basic.sh b/test/test-basic.sh
index 61ad4b7c..7005d3ce 100755
--- a/test/test-basic.sh
+++ b/test/test-basic.sh
@@ -2,6 +2,7 @@
. ./test-pre.sh
+OS=$(uname -s)
AFL_GCC=afl-gcc
$ECHO "$BLUE[*] Testing: ${AFL_GCC}, afl-showmap, afl-fuzz, afl-cmin and afl-tmin"
@@ -61,7 +62,7 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc
}
# now we want to be sure that afl-fuzz is working
# make sure crash reporter is disabled on Mac OS X
- (test "$(uname -s)" = "Darwin" && test $(launchctl list 2>/dev/null | grep -q '\.ReportCrash$') && {
+ (test "$OS" = "Darwin" && test $(launchctl list 2>/dev/null | grep -q '\.ReportCrash$') && {
$ECHO "$RED[!] we cannot run afl-fuzz with enabled crash reporter. Run 'sudo sh afl-system-config'.$RESET"
true
}) || {
@@ -84,16 +85,20 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc
}
echo 000000000000000000000000 > in/in2
echo 111 > in/in3
- mkdir -p in2
- ../afl-cmin -m ${MEM_LIMIT} -i in -o in2 -- ./test-instr.plain >/dev/null 2>&1 # why is afl-forkserver writing to stderr?
- CNT=`ls in2/* 2>/dev/null | wc -l`
- case "$CNT" in
- *2) $ECHO "$GREEN[+] afl-cmin correctly minimized the number of testcases" ;;
- *) $ECHO "$RED[!] afl-cmin did not correctly minimize the number of testcases ($CNT)"
- CODE=1
- ;;
- esac
- rm -f in2/in*
+ test "$OS" = "Darwin" && {
+ $ECHO "$GREY[*] afl-cmin not available on macOS, cannot test afl-cmin"
+ } || {
+ mkdir -p in2
+ ../afl-cmin -m ${MEM_LIMIT} -i in -o in2 -- ./test-instr.plain >/dev/null 2>&1 # why is afl-forkserver writing to stderr?
+ CNT=`ls in2/* 2>/dev/null | wc -l`
+ case "$CNT" in
+ *2) $ECHO "$GREEN[+] afl-cmin correctly minimized the number of testcases" ;;
+ *) $ECHO "$RED[!] afl-cmin did not correctly minimize the number of testcases ($CNT)"
+ CODE=1
+ ;;
+ esac
+ rm -f in2/in*
+ }
export AFL_QUIET=1
if command -v bash >/dev/null ; then {
../afl-cmin.bash -m ${MEM_LIMIT} -i in -o in2 -- ./test-instr.plain >/dev/null
@@ -182,7 +187,7 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc
}
# now we want to be sure that afl-fuzz is working
# make sure crash reporter is disabled on Mac OS X
- (test "$(uname -s)" = "Darwin" && test $(launchctl list 2>/dev/null | grep -q '\.ReportCrash$') && {
+ (test "$OS" = "Darwin" && test $(launchctl list 2>/dev/null | grep -q '\.ReportCrash$') && {
$ECHO "$RED[!] we cannot run afl-fuzz with enabled crash reporter. Run 'sudo sh afl-system-config'.$RESET"
true
}) || {
@@ -204,25 +209,29 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc
}
}
echo 000000000000000000000000 > in/in2
- echo AAA > in/in3
- mkdir -p in2
- ../afl-cmin -m ${MEM_LIMIT} -i in -o in2 -- ./test-instr.plain >/dev/null 2>&1 # why is afl-forkserver writing to stderr?
- CNT=`ls in2/* 2>/dev/null | wc -l`
- case "$CNT" in
- *2) $ECHO "$GREEN[+] afl-cmin correctly minimized the number of testcases" ;;
- \ *1|1) { # allow leading whitecase for portability
- test -s in2/* && $ECHO "$YELLOW[?] afl-cmin did minimize to one testcase. This can be a bug or due compiler optimization."
- test -s in2/* || {
- $ECHO "$RED[!] afl-cmin did not correctly minimize the number of testcases ($CNT)"
- CODE=1
+ echo AAA > in/in2
+ test "$OS" = "Darwin" && {
+ $ECHO "$GREY[*] afl-cmin not available on macOS, cannot test afl-cmin"
+ } || {
+ mkdir -p in2
+ ../afl-cmin -m ${MEM_LIMIT} -i in -o in2 -- ./test-instr.plain >/dev/null 2>&1 # why is afl-forkserver writing to stderr?
+ CNT=`ls in2/* 2>/dev/null | wc -l`
+ case "$CNT" in
+ *2) $ECHO "$GREEN[+] afl-cmin correctly minimized the number of testcases" ;;
+ \ *1|1) { # allow leading whitecase for portability
+ test -s in2/* && $ECHO "$YELLOW[?] afl-cmin did minimize to one testcase. This can be a bug or due compiler optimization."
+ test -s in2/* || {
+ $ECHO "$RED[!] afl-cmin did not correctly minimize the number of testcases ($CNT)"
+ CODE=1
+ }
}
- }
- ;;
- *) $ECHO "$RED[!] afl-cmin did not correctly minimize the number of testcases ($CNT)"
- CODE=1
- ;;
- esac
- rm -f in2/in*
+ ;;
+ *) $ECHO "$RED[!] afl-cmin did not correctly minimize the number of testcases ($CNT)"
+ CODE=1
+ ;;
+ esac
+ rm -f in2/in*
+ }
export AFL_QUIET=1
if command -v bash >/dev/null ; then {
../afl-cmin.bash -m ${MEM_LIMIT} -i in -o in2 -- ./test-instr.plain >/dev/null
diff --git a/test/test-compilers.sh b/test/test-compilers.sh
new file mode 100755
index 00000000..b47cf38d
--- /dev/null
+++ b/test/test-compilers.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+echo Testing compilers ...
+for cc in afl-cc afl-gcc afl-clang afl-clang-fast afl-clang-lto afl-gcc-fast; do
+ test -e ../$cc && { { ../$cc -o t ../test-instr.c >/dev/null 2<&1 && echo Success: $cc ; } || echo Failing: $cc ; } || echo Missing: $cc
+done
+rm -f t
+echo Done!
diff --git a/test/test-llvm.sh b/test/test-llvm.sh
index 95e43b1c..53bbd7b4 100755
--- a/test/test-llvm.sh
+++ b/test/test-llvm.sh
@@ -2,6 +2,8 @@
. ./test-pre.sh
+OS=$(uname -s)
+
$ECHO "$BLUE[*] Testing: llvm_mode, afl-showmap, afl-fuzz, afl-cmin and afl-tmin"
test -e ../afl-clang-fast -a -e ../split-switches-pass.so && {
../afl-clang-fast -o test-instr.plain ../test-instr.c > /dev/null 2>&1
@@ -123,7 +125,7 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && {
}
# now we want to be sure that afl-fuzz is working
# make sure crash reporter is disabled on Mac OS X
- (test "$(uname -s)" = "Darwin" && test $(launchctl list 2>/dev/null | grep -q '\.ReportCrash$') && {
+ (test "$OS" = "Darwin" && test $(launchctl list 2>/dev/null | grep -q '\.ReportCrash$') && {
$ECHO "$RED[!] we cannot run afl-fuzz with enabled crash reporter. Run 'sudo sh afl-system-config'.$RESET"
CODE=1
true
@@ -146,18 +148,22 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && {
}
}
test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc" || {
+ mkdir -p in2
echo 000000000000000000000000 > in/in2
echo 111 > in/in3
- mkdir -p in2
- ../afl-cmin -m ${MEM_LIMIT} -i in -o in2 -- ./test-instr.plain >/dev/null 2>&1 # why is afl-forkserver writing to stderr?
- CNT=`ls in2/* 2>/dev/null | wc -l`
- case "$CNT" in
- *2) $ECHO "$GREEN[+] afl-cmin correctly minimized the number of testcases" ;;
- *) $ECHO "$RED[!] afl-cmin did not correctly minimize the number of testcases ($CNT)"
- CODE=1
- ;;
- esac
- rm -f in2/in*
+ test "$OS" = "Darwin" && {
+ $ECHO "$GREY[*] afl-cmin not available on macOS, cannot test afl-cmin"
+ } || {
+ ../afl-cmin -m ${MEM_LIMIT} -i in -o in2 -- ./test-instr.plain >/dev/null 2>&1 # why is afl-forkserver writing to stderr?
+ CNT=`ls in2/* 2>/dev/null | wc -l`
+ case "$CNT" in
+ *2) $ECHO "$GREEN[+] afl-cmin correctly minimized the number of testcases" ;;
+ *) $ECHO "$RED[!] afl-cmin did not correctly minimize the number of testcases ($CNT)"
+ CODE=1
+ ;;
+ esac
+ rm -f in2/in*
+ }
export AFL_QUIET=1
if type bash >/dev/null ; then {
../afl-cmin.bash -m ${MEM_LIMIT} -i in -o in2 -- ./test-instr.plain >/dev/null
diff --git a/test/test-nyx-mode.sh b/test/test-nyx-mode.sh
new file mode 100755
index 00000000..6de63f1b
--- /dev/null
+++ b/test/test-nyx-mode.sh
@@ -0,0 +1,79 @@
+#!/bin/sh
+
+. ./test-pre.sh
+
+$ECHO "$BLUE[*] Testing: nyx_mode"
+
+test "$CI" = "true" && {
+ $ECHO "$YELLOW[-] nyx_mode cannot be tested in the Github CI, skipping ..."
+ exit 0
+}
+
+unset AFL_CC
+
+test -e ../libnyx.so && {
+ ../afl-cc -o test-instr ../test-instr.c > errors 2>&1
+ test -e test-instr && {
+ {
+ rm -rf nyx-test in out
+ $ECHO "$GREY[*] running nyx_packer"
+ python3 ../nyx_mode/packer/packer/nyx_packer.py \
+ ./test-instr \
+ nyx-test \
+ afl \
+ instrumentation \
+ --fast_reload_mode \
+ --purge > /dev/null 2>&1
+
+ test -e nyx-test/test-instr && {
+
+ $ECHO "$GREY[*] running nyx_config_gen"
+ python3 ../nyx_mode/packer/packer/nyx_config_gen.py nyx-test Kernel > /dev/null 2>&1
+
+ test -e nyx-test/config.ron && {
+ sudo modprobe -r kvm-intel
+ sudo modprobe -r kvm
+ sudo modprobe kvm enable_vmware_backdoor=y
+ sudo modprobe kvm-intel
+ #cat /sys/module/kvm/parameters/enable_vmware_backdoor
+
+ mkdir -p in
+ echo 00000 > in/in
+ $ECHO "$GREY[*] running afl-fuzz for nyx_mode, this will take approx 10 seconds"
+ {
+ AFL_DEBUG=1 ../afl-fuzz -i in -o out -V05 -X -- ./nyx-test >>errors 2>&1
+ } >>errors 2>&1
+ test -n "$( ls out/default/queue/id:000002* 2>/dev/null )" && {
+ $ECHO "$GREEN[+] afl-fuzz is working correctly with nyx_mode"
+ RUNTIME=`grep execs_done out/default/fuzzer_stats | awk '{print$3}'`
+ rm -rf errors nyx-test test-instr in out
+ } || {
+ echo CUT------------------------------------------------------------------CUT
+ cat errors
+ echo CUT------------------------------------------------------------------CUT
+ $ECHO "$RED[!] afl-fuzz is not working correctly with nyx_mode"
+ CODE=1
+ }
+ } || {
+ $ECHO "$RED[!] nyx_packer failed, likely install requirements not met."
+ CODE=1
+ }
+ } || {
+ $ECHO "$RED[!] nyx_packer failed, likely install requirements not met."
+ CODE=1
+ }
+ #rm -rf test-instr in out errors nyx-test
+ }
+ } || {
+ echo CUT------------------------------------------------------------------CUT
+ cat errors
+ echo CUT------------------------------------------------------------------CUT
+ $ECHO "$RED[!] afl-cc compilation of test targets failed - what is going on??"
+ CODE=1
+ }
+} || {
+ $ECHO "$YELLOW[-] nyx_mode is not compiled, cannot test"
+ INCOMPLETE=1
+}
+
+. ./test-post.sh
diff --git a/test/test-pre.sh b/test/test-pre.sh
index 1ca9dfb5..ce996415 100755
--- a/test/test-pre.sh
+++ b/test/test-pre.sh
@@ -20,7 +20,7 @@ echo foobar | grep -qE 'asd|oob' 2>/dev/null || { echo Error: grep command does
test -e ./test-all.sh || cd $(dirname $0) || exit 1
test -e ./test-all.sh || { echo Error: you must be in the test/ directory ; exit 1 ; }
export AFL_PATH=`pwd`/..
-export AFL_NO_AFFINITY=1 # workaround for travis that fails for no avail cores
+export AFL_TRY_AFFINITY=1 # workaround for travis that fails for no avail cores
echo 1 > test.1
echo 1 > test.2
diff --git a/utils/dynamic_covfilter/README.md b/utils/dynamic_covfilter/README.md
new file mode 100644
index 00000000..381e0855
--- /dev/null
+++ b/utils/dynamic_covfilter/README.md
@@ -0,0 +1,60 @@
+# Dynamic Instrumentation Filter
+
+Sometimes it can be beneficial to limit the instrumentation feedback to
+specific code locations. It is possible to do so at compile-time by simply
+not instrumenting any undesired locations. However, there are situations
+where doing this dynamically without requiring a new build can be beneficial.
+Especially when dealing with larger builds, it is much more convenient to
+select the target code locations at runtime instead of doing so at build time.
+
+There are two ways of doing this in AFL++. Both approaches require a build of
+AFL++ with `CODE_COVERAGE=1`, so make sure to build AFL++ first by invoking
+
+`CODE_COVERAGE=1 make`
+
+Once you have built AFL++, you can choose out of two approaches:
+
+## Simple Selection with `AFL_PC_FILTER`
+
+This approach requires a build with `AFL_INSTRUMENTATION=llvmnative` or
+`llvmcodecov` as well as an AddressSanitizer build with debug information.
+
+By setting the environment variable `AFL_PC_FILTER` to a string, the runtime
+symbolizer is enabled in the AFL++ runtime. At startup, the runtime will call
+the `__sanitizer_symbolize_pc` API to resolve every PC in every loaded module.
+The runtime then matches the result using `strstr` and disables the PC guard
+if the symbolized PC does not contain the specified string.
+
+This approach has the benefit of being very easy to use. The downside is that
+it causes significant startup delays with large binaries and that it requires
+an AddressSanitizer build.
+
+This method has no additional runtime overhead after startup.
+
+## Selection using pre-symbolized data file with `AFL_PC_FILTER_FILE`
+
+To avoid large startup time delays, a specific module can be pre-symbolized
+using the `make_symbol_list.py` script. This script outputs a sorted list of
+functions with their respective relative offsets and lengths in the target
+binary:
+
+`python3 make_symbol_list.py libxul.so > libxul.symbols.txt`
+
+The resulting list can be filtered, e.g. using grep:
+
+`grep -i "webgl" libxul.symbols.txt > libxul.webgl.symbols.txt`
+
+Finally, you can run with `AFL_PC_FILTER_FILE=libxul.webgl.symbols.txt` to
+restrict instrumentation feedback to the given locations. This approach only
+has a minimal startup time delay due to the implementation only using binary
+search on the given file per PC rather than reading debug information for every
+PC. It also works well with Nyx, where symbolizing is usually disabled for the
+target process to avoid delays with frequent crashes.
+
+Similar to the previous method, This approach requires a build with
+`AFL_INSTRUMENTATION=llvmnative` or `llvmcodecov` as well debug information.
+However, it does not require the ASan runtime as it doesn't do the symbolizing
+in process. Due to the way it maps PCs to symbols, it is less accurate when it
+comes to includes and inlines (it assumes all PCs within a function belong to
+that function and originate from the same file). For most purposes, this should
+be a reasonable simplification to quickly process even the largest binaries.
diff --git a/utils/dynamic_covfilter/make_symbol_list.py b/utils/dynamic_covfilter/make_symbol_list.py
new file mode 100644
index 00000000..d1dd6ab3
--- /dev/null
+++ b/utils/dynamic_covfilter/make_symbol_list.py
@@ -0,0 +1,73 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# Written by Christian Holler
+
+import json
+import os
+import sys
+import subprocess
+
+if len(sys.argv) != 2:
+ print("Usage: %s binfile" % os.path.basename(sys.argv[0]))
+ sys.exit(1)
+
+binfile = sys.argv[1]
+
+addr2len = {}
+addrs = []
+
+output = subprocess.check_output(["objdump", "-t", binfile]).decode("utf-8")
+for line in output.splitlines():
+ line = line.replace("\t", " ")
+ components = [x for x in line.split(" ") if x]
+ if not components:
+ continue
+ try:
+ start_addr = int(components[0], 16)
+ except ValueError:
+ continue
+
+ # Length has variable position in objdump output
+ length = None
+ for comp in components[1:]:
+ if len(comp) == 16:
+ try:
+ length = int(comp, 16)
+ break
+ except:
+ continue
+
+ if length is None:
+ print("ERROR: Couldn't determine function section length: %s" % line)
+
+ func = components[-1]
+
+ addrs.append(start_addr)
+ addr2len[str(hex(start_addr))] = str(length)
+
+# The search implementation in the AFL runtime expects everything sorted.
+addrs.sort()
+addrs = [str(hex(addr)) for addr in addrs]
+
+# We symbolize in one go to speed things up with large binaries.
+output = subprocess.check_output([
+ "llvm-addr2line",
+ "--output-style=JSON",
+ "-f", "-C", "-a", "-e",
+ binfile],
+ input="\n".join(addrs).encode("utf-8")).decode("utf-8")
+
+output = output.strip().splitlines()
+for line in output:
+ output = json.loads(line)
+ if "Symbol" in output and output["Address"] in addr2len:
+ final_output = [
+ output["Address"],
+ addr2len[output["Address"]],
+ os.path.basename(output["ModuleName"]),
+ output["Symbol"][0]["FileName"],
+ output["Symbol"][0]["FunctionName"]
+ ]
+ print("\t".join(final_output))
--
cgit 1.4.1
From 5ba66a8860657b21c45480f1d565634cfe38a7dc Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 1 Feb 2024 15:22:51 +0100
Subject: final touches for skipdet
---
GNUmakefile.llvm | 2 +-
docs/Changelog.md | 2 ++
src/afl-forkserver.c | 4 +++-
src/afl-fuzz-state.c | 2 +-
src/afl-fuzz.c | 22 ++++++++++++++--------
test/test-custom-mutators.sh | 4 ++--
6 files changed, 23 insertions(+), 13 deletions(-)
(limited to 'docs')
diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm
index 7437130d..ec8fefe4 100644
--- a/GNUmakefile.llvm
+++ b/GNUmakefile.llvm
@@ -45,7 +45,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_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^[0-2]\.|^3.[0-7]\.' && echo 1 || echo 0 )
+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 )
LLVM_NEW_API = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[0-9]' && echo 1 || echo 0 )
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 720a0689..29081549 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -9,6 +9,8 @@
explore is slightly better now.
- fixed minor issues in the mutation engine, thanks to @futhewo for
reporting!
+ - better deterministic fuzzing is now available, benchmarks have shown
+ to improve fuzzing. Enable with -D. Thanks to @kdsjZh for the PR!
- afl-cc:
- large rewrite by @SonicStark which fixes a few corner cases, thanks!
- LTO mode now requires llvm 12+
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index 214b4fe9..ded0c21d 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -1019,7 +1019,9 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
if (status >= 0x41464c00 && status <= 0x41464cff) {
- FATAL("Target uses the new forkserver model, you need to switch to a newer afl-fuzz too!");
+ FATAL(
+ "Target uses the new forkserver model, you need to switch to a newer "
+ "afl-fuzz too!");
}
diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c
index 6cf580ce..b647ac84 100644
--- a/src/afl-fuzz-state.c
+++ b/src/afl-fuzz-state.c
@@ -102,7 +102,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) {
afl->stats_update_freq = 1;
afl->stats_file_update_freq_msecs = STATS_UPDATE_SEC * 1000;
afl->stats_avg_exec = 0;
- afl->skip_deterministic = 0;
+ afl->skip_deterministic = 1;
afl->sync_time = SYNC_TIME;
afl->cmplog_lvl = 2;
afl->min_length = 1;
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 7db1aeb3..69064d51 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -170,7 +170,7 @@ static void usage(u8 *argv0, int more_help) {
" -g minlength - set min length of generated fuzz input (default: 1)\n"
" -G maxlength - set max length of generated fuzz input (default: "
"%lu)\n"
- " -D - enable deterministic fuzzing (once per queue entry)\n"
+ " -D - enable (a new) effective deterministic fuzzing\n"
" -L minutes - use MOpt(imize) mode and set the time limit for "
"entering the\n"
" pacemaker mode (minutes of no new finds). 0 = "
@@ -955,14 +955,20 @@ int main(int argc, char **argv_orig, char **envp) {
break;
- case 'D': /* no deterministic */
+ case 'D': /* partial deterministic */
- afl->skip_deterministic = 1;
+ afl->skip_deterministic = 0;
break;
- case 'd': /* partial deterministic */
+ case 'd': /* no deterministic */
- afl->skip_deterministic = 0;
+ // this is the default and currently a lot of infrastructure enforces
+ // it (e.g. clusterfuzz, fuzzbench) based on that this feature
+ // originally was bad performance wise. We now have a better
+ // implementation, hence if it is activated, we do not want to
+ // deactivate it by such setups.
+
+ // afl->skip_deterministic = 1;
break;
case 'B': /* load bitmap */
@@ -1424,11 +1430,11 @@ int main(int argc, char **argv_orig, char **envp) {
}
#endif
+
+ // silently disable deterministic mutation if custom mutators are used
if (!afl->skip_deterministic && afl->afl_env.afl_custom_mutator_only) {
- FATAL(
- "Using -D determinstic fuzzing is incompatible with "
- "AFL_CUSTOM_MUTATOR_ONLY!");
+ afl->skip_deterministic = 1;
}
diff --git a/test/test-custom-mutators.sh b/test/test-custom-mutators.sh
index 49feedc0..8c8b0ad3 100755
--- a/test/test-custom-mutators.sh
+++ b/test/test-custom-mutators.sh
@@ -38,7 +38,7 @@ test -e test-custom-mutator.c -a -e ${CUSTOM_MUTATOR_PATH}/example.c -a -e ${CUS
# Run afl-fuzz w/ the C mutator
$ECHO "$GREY[*] running afl-fuzz for the C mutator, this will take approx 10 seconds"
{
- AFL_CUSTOM_MUTATOR_LIBRARY=./libexamplemutator.so AFL_CUSTOM_MUTATOR_ONLY=1 ../afl-fuzz -V07 -m ${MEM_LIMIT} -i in -o out -- ./test-custom-mutator >>errors 2>&1
+ AFL_CUSTOM_MUTATOR_LIBRARY=./libexamplemutator.so AFL_CUSTOM_MUTATOR_ONLY=1 ../afl-fuzz -V07 -m ${MEM_LIMIT} -i in -o out -d -- ./test-custom-mutator >>errors 2>&1
} >>errors 2>&1
# Check results
@@ -58,7 +58,7 @@ test -e test-custom-mutator.c -a -e ${CUSTOM_MUTATOR_PATH}/example.c -a -e ${CUS
# Run afl-fuzz w/ multiple C mutators
$ECHO "$GREY[*] running afl-fuzz with multiple custom C mutators, this will take approx 10 seconds"
{
- AFL_CUSTOM_MUTATOR_LIBRARY="./libexamplemutator.so;./libexamplemutator2.so" AFL_CUSTOM_MUTATOR_ONLY=1 ../afl-fuzz -V07 -m ${MEM_LIMIT} -i in -o out -- ./test-multiple-mutators >>errors 2>&1
+ AFL_CUSTOM_MUTATOR_LIBRARY="./libexamplemutator.so;./libexamplemutator2.so" AFL_CUSTOM_MUTATOR_ONLY=1 ../afl-fuzz -V07 -m ${MEM_LIMIT} -i in -o out -d -- ./test-multiple-mutators >>errors 2>&1
} >>errors 2>&1
test -n "$( ls out/default/crashes/id:000000* 2>/dev/null )" && { # TODO: update here
--
cgit 1.4.1
From a9292626a6a94b22f8b9123ff4ee160466c9b6fd Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sat, 3 Feb 2024 10:51:55 +0100
Subject: nits
---
docs/INSTALL.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'docs')
diff --git a/docs/INSTALL.md b/docs/INSTALL.md
index 1379df0a..84bbe3ea 100644
--- a/docs/INSTALL.md
+++ b/docs/INSTALL.md
@@ -114,10 +114,10 @@ freshly installed clang, clang++, llvm-config, gmake and coreutils, e.g.:
# Depending on your MacOS system + brew version it is either
export PATH="/opt/homebrew/opt/llvm/bin:$PATH"
# or
-export PATH="/usr/local/opt/llvm/bin:$PATH"
+export PATH="/usr/local/opt/llvm/bin:/usr/local/opt/coreutils/libexec/gnubin:$PATH"
# you can check with "brew info llvm"
-export PATH="/usr/local/opt/coreutils/libexec/gnubin:/usr/local/bin:$PATH"
+export PATH="/usr/local/bin:$PATH"
export CC=clang
export CXX=clang++
gmake
--
cgit 1.4.1
From ed1a6f8a570c6fcabee962f402d8d58f6cea77b7 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sat, 3 Feb 2024 11:01:31 +0100
Subject: 2024 v4.10c release
---
GNUmakefile.gcc_plugin | 2 +-
README.md | 4 ++--
afl-cmin.bash | 2 +-
afl-whatsup | 2 +-
docs/Changelog.md | 3 +--
frida_mode/Scripting.md | 2 +-
frida_mode/test/cmplog/cmplog.c | 2 +-
frida_mode/test/deferred/testinstr.c | 2 +-
frida_mode/test/dynamic/testinstr.c | 2 +-
frida_mode/test/entry_point/testinstr.c | 2 +-
frida_mode/test/exe/testinstr.c | 2 +-
frida_mode/test/js/test.c | 2 +-
frida_mode/test/js/test2.c | 2 +-
frida_mode/test/output/testinstr.c | 2 +-
frida_mode/test/perf/perf.c | 2 +-
frida_mode/test/persistent_ret/testinstr.c | 2 +-
frida_mode/test/testinstr/testinstr.c | 2 +-
frida_mode/test/unstable/unstable.c | 2 +-
frida_mode/util/frida_get_symbol_addr.sh | 2 +-
include/afl-as.h | 2 +-
include/afl-fuzz.h | 2 +-
include/afl-prealloc.h | 2 +-
include/alloc-inl.h | 2 +-
include/cmplog.h | 2 +-
include/common.h | 2 +-
include/config.h | 4 ++--
include/debug.h | 2 +-
include/forkserver.h | 2 +-
include/hash.h | 2 +-
include/list.h | 2 +-
include/sharedmem.h | 2 +-
include/snapshot-inl.h | 2 +-
include/types.h | 2 +-
include/xxhash.h | 2 +-
instrumentation/afl-compiler-rt.o.c | 2 +-
instrumentation/afl-gcc-cmplog-pass.so.cc | 2 +-
instrumentation/afl-gcc-cmptrs-pass.so.cc | 2 +-
instrumentation/afl-gcc-common.h | 2 +-
instrumentation/afl-gcc-pass.so.cc | 2 +-
instrumentation/afl-llvm-dict2file.so.cc | 2 +-
instrumentation/afl-llvm-lto-instrumentlist.so.cc | 2 +-
instrumentation/afl-llvm-pass.so.cc | 2 +-
instrumentation/cmplog-instructions-pass.cc | 2 +-
instrumentation/cmplog-routines-pass.cc | 2 +-
instrumentation/cmplog-switches-pass.cc | 2 +-
instrumentation/injection-pass.cc | 2 +-
qemu_mode/build_qemu_support.sh | 2 +-
qemu_mode/fastexit/Makefile | 2 +-
qemu_mode/libcompcov/Makefile | 2 +-
qemu_mode/libcompcov/compcovtest.cc | 2 +-
qemu_mode/libcompcov/libcompcov.so.c | 2 +-
qemu_mode/libqasan/Makefile | 2 +-
qemu_mode/libqasan/hooks.c | 2 +-
qemu_mode/libqasan/libqasan.c | 2 +-
qemu_mode/libqasan/libqasan.h | 2 +-
qemu_mode/libqasan/malloc.c | 2 +-
qemu_mode/libqasan/patch.c | 2 +-
qemu_mode/libqasan/string.c | 2 +-
qemu_mode/libqasan/uninstrument.c | 2 +-
qemu_mode/unsigaction/Makefile | 2 +-
qemu_mode/util/qemu_get_symbol_addr.sh | 2 +-
src/afl-analyze.c | 2 +-
src/afl-as.c | 2 +-
src/afl-cc.c | 2 +-
src/afl-common.c | 2 +-
src/afl-forkserver.c | 2 +-
src/afl-fuzz-bitmap.c | 2 +-
src/afl-fuzz-cmplog.c | 2 +-
src/afl-fuzz-extras.c | 2 +-
src/afl-fuzz-init.c | 2 +-
src/afl-fuzz-mutators.c | 2 +-
src/afl-fuzz-one.c | 2 +-
src/afl-fuzz-python.c | 2 +-
src/afl-fuzz-queue.c | 2 +-
src/afl-fuzz-redqueen.c | 2 +-
src/afl-fuzz-run.c | 2 +-
src/afl-fuzz-state.c | 2 +-
src/afl-fuzz-stats.c | 2 +-
src/afl-fuzz.c | 2 +-
src/afl-gotcpu.c | 2 +-
src/afl-ld-lto.c | 2 +-
src/afl-sharedmem.c | 2 +-
src/afl-showmap.c | 2 +-
src/afl-tmin.c | 2 +-
test-instr.c | 2 +-
unicorn_mode/build_unicorn_support.sh | 2 +-
utils/afl_network_proxy/afl-network-client.c | 2 +-
utils/afl_network_proxy/afl-network-server.c | 2 +-
utils/afl_proxy/afl-proxy.c | 2 +-
utils/afl_untracer/afl-untracer.c | 2 +-
utils/afl_untracer/libtestinstr.c | 2 +-
utils/argv_fuzzing/Makefile | 2 +-
utils/argv_fuzzing/argvfuzz.c | 2 +-
utils/distributed_fuzzing/sync_script.sh | 2 +-
utils/libdislocator/libdislocator.so.c | 2 +-
utils/libtokencap/libtokencap.so.c | 2 +-
utils/persistent_mode/test-instr.c | 2 +-
97 files changed, 99 insertions(+), 100 deletions(-)
(limited to 'docs')
diff --git a/GNUmakefile.gcc_plugin b/GNUmakefile.gcc_plugin
index 16c98399..8f06792d 100644
--- a/GNUmakefile.gcc_plugin
+++ b/GNUmakefile.gcc_plugin
@@ -11,7 +11,7 @@
# from Laszlo Szekeres.
#
# Copyright 2015 Google Inc. All rights reserved.
-# Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+# Copyright 2019-2024 AFLplusplus Project. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/README.md b/README.md
index fd48cb14..f713e971 100644
--- a/README.md
+++ b/README.md
@@ -2,9 +2,9 @@
-Release version: [4.09c](https://github.com/AFLplusplus/AFLplusplus/releases)
+Release version: [4.10c](https://github.com/AFLplusplus/AFLplusplus/releases)
-GitHub version: 4.10a
+GitHub version: 4.10c
Repository:
[https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)
diff --git a/afl-cmin.bash b/afl-cmin.bash
index fda48fb4..6c271220 100755
--- a/afl-cmin.bash
+++ b/afl-cmin.bash
@@ -7,7 +7,7 @@
#
# Copyright 2014, 2015 Google Inc. All rights reserved.
#
-# Copyright 2019-2023 AFLplusplus
+# Copyright 2019-2024 AFLplusplus
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/afl-whatsup b/afl-whatsup
index 5b7cbcd6..aa081e41 100755
--- a/afl-whatsup
+++ b/afl-whatsup
@@ -6,7 +6,7 @@
# Originally written by Michal Zalewski
#
# Copyright 2015 Google Inc. All rights reserved.
-# Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+# Copyright 2019-2024 AFLplusplus Project. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 29081549..48003f4b 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -3,7 +3,7 @@
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.10a (dev)
+### Version ++4.10c (release)
- afl-fuzz:
- default power schedule is now EXPLORE, due a fix in fast schedules
explore is slightly better now.
@@ -34,7 +34,6 @@
- updated the custom grammar mutator
- document afl-cmin does not work on macOS (but afl-cmin.bash does)
-
### Version ++4.09c (release)
- afl-fuzz:
- fixed the new mutation implementation for two bugs
diff --git a/frida_mode/Scripting.md b/frida_mode/Scripting.md
index dfd09e7b..653687f0 100644
--- a/frida_mode/Scripting.md
+++ b/frida_mode/Scripting.md
@@ -390,7 +390,7 @@ Consider the [following](test/js/test2.c) test code...
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
diff --git a/frida_mode/test/cmplog/cmplog.c b/frida_mode/test/cmplog/cmplog.c
index 2565b35c..d397f36e 100644
--- a/frida_mode/test/cmplog/cmplog.c
+++ b/frida_mode/test/cmplog/cmplog.c
@@ -2,7 +2,7 @@
//
// Author: Mateusz Jurczyk (mjurczyk@google.com)
//
-// Copyright 2019-2023 Google LLC
+// Copyright 2019-2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/frida_mode/test/deferred/testinstr.c b/frida_mode/test/deferred/testinstr.c
index 0ab44582..4e5124ed 100644
--- a/frida_mode/test/deferred/testinstr.c
+++ b/frida_mode/test/deferred/testinstr.c
@@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
diff --git a/frida_mode/test/dynamic/testinstr.c b/frida_mode/test/dynamic/testinstr.c
index 8b285f6d..0abc61fd 100644
--- a/frida_mode/test/dynamic/testinstr.c
+++ b/frida_mode/test/dynamic/testinstr.c
@@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
diff --git a/frida_mode/test/entry_point/testinstr.c b/frida_mode/test/entry_point/testinstr.c
index 24d9a615..75e71bda 100644
--- a/frida_mode/test/entry_point/testinstr.c
+++ b/frida_mode/test/entry_point/testinstr.c
@@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
diff --git a/frida_mode/test/exe/testinstr.c b/frida_mode/test/exe/testinstr.c
index d965502e..7b603659 100644
--- a/frida_mode/test/exe/testinstr.c
+++ b/frida_mode/test/exe/testinstr.c
@@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
diff --git a/frida_mode/test/js/test.c b/frida_mode/test/js/test.c
index 87c9cdf6..9799bf3b 100644
--- a/frida_mode/test/js/test.c
+++ b/frida_mode/test/js/test.c
@@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
diff --git a/frida_mode/test/js/test2.c b/frida_mode/test/js/test2.c
index 6b680a24..60b30eb5 100644
--- a/frida_mode/test/js/test2.c
+++ b/frida_mode/test/js/test2.c
@@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
diff --git a/frida_mode/test/output/testinstr.c b/frida_mode/test/output/testinstr.c
index d965502e..7b603659 100644
--- a/frida_mode/test/output/testinstr.c
+++ b/frida_mode/test/output/testinstr.c
@@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
diff --git a/frida_mode/test/perf/perf.c b/frida_mode/test/perf/perf.c
index d9626974..55efba26 100644
--- a/frida_mode/test/perf/perf.c
+++ b/frida_mode/test/perf/perf.c
@@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
diff --git a/frida_mode/test/persistent_ret/testinstr.c b/frida_mode/test/persistent_ret/testinstr.c
index 12365ceb..85aa2b80 100644
--- a/frida_mode/test/persistent_ret/testinstr.c
+++ b/frida_mode/test/persistent_ret/testinstr.c
@@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
diff --git a/frida_mode/test/testinstr/testinstr.c b/frida_mode/test/testinstr/testinstr.c
index d965502e..7b603659 100644
--- a/frida_mode/test/testinstr/testinstr.c
+++ b/frida_mode/test/testinstr/testinstr.c
@@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
diff --git a/frida_mode/test/unstable/unstable.c b/frida_mode/test/unstable/unstable.c
index a87b6c74..16978e7e 100644
--- a/frida_mode/test/unstable/unstable.c
+++ b/frida_mode/test/unstable/unstable.c
@@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
diff --git a/frida_mode/util/frida_get_symbol_addr.sh b/frida_mode/util/frida_get_symbol_addr.sh
index 2e682255..53d5b802 100755
--- a/frida_mode/util/frida_get_symbol_addr.sh
+++ b/frida_mode/util/frida_get_symbol_addr.sh
@@ -1,5 +1,5 @@
#!/bin/bash
-# Copyright 2023 AFLplusplus
+# Copyright 2024 AFLplusplus
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/include/afl-as.h b/include/afl-as.h
index 486314e2..612f34f4 100644
--- a/include/afl-as.h
+++ b/include/afl-as.h
@@ -10,7 +10,7 @@
Dominik Maier
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index c2b09b2e..c24f39e2 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -10,7 +10,7 @@
Dominik Maier
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/include/afl-prealloc.h b/include/afl-prealloc.h
index d19a7b52..3c621d79 100644
--- a/include/afl-prealloc.h
+++ b/include/afl-prealloc.h
@@ -10,7 +10,7 @@
Dominik Maier
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/include/alloc-inl.h b/include/alloc-inl.h
index cff808b2..0aa417be 100644
--- a/include/alloc-inl.h
+++ b/include/alloc-inl.h
@@ -10,7 +10,7 @@
Dominik Maier
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/include/cmplog.h b/include/cmplog.h
index e4821444..6bfc146b 100644
--- a/include/cmplog.h
+++ b/include/cmplog.h
@@ -12,7 +12,7 @@
Dominik Maier
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/include/common.h b/include/common.h
index a9739a7d..0df07dee 100644
--- a/include/common.h
+++ b/include/common.h
@@ -10,7 +10,7 @@
Dominik Maier
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/include/config.h b/include/config.h
index 7ad73c2f..9349828f 100644
--- a/include/config.h
+++ b/include/config.h
@@ -10,7 +10,7 @@
Heiko Eissfeldt ,
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@
/* Version string: */
// c = release, a = volatile github dev, e = experimental branch
-#define VERSION "++4.10a"
+#define VERSION "++4.10c"
/******************************************************
* *
diff --git a/include/debug.h b/include/debug.h
index 234d8fc4..4b812f8e 100644
--- a/include/debug.h
+++ b/include/debug.h
@@ -10,7 +10,7 @@
Dominik Maier
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/include/forkserver.h b/include/forkserver.h
index f1d3b5b1..be7f9e8d 100644
--- a/include/forkserver.h
+++ b/include/forkserver.h
@@ -12,7 +12,7 @@
Dominik Maier >
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/include/hash.h b/include/hash.h
index 0243c5b7..5d56a108 100644
--- a/include/hash.h
+++ b/include/hash.h
@@ -15,7 +15,7 @@
Other code written by Michal Zalewski
Copyright 2016 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/include/list.h b/include/list.h
index 283bf035..441eccd3 100644
--- a/include/list.h
+++ b/include/list.h
@@ -10,7 +10,7 @@
Dominik Maier
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/include/sharedmem.h b/include/sharedmem.h
index d32bd845..4484066e 100644
--- a/include/sharedmem.h
+++ b/include/sharedmem.h
@@ -12,7 +12,7 @@
Dominik Maier
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/include/snapshot-inl.h b/include/snapshot-inl.h
index 3864e473..b2c81402 100644
--- a/include/snapshot-inl.h
+++ b/include/snapshot-inl.h
@@ -12,7 +12,7 @@
Dominik Maier
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/include/types.h b/include/types.h
index d6476d82..22332135 100644
--- a/include/types.h
+++ b/include/types.h
@@ -10,7 +10,7 @@
Dominik Maier
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/include/xxhash.h b/include/xxhash.h
index a8bd6f27..9a880470 100644
--- a/include/xxhash.h
+++ b/include/xxhash.h
@@ -1,7 +1,7 @@
/*
* xxHash - Extremely Fast Hash algorithm
* Header File
- * Copyright (C) 2012-2023 Yann Collet
+ * Copyright (C) 2012-2024 Yann Collet
*
* BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php)
*
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index 8e55d6a0..caa3c3a8 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -3,7 +3,7 @@
------------------------------------------------
Copyright 2015, 2016 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/instrumentation/afl-gcc-cmplog-pass.so.cc b/instrumentation/afl-gcc-cmplog-pass.so.cc
index b4e6fda9..774dd5fd 100644
--- a/instrumentation/afl-gcc-cmplog-pass.so.cc
+++ b/instrumentation/afl-gcc-cmplog-pass.so.cc
@@ -3,7 +3,7 @@
Copyright 2014-2019 Free Software Foundation, Inc
Copyright 2015, 2016 Google Inc. All rights reserved.
Copyright 2019-2020 AFLplusplus Project. All rights reserved.
- Copyright 2019-2023 AdaCore
+ Copyright 2019-2024 AdaCore
Written by Alexandre Oliva , based on the AFL++
LLVM CmpLog pass by Andrea Fioraldi , and
diff --git a/instrumentation/afl-gcc-cmptrs-pass.so.cc b/instrumentation/afl-gcc-cmptrs-pass.so.cc
index c56263dd..929a9d7a 100644
--- a/instrumentation/afl-gcc-cmptrs-pass.so.cc
+++ b/instrumentation/afl-gcc-cmptrs-pass.so.cc
@@ -3,7 +3,7 @@
Copyright 2014-2019 Free Software Foundation, Inc
Copyright 2015, 2016 Google Inc. All rights reserved.
Copyright 2019-2020 AFLplusplus Project. All rights reserved.
- Copyright 2019-2023 AdaCore
+ Copyright 2019-2024 AdaCore
Written by Alexandre Oliva , based on the AFL++
LLVM CmpLog Routines pass by Andrea Fioraldi
diff --git a/instrumentation/afl-gcc-common.h b/instrumentation/afl-gcc-common.h
index 1d5eb466..80ded57d 100644
--- a/instrumentation/afl-gcc-common.h
+++ b/instrumentation/afl-gcc-common.h
@@ -2,7 +2,7 @@
Copyright 2014-2019 Free Software Foundation, Inc
Copyright 2015, 2016 Google Inc. All rights reserved.
- Copyright 2019-2023 AdaCore
+ Copyright 2019-2024 AdaCore
Written by Alexandre Oliva , based on the AFL++
GCC plugin.
diff --git a/instrumentation/afl-gcc-pass.so.cc b/instrumentation/afl-gcc-pass.so.cc
index 4d7fd0ef..41b1e5af 100644
--- a/instrumentation/afl-gcc-pass.so.cc
+++ b/instrumentation/afl-gcc-pass.so.cc
@@ -2,7 +2,7 @@
Copyright 2014-2019 Free Software Foundation, Inc
Copyright 2015, 2016 Google Inc. All rights reserved.
- Copyright 2019-2023 AdaCore
+ Copyright 2019-2024 AdaCore
Written by Alexandre Oliva , based on the AFL
LLVM pass by Laszlo Szekeres and Michal
diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc
index c60f3e06..ac497b5b 100644
--- a/instrumentation/afl-llvm-dict2file.so.cc
+++ b/instrumentation/afl-llvm-dict2file.so.cc
@@ -4,7 +4,7 @@
Written by Marc Heuse
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/instrumentation/afl-llvm-lto-instrumentlist.so.cc b/instrumentation/afl-llvm-lto-instrumentlist.so.cc
index 61f97d77..e0899cd3 100644
--- a/instrumentation/afl-llvm-lto-instrumentlist.so.cc
+++ b/instrumentation/afl-llvm-lto-instrumentlist.so.cc
@@ -9,7 +9,7 @@
from afl-as.c are Michal's fault.
Copyright 2015, 2016 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/instrumentation/afl-llvm-pass.so.cc b/instrumentation/afl-llvm-pass.so.cc
index 052488a9..62f5023d 100644
--- a/instrumentation/afl-llvm-pass.so.cc
+++ b/instrumentation/afl-llvm-pass.so.cc
@@ -12,7 +12,7 @@
NGRAM previous location coverage comes from Adrian Herrera.
Copyright 2015, 2016 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/instrumentation/cmplog-instructions-pass.cc b/instrumentation/cmplog-instructions-pass.cc
index 8be8c294..dc60221e 100644
--- a/instrumentation/cmplog-instructions-pass.cc
+++ b/instrumentation/cmplog-instructions-pass.cc
@@ -5,7 +5,7 @@
Written by Andrea Fioraldi
Copyright 2015, 2016 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/instrumentation/cmplog-routines-pass.cc b/instrumentation/cmplog-routines-pass.cc
index b27e06e0..78317d5d 100644
--- a/instrumentation/cmplog-routines-pass.cc
+++ b/instrumentation/cmplog-routines-pass.cc
@@ -5,7 +5,7 @@
Written by Andrea Fioraldi
Copyright 2015, 2016 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/instrumentation/cmplog-switches-pass.cc b/instrumentation/cmplog-switches-pass.cc
index 01da6da7..3e05c13d 100644
--- a/instrumentation/cmplog-switches-pass.cc
+++ b/instrumentation/cmplog-switches-pass.cc
@@ -5,7 +5,7 @@
Written by Andrea Fioraldi
Copyright 2015, 2016 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/instrumentation/injection-pass.cc b/instrumentation/injection-pass.cc
index 971b103b..2280208b 100644
--- a/instrumentation/injection-pass.cc
+++ b/instrumentation/injection-pass.cc
@@ -5,7 +5,7 @@
Written by Marc Heuse
Copyright 2015, 2016 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/qemu_mode/build_qemu_support.sh b/qemu_mode/build_qemu_support.sh
index 3f8a88f2..45019cc8 100755
--- a/qemu_mode/build_qemu_support.sh
+++ b/qemu_mode/build_qemu_support.sh
@@ -13,7 +13,7 @@
# counters by Andrea Fioraldi
#
# Copyright 2015, 2016, 2017 Google Inc. All rights reserved.
-# Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+# Copyright 2019-2024 AFLplusplus Project. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/qemu_mode/fastexit/Makefile b/qemu_mode/fastexit/Makefile
index c7b79277..be80207d 100644
--- a/qemu_mode/fastexit/Makefile
+++ b/qemu_mode/fastexit/Makefile
@@ -4,7 +4,7 @@
#
# Written by Andrea Fioraldi
#
-# Copyright 2019-2023 Andrea Fioraldi. All rights reserved.
+# Copyright 2019-2024 Andrea Fioraldi. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/qemu_mode/libcompcov/Makefile b/qemu_mode/libcompcov/Makefile
index 7260df87..4761ac02 100644
--- a/qemu_mode/libcompcov/Makefile
+++ b/qemu_mode/libcompcov/Makefile
@@ -4,7 +4,7 @@
#
# Written by Andrea Fioraldi
#
-# Copyright 2019-2023 Andrea Fioraldi. All rights reserved.
+# Copyright 2019-2024 Andrea Fioraldi. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/qemu_mode/libcompcov/compcovtest.cc b/qemu_mode/libcompcov/compcovtest.cc
index 23215013..11797091 100644
--- a/qemu_mode/libcompcov/compcovtest.cc
+++ b/qemu_mode/libcompcov/compcovtest.cc
@@ -2,7 +2,7 @@
//
// Author: Mateusz Jurczyk (mjurczyk@google.com)
//
-// Copyright 2019-2023 Google LLC
+// Copyright 2019-2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/qemu_mode/libcompcov/libcompcov.so.c b/qemu_mode/libcompcov/libcompcov.so.c
index b57e9701..36f7b2e2 100644
--- a/qemu_mode/libcompcov/libcompcov.so.c
+++ b/qemu_mode/libcompcov/libcompcov.so.c
@@ -5,7 +5,7 @@
Written and maintained by Andrea Fioraldi
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/qemu_mode/libqasan/Makefile b/qemu_mode/libqasan/Makefile
index 61782894..7366d6f6 100644
--- a/qemu_mode/libqasan/Makefile
+++ b/qemu_mode/libqasan/Makefile
@@ -4,7 +4,7 @@
#
# Written by Andrea Fioraldi
#
-# Copyright 2019-2023 Andrea Fioraldi. All rights reserved.
+# Copyright 2019-2024 Andrea Fioraldi. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/qemu_mode/libqasan/hooks.c b/qemu_mode/libqasan/hooks.c
index a9fd0ce9..cf1b0820 100644
--- a/qemu_mode/libqasan/hooks.c
+++ b/qemu_mode/libqasan/hooks.c
@@ -1,5 +1,5 @@
/*******************************************************************************
-Copyright (c) 2019-2023, Andrea Fioraldi
+Copyright (c) 2019-2024, Andrea Fioraldi
Redistribution and use in source and binary forms, with or without
diff --git a/qemu_mode/libqasan/libqasan.c b/qemu_mode/libqasan/libqasan.c
index 12be7778..45f47d5a 100644
--- a/qemu_mode/libqasan/libqasan.c
+++ b/qemu_mode/libqasan/libqasan.c
@@ -1,5 +1,5 @@
/*******************************************************************************
-Copyright (c) 2019-2023, Andrea Fioraldi
+Copyright (c) 2019-2024, Andrea Fioraldi
Redistribution and use in source and binary forms, with or without
diff --git a/qemu_mode/libqasan/libqasan.h b/qemu_mode/libqasan/libqasan.h
index a430c868..f0844e23 100644
--- a/qemu_mode/libqasan/libqasan.h
+++ b/qemu_mode/libqasan/libqasan.h
@@ -1,5 +1,5 @@
/*******************************************************************************
-Copyright (c) 2019-2023, Andrea Fioraldi
+Copyright (c) 2019-2024, Andrea Fioraldi
Redistribution and use in source and binary forms, with or without
diff --git a/qemu_mode/libqasan/malloc.c b/qemu_mode/libqasan/malloc.c
index 4448f480..ae470b56 100644
--- a/qemu_mode/libqasan/malloc.c
+++ b/qemu_mode/libqasan/malloc.c
@@ -1,5 +1,5 @@
/*******************************************************************************
-Copyright (c) 2019-2023, Andrea Fioraldi
+Copyright (c) 2019-2024, Andrea Fioraldi
Redistribution and use in source and binary forms, with or without
diff --git a/qemu_mode/libqasan/patch.c b/qemu_mode/libqasan/patch.c
index 38e0903b..4ce8c3d8 100644
--- a/qemu_mode/libqasan/patch.c
+++ b/qemu_mode/libqasan/patch.c
@@ -1,5 +1,5 @@
/*******************************************************************************
-Copyright (c) 2019-2023, Andrea Fioraldi
+Copyright (c) 2019-2024, Andrea Fioraldi
Redistribution and use in source and binary forms, with or without
diff --git a/qemu_mode/libqasan/string.c b/qemu_mode/libqasan/string.c
index e17cff4b..cd14d57b 100644
--- a/qemu_mode/libqasan/string.c
+++ b/qemu_mode/libqasan/string.c
@@ -1,5 +1,5 @@
/*******************************************************************************
-Copyright (c) 2019-2023, Andrea Fioraldi
+Copyright (c) 2019-2024, Andrea Fioraldi
Redistribution and use in source and binary forms, with or without
diff --git a/qemu_mode/libqasan/uninstrument.c b/qemu_mode/libqasan/uninstrument.c
index e37a9b46..996f2a74 100644
--- a/qemu_mode/libqasan/uninstrument.c
+++ b/qemu_mode/libqasan/uninstrument.c
@@ -7,7 +7,7 @@ for some strange reason.
*/
/*******************************************************************************
-Copyright (c) 2019-2023, Andrea Fioraldi
+Copyright (c) 2019-2024, Andrea Fioraldi
Redistribution and use in source and binary forms, with or without
diff --git a/qemu_mode/unsigaction/Makefile b/qemu_mode/unsigaction/Makefile
index c1a7397f..d5e807d8 100644
--- a/qemu_mode/unsigaction/Makefile
+++ b/qemu_mode/unsigaction/Makefile
@@ -4,7 +4,7 @@
#
# Written by Andrea Fioraldi
#
-# Copyright 2019-2023 Andrea Fioraldi. All rights reserved.
+# Copyright 2019-2024 Andrea Fioraldi. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/qemu_mode/util/qemu_get_symbol_addr.sh b/qemu_mode/util/qemu_get_symbol_addr.sh
index e0a7ae80..5e00f1b2 100755
--- a/qemu_mode/util/qemu_get_symbol_addr.sh
+++ b/qemu_mode/util/qemu_get_symbol_addr.sh
@@ -1,5 +1,5 @@
#!/bin/bash
-# Copyright 2023 AFLplusplus
+# Copyright 2024 AFLplusplus
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/src/afl-analyze.c b/src/afl-analyze.c
index 5b122741..95f32fee 100644
--- a/src/afl-analyze.c
+++ b/src/afl-analyze.c
@@ -9,7 +9,7 @@
Andrea Fioraldi
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-as.c b/src/afl-as.c
index 772e31b3..09ba75bf 100644
--- a/src/afl-as.c
+++ b/src/afl-as.c
@@ -9,7 +9,7 @@
Andrea Fioraldi
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 98310545..e9564277 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -5,7 +5,7 @@
Written by Michal Zalewski, Laszlo Szekeres and Marc Heuse
Copyright 2015, 2016 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-common.c b/src/afl-common.c
index ba498b3b..87003b03 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -9,7 +9,7 @@
Andrea Fioraldi
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index ded0c21d..0a77d61c 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -13,7 +13,7 @@
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c
index 5f67347c..d056ac9f 100644
--- a/src/afl-fuzz-bitmap.c
+++ b/src/afl-fuzz-bitmap.c
@@ -9,7 +9,7 @@
Andrea Fioraldi
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-fuzz-cmplog.c b/src/afl-fuzz-cmplog.c
index 3e6432ca..21f34e12 100644
--- a/src/afl-fuzz-cmplog.c
+++ b/src/afl-fuzz-cmplog.c
@@ -11,7 +11,7 @@
Andrea Fioraldi
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c
index 905431d1..3b1d13f1 100644
--- a/src/afl-fuzz-extras.c
+++ b/src/afl-fuzz-extras.c
@@ -9,7 +9,7 @@
Andrea Fioraldi
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index 057d8cf5..76291cc4 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -9,7 +9,7 @@
Andrea Fioraldi
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c
index 17fb9368..ae4d6668 100644
--- a/src/afl-fuzz-mutators.c
+++ b/src/afl-fuzz-mutators.c
@@ -10,7 +10,7 @@
Dominik Maier
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index c163a420..d9c074ec 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -9,7 +9,7 @@
Andrea Fioraldi
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c
index 4c7da774..16a398fd 100644
--- a/src/afl-fuzz-python.c
+++ b/src/afl-fuzz-python.c
@@ -9,7 +9,7 @@
Andrea Fioraldi
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c
index 67931bba..1ea50418 100644
--- a/src/afl-fuzz-queue.c
+++ b/src/afl-fuzz-queue.c
@@ -9,7 +9,7 @@
Andrea Fioraldi
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index 9e9b3822..eead7a8b 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -11,7 +11,7 @@
Andrea Fioraldi
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c
index 1ee8ebe7..d764952c 100644
--- a/src/afl-fuzz-run.c
+++ b/src/afl-fuzz-run.c
@@ -10,7 +10,7 @@
Dominik Maier
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c
index b647ac84..4467cae8 100644
--- a/src/afl-fuzz-state.c
+++ b/src/afl-fuzz-state.c
@@ -9,7 +9,7 @@
Andrea Fioraldi
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index 4b83ad29..76577081 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -9,7 +9,7 @@
Andrea Fioraldi
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 69064d51..12d67fe7 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -9,7 +9,7 @@
Andrea Fioraldi
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-gotcpu.c b/src/afl-gotcpu.c
index 4f851099..7aee2985 100644
--- a/src/afl-gotcpu.c
+++ b/src/afl-gotcpu.c
@@ -9,7 +9,7 @@
Andrea Fioraldi
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-ld-lto.c b/src/afl-ld-lto.c
index 7ce5de41..513c1ae9 100644
--- a/src/afl-ld-lto.c
+++ b/src/afl-ld-lto.c
@@ -9,7 +9,7 @@
Andrea Fioraldi
Dominik Maier
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-sharedmem.c b/src/afl-sharedmem.c
index a2c81586..daea8f46 100644
--- a/src/afl-sharedmem.c
+++ b/src/afl-sharedmem.c
@@ -11,7 +11,7 @@
Andrea Fioraldi
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index 7a639cf6..20ba5a5e 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -12,7 +12,7 @@
Dominik Maier
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-tmin.c b/src/afl-tmin.c
index e7442d1d..4e5dab41 100644
--- a/src/afl-tmin.c
+++ b/src/afl-tmin.c
@@ -12,7 +12,7 @@
Dominik Maier
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/test-instr.c b/test-instr.c
index eda5189c..28552893 100644
--- a/test-instr.c
+++ b/test-instr.c
@@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
diff --git a/unicorn_mode/build_unicorn_support.sh b/unicorn_mode/build_unicorn_support.sh
index d3d16ad5..baca2171 100755
--- a/unicorn_mode/build_unicorn_support.sh
+++ b/unicorn_mode/build_unicorn_support.sh
@@ -14,7 +14,7 @@
#
#
# Copyright 2017 Battelle Memorial Institute. All rights reserved.
-# Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+# Copyright 2019-2024 AFLplusplus Project. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/utils/afl_network_proxy/afl-network-client.c b/utils/afl_network_proxy/afl-network-client.c
index 0416f0f9..1f04dd87 100644
--- a/utils/afl_network_proxy/afl-network-client.c
+++ b/utils/afl_network_proxy/afl-network-client.c
@@ -4,7 +4,7 @@
Written by Marc Heuse
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/utils/afl_network_proxy/afl-network-server.c b/utils/afl_network_proxy/afl-network-server.c
index 95b0a551..c4a700f4 100644
--- a/utils/afl_network_proxy/afl-network-server.c
+++ b/utils/afl_network_proxy/afl-network-server.c
@@ -12,7 +12,7 @@
Dominik Maier
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/utils/afl_proxy/afl-proxy.c b/utils/afl_proxy/afl-proxy.c
index 531a97a2..6cf47636 100644
--- a/utils/afl_proxy/afl-proxy.c
+++ b/utils/afl_proxy/afl-proxy.c
@@ -4,7 +4,7 @@
Written by Marc Heuse
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/utils/afl_untracer/afl-untracer.c b/utils/afl_untracer/afl-untracer.c
index 0e3f8a45..e6a74518 100644
--- a/utils/afl_untracer/afl-untracer.c
+++ b/utils/afl_untracer/afl-untracer.c
@@ -4,7 +4,7 @@
Written by Marc Heuse
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/utils/afl_untracer/libtestinstr.c b/utils/afl_untracer/libtestinstr.c
index b7afc325..0a98778a 100644
--- a/utils/afl_untracer/libtestinstr.c
+++ b/utils/afl_untracer/libtestinstr.c
@@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
diff --git a/utils/argv_fuzzing/Makefile b/utils/argv_fuzzing/Makefile
index 6786467a..ba977e5f 100644
--- a/utils/argv_fuzzing/Makefile
+++ b/utils/argv_fuzzing/Makefile
@@ -2,7 +2,7 @@
# american fuzzy lop++ - argvfuzz
# --------------------------------
#
-# Copyright 2019-2023 Kjell Braden
+# Copyright 2019-2024 Kjell Braden
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/utils/argv_fuzzing/argvfuzz.c b/utils/argv_fuzzing/argvfuzz.c
index 41eead0c..47383138 100644
--- a/utils/argv_fuzzing/argvfuzz.c
+++ b/utils/argv_fuzzing/argvfuzz.c
@@ -2,7 +2,7 @@
american fuzzy lop++ - LD_PRELOAD for fuzzing argv in binaries
------------------------------------------------------------
- Copyright 2019-2023 Kjell Braden
+ Copyright 2019-2024 Kjell Braden
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/utils/distributed_fuzzing/sync_script.sh b/utils/distributed_fuzzing/sync_script.sh
index b22816f1..861b65c8 100755
--- a/utils/distributed_fuzzing/sync_script.sh
+++ b/utils/distributed_fuzzing/sync_script.sh
@@ -6,7 +6,7 @@
# Originally written by Michal Zalewski
#
# Copyright 2014 Google Inc. All rights reserved.
-# Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+# Copyright 2019-2024 AFLplusplus Project. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/utils/libdislocator/libdislocator.so.c b/utils/libdislocator/libdislocator.so.c
index 1cd7abc6..b80be1a1 100644
--- a/utils/libdislocator/libdislocator.so.c
+++ b/utils/libdislocator/libdislocator.so.c
@@ -6,7 +6,7 @@
Originally written by Michal Zalewski
Copyright 2016 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/utils/libtokencap/libtokencap.so.c b/utils/libtokencap/libtokencap.so.c
index f4024799..cc499150 100644
--- a/utils/libtokencap/libtokencap.so.c
+++ b/utils/libtokencap/libtokencap.so.c
@@ -6,7 +6,7 @@
Originally written by Michal Zalewski
Copyright 2016 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/utils/persistent_mode/test-instr.c b/utils/persistent_mode/test-instr.c
index 4ead6577..72e26e93 100644
--- a/utils/persistent_mode/test-instr.c
+++ b/utils/persistent_mode/test-instr.c
@@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
--
cgit 1.4.1
From 602eceed8b56eef62d673a54b6011541bf1ab60a Mon Sep 17 00:00:00 2001
From: van Hauser
Date: Sat, 3 Feb 2024 11:55:51 +0100
Subject: push to stable (#1983)
* Output afl-clang-fast stuffs only if necessary (#1912)
* afl-cc header
* afl-cc common declarations
- Add afl-cc-state.c
- Strip includes, find_object, debug/be_quiet/have_*/callname setting from afl-cc.c
- Use debugf_args in main
- Modify execvp stuffs to fit new aflcc struct
* afl-cc show usage
* afl-cc mode selecting
1. compiler_mode by callname in argv[0]
2. compiler_mode by env "AFL_CC_COMPILER"
3. compiler_mode/instrument_mode by command line options "--afl-..."
4. instrument_mode/compiler_mode by various env vars including "AFL_LLVM_INSTRUMENT"
5. final checking steps
6. print "... - mode: %s-%s\n"
7. determine real argv[0] according to compiler_mode
* afl-cc macro defs
* afl-cc linking behaviors
* afl-cc fsanitize behaviors
* afl-cc misc
* afl-cc body update
* afl-cc all-in-one
formated with custom-format.py
* nits
---------
Co-authored-by: vanhauser-thc
* changelog
* update grammar mutator
* lto llvm 12+
* docs(custom_mutators): fix missing ':' (#1953)
* Fix broken LTO mode and response file support (#1948)
* Strip `-Wl,-no-undefined` during compilation (#1952)
Make the compiler wrapper stripping `-Wl,-no-undefined` in addition to `-Wl,--no-undefined`.
Both versions of the flag are accepted by clang and, therefore, used by building systems in the wild (e.g., samba will not build without this fix).
* Remove dead code in write_to_testcase (#1955)
The custom_mutators_count check in if case is duplicate with if condition.
The else case is custom_mutators_count == 0, neither custom_mutator_list iteration nor sent check needed.
Signed-off-by: Xeonacid
* update qemuafl
* WIP: Add ability to generate drcov trace using QEMU backend (#1956)
* Document new drcov QEMU plugin
* Add link to lightkeeper for QEMU drcov file loading
---------
Co-authored-by: Jean-Romain Garnier
* code format
* changelog
* sleep on uid != 0 afl-system-config
* fix segv about skip_next, warn on unsupported cases of linking options (#1958)
* todos
* ensure afl-cc only allows available compiler modes
* update grammar mutator
* disable aslr on apple
* fix for arm64
* help selective instrumentation
* typos
* macos
* add compiler test script
* apple fixes
* bump nyx submodules (#1963)
* fix docs
* update changelog
* update grammar mutator
* improve compiler test script
* gcc asan workaround (#1966)
* fix github merge fuckup
* fix
* Fix afl-cc (#1968)
- Check if too many cmdline params here, each time before insert a new param.
- Check if it is "-fsanitize=..." before we do sth.
- Remove improper param_st transfer.
* Avoid adding llvmnative instrumentation when linking rust sanitizer runtime (#1969)
* Dynamic instrumentation filtering for LLVM native (#1971)
* Add two dynamic instrumentation filter methods to runtime
* Always use pc-table with native pcguard
* Add make_symbol_list.py and README
* changelog
* todos
* new forkserver check
* fix
* nyx test for CI
* improve nyx docs
* Fixes to afl-cc and documentation (#1974)
* Always compile with -ldl when building for CODE_COVERAGE
When building with CODE_COVERAGE, the afl runtime contains code that
calls `dladdr` which requires -ldl. Under most circumstances, clang
already adds this (e.g. when building with pc-table), but there are some
circumstances where it isn't added automatically.
* Add visibility declaration to __afl_connected
When building with hidden visibility, the use of __AFL_LOOP inside such
code can cause linker errors due to __afl_connected being declared
"hidden".
* Update docs to clarify that CODE_COVERAGE=1 is required for dynamic_covfilter
* nits
* nyx build script updates
* test error output
* debug ci
* debug ci
* Improve afl-cc (#1975)
* update response file support
- full support of rsp file
- fix some segv issues
* Improve afl-cc
- remove dead code about allow/denylist options of sancov
- missing `if (!aflcc->have_msan)`
- add docs for each function
- typo
* enable nyx
* debug ci
* debug ci
* debug ci
* debug ci
* debug ci
* debug ci
* debug ci
* debug ci
* fix ci
* clean test script
* NO_NYX
* NO_NYX
* fix ci
* debug ci
* fix ci
* finalize ci fix
* Enhancement on Deterministic stage (#1972)
* fuzzer: init commit based on aflpp 60dc37a8cf09f8e9048e4b6a2204d6c90b27655a
* fuzzers: adding the skip variables and initialize
* log: profile the det/havoc finding
* log: add profile log output
* fuzzers: sperate log/skipdet module
* fuzzers: add quick eff_map calc
* fuzzers: add skip_eff_map in fuzz_one
* fuzzers: mark whole input space in eff_map
* fuzzers: add undet bit threshold to skip some seeds
* fuzzers: fix one byte overflow
* fuzzers: fix overflow
* fix code format
* add havoc only again
* code format
* remove log to INTROSPECTION, rename skipdet module
* rename skipdet module
* remove log to stats
* clean redundant code
* code format
* remove redundant code format check
* remove redundant doc
* remove redundant objects
* clean files
* change -d to default skipdet
* disable deterministic when using CUSTOM_MUTATOR
* revert fix
* final touches for skipdet
* remove unused var
* remove redundant eff struct (#1977)
* update QEMU-Nyx submodule (#1978)
* update QEMU-Nyx submodule (#1980)
* Fix type in AFL_NOOPT env variable in afl-cc help message (#1982)
* nits
* 2024 v4.10c release
* fixes
---------
Signed-off-by: Xeonacid
Co-authored-by: Sonic <50692172+SonicStark@users.noreply.github.com>
Co-authored-by: Xeonacid
Co-authored-by: Nils Bars
Co-authored-by: Jean-Romain Garnier <7504819+JRomainG@users.noreply.github.com>
Co-authored-by: Jean-Romain Garnier
Co-authored-by: Sergej Schumilo
Co-authored-by: Christian Holler (:decoder)
Co-authored-by: Han Zheng <35988108+kdsjZh@users.noreply.github.com>
Co-authored-by: Khaled Yakdan
---
.gitmodules | 6 +-
GNUmakefile.gcc_plugin | 2 +-
GNUmakefile.llvm | 2 +-
README.md | 4 +-
afl-cmin.bash | 2 +-
afl-whatsup | 2 +-
docs/Changelog.md | 5 +-
docs/INSTALL.md | 4 +-
frida_mode/Scripting.md | 2 +-
frida_mode/test/cmplog/cmplog.c | 2 +-
frida_mode/test/deferred/testinstr.c | 2 +-
frida_mode/test/dynamic/testinstr.c | 2 +-
frida_mode/test/entry_point/testinstr.c | 2 +-
frida_mode/test/exe/testinstr.c | 2 +-
frida_mode/test/js/test.c | 2 +-
frida_mode/test/js/test2.c | 2 +-
frida_mode/test/output/testinstr.c | 2 +-
frida_mode/test/perf/perf.c | 2 +-
frida_mode/test/persistent_ret/testinstr.c | 2 +-
frida_mode/test/testinstr/testinstr.c | 2 +-
frida_mode/test/unstable/unstable.c | 2 +-
frida_mode/util/frida_get_symbol_addr.sh | 2 +-
include/afl-as.h | 2 +-
include/afl-fuzz.h | 60 +++-
include/afl-prealloc.h | 2 +-
include/alloc-inl.h | 2 +-
include/cmplog.h | 2 +-
include/common.h | 2 +-
include/config.h | 16 +-
include/debug.h | 2 +-
include/forkserver.h | 5 +-
include/hash.h | 2 +-
include/list.h | 2 +-
include/sharedmem.h | 2 +-
include/snapshot-inl.h | 2 +-
include/types.h | 2 +-
include/xxhash.h | 2 +-
instrumentation/afl-compiler-rt.o.c | 2 +-
instrumentation/afl-gcc-cmplog-pass.so.cc | 2 +-
instrumentation/afl-gcc-cmptrs-pass.so.cc | 2 +-
instrumentation/afl-gcc-common.h | 2 +-
instrumentation/afl-gcc-pass.so.cc | 2 +-
instrumentation/afl-llvm-dict2file.so.cc | 2 +-
instrumentation/afl-llvm-lto-instrumentlist.so.cc | 2 +-
instrumentation/afl-llvm-pass.so.cc | 2 +-
instrumentation/cmplog-instructions-pass.cc | 2 +-
instrumentation/cmplog-routines-pass.cc | 2 +-
instrumentation/cmplog-switches-pass.cc | 2 +-
instrumentation/injection-pass.cc | 2 +-
nyx_mode/QEMU-Nyx | 2 +-
nyx_mode/QEMU_NYX_VERSION | 2 +-
qemu_mode/build_qemu_support.sh | 2 +-
qemu_mode/fastexit/Makefile | 2 +-
qemu_mode/libcompcov/Makefile | 2 +-
qemu_mode/libcompcov/compcovtest.cc | 2 +-
qemu_mode/libcompcov/libcompcov.so.c | 2 +-
qemu_mode/libqasan/Makefile | 2 +-
qemu_mode/libqasan/hooks.c | 2 +-
qemu_mode/libqasan/libqasan.c | 2 +-
qemu_mode/libqasan/libqasan.h | 2 +-
qemu_mode/libqasan/malloc.c | 2 +-
qemu_mode/libqasan/patch.c | 2 +-
qemu_mode/libqasan/string.c | 2 +-
qemu_mode/libqasan/uninstrument.c | 2 +-
qemu_mode/unsigaction/Makefile | 2 +-
qemu_mode/util/qemu_get_symbol_addr.sh | 2 +-
src/afl-analyze.c | 2 +-
src/afl-as.c | 2 +-
src/afl-cc.c | 4 +-
src/afl-common.c | 2 +-
src/afl-forkserver.c | 6 +-
src/afl-fuzz-bitmap.c | 2 +-
src/afl-fuzz-cmplog.c | 2 +-
src/afl-fuzz-extras.c | 2 +-
src/afl-fuzz-init.c | 17 +-
src/afl-fuzz-mutators.c | 2 +-
src/afl-fuzz-one.c | 237 ++++++-------
src/afl-fuzz-python.c | 2 +-
src/afl-fuzz-queue.c | 13 +-
src/afl-fuzz-redqueen.c | 2 +-
src/afl-fuzz-run.c | 2 +-
src/afl-fuzz-skipdet.c | 403 ++++++++++++++++++++++
src/afl-fuzz-state.c | 10 +-
src/afl-fuzz-stats.c | 40 ++-
src/afl-fuzz.c | 27 +-
src/afl-gotcpu.c | 2 +-
src/afl-ld-lto.c | 2 +-
src/afl-sharedmem.c | 2 +-
src/afl-showmap.c | 2 +-
src/afl-tmin.c | 2 +-
test-instr.c | 2 +-
test/test-custom-mutators.sh | 4 +-
unicorn_mode/build_unicorn_support.sh | 2 +-
utils/afl_network_proxy/afl-network-client.c | 2 +-
utils/afl_network_proxy/afl-network-server.c | 2 +-
utils/afl_proxy/afl-proxy.c | 2 +-
utils/afl_untracer/afl-untracer.c | 2 +-
utils/afl_untracer/libtestinstr.c | 2 +-
utils/argv_fuzzing/Makefile | 2 +-
utils/argv_fuzzing/argvfuzz.c | 2 +-
utils/distributed_fuzzing/sync_script.sh | 2 +-
utils/libdislocator/libdislocator.so.c | 2 +-
utils/libtokencap/libtokencap.so.c | 2 +-
utils/persistent_mode/test-instr.c | 2 +-
104 files changed, 793 insertions(+), 242 deletions(-)
create mode 100644 src/afl-fuzz-skipdet.c
(limited to 'docs')
diff --git a/.gitmodules b/.gitmodules
index 18fda27e..7fce4460 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -19,9 +19,9 @@
[submodule "nyx_mode/libnyx"]
path = nyx_mode/libnyx
url = https://github.com/nyx-fuzz/libnyx.git
-[submodule "nyx_mode/QEMU-Nyx"]
- path = nyx_mode/QEMU-Nyx
- url = https://github.com/nyx-fuzz/qemu-nyx.git
[submodule "nyx_mode/packer"]
path = nyx_mode/packer
url = https://github.com/nyx-fuzz/packer.git
+[submodule "nyx_mode/QEMU-Nyx"]
+ path = nyx_mode/QEMU-Nyx
+ url = https://github.com/nyx-fuzz/QEMU-Nyx
diff --git a/GNUmakefile.gcc_plugin b/GNUmakefile.gcc_plugin
index 16c98399..8f06792d 100644
--- a/GNUmakefile.gcc_plugin
+++ b/GNUmakefile.gcc_plugin
@@ -11,7 +11,7 @@
# from Laszlo Szekeres.
#
# Copyright 2015 Google Inc. All rights reserved.
-# Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+# Copyright 2019-2024 AFLplusplus Project. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm
index 7437130d..ec8fefe4 100644
--- a/GNUmakefile.llvm
+++ b/GNUmakefile.llvm
@@ -45,7 +45,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_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^[0-2]\.|^3.[0-7]\.' && echo 1 || echo 0 )
+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 )
LLVM_NEW_API = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[0-9]' && echo 1 || echo 0 )
diff --git a/README.md b/README.md
index fd48cb14..f713e971 100644
--- a/README.md
+++ b/README.md
@@ -2,9 +2,9 @@
-Release version: [4.09c](https://github.com/AFLplusplus/AFLplusplus/releases)
+Release version: [4.10c](https://github.com/AFLplusplus/AFLplusplus/releases)
-GitHub version: 4.10a
+GitHub version: 4.10c
Repository:
[https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)
diff --git a/afl-cmin.bash b/afl-cmin.bash
index fda48fb4..6c271220 100755
--- a/afl-cmin.bash
+++ b/afl-cmin.bash
@@ -7,7 +7,7 @@
#
# Copyright 2014, 2015 Google Inc. All rights reserved.
#
-# Copyright 2019-2023 AFLplusplus
+# Copyright 2019-2024 AFLplusplus
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/afl-whatsup b/afl-whatsup
index 5b7cbcd6..aa081e41 100755
--- a/afl-whatsup
+++ b/afl-whatsup
@@ -6,7 +6,7 @@
# Originally written by Michal Zalewski
#
# Copyright 2015 Google Inc. All rights reserved.
-# Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+# Copyright 2019-2024 AFLplusplus Project. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 720a0689..48003f4b 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -3,12 +3,14 @@
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.10a (dev)
+### Version ++4.10c (release)
- afl-fuzz:
- default power schedule is now EXPLORE, due a fix in fast schedules
explore is slightly better now.
- fixed minor issues in the mutation engine, thanks to @futhewo for
reporting!
+ - better deterministic fuzzing is now available, benchmarks have shown
+ to improve fuzzing. Enable with -D. Thanks to @kdsjZh for the PR!
- afl-cc:
- large rewrite by @SonicStark which fixes a few corner cases, thanks!
- LTO mode now requires llvm 12+
@@ -32,7 +34,6 @@
- updated the custom grammar mutator
- document afl-cmin does not work on macOS (but afl-cmin.bash does)
-
### Version ++4.09c (release)
- afl-fuzz:
- fixed the new mutation implementation for two bugs
diff --git a/docs/INSTALL.md b/docs/INSTALL.md
index 1379df0a..84bbe3ea 100644
--- a/docs/INSTALL.md
+++ b/docs/INSTALL.md
@@ -114,10 +114,10 @@ freshly installed clang, clang++, llvm-config, gmake and coreutils, e.g.:
# Depending on your MacOS system + brew version it is either
export PATH="/opt/homebrew/opt/llvm/bin:$PATH"
# or
-export PATH="/usr/local/opt/llvm/bin:$PATH"
+export PATH="/usr/local/opt/llvm/bin:/usr/local/opt/coreutils/libexec/gnubin:$PATH"
# you can check with "brew info llvm"
-export PATH="/usr/local/opt/coreutils/libexec/gnubin:/usr/local/bin:$PATH"
+export PATH="/usr/local/bin:$PATH"
export CC=clang
export CXX=clang++
gmake
diff --git a/frida_mode/Scripting.md b/frida_mode/Scripting.md
index dfd09e7b..653687f0 100644
--- a/frida_mode/Scripting.md
+++ b/frida_mode/Scripting.md
@@ -390,7 +390,7 @@ Consider the [following](test/js/test2.c) test code...
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
diff --git a/frida_mode/test/cmplog/cmplog.c b/frida_mode/test/cmplog/cmplog.c
index 2565b35c..d397f36e 100644
--- a/frida_mode/test/cmplog/cmplog.c
+++ b/frida_mode/test/cmplog/cmplog.c
@@ -2,7 +2,7 @@
//
// Author: Mateusz Jurczyk (mjurczyk@google.com)
//
-// Copyright 2019-2023 Google LLC
+// Copyright 2019-2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/frida_mode/test/deferred/testinstr.c b/frida_mode/test/deferred/testinstr.c
index 0ab44582..4e5124ed 100644
--- a/frida_mode/test/deferred/testinstr.c
+++ b/frida_mode/test/deferred/testinstr.c
@@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
diff --git a/frida_mode/test/dynamic/testinstr.c b/frida_mode/test/dynamic/testinstr.c
index 8b285f6d..0abc61fd 100644
--- a/frida_mode/test/dynamic/testinstr.c
+++ b/frida_mode/test/dynamic/testinstr.c
@@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
diff --git a/frida_mode/test/entry_point/testinstr.c b/frida_mode/test/entry_point/testinstr.c
index 24d9a615..75e71bda 100644
--- a/frida_mode/test/entry_point/testinstr.c
+++ b/frida_mode/test/entry_point/testinstr.c
@@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
diff --git a/frida_mode/test/exe/testinstr.c b/frida_mode/test/exe/testinstr.c
index d965502e..7b603659 100644
--- a/frida_mode/test/exe/testinstr.c
+++ b/frida_mode/test/exe/testinstr.c
@@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
diff --git a/frida_mode/test/js/test.c b/frida_mode/test/js/test.c
index 87c9cdf6..9799bf3b 100644
--- a/frida_mode/test/js/test.c
+++ b/frida_mode/test/js/test.c
@@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
diff --git a/frida_mode/test/js/test2.c b/frida_mode/test/js/test2.c
index 6b680a24..60b30eb5 100644
--- a/frida_mode/test/js/test2.c
+++ b/frida_mode/test/js/test2.c
@@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
diff --git a/frida_mode/test/output/testinstr.c b/frida_mode/test/output/testinstr.c
index d965502e..7b603659 100644
--- a/frida_mode/test/output/testinstr.c
+++ b/frida_mode/test/output/testinstr.c
@@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
diff --git a/frida_mode/test/perf/perf.c b/frida_mode/test/perf/perf.c
index d9626974..55efba26 100644
--- a/frida_mode/test/perf/perf.c
+++ b/frida_mode/test/perf/perf.c
@@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
diff --git a/frida_mode/test/persistent_ret/testinstr.c b/frida_mode/test/persistent_ret/testinstr.c
index 12365ceb..85aa2b80 100644
--- a/frida_mode/test/persistent_ret/testinstr.c
+++ b/frida_mode/test/persistent_ret/testinstr.c
@@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
diff --git a/frida_mode/test/testinstr/testinstr.c b/frida_mode/test/testinstr/testinstr.c
index d965502e..7b603659 100644
--- a/frida_mode/test/testinstr/testinstr.c
+++ b/frida_mode/test/testinstr/testinstr.c
@@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
diff --git a/frida_mode/test/unstable/unstable.c b/frida_mode/test/unstable/unstable.c
index a87b6c74..16978e7e 100644
--- a/frida_mode/test/unstable/unstable.c
+++ b/frida_mode/test/unstable/unstable.c
@@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
diff --git a/frida_mode/util/frida_get_symbol_addr.sh b/frida_mode/util/frida_get_symbol_addr.sh
index 2e682255..53d5b802 100755
--- a/frida_mode/util/frida_get_symbol_addr.sh
+++ b/frida_mode/util/frida_get_symbol_addr.sh
@@ -1,5 +1,5 @@
#!/bin/bash
-# Copyright 2023 AFLplusplus
+# Copyright 2024 AFLplusplus
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/include/afl-as.h b/include/afl-as.h
index 486314e2..612f34f4 100644
--- a/include/afl-as.h
+++ b/include/afl-as.h
@@ -10,7 +10,7 @@
Dominik Maier
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index f1813df6..c24f39e2 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -10,7 +10,7 @@
Dominik Maier
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -149,6 +149,48 @@ struct tainted {
};
+struct inf_profile {
+
+ u32 inf_skipped_bytes; /* Inference Stage Profiling */
+ u64 inf_execs_cost, inf_time_cost;
+
+};
+
+/* ToDo: add cmplog profile as well */
+struct havoc_profile {
+
+ u32 queued_det_stage, /* Det/Havoc Stage Profiling */
+ queued_havoc_stage, total_queued_det, edge_det_stage, edge_havoc_stage,
+ total_det_edge;
+
+ u64 det_stage_time, havoc_stage_time, total_det_time;
+
+};
+
+struct skipdet_entry {
+
+ u8 continue_inf, done_eff;
+ u32 undet_bits, quick_eff_bytes;
+
+ u8 *skip_eff_map, /* we'v finish the eff_map */
+ *done_inf_map; /* some bytes are not done yet */
+
+};
+
+struct skipdet_global {
+
+ u8 use_skip_havoc;
+
+ u32 undet_bits_threshold;
+
+ u64 last_cov_undet;
+
+ u8 *virgin_det_bits; /* global fuzzed bits */
+
+ struct inf_profile *inf_prof;
+
+};
+
struct queue_entry {
u8 *fname; /* File name for the test case */
@@ -203,6 +245,8 @@ struct queue_entry {
struct queue_entry *mother; /* queue entry this based on */
+ struct skipdet_entry *skipdet_e;
+
};
struct extra_data {
@@ -247,6 +291,8 @@ enum {
/* 19 */ STAGE_CUSTOM_MUTATOR,
/* 20 */ STAGE_COLORIZATION,
/* 21 */ STAGE_ITS,
+ /* 22 */ STAGE_INF,
+ /* 23 */ STAGE_QUICK,
STAGE_NUM_MAX
@@ -782,6 +828,11 @@ typedef struct afl_state {
* is too large) */
struct queue_entry **q_testcase_cache;
+ /* Global Profile Data for deterministic/havoc-splice stage */
+ struct havoc_profile *havoc_prof;
+
+ struct skipdet_global *skipdet_g;
+
#ifdef INTROSPECTION
char mutation[8072];
char m_tmp[4096];
@@ -1232,6 +1283,13 @@ AFL_RAND_RETURN rand_next(afl_state_t *afl);
/* probability between 0.0 and 1.0 */
double rand_next_percent(afl_state_t *afl);
+/* SkipDet Functions */
+
+u8 skip_deterministic_stage(afl_state_t *, u8 *, u8 *, u32, u64);
+u8 is_det_timeout(u64, u8);
+
+void plot_profile_data(afl_state_t *, struct queue_entry *);
+
/**** Inline routines ****/
/* Generate a random number (from 0 to limit - 1). This may
diff --git a/include/afl-prealloc.h b/include/afl-prealloc.h
index d19a7b52..3c621d79 100644
--- a/include/afl-prealloc.h
+++ b/include/afl-prealloc.h
@@ -10,7 +10,7 @@
Dominik Maier
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/include/alloc-inl.h b/include/alloc-inl.h
index cff808b2..0aa417be 100644
--- a/include/alloc-inl.h
+++ b/include/alloc-inl.h
@@ -10,7 +10,7 @@
Dominik Maier
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/include/cmplog.h b/include/cmplog.h
index e4821444..6bfc146b 100644
--- a/include/cmplog.h
+++ b/include/cmplog.h
@@ -12,7 +12,7 @@
Dominik Maier
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/include/common.h b/include/common.h
index a9739a7d..0df07dee 100644
--- a/include/common.h
+++ b/include/common.h
@@ -10,7 +10,7 @@
Dominik Maier
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/include/config.h b/include/config.h
index 63340650..9349828f 100644
--- a/include/config.h
+++ b/include/config.h
@@ -10,7 +10,7 @@
Heiko Eissfeldt ,
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@
/* Version string: */
// c = release, a = volatile github dev, e = experimental branch
-#define VERSION "++4.10a"
+#define VERSION "++4.10c"
/******************************************************
* *
@@ -52,6 +52,18 @@
/* Default file permission umode when creating files (default: 0600) */
#define DEFAULT_PERMISSION 0600
+/* SkipDet's global configuration */
+
+#define MINIMAL_BLOCK_SIZE 64
+#define SMALL_DET_TIME (60 * 1000 * 1000U)
+#define MAXIMUM_INF_EXECS (16 * 1024U)
+#define MAXIMUM_QUICK_EFF_EXECS (64 * 1024U)
+#define THRESHOLD_DEC_TIME (20 * 60 * 1000U)
+
+/* Set the Prob of selecting eff_bytes 3 times more than original,
+ Now disabled */
+#define EFF_HAVOC_RATE 3
+
/* CMPLOG/REDQUEEN TUNING
*
* Here you can modify tuning and solving options for CMPLOG.
diff --git a/include/debug.h b/include/debug.h
index 234d8fc4..4b812f8e 100644
--- a/include/debug.h
+++ b/include/debug.h
@@ -10,7 +10,7 @@
Dominik Maier
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/include/forkserver.h b/include/forkserver.h
index f6230fe8..be7f9e8d 100644
--- a/include/forkserver.h
+++ b/include/forkserver.h
@@ -12,7 +12,7 @@
Dominik Maier >
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -126,7 +126,8 @@ typedef struct afl_forkserver {
u8 *out_file, /* File to fuzz, if any */
*target_path; /* Path of the target */
- FILE *plot_file; /* Gnuplot output file */
+ FILE *plot_file, /* Gnuplot output file */
+ *det_plot_file;
/* Note: last_run_timed_out is u32 to send it to the child as 4 byte array */
u32 last_run_timed_out; /* Traced process timed out? */
diff --git a/include/hash.h b/include/hash.h
index 0243c5b7..5d56a108 100644
--- a/include/hash.h
+++ b/include/hash.h
@@ -15,7 +15,7 @@
Other code written by Michal Zalewski
Copyright 2016 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/include/list.h b/include/list.h
index 283bf035..441eccd3 100644
--- a/include/list.h
+++ b/include/list.h
@@ -10,7 +10,7 @@
Dominik Maier
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/include/sharedmem.h b/include/sharedmem.h
index d32bd845..4484066e 100644
--- a/include/sharedmem.h
+++ b/include/sharedmem.h
@@ -12,7 +12,7 @@
Dominik Maier
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/include/snapshot-inl.h b/include/snapshot-inl.h
index 3864e473..b2c81402 100644
--- a/include/snapshot-inl.h
+++ b/include/snapshot-inl.h
@@ -12,7 +12,7 @@
Dominik Maier
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/include/types.h b/include/types.h
index d6476d82..22332135 100644
--- a/include/types.h
+++ b/include/types.h
@@ -10,7 +10,7 @@
Dominik Maier
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/include/xxhash.h b/include/xxhash.h
index a8bd6f27..9a880470 100644
--- a/include/xxhash.h
+++ b/include/xxhash.h
@@ -1,7 +1,7 @@
/*
* xxHash - Extremely Fast Hash algorithm
* Header File
- * Copyright (C) 2012-2023 Yann Collet
+ * Copyright (C) 2012-2024 Yann Collet
*
* BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php)
*
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index 8e55d6a0..caa3c3a8 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -3,7 +3,7 @@
------------------------------------------------
Copyright 2015, 2016 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/instrumentation/afl-gcc-cmplog-pass.so.cc b/instrumentation/afl-gcc-cmplog-pass.so.cc
index b4e6fda9..774dd5fd 100644
--- a/instrumentation/afl-gcc-cmplog-pass.so.cc
+++ b/instrumentation/afl-gcc-cmplog-pass.so.cc
@@ -3,7 +3,7 @@
Copyright 2014-2019 Free Software Foundation, Inc
Copyright 2015, 2016 Google Inc. All rights reserved.
Copyright 2019-2020 AFLplusplus Project. All rights reserved.
- Copyright 2019-2023 AdaCore
+ Copyright 2019-2024 AdaCore
Written by Alexandre Oliva , based on the AFL++
LLVM CmpLog pass by Andrea Fioraldi , and
diff --git a/instrumentation/afl-gcc-cmptrs-pass.so.cc b/instrumentation/afl-gcc-cmptrs-pass.so.cc
index c56263dd..929a9d7a 100644
--- a/instrumentation/afl-gcc-cmptrs-pass.so.cc
+++ b/instrumentation/afl-gcc-cmptrs-pass.so.cc
@@ -3,7 +3,7 @@
Copyright 2014-2019 Free Software Foundation, Inc
Copyright 2015, 2016 Google Inc. All rights reserved.
Copyright 2019-2020 AFLplusplus Project. All rights reserved.
- Copyright 2019-2023 AdaCore
+ Copyright 2019-2024 AdaCore
Written by Alexandre Oliva , based on the AFL++
LLVM CmpLog Routines pass by Andrea Fioraldi
diff --git a/instrumentation/afl-gcc-common.h b/instrumentation/afl-gcc-common.h
index 1d5eb466..80ded57d 100644
--- a/instrumentation/afl-gcc-common.h
+++ b/instrumentation/afl-gcc-common.h
@@ -2,7 +2,7 @@
Copyright 2014-2019 Free Software Foundation, Inc
Copyright 2015, 2016 Google Inc. All rights reserved.
- Copyright 2019-2023 AdaCore
+ Copyright 2019-2024 AdaCore
Written by Alexandre Oliva , based on the AFL++
GCC plugin.
diff --git a/instrumentation/afl-gcc-pass.so.cc b/instrumentation/afl-gcc-pass.so.cc
index 4d7fd0ef..41b1e5af 100644
--- a/instrumentation/afl-gcc-pass.so.cc
+++ b/instrumentation/afl-gcc-pass.so.cc
@@ -2,7 +2,7 @@
Copyright 2014-2019 Free Software Foundation, Inc
Copyright 2015, 2016 Google Inc. All rights reserved.
- Copyright 2019-2023 AdaCore
+ Copyright 2019-2024 AdaCore
Written by Alexandre Oliva , based on the AFL
LLVM pass by Laszlo Szekeres and Michal
diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc
index c60f3e06..ac497b5b 100644
--- a/instrumentation/afl-llvm-dict2file.so.cc
+++ b/instrumentation/afl-llvm-dict2file.so.cc
@@ -4,7 +4,7 @@
Written by Marc Heuse
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/instrumentation/afl-llvm-lto-instrumentlist.so.cc b/instrumentation/afl-llvm-lto-instrumentlist.so.cc
index 61f97d77..e0899cd3 100644
--- a/instrumentation/afl-llvm-lto-instrumentlist.so.cc
+++ b/instrumentation/afl-llvm-lto-instrumentlist.so.cc
@@ -9,7 +9,7 @@
from afl-as.c are Michal's fault.
Copyright 2015, 2016 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/instrumentation/afl-llvm-pass.so.cc b/instrumentation/afl-llvm-pass.so.cc
index 052488a9..62f5023d 100644
--- a/instrumentation/afl-llvm-pass.so.cc
+++ b/instrumentation/afl-llvm-pass.so.cc
@@ -12,7 +12,7 @@
NGRAM previous location coverage comes from Adrian Herrera.
Copyright 2015, 2016 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/instrumentation/cmplog-instructions-pass.cc b/instrumentation/cmplog-instructions-pass.cc
index 8be8c294..dc60221e 100644
--- a/instrumentation/cmplog-instructions-pass.cc
+++ b/instrumentation/cmplog-instructions-pass.cc
@@ -5,7 +5,7 @@
Written by Andrea Fioraldi
Copyright 2015, 2016 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/instrumentation/cmplog-routines-pass.cc b/instrumentation/cmplog-routines-pass.cc
index b27e06e0..78317d5d 100644
--- a/instrumentation/cmplog-routines-pass.cc
+++ b/instrumentation/cmplog-routines-pass.cc
@@ -5,7 +5,7 @@
Written by Andrea Fioraldi
Copyright 2015, 2016 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/instrumentation/cmplog-switches-pass.cc b/instrumentation/cmplog-switches-pass.cc
index 01da6da7..3e05c13d 100644
--- a/instrumentation/cmplog-switches-pass.cc
+++ b/instrumentation/cmplog-switches-pass.cc
@@ -5,7 +5,7 @@
Written by Andrea Fioraldi
Copyright 2015, 2016 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/instrumentation/injection-pass.cc b/instrumentation/injection-pass.cc
index 971b103b..2280208b 100644
--- a/instrumentation/injection-pass.cc
+++ b/instrumentation/injection-pass.cc
@@ -5,7 +5,7 @@
Written by Marc Heuse
Copyright 2015, 2016 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/nyx_mode/QEMU-Nyx b/nyx_mode/QEMU-Nyx
index 1def26f8..e5e1c4c2 160000
--- a/nyx_mode/QEMU-Nyx
+++ b/nyx_mode/QEMU-Nyx
@@ -1 +1 @@
-Subproject commit 1def26f83e83556d767754581fa52081ffb54b09
+Subproject commit e5e1c4c21ff9c4dc80e6409d4eab47146c6024cd
diff --git a/nyx_mode/QEMU_NYX_VERSION b/nyx_mode/QEMU_NYX_VERSION
index cac32d41..c6ed0c6a 100644
--- a/nyx_mode/QEMU_NYX_VERSION
+++ b/nyx_mode/QEMU_NYX_VERSION
@@ -1 +1 @@
-1def26f83e
+e5e1c4c21ff9c4dc80e6409d4eab47146c6024cd
diff --git a/qemu_mode/build_qemu_support.sh b/qemu_mode/build_qemu_support.sh
index 3f8a88f2..45019cc8 100755
--- a/qemu_mode/build_qemu_support.sh
+++ b/qemu_mode/build_qemu_support.sh
@@ -13,7 +13,7 @@
# counters by Andrea Fioraldi
#
# Copyright 2015, 2016, 2017 Google Inc. All rights reserved.
-# Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+# Copyright 2019-2024 AFLplusplus Project. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/qemu_mode/fastexit/Makefile b/qemu_mode/fastexit/Makefile
index c7b79277..be80207d 100644
--- a/qemu_mode/fastexit/Makefile
+++ b/qemu_mode/fastexit/Makefile
@@ -4,7 +4,7 @@
#
# Written by Andrea Fioraldi
#
-# Copyright 2019-2023 Andrea Fioraldi. All rights reserved.
+# Copyright 2019-2024 Andrea Fioraldi. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/qemu_mode/libcompcov/Makefile b/qemu_mode/libcompcov/Makefile
index 7260df87..4761ac02 100644
--- a/qemu_mode/libcompcov/Makefile
+++ b/qemu_mode/libcompcov/Makefile
@@ -4,7 +4,7 @@
#
# Written by Andrea Fioraldi
#
-# Copyright 2019-2023 Andrea Fioraldi. All rights reserved.
+# Copyright 2019-2024 Andrea Fioraldi. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/qemu_mode/libcompcov/compcovtest.cc b/qemu_mode/libcompcov/compcovtest.cc
index 23215013..11797091 100644
--- a/qemu_mode/libcompcov/compcovtest.cc
+++ b/qemu_mode/libcompcov/compcovtest.cc
@@ -2,7 +2,7 @@
//
// Author: Mateusz Jurczyk (mjurczyk@google.com)
//
-// Copyright 2019-2023 Google LLC
+// Copyright 2019-2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/qemu_mode/libcompcov/libcompcov.so.c b/qemu_mode/libcompcov/libcompcov.so.c
index b57e9701..36f7b2e2 100644
--- a/qemu_mode/libcompcov/libcompcov.so.c
+++ b/qemu_mode/libcompcov/libcompcov.so.c
@@ -5,7 +5,7 @@
Written and maintained by Andrea Fioraldi
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/qemu_mode/libqasan/Makefile b/qemu_mode/libqasan/Makefile
index 61782894..7366d6f6 100644
--- a/qemu_mode/libqasan/Makefile
+++ b/qemu_mode/libqasan/Makefile
@@ -4,7 +4,7 @@
#
# Written by Andrea Fioraldi
#
-# Copyright 2019-2023 Andrea Fioraldi. All rights reserved.
+# Copyright 2019-2024 Andrea Fioraldi. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/qemu_mode/libqasan/hooks.c b/qemu_mode/libqasan/hooks.c
index a9fd0ce9..cf1b0820 100644
--- a/qemu_mode/libqasan/hooks.c
+++ b/qemu_mode/libqasan/hooks.c
@@ -1,5 +1,5 @@
/*******************************************************************************
-Copyright (c) 2019-2023, Andrea Fioraldi
+Copyright (c) 2019-2024, Andrea Fioraldi
Redistribution and use in source and binary forms, with or without
diff --git a/qemu_mode/libqasan/libqasan.c b/qemu_mode/libqasan/libqasan.c
index 12be7778..45f47d5a 100644
--- a/qemu_mode/libqasan/libqasan.c
+++ b/qemu_mode/libqasan/libqasan.c
@@ -1,5 +1,5 @@
/*******************************************************************************
-Copyright (c) 2019-2023, Andrea Fioraldi
+Copyright (c) 2019-2024, Andrea Fioraldi
Redistribution and use in source and binary forms, with or without
diff --git a/qemu_mode/libqasan/libqasan.h b/qemu_mode/libqasan/libqasan.h
index a430c868..f0844e23 100644
--- a/qemu_mode/libqasan/libqasan.h
+++ b/qemu_mode/libqasan/libqasan.h
@@ -1,5 +1,5 @@
/*******************************************************************************
-Copyright (c) 2019-2023, Andrea Fioraldi
+Copyright (c) 2019-2024, Andrea Fioraldi
Redistribution and use in source and binary forms, with or without
diff --git a/qemu_mode/libqasan/malloc.c b/qemu_mode/libqasan/malloc.c
index 4448f480..ae470b56 100644
--- a/qemu_mode/libqasan/malloc.c
+++ b/qemu_mode/libqasan/malloc.c
@@ -1,5 +1,5 @@
/*******************************************************************************
-Copyright (c) 2019-2023, Andrea Fioraldi
+Copyright (c) 2019-2024, Andrea Fioraldi
Redistribution and use in source and binary forms, with or without
diff --git a/qemu_mode/libqasan/patch.c b/qemu_mode/libqasan/patch.c
index 38e0903b..4ce8c3d8 100644
--- a/qemu_mode/libqasan/patch.c
+++ b/qemu_mode/libqasan/patch.c
@@ -1,5 +1,5 @@
/*******************************************************************************
-Copyright (c) 2019-2023, Andrea Fioraldi
+Copyright (c) 2019-2024, Andrea Fioraldi
Redistribution and use in source and binary forms, with or without
diff --git a/qemu_mode/libqasan/string.c b/qemu_mode/libqasan/string.c
index e17cff4b..cd14d57b 100644
--- a/qemu_mode/libqasan/string.c
+++ b/qemu_mode/libqasan/string.c
@@ -1,5 +1,5 @@
/*******************************************************************************
-Copyright (c) 2019-2023, Andrea Fioraldi
+Copyright (c) 2019-2024, Andrea Fioraldi
Redistribution and use in source and binary forms, with or without
diff --git a/qemu_mode/libqasan/uninstrument.c b/qemu_mode/libqasan/uninstrument.c
index e37a9b46..996f2a74 100644
--- a/qemu_mode/libqasan/uninstrument.c
+++ b/qemu_mode/libqasan/uninstrument.c
@@ -7,7 +7,7 @@ for some strange reason.
*/
/*******************************************************************************
-Copyright (c) 2019-2023, Andrea Fioraldi
+Copyright (c) 2019-2024, Andrea Fioraldi
Redistribution and use in source and binary forms, with or without
diff --git a/qemu_mode/unsigaction/Makefile b/qemu_mode/unsigaction/Makefile
index c1a7397f..d5e807d8 100644
--- a/qemu_mode/unsigaction/Makefile
+++ b/qemu_mode/unsigaction/Makefile
@@ -4,7 +4,7 @@
#
# Written by Andrea Fioraldi
#
-# Copyright 2019-2023 Andrea Fioraldi. All rights reserved.
+# Copyright 2019-2024 Andrea Fioraldi. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/qemu_mode/util/qemu_get_symbol_addr.sh b/qemu_mode/util/qemu_get_symbol_addr.sh
index e0a7ae80..5e00f1b2 100755
--- a/qemu_mode/util/qemu_get_symbol_addr.sh
+++ b/qemu_mode/util/qemu_get_symbol_addr.sh
@@ -1,5 +1,5 @@
#!/bin/bash
-# Copyright 2023 AFLplusplus
+# Copyright 2024 AFLplusplus
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/src/afl-analyze.c b/src/afl-analyze.c
index 5b122741..95f32fee 100644
--- a/src/afl-analyze.c
+++ b/src/afl-analyze.c
@@ -9,7 +9,7 @@
Andrea Fioraldi
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-as.c b/src/afl-as.c
index 772e31b3..09ba75bf 100644
--- a/src/afl-as.c
+++ b/src/afl-as.c
@@ -9,7 +9,7 @@
Andrea Fioraldi
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-cc.c b/src/afl-cc.c
index c300ddfc..e9564277 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -5,7 +5,7 @@
Written by Michal Zalewski, Laszlo Szekeres and Marc Heuse
Copyright 2015, 2016 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -2830,7 +2830,7 @@ static void maybe_usage(aflcc_state_t *aflcc, int argc, char **argv) {
" 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 like a normal compiler (to pass configure "
+ " AFL_NOOPT: behave like a normal compiler (to pass configure "
"tests)\n"
" AFL_PATH: path to instrumenting pass and runtime "
"(afl-compiler-rt.*o)\n"
diff --git a/src/afl-common.c b/src/afl-common.c
index ba498b3b..87003b03 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -9,7 +9,7 @@
Andrea Fioraldi
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index 214b4fe9..0a77d61c 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -13,7 +13,7 @@
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -1019,7 +1019,9 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
if (status >= 0x41464c00 && status <= 0x41464cff) {
- FATAL("Target uses the new forkserver model, you need to switch to a newer afl-fuzz too!");
+ FATAL(
+ "Target uses the new forkserver model, you need to switch to a newer "
+ "afl-fuzz too!");
}
diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c
index 5f67347c..d056ac9f 100644
--- a/src/afl-fuzz-bitmap.c
+++ b/src/afl-fuzz-bitmap.c
@@ -9,7 +9,7 @@
Andrea Fioraldi
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-fuzz-cmplog.c b/src/afl-fuzz-cmplog.c
index 3e6432ca..21f34e12 100644
--- a/src/afl-fuzz-cmplog.c
+++ b/src/afl-fuzz-cmplog.c
@@ -11,7 +11,7 @@
Andrea Fioraldi
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c
index 905431d1..3b1d13f1 100644
--- a/src/afl-fuzz-extras.c
+++ b/src/afl-fuzz-extras.c
@@ -9,7 +9,7 @@
Andrea Fioraldi
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index 8ab44a3b..76291cc4 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -9,7 +9,7 @@
Andrea Fioraldi
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -2236,6 +2236,21 @@ void setup_dirs_fds(afl_state_t *afl) {
fflush(afl->fsrv.plot_file);
+#ifdef INTROSPECTION
+
+ tmp = alloc_printf("%s/plot_det_data", afl->out_dir);
+
+ int fd = open(tmp, O_WRONLY | O_CREAT, DEFAULT_PERMISSION);
+ if (fd < 0) { PFATAL("Unable to create '%s'", tmp); }
+ ck_free(tmp);
+
+ afl->fsrv.det_plot_file = fdopen(fd, "w");
+ if (!afl->fsrv.det_plot_file) { PFATAL("fdopen() failed"); }
+
+ if (afl->in_place_resume) { fseek(afl->fsrv.det_plot_file, 0, SEEK_END); }
+
+#endif
+
/* ignore errors */
}
diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c
index 17fb9368..ae4d6668 100644
--- a/src/afl-fuzz-mutators.c
+++ b/src/afl-fuzz-mutators.c
@@ -10,7 +10,7 @@
Dominik Maier
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index 01e34b69..d9c074ec 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -9,7 +9,7 @@
Andrea Fioraldi
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -329,9 +329,9 @@ u8 fuzz_one_original(afl_state_t *afl) {
u32 len, temp_len;
u32 j;
u32 i;
- u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0;
+ u8 *in_buf, *out_buf, *orig_in, *ex_tmp;
u64 havoc_queued = 0, orig_hit_cnt, new_hit_cnt = 0, prev_cksum, _prev_cksum;
- u32 splice_cycle = 0, perf_score = 100, orig_perf, eff_cnt = 1;
+ u32 splice_cycle = 0, perf_score = 100, orig_perf;
u8 ret_val = 1, doing_det = 0;
@@ -545,12 +545,37 @@ u8 fuzz_one_original(afl_state_t *afl) {
}
+ u64 before_det_time = get_cur_time();
+#ifdef INTROSPECTION
+
+ u64 before_havoc_time;
+ u32 before_det_findings = afl->queued_items,
+ before_det_edges = count_non_255_bytes(afl, afl->virgin_bits),
+ before_havoc_findings, before_havoc_edges;
+ u8 is_logged = 0;
+
+#endif
+ if (!afl->skip_deterministic) {
+
+ if (!skip_deterministic_stage(afl, in_buf, out_buf, len, before_det_time)) {
+
+ goto abandon_entry;
+
+ }
+
+ }
+
+ u8 *skip_eff_map = afl->queue_cur->skipdet_e->skip_eff_map;
+
/* Skip right away if -d is given, if it has not been chosen sufficiently
often to warrant the expensive deterministic stage (fuzz_level), or
if it has gone through deterministic testing in earlier, resumed runs
(passed_det). */
+ /* if skipdet decide to skip the seed or no interesting bytes found,
+ we skip the whole deterministic stage as well */
if (likely(afl->skip_deterministic) || likely(afl->queue_cur->passed_det) ||
+ likely(!afl->queue_cur->skipdet_e->quick_eff_bytes) ||
likely(perf_score <
(afl->queue_cur->depth * 30 <= afl->havoc_max_mult * 100
? afl->queue_cur->depth * 30
@@ -609,6 +634,10 @@ u8 fuzz_one_original(afl_state_t *afl) {
afl->stage_cur_byte = afl->stage_cur >> 3;
+ if (!skip_eff_map[afl->stage_cur_byte]) continue;
+
+ if (is_det_timeout(before_det_time, 0)) { goto custom_mutator_stage; }
+
FLIP_BIT(out_buf, afl->stage_cur);
#ifdef INTROSPECTION
@@ -725,6 +754,10 @@ u8 fuzz_one_original(afl_state_t *afl) {
afl->stage_cur_byte = afl->stage_cur >> 3;
+ if (!skip_eff_map[afl->stage_cur_byte]) continue;
+
+ if (is_det_timeout(before_det_time, 0)) { goto custom_mutator_stage; }
+
FLIP_BIT(out_buf, afl->stage_cur);
FLIP_BIT(out_buf, afl->stage_cur + 1);
@@ -760,6 +793,10 @@ u8 fuzz_one_original(afl_state_t *afl) {
afl->stage_cur_byte = afl->stage_cur >> 3;
+ if (!skip_eff_map[afl->stage_cur_byte]) continue;
+
+ if (is_det_timeout(before_det_time, 0)) { goto custom_mutator_stage; }
+
FLIP_BIT(out_buf, afl->stage_cur);
FLIP_BIT(out_buf, afl->stage_cur + 1);
FLIP_BIT(out_buf, afl->stage_cur + 2);
@@ -787,34 +824,6 @@ u8 fuzz_one_original(afl_state_t *afl) {
afl->queue_cur->stats_mutated += afl->stage_max;
#endif
- /* Effector map setup. These macros calculate:
-
- EFF_APOS - position of a particular file offset in the map.
- EFF_ALEN - length of a map with a particular number of bytes.
- EFF_SPAN_ALEN - map span for a sequence of bytes.
-
- */
-
-#define EFF_APOS(_p) ((_p) >> EFF_MAP_SCALE2)
-#define EFF_REM(_x) ((_x) & ((1 << EFF_MAP_SCALE2) - 1))
-#define EFF_ALEN(_l) (EFF_APOS(_l) + !!EFF_REM(_l))
-#define EFF_SPAN_ALEN(_p, _l) (EFF_APOS((_p) + (_l)-1) - EFF_APOS(_p) + 1)
-
- /* Initialize effector map for the next step (see comments below). Always
- flag first and last byte as doing something. */
-
- eff_map = afl_realloc(AFL_BUF_PARAM(eff), EFF_ALEN(len));
- if (unlikely(!eff_map)) { PFATAL("alloc"); }
- memset(eff_map, 0, EFF_ALEN(len));
- eff_map[0] = 1;
-
- if (EFF_APOS(len - 1) != 0) {
-
- eff_map[EFF_APOS(len - 1)] = 1;
- ++eff_cnt;
-
- }
-
/* Walking byte. */
afl->stage_name = "bitflip 8/8";
@@ -828,6 +837,10 @@ u8 fuzz_one_original(afl_state_t *afl) {
afl->stage_cur_byte = afl->stage_cur;
+ if (!skip_eff_map[afl->stage_cur_byte]) continue;
+
+ if (is_det_timeout(before_det_time, 0)) { goto custom_mutator_stage; }
+
out_buf[afl->stage_cur] ^= 0xFF;
#ifdef INTROSPECTION
@@ -837,59 +850,19 @@ u8 fuzz_one_original(afl_state_t *afl) {
if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; }
- /* We also use this stage to pull off a simple trick: we identify
- bytes that seem to have no effect on the current execution path
- even when fully flipped - and we skip them during more expensive
- deterministic stages, such as arithmetics or known ints. */
-
- if (!eff_map[EFF_APOS(afl->stage_cur)]) {
-
- u64 cksum;
-
- /* If in non-instrumented mode or if the file is very short, just flag
- everything without wasting time on checksums. */
-
- if (!afl->non_instrumented_mode && len >= EFF_MIN_LEN) {
-
- cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
-
- } else {
-
- cksum = ~prev_cksum;
-
- }
-
- if (cksum != prev_cksum) {
-
- eff_map[EFF_APOS(afl->stage_cur)] = 1;
- ++eff_cnt;
-
- }
-
- }
-
out_buf[afl->stage_cur] ^= 0xFF;
}
- /* If the effector map is more than EFF_MAX_PERC dense, just flag the
- whole thing as worth fuzzing, since we wouldn't be saving much time
- anyway. */
-
- if (eff_cnt != (u32)EFF_ALEN(len) &&
- eff_cnt * 100 / EFF_ALEN(len) > EFF_MAX_PERC) {
+ /* New effective bytes calculation. */
- memset(eff_map, 1, EFF_ALEN(len));
+ for (i = 0; i < len; i++) {
- afl->blocks_eff_select += EFF_ALEN(len);
-
- } else {
-
- afl->blocks_eff_select += eff_cnt;
+ if (skip_eff_map[i]) afl->blocks_eff_select += 1;
}
- afl->blocks_eff_total += EFF_ALEN(len);
+ afl->blocks_eff_total += len;
new_hit_cnt = afl->queued_items + afl->saved_crashes;
@@ -914,12 +887,9 @@ u8 fuzz_one_original(afl_state_t *afl) {
/* Let's consult the effector map... */
- if (!eff_map[EFF_APOS(i)] && !eff_map[EFF_APOS(i + 1)]) {
-
- --afl->stage_max;
- continue;
+ if (!skip_eff_map[i]) continue;
- }
+ if (is_det_timeout(before_det_time, 0)) { goto custom_mutator_stage; }
afl->stage_cur_byte = i;
@@ -959,13 +929,10 @@ u8 fuzz_one_original(afl_state_t *afl) {
for (i = 0; i < len - 3; ++i) {
/* Let's consult the effector map... */
- if (!eff_map[EFF_APOS(i)] && !eff_map[EFF_APOS(i + 1)] &&
- !eff_map[EFF_APOS(i + 2)] && !eff_map[EFF_APOS(i + 3)]) {
- --afl->stage_max;
- continue;
+ if (!skip_eff_map[i]) continue;
- }
+ if (is_det_timeout(before_det_time, 0)) { goto custom_mutator_stage; }
afl->stage_cur_byte = i;
@@ -1016,12 +983,9 @@ skip_bitflip:
/* Let's consult the effector map... */
- if (!eff_map[EFF_APOS(i)]) {
-
- afl->stage_max -= 2 * ARITH_MAX;
- continue;
+ if (!skip_eff_map[i]) continue;
- }
+ if (is_det_timeout(before_det_time, 0)) { goto custom_mutator_stage; }
afl->stage_cur_byte = i;
@@ -1103,12 +1067,9 @@ skip_bitflip:
/* Let's consult the effector map... */
- if (!eff_map[EFF_APOS(i)] && !eff_map[EFF_APOS(i + 1)]) {
-
- afl->stage_max -= 4 * ARITH_MAX;
- continue;
+ if (!skip_eff_map[i]) continue;
- }
+ if (is_det_timeout(before_det_time, 0)) { goto custom_mutator_stage; }
afl->stage_cur_byte = i;
@@ -1236,13 +1197,9 @@ skip_bitflip:
/* Let's consult the effector map... */
- if (!eff_map[EFF_APOS(i)] && !eff_map[EFF_APOS(i + 1)] &&
- !eff_map[EFF_APOS(i + 2)] && !eff_map[EFF_APOS(i + 3)]) {
-
- afl->stage_max -= 4 * ARITH_MAX;
- continue;
+ if (!skip_eff_map[i]) continue;
- }
+ if (is_det_timeout(before_det_time, 0)) { goto custom_mutator_stage; }
afl->stage_cur_byte = i;
@@ -1374,12 +1331,9 @@ skip_arith:
/* Let's consult the effector map... */
- if (!eff_map[EFF_APOS(i)]) {
-
- afl->stage_max -= sizeof(interesting_8);
- continue;
+ if (!skip_eff_map[i]) continue;
- }
+ if (is_det_timeout(before_det_time, 0)) { goto custom_mutator_stage; }
afl->stage_cur_byte = i;
@@ -1437,12 +1391,9 @@ skip_arith:
/* Let's consult the effector map... */
- if (!eff_map[EFF_APOS(i)] && !eff_map[EFF_APOS(i + 1)]) {
+ if (!skip_eff_map[i]) continue;
- afl->stage_max -= sizeof(interesting_16);
- continue;
-
- }
+ if (is_det_timeout(before_det_time, 0)) { goto custom_mutator_stage; }
afl->stage_cur_byte = i;
@@ -1528,13 +1479,9 @@ skip_arith:
/* Let's consult the effector map... */
- if (!eff_map[EFF_APOS(i)] && !eff_map[EFF_APOS(i + 1)] &&
- !eff_map[EFF_APOS(i + 2)] && !eff_map[EFF_APOS(i + 3)]) {
+ if (!skip_eff_map[i]) continue;
- afl->stage_max -= sizeof(interesting_32) >> 1;
- continue;
-
- }
+ if (is_det_timeout(before_det_time, 0)) { goto custom_mutator_stage; }
afl->stage_cur_byte = i;
@@ -1626,6 +1573,10 @@ skip_interest:
u32 last_len = 0;
+ if (!skip_eff_map[i]) continue;
+
+ if (is_det_timeout(before_det_time, 0)) { goto custom_mutator_stage; }
+
afl->stage_cur_byte = i;
/* Extras are sorted by size, from smallest to largest. This means
@@ -1643,9 +1594,7 @@ skip_interest:
if ((afl->extras_cnt > afl->max_det_extras &&
rand_below(afl, afl->extras_cnt) >= afl->max_det_extras) ||
afl->extras[j].len > len - i ||
- !memcmp(afl->extras[j].data, out_buf + i, afl->extras[j].len) ||
- !memchr(eff_map + EFF_APOS(i), 1,
- EFF_SPAN_ALEN(i, afl->extras[j].len))) {
+ !memcmp(afl->extras[j].data, out_buf + i, afl->extras[j].len)) {
--afl->stage_max;
continue;
@@ -1693,6 +1642,10 @@ skip_interest:
for (i = 0; i <= (u32)len; ++i) {
+ if (!skip_eff_map[i % len]) continue;
+
+ if (is_det_timeout(before_det_time, 0)) { goto custom_mutator_stage; }
+
afl->stage_cur_byte = i;
for (j = 0; j < afl->extras_cnt; ++j) {
@@ -1755,6 +1708,10 @@ skip_user_extras:
u32 last_len = 0;
+ if (!skip_eff_map[i]) continue;
+
+ if (is_det_timeout(before_det_time, 0)) { goto custom_mutator_stage; }
+
afl->stage_cur_byte = i;
u32 min_extra_len = MIN(afl->a_extras_cnt, (u32)USE_AUTO_EXTRAS);
@@ -1763,9 +1720,7 @@ skip_user_extras:
/* See the comment in the earlier code; extras are sorted by size. */
if (afl->a_extras[j].len > len - i ||
- !memcmp(afl->a_extras[j].data, out_buf + i, afl->a_extras[j].len) ||
- !memchr(eff_map + EFF_APOS(i), 1,
- EFF_SPAN_ALEN(i, afl->a_extras[j].len))) {
+ !memcmp(afl->a_extras[j].data, out_buf + i, afl->a_extras[j].len)) {
--afl->stage_max;
continue;
@@ -1813,6 +1768,10 @@ skip_user_extras:
for (i = 0; i <= (u32)len; ++i) {
+ if (!skip_eff_map[i % len]) continue;
+
+ if (is_det_timeout(before_det_time, 0)) { goto custom_mutator_stage; }
+
afl->stage_cur_byte = i;
for (j = 0; j < afl->a_extras_cnt; ++j) {
@@ -2020,6 +1979,19 @@ custom_mutator_stage:
havoc_stage:
+#ifdef INTROSPECTION
+
+ if (!is_logged) {
+
+ is_logged = 1;
+ before_havoc_findings = afl->queued_items;
+ before_havoc_edges = count_non_255_bytes(afl, afl->virgin_bits);
+ before_havoc_time = get_cur_time();
+
+ }
+
+#endif
+
if (unlikely(afl->custom_only)) {
/* Force UI update */
@@ -3430,6 +3402,25 @@ retry_splicing:
ret_val = 0;
+#ifdef INTROSPECTION
+
+ afl->havoc_prof->queued_det_stage =
+ before_havoc_findings - before_det_findings;
+ afl->havoc_prof->queued_havoc_stage =
+ afl->queued_items - before_havoc_findings;
+ afl->havoc_prof->total_queued_det += afl->havoc_prof->queued_det_stage;
+ afl->havoc_prof->edge_det_stage = before_havoc_edges - before_det_edges;
+ afl->havoc_prof->edge_havoc_stage =
+ count_non_255_bytes(afl, afl->virgin_bits) - before_havoc_edges;
+ afl->havoc_prof->total_det_edge += afl->havoc_prof->edge_det_stage;
+ afl->havoc_prof->det_stage_time = before_havoc_time - before_det_time;
+ afl->havoc_prof->havoc_stage_time = get_cur_time() - before_havoc_time;
+ afl->havoc_prof->total_det_time += afl->havoc_prof->det_stage_time;
+
+ plot_profile_data(afl, afl->queue_cur);
+
+#endif
+
/* we are through with this queue entry - for this iteration */
abandon_entry:
diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c
index 4c7da774..16a398fd 100644
--- a/src/afl-fuzz-python.c
+++ b/src/afl-fuzz-python.c
@@ -9,7 +9,7 @@
Andrea Fioraldi
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c
index 4b9627f7..1ea50418 100644
--- a/src/afl-fuzz-queue.c
+++ b/src/afl-fuzz-queue.c
@@ -9,7 +9,7 @@
Andrea Fioraldi
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
@@ -664,6 +664,8 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) {
}
+ q->skipdet_e = (struct skipdet_entry *)ck_alloc(sizeof(struct skipdet_entry));
+
}
/* Destroy the entire queue. */
@@ -679,6 +681,15 @@ void destroy_queue(afl_state_t *afl) {
q = afl->queue_buf[i];
ck_free(q->fname);
ck_free(q->trace_mini);
+ if (q->skipdet_e) {
+
+ if (q->skipdet_e->done_inf_map) ck_free(q->skipdet_e->done_inf_map);
+ if (q->skipdet_e->skip_eff_map) ck_free(q->skipdet_e->skip_eff_map);
+
+ ck_free(q->skipdet_e);
+
+ }
+
ck_free(q);
}
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index 9e9b3822..eead7a8b 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -11,7 +11,7 @@
Andrea Fioraldi
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c
index 1ee8ebe7..d764952c 100644
--- a/src/afl-fuzz-run.c
+++ b/src/afl-fuzz-run.c
@@ -10,7 +10,7 @@
Dominik Maier
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-fuzz-skipdet.c b/src/afl-fuzz-skipdet.c
new file mode 100644
index 00000000..e52d59a3
--- /dev/null
+++ b/src/afl-fuzz-skipdet.c
@@ -0,0 +1,403 @@
+
+
+#include "afl-fuzz.h"
+
+void flip_range(u8 *input, u32 pos, u32 size) {
+
+ for (u32 i = 0; i < size; i++)
+ input[pos + i] ^= 0xFF;
+
+ return;
+
+}
+
+#define MAX_EFF_TIMEOUT (10 * 60 * 1000)
+#define MAX_DET_TIMEOUT (15 * 60 * 1000)
+u8 is_det_timeout(u64 cur_ms, u8 is_flip) {
+
+ if (is_flip) {
+
+ if (unlikely(get_cur_time() - cur_ms > MAX_EFF_TIMEOUT)) return 1;
+
+ } else {
+
+ if (unlikely(get_cur_time() - cur_ms > MAX_DET_TIMEOUT)) return 1;
+
+ }
+
+ return 0;
+
+}
+
+/* decide if the seed should be deterministically fuzzed */
+
+u8 should_det_fuzz(afl_state_t *afl, struct queue_entry *q) {
+
+ if (!afl->skipdet_g->virgin_det_bits) {
+
+ afl->skipdet_g->virgin_det_bits =
+ (u8 *)ck_alloc(sizeof(u8) * afl->fsrv.map_size);
+
+ }
+
+ if (!q->favored || q->passed_det) return 0;
+ if (!q->trace_mini) return 0;
+
+ if (!afl->skipdet_g->last_cov_undet)
+ afl->skipdet_g->last_cov_undet = get_cur_time();
+
+ if (get_cur_time() - afl->skipdet_g->last_cov_undet >= THRESHOLD_DEC_TIME) {
+
+ if (afl->skipdet_g->undet_bits_threshold >= 2) {
+
+ afl->skipdet_g->undet_bits_threshold *= 0.75;
+ afl->skipdet_g->last_cov_undet = get_cur_time();
+
+ }
+
+ }
+
+ u32 new_det_bits = 0;
+
+ for (u32 i = 0; i < afl->fsrv.map_size; i++) {
+
+ if (unlikely(q->trace_mini[i >> 3] & (1 << (i & 7)))) {
+
+ if (!afl->skipdet_g->virgin_det_bits[i]) { new_det_bits++; }
+
+ }
+
+ }
+
+ if (!afl->skipdet_g->undet_bits_threshold)
+ afl->skipdet_g->undet_bits_threshold = new_det_bits * 0.05;
+
+ if (new_det_bits >= afl->skipdet_g->undet_bits_threshold) {
+
+ afl->skipdet_g->last_cov_undet = get_cur_time();
+ q->skipdet_e->undet_bits = new_det_bits;
+
+ for (u32 i = 0; i < afl->fsrv.map_size; i++) {
+
+ if (unlikely(q->trace_mini[i >> 3] & (1 << (i & 7)))) {
+
+ if (!afl->skipdet_g->virgin_det_bits[i])
+ afl->skipdet_g->virgin_det_bits[i] = 1;
+
+ }
+
+ }
+
+ return 1;
+
+ }
+
+ return 0;
+
+}
+
+/*
+ consists of two stages that
+ return 0 if exec failed.
+*/
+
+u8 skip_deterministic_stage(afl_state_t *afl, u8 *orig_buf, u8 *out_buf,
+ u32 len, u64 before_det_time) {
+
+ u64 orig_hit_cnt, new_hit_cnt;
+
+ if (afl->queue_cur->skipdet_e->done_eff) return 1;
+
+ if (!should_det_fuzz(afl, afl->queue_cur)) return 1;
+
+ /* Add check to make sure that for seeds without too much undet bits,
+ we ignore them */
+
+ /******************
+ * SKIP INFERENCE *
+ ******************/
+
+ afl->stage_short = "inf";
+ afl->stage_name = "inference";
+ afl->stage_cur = 0;
+ orig_hit_cnt = afl->queued_items + afl->saved_crashes;
+
+ u8 *inf_eff_map = (u8 *)ck_alloc(sizeof(u8) * len);
+ memset(inf_eff_map, 1, sizeof(u8) * len);
+
+ if (common_fuzz_stuff(afl, orig_buf, len)) { return 0; }
+
+ u64 prev_cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
+ u64 _prev_cksum = prev_cksum;
+
+ if (MINIMAL_BLOCK_SIZE * 8 < len) {
+
+ // u64 size_skiped = 0, quick_skip_exec = total_execs, quick_skip_time =
+ // get_cur_time();
+ u64 pre_inf_exec = afl->fsrv.total_execs, pre_inf_time = get_cur_time();
+
+ /* if determine stage time / input size is too small, just go ahead */
+
+ u32 pos = 0, cur_block_size = MINIMAL_BLOCK_SIZE, max_block_size = len / 8;
+
+ while (pos < len - 1) {
+
+ cur_block_size = MINIMAL_BLOCK_SIZE;
+
+ while (cur_block_size < max_block_size) {
+
+ u32 flip_block_size =
+ (cur_block_size + pos < len) ? cur_block_size : len - 1 - pos;
+
+ afl->stage_cur += 1;
+
+ flip_range(out_buf, pos, flip_block_size);
+
+ if (common_fuzz_stuff(afl, out_buf, len)) return 0;
+
+ flip_range(out_buf, pos, flip_block_size);
+
+ u64 cksum =
+ hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
+
+ // printf("Now trying range %d with %d, %s.\n", pos, cur_block_size,
+ // (cksum == prev_cksum) ? (u8*)"Yes" : (u8*) "Not");
+
+ /* continue until we fail or exceed length */
+ if (cksum == _prev_cksum) {
+
+ cur_block_size *= 2;
+
+ if (cur_block_size >= len - 1 - pos) break;
+
+ } else {
+
+ break;
+
+ }
+
+ }
+
+ if (cur_block_size == MINIMAL_BLOCK_SIZE) {
+
+ /* we failed early on*/
+
+ pos += cur_block_size;
+
+ } else {
+
+ u32 cur_skip_len = (cur_block_size / 2 + pos < len)
+ ? (cur_block_size / 2)
+ : (len - pos - 1);
+
+ memset(inf_eff_map + pos, 0, cur_skip_len);
+
+ afl->skipdet_g->inf_prof->inf_skipped_bytes += cur_skip_len;
+
+ pos += cur_skip_len;
+
+ }
+
+ }
+
+ afl->skipdet_g->inf_prof->inf_execs_cost +=
+ (afl->fsrv.total_execs - pre_inf_exec);
+ afl->skipdet_g->inf_prof->inf_time_cost += (get_cur_time() - pre_inf_time);
+ // PFATAL("Done, now have %d bytes skipped, with exec %lld, time %lld.\n",
+ // afl->inf_skipped_bytes, afl->inf_execs_cost, afl->inf_time_cost);
+
+ } else
+
+ memset(inf_eff_map, 1, len);
+
+ new_hit_cnt = afl->queued_items + afl->saved_crashes;
+
+ afl->stage_finds[STAGE_INF] += new_hit_cnt - orig_hit_cnt;
+ afl->stage_cycles[STAGE_INF] += afl->stage_cur;
+
+ /****************************
+ * Quick Skip Effective Map *
+ ****************************/
+
+ /* Quick Effective Map Calculation */
+
+ afl->stage_short = "quick";
+ afl->stage_name = "quick eff";
+ afl->stage_cur = 0;
+ afl->stage_max = 32 * 1024;
+
+ orig_hit_cnt = afl->queued_items + afl->saved_crashes;
+
+ u32 before_skip_inf = afl->queued_items;
+
+ /* clean all the eff bytes, since previous eff bytes are already fuzzed */
+ u8 *skip_eff_map = afl->queue_cur->skipdet_e->skip_eff_map,
+ *done_inf_map = afl->queue_cur->skipdet_e->done_inf_map;
+
+ if (!skip_eff_map) {
+
+ skip_eff_map = (u8 *)ck_alloc(sizeof(u8) * len);
+ afl->queue_cur->skipdet_e->skip_eff_map = skip_eff_map;
+
+ } else {
+
+ memset(skip_eff_map, 0, sizeof(u8) * len);
+
+ }
+
+ /* restore the starting point */
+ if (!done_inf_map) {
+
+ done_inf_map = (u8 *)ck_alloc(sizeof(u8) * len);
+ afl->queue_cur->skipdet_e->done_inf_map = done_inf_map;
+
+ } else {
+
+ for (afl->stage_cur = 0; afl->stage_cur < len; afl->stage_cur++) {
+
+ if (done_inf_map[afl->stage_cur] == 0) break;
+
+ }
+
+ }
+
+ /* depending on the seed's performance, we could search eff bytes
+ for multiple rounds */
+
+ u8 eff_round_continue = 1, eff_round_done = 0, done_eff = 0, repeat_eff = 0,
+ fuzz_nearby = 0, *non_eff_bytes = 0;
+
+ u64 before_eff_execs = afl->fsrv.total_execs;
+
+ if (getenv("REPEAT_EFF")) repeat_eff = 1;
+ if (getenv("FUZZ_NEARBY")) fuzz_nearby = 1;
+
+ if (fuzz_nearby) {
+
+ non_eff_bytes = (u8 *)ck_alloc(sizeof(u8) * len);
+
+ // clean exec cksum
+ if (common_fuzz_stuff(afl, out_buf, len)) { return 0; }
+ prev_cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
+
+ }
+
+ do {
+
+ eff_round_continue = 0;
+ afl->stage_max = 32 * 1024;
+
+ for (; afl->stage_cur < afl->stage_max && afl->stage_cur < len;
+ ++afl->stage_cur) {
+
+ afl->stage_cur_byte = afl->stage_cur;
+
+ if (!inf_eff_map[afl->stage_cur_byte] ||
+ skip_eff_map[afl->stage_cur_byte])
+ continue;
+
+ if (is_det_timeout(before_det_time, 1)) { goto cleanup_skipdet; }
+
+ u8 orig = out_buf[afl->stage_cur_byte], replace = rand_below(afl, 256);
+
+ while (replace == orig) {
+
+ replace = rand_below(afl, 256);
+
+ }
+
+ out_buf[afl->stage_cur_byte] = replace;
+
+ before_skip_inf = afl->queued_items;
+
+ if (common_fuzz_stuff(afl, out_buf, len)) { return 0; }
+
+ out_buf[afl->stage_cur_byte] = orig;
+
+ if (fuzz_nearby) {
+
+ if (prev_cksum ==
+ hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST)) {
+
+ non_eff_bytes[afl->stage_cur_byte] = 1;
+
+ }
+
+ }
+
+ if (afl->queued_items != before_skip_inf) {
+
+ skip_eff_map[afl->stage_cur_byte] = 1;
+ afl->queue_cur->skipdet_e->quick_eff_bytes += 1;
+
+ if (afl->stage_max < MAXIMUM_QUICK_EFF_EXECS) { afl->stage_max *= 2; }
+
+ if (afl->stage_max == MAXIMUM_QUICK_EFF_EXECS && repeat_eff)
+ eff_round_continue = 1;
+
+ }
+
+ done_inf_map[afl->stage_cur_byte] = 1;
+
+ }
+
+ afl->stage_cur = 0;
+ done_eff = 1;
+
+ if (++eff_round_done >= 8) break;
+
+ } while (eff_round_continue);
+
+ new_hit_cnt = afl->queued_items + afl->saved_crashes;
+
+ afl->stage_finds[STAGE_QUICK] += new_hit_cnt - orig_hit_cnt;
+ afl->stage_cycles[STAGE_QUICK] += (afl->fsrv.total_execs - before_eff_execs);
+
+cleanup_skipdet:
+
+ if (fuzz_nearby) {
+
+ u8 *nearby_bytes = (u8 *)ck_alloc(sizeof(u8) * len);
+
+ u32 i = 3;
+ while (i < len) {
+
+ // assume DWORD size, from i - 3 -> i + 3
+ if (skip_eff_map[i]) {
+
+ u32 fill_length = (i + 3 < len) ? 7 : len - i + 2;
+ memset(nearby_bytes + i - 3, 1, fill_length);
+ i += 3;
+
+ } else
+
+ i += 1;
+
+ }
+
+ for (i = 0; i < len; i++) {
+
+ if (nearby_bytes[i] && !non_eff_bytes[i]) skip_eff_map[i] = 1;
+
+ }
+
+ ck_free(nearby_bytes);
+ ck_free(non_eff_bytes);
+
+ }
+
+ if (done_eff) {
+
+ afl->queue_cur->skipdet_e->continue_inf = 0;
+ afl->queue_cur->skipdet_e->done_eff = 1;
+
+ } else {
+
+ afl->queue_cur->skipdet_e->continue_inf = 1;
+
+ }
+
+ return 1;
+
+}
+
diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c
index 7d6fdfb9..4467cae8 100644
--- a/src/afl-fuzz-state.c
+++ b/src/afl-fuzz-state.c
@@ -9,7 +9,7 @@
Andrea Fioraldi
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -140,6 +140,14 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) {
afl->fsrv.child_pid = -1;
afl->fsrv.out_dir_fd = -1;
+ /* Init SkipDet */
+ afl->skipdet_g =
+ (struct skipdet_global *)ck_alloc(sizeof(struct skipdet_global));
+ afl->skipdet_g->inf_prof =
+ (struct inf_profile *)ck_alloc(sizeof(struct inf_profile));
+ afl->havoc_prof =
+ (struct havoc_profile *)ck_alloc(sizeof(struct havoc_profile));
+
init_mopt_globals(afl);
list_append(&afl_states, afl);
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index deb28b7a..76577081 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -9,7 +9,7 @@
Andrea Fioraldi
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -502,6 +502,44 @@ void maybe_update_plot_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
}
+/* Log deterministic stage efficiency */
+
+void plot_profile_data(afl_state_t *afl, struct queue_entry *q) {
+
+ u64 current_ms = get_cur_time() - afl->start_time;
+
+ u32 current_edges = count_non_255_bytes(afl, afl->virgin_bits);
+ double det_finding_rate = (double)afl->havoc_prof->total_det_edge * 100.0 /
+ (double)current_edges,
+ det_time_rate = (double)afl->havoc_prof->total_det_time * 100.0 /
+ (double)current_ms;
+
+ u32 ndet_bits = 0;
+ for (u32 i = 0; i < afl->fsrv.map_size; i++) {
+
+ if (afl->skipdet_g->virgin_det_bits[i]) ndet_bits += 1;
+
+ }
+
+ double det_fuzzed_rate = (double)ndet_bits * 100.0 / (double)current_edges;
+
+ fprintf(afl->fsrv.det_plot_file,
+ "[%02lld:%02lld:%02lld] fuzz %d (%d), find %d/%d among %d(%02.2f) "
+ "and spend %lld/%lld(%02.2f), cover %02.2f yet, %d/%d undet bits, "
+ "continue %d.\n",
+ current_ms / 1000 / 3600, (current_ms / 1000 / 60) % 60,
+ (current_ms / 1000) % 60, afl->current_entry, q->fuzz_level,
+ afl->havoc_prof->edge_det_stage, afl->havoc_prof->edge_havoc_stage,
+ current_edges, det_finding_rate,
+ afl->havoc_prof->det_stage_time / 1000,
+ afl->havoc_prof->havoc_stage_time / 1000, det_time_rate,
+ det_fuzzed_rate, q->skipdet_e->undet_bits,
+ afl->skipdet_g->undet_bits_threshold, q->skipdet_e->continue_inf);
+
+ fflush(afl->fsrv.det_plot_file);
+
+}
+
/* Check terminal dimensions after resize. */
static void check_term_size(afl_state_t *afl) {
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 8cf6c735..12d67fe7 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -9,7 +9,7 @@
Andrea Fioraldi
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -170,7 +170,7 @@ static void usage(u8 *argv0, int more_help) {
" -g minlength - set min length of generated fuzz input (default: 1)\n"
" -G maxlength - set max length of generated fuzz input (default: "
"%lu)\n"
- " -D - enable deterministic fuzzing (once per queue entry)\n"
+ " -D - enable (a new) effective deterministic fuzzing\n"
" -L minutes - use MOpt(imize) mode and set the time limit for "
"entering the\n"
" pacemaker mode (minutes of no new finds). 0 = "
@@ -955,14 +955,20 @@ int main(int argc, char **argv_orig, char **envp) {
break;
- case 'D': /* enforce deterministic */
+ case 'D': /* partial deterministic */
afl->skip_deterministic = 0;
break;
- case 'd': /* skip deterministic */
+ case 'd': /* no deterministic */
- afl->skip_deterministic = 1;
+ // this is the default and currently a lot of infrastructure enforces
+ // it (e.g. clusterfuzz, fuzzbench) based on that this feature
+ // originally was bad performance wise. We now have a better
+ // implementation, hence if it is activated, we do not want to
+ // deactivate it by such setups.
+
+ // afl->skip_deterministic = 1;
break;
case 'B': /* load bitmap */
@@ -1424,11 +1430,11 @@ int main(int argc, char **argv_orig, char **envp) {
}
#endif
+
+ // silently disable deterministic mutation if custom mutators are used
if (!afl->skip_deterministic && afl->afl_env.afl_custom_mutator_only) {
- FATAL(
- "Using -D determinstic fuzzing is incompatible with "
- "AFL_CUSTOM_MUTATOR_ONLY!");
+ afl->skip_deterministic = 1;
}
@@ -3031,6 +3037,11 @@ stop_fuzzing:
if (frida_afl_preload) { ck_free(frida_afl_preload); }
fclose(afl->fsrv.plot_file);
+
+ #ifdef INTROSPECTION
+ fclose(afl->fsrv.det_plot_file);
+ #endif
+
destroy_queue(afl);
destroy_extras(afl);
destroy_custom_mutators(afl);
diff --git a/src/afl-gotcpu.c b/src/afl-gotcpu.c
index 4f851099..7aee2985 100644
--- a/src/afl-gotcpu.c
+++ b/src/afl-gotcpu.c
@@ -9,7 +9,7 @@
Andrea Fioraldi
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-ld-lto.c b/src/afl-ld-lto.c
index 7ce5de41..513c1ae9 100644
--- a/src/afl-ld-lto.c
+++ b/src/afl-ld-lto.c
@@ -9,7 +9,7 @@
Andrea Fioraldi
Dominik Maier
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-sharedmem.c b/src/afl-sharedmem.c
index a2c81586..daea8f46 100644
--- a/src/afl-sharedmem.c
+++ b/src/afl-sharedmem.c
@@ -11,7 +11,7 @@
Andrea Fioraldi
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index 7a639cf6..20ba5a5e 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -12,7 +12,7 @@
Dominik Maier
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/afl-tmin.c b/src/afl-tmin.c
index e7442d1d..4e5dab41 100644
--- a/src/afl-tmin.c
+++ b/src/afl-tmin.c
@@ -12,7 +12,7 @@
Dominik Maier
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/test-instr.c b/test-instr.c
index eda5189c..28552893 100644
--- a/test-instr.c
+++ b/test-instr.c
@@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
diff --git a/test/test-custom-mutators.sh b/test/test-custom-mutators.sh
index 49feedc0..8c8b0ad3 100755
--- a/test/test-custom-mutators.sh
+++ b/test/test-custom-mutators.sh
@@ -38,7 +38,7 @@ test -e test-custom-mutator.c -a -e ${CUSTOM_MUTATOR_PATH}/example.c -a -e ${CUS
# Run afl-fuzz w/ the C mutator
$ECHO "$GREY[*] running afl-fuzz for the C mutator, this will take approx 10 seconds"
{
- AFL_CUSTOM_MUTATOR_LIBRARY=./libexamplemutator.so AFL_CUSTOM_MUTATOR_ONLY=1 ../afl-fuzz -V07 -m ${MEM_LIMIT} -i in -o out -- ./test-custom-mutator >>errors 2>&1
+ AFL_CUSTOM_MUTATOR_LIBRARY=./libexamplemutator.so AFL_CUSTOM_MUTATOR_ONLY=1 ../afl-fuzz -V07 -m ${MEM_LIMIT} -i in -o out -d -- ./test-custom-mutator >>errors 2>&1
} >>errors 2>&1
# Check results
@@ -58,7 +58,7 @@ test -e test-custom-mutator.c -a -e ${CUSTOM_MUTATOR_PATH}/example.c -a -e ${CUS
# Run afl-fuzz w/ multiple C mutators
$ECHO "$GREY[*] running afl-fuzz with multiple custom C mutators, this will take approx 10 seconds"
{
- AFL_CUSTOM_MUTATOR_LIBRARY="./libexamplemutator.so;./libexamplemutator2.so" AFL_CUSTOM_MUTATOR_ONLY=1 ../afl-fuzz -V07 -m ${MEM_LIMIT} -i in -o out -- ./test-multiple-mutators >>errors 2>&1
+ AFL_CUSTOM_MUTATOR_LIBRARY="./libexamplemutator.so;./libexamplemutator2.so" AFL_CUSTOM_MUTATOR_ONLY=1 ../afl-fuzz -V07 -m ${MEM_LIMIT} -i in -o out -d -- ./test-multiple-mutators >>errors 2>&1
} >>errors 2>&1
test -n "$( ls out/default/crashes/id:000000* 2>/dev/null )" && { # TODO: update here
diff --git a/unicorn_mode/build_unicorn_support.sh b/unicorn_mode/build_unicorn_support.sh
index d3d16ad5..baca2171 100755
--- a/unicorn_mode/build_unicorn_support.sh
+++ b/unicorn_mode/build_unicorn_support.sh
@@ -14,7 +14,7 @@
#
#
# Copyright 2017 Battelle Memorial Institute. All rights reserved.
-# Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+# Copyright 2019-2024 AFLplusplus Project. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/utils/afl_network_proxy/afl-network-client.c b/utils/afl_network_proxy/afl-network-client.c
index 0416f0f9..1f04dd87 100644
--- a/utils/afl_network_proxy/afl-network-client.c
+++ b/utils/afl_network_proxy/afl-network-client.c
@@ -4,7 +4,7 @@
Written by Marc Heuse
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/utils/afl_network_proxy/afl-network-server.c b/utils/afl_network_proxy/afl-network-server.c
index 95b0a551..c4a700f4 100644
--- a/utils/afl_network_proxy/afl-network-server.c
+++ b/utils/afl_network_proxy/afl-network-server.c
@@ -12,7 +12,7 @@
Dominik Maier
Copyright 2016, 2017 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/utils/afl_proxy/afl-proxy.c b/utils/afl_proxy/afl-proxy.c
index 531a97a2..6cf47636 100644
--- a/utils/afl_proxy/afl-proxy.c
+++ b/utils/afl_proxy/afl-proxy.c
@@ -4,7 +4,7 @@
Written by Marc Heuse
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/utils/afl_untracer/afl-untracer.c b/utils/afl_untracer/afl-untracer.c
index 0e3f8a45..e6a74518 100644
--- a/utils/afl_untracer/afl-untracer.c
+++ b/utils/afl_untracer/afl-untracer.c
@@ -4,7 +4,7 @@
Written by Marc Heuse
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/utils/afl_untracer/libtestinstr.c b/utils/afl_untracer/libtestinstr.c
index b7afc325..0a98778a 100644
--- a/utils/afl_untracer/libtestinstr.c
+++ b/utils/afl_untracer/libtestinstr.c
@@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
diff --git a/utils/argv_fuzzing/Makefile b/utils/argv_fuzzing/Makefile
index 6786467a..ba977e5f 100644
--- a/utils/argv_fuzzing/Makefile
+++ b/utils/argv_fuzzing/Makefile
@@ -2,7 +2,7 @@
# american fuzzy lop++ - argvfuzz
# --------------------------------
#
-# Copyright 2019-2023 Kjell Braden