aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkira Moroo <retrage01@gmail.com>2021-06-22 05:34:20 +0000
committerAkira Moroo <retrage01@gmail.com>2021-11-11 09:52:21 +0000
commit9100f3c416707d926fc100d4441cf32bb1da6dd6 (patch)
treebd0d24e3919acd56c48cda64f5266f5fb99585ef
parent26238516804a45636f8c675d492b048c32b82d31 (diff)
downloadafl++-9100f3c416707d926fc100d4441cf32bb1da6dd6.tar.gz
Add initial CoreSight mode support
The original code is: https://github.com/RICSecLab/AFLplusplus-cs/tree/retrage/coresight-mode-pr Signed-off-by: Akira Moroo <retrage01@gmail.com>
-rw-r--r--.gitignore3
-rw-r--r--.gitmodules6
-rw-r--r--GNUmakefile16
-rw-r--r--coresight_mode/.gitignore2
-rw-r--r--coresight_mode/GNUmakefile59
-rw-r--r--coresight_mode/Makefile21
-rw-r--r--coresight_mode/README.md58
m---------coresight_mode/coresight-trace0
m---------coresight_mode/patchelf0
-rw-r--r--coresight_mode/patches/0001-Add-AFL-forkserver.patch117
-rw-r--r--include/common.h1
-rw-r--r--include/forkserver.h2
-rw-r--r--src/afl-analyze.c18
-rw-r--r--src/afl-common.c29
-rw-r--r--src/afl-fuzz-init.c5
-rw-r--r--src/afl-fuzz-stats.c9
-rw-r--r--src/afl-fuzz.c28
-rw-r--r--src/afl-showmap.c22
-rw-r--r--src/afl-tmin.c16
19 files changed, 395 insertions, 17 deletions
diff --git a/.gitignore b/.gitignore
index 5268bb37..22ee6bf1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,6 +30,7 @@ afl-g++-fast
afl-gotcpu
afl-ld
afl-ld-lto
+afl-cs-proxy
afl-qemu-trace
afl-showmap
afl-tmin
@@ -94,3 +95,5 @@ utils/optimin/optimin
utils/persistent_mode/persistent_demo
utils/persistent_mode/persistent_demo_new
utils/persistent_mode/test-instr
+!coresight_mode
+!coresight_mode/coresight-trace
diff --git a/.gitmodules b/.gitmodules
index 200f3ecc..cd9d73e9 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -13,3 +13,9 @@
[submodule "utils/optimin/EvalMaxSAT"]
path = utils/optimin/EvalMaxSAT
url = https://github.com/FlorentAvellaneda/EvalMaxSAT
+[submodule "coresight_mode/patchelf"]
+ path = coresight_mode/patchelf
+ url = https://github.com/NixOS/patchelf.git
+[submodule "coresight_mode/coresight-trace"]
+ path = coresight_mode/coresight-trace
+ url = git@github.com:RICSecLab/coresight-trace.git
diff --git a/GNUmakefile b/GNUmakefile
index 06840786..ab57e7ad 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -346,7 +346,7 @@ help:
@echo "HELP --- the following make targets exist:"
@echo "=========================================="
@echo "all: just the main afl++ binaries"
- @echo "binary-only: everything for binary-only fuzzing: qemu_mode, unicorn_mode, libdislocator, libtokencap"
+ @echo "binary-only: everything for binary-only fuzzing: coresight_mode, qemu_mode, unicorn_mode, libdislocator, libtokencap"
@echo "source-only: everything for source code fuzzing: gcc_plugin, libdislocator, libtokencap"
@echo "distrib: everything (for both binary-only and source code fuzzing)"
@echo "man: creates simple man pages from the help option of the programs"
@@ -564,7 +564,7 @@ all_done: test_build
.PHONY: clean
clean:
- rm -rf $(PROGS) libradamsa.so afl-fuzz-document afl-as as afl-g++ afl-clang afl-clang++ *.o src/*.o *~ a.out core core.[1-9][0-9]* *.stackdump .test .test1 .test2 test-instr .test-instr0 .test-instr1 afl-qemu-trace afl-gcc-fast afl-gcc-pass.so afl-g++-fast ld *.so *.8 test/unittests/*.o test/unittests/unit_maybe_alloc test/unittests/preallocable .afl-* afl-gcc afl-g++ afl-clang afl-clang++ test/unittests/unit_hash test/unittests/unit_rand *.dSYM
+ rm -rf $(PROGS) libradamsa.so afl-fuzz-document afl-as as afl-g++ afl-clang afl-clang++ *.o src/*.o *~ a.out core core.[1-9][0-9]* *.stackdump .test .test1 .test2 test-instr .test-instr0 .test-instr1 afl-cs-proxy afl-qemu-trace afl-gcc-fast afl-gcc-pass.so afl-g++-fast ld *.so *.8 test/unittests/*.o test/unittests/unit_maybe_alloc test/unittests/preallocable .afl-* afl-gcc afl-g++ afl-clang afl-clang++ test/unittests/unit_hash test/unittests/unit_rand *.dSYM
-$(MAKE) -f GNUmakefile.llvm clean
-$(MAKE) -f GNUmakefile.gcc_plugin clean
$(MAKE) -C utils/libdislocator clean
@@ -579,19 +579,23 @@ clean:
$(MAKE) -C qemu_mode/libqasan clean
-$(MAKE) -C frida_mode clean
ifeq "$(IN_REPO)" "1"
+ -test -e coresight_mode/coresight-trace/Makefile && $(MAKE) -C coresight_mode/coresight-trace clean || true
-test -e qemu_mode/qemuafl/Makefile && $(MAKE) -C qemu_mode/qemuafl clean || true
test -e unicorn_mode/unicornafl/Makefile && $(MAKE) -C unicorn_mode/unicornafl clean || true
else
+ rm -rf coresight_mode/coresight_trace
rm -rf qemu_mode/qemuafl
rm -rf unicorn_mode/unicornafl
endif
.PHONY: deepclean
deepclean: clean
+ rm -rf coresight_mode/coresight-trace
rm -rf unicorn_mode/unicornafl
rm -rf qemu_mode/qemuafl
ifeq "$(IN_REPO)" "1"
# NEVER EVER ACTIVATE THAT!!!!! git reset --hard >/dev/null 2>&1 || true
+ git checkout coresight_mode/coresight-trace
git checkout unicorn_mode/unicornafl
git checkout qemu_mode/qemuafl
endif
@@ -610,6 +614,9 @@ endif
# -$(MAKE) -C utils/plot_ui
-$(MAKE) -C frida_mode
ifneq "$(SYS)" "Darwin"
+ifeq "$(ARCH)" "aarch64"
+ -$(MAKE) -C coresight_mode
+endif
-cd qemu_mode && sh ./build_qemu_support.sh
-cd unicorn_mode && unset CFLAGS && sh ./build_unicorn_support.sh
endif
@@ -624,6 +631,9 @@ binary-only: test_shm test_python ready $(PROGS)
# -$(MAKE) -C utils/plot_ui
-$(MAKE) -C frida_mode
ifneq "$(SYS)" "Darwin"
+ifeq "$(ARCH)" "aarch64"
+ -$(MAKE) -C coresight_mode
+endif
-cd qemu_mode && sh ./build_qemu_support.sh
-cd unicorn_mode && unset CFLAGS && sh ./build_unicorn_support.sh
endif
@@ -695,7 +705,7 @@ endif
.PHONY: uninstall
uninstall:
- -cd $${DESTDIR}$(BIN_PATH) && rm -f $(PROGS) $(SH_PROGS) afl-qemu-trace afl-plot-ui afl-fuzz-document afl-network-server afl-g* afl-plot.sh afl-as afl-ld-lto afl-c* afl-lto*
+ -cd $${DESTDIR}$(BIN_PATH) && rm -f $(PROGS) $(SH_PROGS) afl-cs-proxy afl-qemu-trace afl-plot-ui afl-fuzz-document afl-network-server afl-g* afl-plot.sh afl-as afl-ld-lto afl-c* afl-lto*
-cd $${DESTDIR}$(HELPER_PATH) && rm -f afl-g*.*o afl-llvm-*.*o afl-compiler-*.*o libdislocator.so libtokencap.so libcompcov.so libqasan.so afl-frida-trace.so socketfuzz*.so argvfuzz*.so libAFLDriver.a libAFLQemuDriver.a as afl-as SanitizerCoverage*.so compare-transform-pass.so cmplog-*-pass.so split-*-pass.so dynamic_list.txt
-rm -rf $${DESTDIR}$(MISC_PATH)/testcases $${DESTDIR}$(MISC_PATH)/dictionaries
-sh -c "ls docs/*.md | sed 's|^docs/|$${DESTDIR}$(DOC_PATH)/|' | xargs rm -f"
diff --git a/coresight_mode/.gitignore b/coresight_mode/.gitignore
new file mode 100644
index 00000000..dedb1613
--- /dev/null
+++ b/coresight_mode/.gitignore
@@ -0,0 +1,2 @@
+.local
+glibc*
diff --git a/coresight_mode/GNUmakefile b/coresight_mode/GNUmakefile
new file mode 100644
index 00000000..69b72f91
--- /dev/null
+++ b/coresight_mode/GNUmakefile
@@ -0,0 +1,59 @@
+#!/usr/bin/env make
+# SPDX-License-Identifier: Apache-2.0
+# Copyright 2021 Ricerca Security, Inc. All rights reserved.
+
+SHELL:=bash
+PREFIX?=$(shell pwd)/.local
+
+CS_TRACE:=coresight-trace
+
+PATCHELF?=$(PREFIX)/bin/patchelf
+
+GLIBC_VER:=2.33
+GLIBC_NAME:=glibc-$(GLIBC_VER)
+GLIBC_URL_BASE:=http://ftp.gnu.org/gnu/glibc
+GLIBC_PATCH:=patches/0002-glibc-Add-AFL-forkserver.patch
+GLIBC_LDSO?=$(PREFIX)/lib/ld-linux-aarch64.so.1
+
+OUTPUT?="$(TARGET).patched"
+
+all: build
+
+build:
+ git submodule update --init --recursive $(CS_TRACE)
+ $(MAKE) -C $(CS_TRACE)
+ cp $(CS_TRACE)/cs-proxy ../afl-cs-proxy
+
+patch: | $(PATCHELF) $(GLIBC_LDSO)
+ @if test -z "$(TARGET)"; then echo "TARGET is not set"; exit 1; fi
+ $(PATCHELF) \
+ --set-interpreter $(GLIBC_LDSO) \
+ --set-rpath $(dir $(GLIBC_LDSO)) \
+ --output $(OUTPUT) \
+ $(TARGET)
+
+$(PATCHELF): patchelf
+ git submodule update --init $<
+ cd $< && \
+ ./bootstrap.sh && \
+ ./configure --prefix=$(PREFIX) && \
+ $(MAKE) && \
+ $(MAKE) check && \
+ $(MAKE) install
+
+$(GLIBC_LDSO): | $(GLIBC_NAME).tar.xz
+ tar -xf $(GLIBC_NAME).tar.xz
+ patch -p1 < $(GLIBC_PATCH)
+ mkdir -p $(GLIBC_NAME)/build
+ cd $(GLIBC_NAME)/build && \
+ ../configure --prefix=$(PREFIX) && \
+ $(MAKE) && \
+ $(MAKE) install
+
+$(GLIBC_NAME).tar.xz:
+ wget -O $@ $(GLIBC_URL_BASE)/$@
+
+clean:
+ $(MAKE) -C $(CS_TRACE) clean
+
+.PHONY: all build patch clean
diff --git a/coresight_mode/Makefile b/coresight_mode/Makefile
new file mode 100644
index 00000000..fb8990b9
--- /dev/null
+++ b/coresight_mode/Makefile
@@ -0,0 +1,21 @@
+#!/usr/bin/env make
+# SPDX-License-Identifier: Apache-2.0
+# Copyright 2021 Ricerca Security, Inc. All rights reserved.
+
+all:
+ @echo trying to use GNU make...
+ @gmake all || echo please install GNUmake
+
+build:
+ @echo trying to use GNU make...
+ @gmake build || echo please install GNUmake
+
+patch:
+ @echo trying to use GNU make...
+ @gmake patch || echo please install GNUmake
+
+clean:
+ @echo trying to use GNU make...
+ @gmake clean || echo please install GNUmake
+
+.PHONY: all build patch clean
diff --git a/coresight_mode/README.md b/coresight_mode/README.md
new file mode 100644
index 00000000..e08421ed
--- /dev/null
+++ b/coresight_mode/README.md
@@ -0,0 +1,58 @@
+# AFL++ CoreSight mode
+
+CoreSight mode enables binary-only fuzzing on ARM64 Linux using CoreSight.
+
+NOTE: CoreSight mode is in the early development stage. Not applicable for production use.
+
+## Getting started
+
+Please read the [RICSec/coresight-trace README](https://github.com/RICSecLab/coresight-trace/blob/master/README.md) and check the prerequisites before getting started.
+
+CoreSight mode supports the AFL fork server mode to reduce `exec` system call overhead. To support it for binary-only fuzzing, it needs to modify the target ELF binary to re-link to the patched glibc. We employ this design from [PTrix](https://github.com/junxzm1990/afl-pt).
+
+Check out all the git submodules in the `cs_mode` directory:
+
+```bash
+git submodule update --init --recursive
+```
+
+### Build coresight-trace
+
+There are some notes on building coresight-trace. Refer to the [README](https://github.com/RICSecLab/coresight-trace/blob/master/README.md) for the details. Run make in the `cs_mode` directory:
+
+```bash
+make build
+```
+
+Make sure `cs-proxy` is placed in the AFL++ root directory as `afl-cs-proxy`.
+
+### Patch COTS binary
+
+The fork server mode requires patchelf and the patched glibc. The dependency build can be done by just run make:
+
+```bash
+make patch TARGET=$BIN
+```
+
+The above make command builds and installs the dependencies to `$PREFIX` (default to `$PWD/.local`) at the first time. Then, it runs `patchelf` to `$BIN` with output `$OUTPUT` (`$BIN.patched` by default).
+
+### Run afl-fuzz
+
+Run `afl-fuzz` with `-A` option to use CoreSight mode.
+
+```bash
+sudo afl-fuzz -A -i input -o output -- $OUTPUT @@
+```
+
+## Environment Variables
+
+There are AFL++ CoreSight mode-specific environment variables for run-time configuration.
+
+* `AFL_CS_CUSTOM_BIN` overrides the proxy application path. `afl-cs-proxy` will be used if not defined.
+
+* `AFLCS_COV` specifies coverage type on CoreSight trace decoding. `edge` and `path` is supported. The default value is `edge`.
+* `AFLCS_UDMABUF` is the u-dma-buf device number used to store trace data in the DMA region. The default value is `0`.
+
+## Acknowledgements
+
+This project has received funding from the Acquisition, Technology & Logistics Agency (ATLA) under the National Security Technology Research Promotion Fund 2021 (JPJ004596).
diff --git a/coresight_mode/coresight-trace b/coresight_mode/coresight-trace
new file mode 160000
+Subproject ec0fd6104720ac0b59967616363dc18209adc02
diff --git a/coresight_mode/patchelf b/coresight_mode/patchelf
new file mode 160000
+Subproject 7ec8edbe094ee13c91dadca191f92b9dfac8c0f
diff --git a/coresight_mode/patches/0001-Add-AFL-forkserver.patch b/coresight_mode/patches/0001-Add-AFL-forkserver.patch
new file mode 100644
index 00000000..51c242c4
--- /dev/null
+++ b/coresight_mode/patches/0001-Add-AFL-forkserver.patch
@@ -0,0 +1,117 @@
+diff --git a/glibc-2.33/elf/rtld.c b/glibc-2.33/elf/rtld.c
+index 596b6ac3..2ee270d4 100644
+--- a/glibc-2.33/elf/rtld.c
++++ b/glibc-2.33/elf/rtld.c
+@@ -169,6 +169,99 @@ uintptr_t __pointer_chk_guard_local
+ strong_alias (__pointer_chk_guard_local, __pointer_chk_guard)
+ #endif
+
++#define AFLCS_RTLD 1
++
++#if AFLCS_RTLD
++
++#include <sys/shm.h>
++#include <sys/types.h>
++#include <sys/wait.h>
++#include <dlfcn.h>
++#include <signal.h>
++
++#include <asm/unistd.h>
++#include <unistd.h>
++
++#define FORKSRV_FD 198
++
++#define AFLCS_ENABLE "__AFLCS_ENABLE"
++
++/* We use this additional AFLCS_# AFLCS_#+1 pair to communicate with proxy */
++#define AFLCS_FORKSRV_FD (FORKSRV_FD - 3)
++#define AFLCS_RTLD_SNIPPET do { __cs_start_forkserver(); } while(0)
++
++/* Fork server logic, invoked before we return from _dl_start. */
++
++static void __cs_start_forkserver(void) {
++ int status;
++ pid_t child_pid;
++ static char tmp[4] = {0, 0, 0, 0};
++
++ if (!getenv(AFLCS_ENABLE)) {
++ return;
++ }
++
++ if (write(AFLCS_FORKSRV_FD + 1, tmp, 4) != 4) {
++ _exit(-1);
++ }
++
++ /* All right, let's await orders... */
++ while (1) {
++ /* Whoops, parent dead? */
++ if (read(AFLCS_FORKSRV_FD, tmp, 4) != 4) {
++ _exit(1);
++ }
++
++ child_pid = INLINE_SYSCALL(clone, 5,
++ CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, 0,
++ NULL, NULL, &THREAD_SELF->tid);
++ if (child_pid < 0) {
++ _exit(4);
++ }
++ if (!child_pid) {
++ /* Child process. Wait for parent start tracing */
++ kill(getpid(), SIGSTOP);
++ /* Close descriptors and run free. */
++ close(AFLCS_FORKSRV_FD);
++ close(AFLCS_FORKSRV_FD + 1);
++ return;
++ }
++
++ /* Parent. */
++ if (write(AFLCS_FORKSRV_FD + 1, &child_pid, 4) != 4) {
++ _exit(5);
++ }
++
++ /* Wait until SIGCONT is signaled. */
++ if (waitpid(child_pid, &status, WCONTINUED) < 0) {
++ _exit(6);
++ }
++ if (!WIFCONTINUED(status)) {
++ /* Relay status to proxy. */
++ if (write(AFLCS_FORKSRV_FD + 1, &status, 4) != 4) {
++ _exit(7);
++ }
++ continue;
++ }
++ while (1) {
++ /* Get status. */
++ if (waitpid(child_pid, &status, WUNTRACED) < 0) {
++ _exit(8);
++ }
++ /* Relay status to proxy. */
++ if (write(AFLCS_FORKSRV_FD + 1, &status, 4) != 4) {
++ _exit(9);
++ }
++ if (!(WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP)) {
++ /* The child process is exited. */
++ break;
++ }
++ }
++ }
++}
++
++#endif /* AFLCS_RTLD */
++
+ /* Check that AT_SECURE=0, or that the passed name does not contain
+ directories and is not overly long. Reject empty names
+ unconditionally. */
+@@ -588,6 +681,12 @@ _dl_start (void *arg)
+ # define ELF_MACHINE_START_ADDRESS(map, start) (start)
+ #endif
+
++ /* AFL-CS-START */
++#if AFLCS_RTLD
++ AFLCS_RTLD_SNIPPET;
++#endif
++ /* AFL-CS-END */
++
+ return ELF_MACHINE_START_ADDRESS (GL(dl_ns)[LM_ID_BASE]._ns_loaded, entry);
+ }
+ }
diff --git a/include/common.h b/include/common.h
index e3997aa4..6c8e3b3a 100644
--- a/include/common.h
+++ b/include/common.h
@@ -46,6 +46,7 @@ void check_environment_vars(char **env);
char **argv_cpy_dup(int argc, char **argv);
void argv_cpy_free(char **argv);
+char **get_cs_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv);
char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv);
char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv);
char * get_afl_env(char *env);
diff --git a/include/forkserver.h b/include/forkserver.h
index 7af01cb2..464f208d 100644
--- a/include/forkserver.h
+++ b/include/forkserver.h
@@ -82,6 +82,8 @@ typedef struct afl_forkserver {
bool frida_asan; /* if running with asan in frida mode */
+ bool cs_mode; /* if running in CoreSight mode or not */
+
bool use_stdin; /* use stdin for sending data */
bool no_unlink; /* do not unlink cur_input */
diff --git a/src/afl-analyze.c b/src/afl-analyze.c
index d52a6d6e..c8b82428 100644
--- a/src/afl-analyze.c
+++ b/src/afl-analyze.c
@@ -77,6 +77,7 @@ static volatile u8 stop_soon; /* Ctrl-C pressed? */
static u8 *target_path;
static u8 frida_mode;
static u8 qemu_mode;
+static u8 cs_mode;
static u32 map_size = MAP_SIZE;
static afl_forkserver_t fsrv = {0}; /* The forkserver */
@@ -790,6 +791,8 @@ static void set_up_environment(char **argv) {
} else {
+ /* CoreSight mode uses the default behavior. */
+
setenv("LD_PRELOAD", getenv("AFL_PRELOAD"), 1);
setenv("DYLD_INSERT_LIBRARIES", getenv("AFL_PRELOAD"), 1);
@@ -845,6 +848,7 @@ static void usage(u8 *argv0) {
" -f file - input file read by the tested program (stdin)\n"
" -t msec - timeout for each run (%u ms)\n"
" -m megs - memory limit for child process (%u MB)\n"
+ " -A - use binary-only instrumentation (CoreSight mode)\n"
" -O - use binary-only instrumentation (FRIDA mode)\n"
" -Q - use binary-only instrumentation (QEMU mode)\n"
" -U - use unicorn-based instrumentation (Unicorn mode)\n"
@@ -890,7 +894,7 @@ int main(int argc, char **argv_orig, char **envp) {
afl_fsrv_init(&fsrv);
- while ((opt = getopt(argc, argv, "+i:f:m:t:eOQUWh")) > 0) {
+ while ((opt = getopt(argc, argv, "+i:f:m:t:eAOQUWh")) > 0) {
switch (opt) {
@@ -989,6 +993,14 @@ int main(int argc, char **argv_orig, char **envp) {
break;
+ case 'A': /* CoreSight mode */
+
+ if (cs_mode) { FATAL("Multiple -A options not supported"); }
+
+ cs_mode = 1;
+ fsrv.cs_mode = cs_mode;
+ break;
+
case 'O': /* FRIDA mode */
if (frida_mode) { FATAL("Multiple -O options not supported"); }
@@ -1080,6 +1092,10 @@ int main(int argc, char **argv_orig, char **envp) {
}
+ } else if (cs_mode) {
+
+ use_argv = get_cs_argv(argv[0], &target_path, argc - optind, argv + optind);
+
} else {
use_argv = argv + optind;
diff --git a/src/afl-common.c b/src/afl-common.c
index ec3b2f3f..6c2d0753 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -204,6 +204,35 @@ void argv_cpy_free(char **argv) {
}
+/* Rewrite argv for CoreSight process tracer. */
+
+char **get_cs_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) {
+
+ if (unlikely(getenv("AFL_CS_CUSTOM_BIN"))) {
+
+ WARNF(
+ "AFL_CS_CUSTOM_BIN is enabled. "
+ "You must run your target under afl-cs-proxy on your own!");
+ return argv;
+
+ }
+
+ char **new_argv = ck_alloc(sizeof(char *) * (argc + 4));
+ if (unlikely(!new_argv)) { FATAL("Illegal amount of arguments specified"); }
+
+ memcpy(&new_argv[3], &argv[1], (int)(sizeof(char *)) * (argc - 1));
+ new_argv[argc + 3] = NULL;
+
+ new_argv[2] = *target_path_p;
+ new_argv[1] = "--";
+
+ /* Now we need to actually find the cs-proxy binary to put in argv[0]. */
+
+ *target_path_p = new_argv[0] = find_afl_binary(own_loc, "afl-cs-proxy");
+ return new_argv;
+
+}
+
/* Rewrite argv for QEMU. */
char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) {
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index 9262d718..e5a4d3d1 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -2645,6 +2645,7 @@ void check_binary(afl_state_t *afl, u8 *fname) {
if (afl->afl_env.afl_skip_bin_check || afl->use_wine || afl->unicorn_mode ||
(afl->fsrv.qemu_mode && getenv("AFL_QEMU_CUSTOM_BIN")) ||
+ (afl->fsrv.cs_mode && getenv("AFL_CS_CUSTOM_BIN")) ||
afl->non_instrumented_mode) {
return;
@@ -2721,7 +2722,7 @@ void check_binary(afl_state_t *afl, u8 *fname) {
#endif /* ^!__APPLE__ */
if (!afl->fsrv.qemu_mode && !afl->fsrv.frida_mode && !afl->unicorn_mode &&
- !afl->non_instrumented_mode &&
+ !afl->fsrv.cs_mode && !afl->non_instrumented_mode &&
!memmem(f_data, f_len, SHM_ENV_VAR, strlen(SHM_ENV_VAR) + 1)) {
SAYF("\n" cLRD "[-] " cRST
@@ -2752,7 +2753,7 @@ void check_binary(afl_state_t *afl, u8 *fname) {
}
- if ((afl->fsrv.qemu_mode || afl->fsrv.frida_mode) &&
+ if ((afl->fsrv.cs_mode || afl->fsrv.qemu_mode || afl->fsrv.frida_mode) &&
memmem(f_data, f_len, SHM_ENV_VAR, strlen(SHM_ENV_VAR) + 1)) {
SAYF("\n" cLRD "[-] " cRST
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index 808bf258..426580d2 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -285,7 +285,7 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
"afl_banner : %s\n"
"afl_version : " VERSION
"\n"
- "target_mode : %s%s%s%s%s%s%s%s%s\n"
+ "target_mode : %s%s%s%s%s%s%s%s%s%s\n"
"command_line : %s\n",
(afl->start_time - afl->prev_run_time) / 1000, cur_time / 1000,
(afl->prev_run_time + cur_time - afl->start_time) / 1000,
@@ -321,12 +321,13 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
afl->q_testcase_cache_count, afl->q_testcase_evictions,
afl->use_banner, afl->unicorn_mode ? "unicorn" : "",
afl->fsrv.qemu_mode ? "qemu " : "",
+ afl->fsrv.cs_mode ? "coresight" : "",
afl->non_instrumented_mode ? " non_instrumented " : "",
afl->no_forkserver ? "no_fsrv " : "", afl->crash_mode ? "crash " : "",
afl->persistent_mode ? "persistent " : "",
afl->shmem_testcase_mode ? "shmem_testcase " : "",
afl->deferred_mode ? "deferred " : "",
- (afl->unicorn_mode || afl->fsrv.qemu_mode ||
+ (afl->unicorn_mode || afl->fsrv.qemu_mode || afl->fsrv.cs_mode ||
afl->non_instrumented_mode || afl->no_forkserver ||
afl->crash_mode || afl->persistent_mode || afl->deferred_mode)
? ""
@@ -1238,7 +1239,9 @@ void show_init_stats(afl_state_t *afl) {
// SAYF("\n");
- if (avg_us > ((afl->fsrv.qemu_mode || afl->unicorn_mode) ? 50000 : 10000)) {
+ if (avg_us > ((afl->fsrv.cs_mode || afl->fsrv.qemu_mode || afl->unicorn_mode)
+ ? 50000
+ : 10000)) {
WARNF(cLRD "The target binary is pretty slow! See %s/perf_tips.md.",
doc_path);
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index c08b8fbb..99eebfaa 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -113,6 +113,7 @@ static void usage(u8 *argv0, int more_help) {
"maximum.\n"
" -m megs - memory limit for child process (%u MB, 0 = no limit "
"[default])\n"
+ " -A - use binary-only instrumentation (CoreSight mode)\n"
" -O - use binary-only instrumentation (FRIDA mode)\n"
" -Q - use binary-only instrumentation (QEMU mode)\n"
" -U - use unicorn-based instrumentation (Unicorn mode)\n"
@@ -434,7 +435,8 @@ int main(int argc, char **argv_orig, char **envp) {
while ((opt = getopt(
argc, argv,
- "+b:B:c:CdDe:E:hi:I:f:F:l:L:m:M:nNOo:p:RQs:S:t:T:UV:Wx:Z")) > 0) {
+ "+Ab:B:c:CdDe:E:hi:I:f:F:l:L:m:M:nNOo:p:RQs:S:t:T:UV:Wx:Z")) >
+ 0) {
switch (opt) {
@@ -825,6 +827,13 @@ int main(int argc, char **argv_orig, char **envp) {
afl->use_banner = optarg;
break;
+ case 'A': /* CoreSight mode */
+
+ if (afl->fsrv.cs_mode) { FATAL("Multiple -A options not supported"); }
+ afl->fsrv.cs_mode = 1;
+
+ break;
+
case 'O': /* FRIDA mode */
if (afl->fsrv.frida_mode) {
@@ -1212,6 +1221,7 @@ int main(int argc, char **argv_orig, char **envp) {
if (afl->crash_mode) { FATAL("-C and -n are mutually exclusive"); }
if (afl->fsrv.frida_mode) { FATAL("-O and -n are mutually exclusive"); }
if (afl->fsrv.qemu_mode) { FATAL("-Q and -n are mutually exclusive"); }
+ if (afl->fsrv.cs_mode) { FATAL("-A and -n are mutually exclusive"); }
if (afl->unicorn_mode) { FATAL("-U and -n are mutually exclusive"); }
}
@@ -1458,6 +1468,8 @@ int main(int argc, char **argv_orig, char **envp) {
} else {
+ /* CoreSight mode uses the default behavior. */
+
setenv("LD_PRELOAD", getenv("AFL_PRELOAD"), 1);
setenv("DYLD_INSERT_LIBRARIES", getenv("AFL_PRELOAD"), 1);
@@ -1651,7 +1663,7 @@ int main(int argc, char **argv_orig, char **envp) {
}
- if (!afl->fsrv.qemu_mode && !afl->fsrv.frida_mode &&
+ if (!afl->fsrv.qemu_mode && !afl->fsrv.frida_mode && !afl->fsrv.cs_mode &&
!afl->non_instrumented_mode) {
check_binary(afl, afl->cmplog_binary);
@@ -1697,6 +1709,11 @@ int main(int argc, char **argv_orig, char **envp) {
}
+ } else if (afl->fsrv.cs_mode) {
+
+ use_argv = get_cs_argv(argv[0], &afl->fsrv.target_path, argc - optind,
+ argv + optind);
+
} else {
use_argv = argv + optind;
@@ -1704,7 +1721,7 @@ int main(int argc, char **argv_orig, char **envp) {
}
if (afl->non_instrumented_mode || afl->fsrv.qemu_mode ||
- afl->fsrv.frida_mode || afl->unicorn_mode) {
+ afl->fsrv.frida_mode || afl->fsrv.cs_mode || afl->unicorn_mode) {
map_size = afl->fsrv.real_map_size = afl->fsrv.map_size = MAP_SIZE;
afl->virgin_bits = ck_realloc(afl->virgin_bits, map_size);
@@ -1724,7 +1741,7 @@ int main(int argc, char **argv_orig, char **envp) {
afl_shm_init(&afl->shm, afl->fsrv.map_size, afl->non_instrumented_mode);
if (!afl->non_instrumented_mode && !afl->fsrv.qemu_mode &&
- !afl->unicorn_mode && !afl->fsrv.frida_mode &&
+ !afl->unicorn_mode && !afl->fsrv.frida_mode && !afl->fsrv.cs_mode &&
!afl->afl_env.afl_skip_bin_check) {
if (map_size <= DEFAULT_SHMEM_SIZE) {
@@ -1777,6 +1794,7 @@ int main(int argc, char **argv_orig, char **envp) {
afl_fsrv_init_dup(&afl->cmplog_fsrv, &afl->fsrv);
// TODO: this is semi-nice
afl->cmplog_fsrv.trace_bits = afl->fsrv.trace_bits;
+ afl->cmplog_fsrv.cs_mode = afl->fsrv.cs_mode;
afl->cmplog_fsrv.qemu_mode = afl->fsrv.qemu_mode;
afl->cmplog_fsrv.frida_mode = afl->fsrv.frida_mode;
afl->cmplog_fsrv.cmplog_binary = afl->cmplog_binary;
@@ -1785,7 +1803,7 @@ int main(int argc, char **argv_orig, char **envp) {
if ((map_size <= DEFAULT_SHMEM_SIZE ||
afl->cmplog_fsrv.map_size < map_size) &&
!afl->non_instrumented_mode && !afl->fsrv.qemu_mode &&
- !afl->fsrv.frida_mode && !afl->unicorn_mode &&
+ !afl->fsrv.frida_mode && !afl->unicorn_mode && !afl->fsrv.cs_mode &&
!afl->afl_env.afl_skip_bin_check) {
afl->cmplog_fsrv.map_size = MAX(map_size, (u32)DEFAULT_SHMEM_SIZE);
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index 6c06c476..daaed767 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -690,6 +690,8 @@ static void set_up_environment(afl_forkserver_t *fsrv, char **argv) {
} else {
+ /* CoreSight mode uses the default behavior. */
+
setenv("LD_PRELOAD", getenv("AFL_PRELOAD"), 1);
setenv("DYLD_INSERT_LIBRARIES", getenv("AFL_PRELOAD"), 1);
@@ -843,6 +845,7 @@ static void usage(u8 *argv0) {
" -t msec - timeout for each run (none)\n"
" -m megs - memory limit for child process (%u MB)\n"
" -O - use binary-only instrumentation (FRIDA mode)\n"
+ " -P - use binary-only instrumentation (CoreSight mode)\n"
" -Q - use binary-only instrumentation (QEMU mode)\n"
" -U - use Unicorn-based instrumentation (Unicorn mode)\n"
" -W - use qemu-based instrumentation with Wine (Wine mode)\n"
@@ -917,7 +920,7 @@ int main(int argc, char **argv_orig, char **envp) {
if (getenv("AFL_QUIET") != NULL) { be_quiet = true; }
- while ((opt = getopt(argc, argv, "+i:o:f:m:t:A:eqCZOQUWbcrsh")) > 0) {
+ while ((opt = getopt(argc, argv, "+i:o:f:m:t:A:eqCZOPQUWbcrsh")) > 0) {
switch (opt) {
@@ -1060,6 +1063,15 @@ int main(int argc, char **argv_orig, char **envp) {
break;
+ /* FIXME: We want to use -P for consistency, but it is already unsed for
+ * undocumenetd feature "Another afl-cmin specific feature." */
+ case 'P': /* CoreSight mode */
+
+ if (fsrv->cs_mode) { FATAL("Multiple -P options not supported"); }
+
+ fsrv->cs_mode = true;
+ break;
+
case 'Q':
if (fsrv->qemu_mode) { FATAL("Multiple -Q options not supported"); }
@@ -1124,6 +1136,7 @@ int main(int argc, char **argv_orig, char **envp) {
}
+ if (fsrv->cs_mode && !mem_limit_given) { fsrv->mem_limit = MEM_LIMIT; }
if (fsrv->qemu_mode && !mem_limit_given) { fsrv->mem_limit = MEM_LIMIT_QEMU; }
if (unicorn_mode && !mem_limit_given) { fsrv->mem_limit = MEM_LIMIT_UNICORN; }
@@ -1204,6 +1217,11 @@ int main(int argc, char **argv_orig, char **envp) {
}
+ } else if (fsrv->cs_mode) {
+
+ use_argv =
+ get_cs_argv(argv[0], &fsrv->target_path, argc - optind, argv + optind);
+
} else {
use_argv = argv + optind;
@@ -1230,7 +1248,7 @@ int main(int argc, char **argv_orig, char **envp) {
fsrv->shmem_fuzz_len = (u32 *)map;
fsrv->shmem_fuzz = map + sizeof(u32);
- if (!fsrv->qemu_mode && !unicorn_mode) {
+ if (!fsrv->cs_mode && !fsrv->qemu_mode && !unicorn_mode) {
u32 save_be_quiet = be_quiet;
be_quiet = !debug;
diff --git a/src/afl-tmin.c b/src/afl-tmin.c
index 3f6f14f9..212b6251 100644
--- a/src/afl-tmin.c
+++ b/src/afl-tmin.c
@@ -808,6 +808,8 @@ static void set_up_environment(afl_forkserver_t *fsrv, char **argv) {
} else {
+ /* CoreSight mode uses the default behavior. */
+
setenv("LD_PRELOAD", getenv("AFL_PRELOAD"), 1);
setenv("DYLD_INSERT_LIBRARIES", getenv("AFL_PRELOAD"), 1);
@@ -921,7 +923,7 @@ int main(int argc, char **argv_orig, char **envp) {
SAYF(cCYA "afl-tmin" VERSION cRST " by Michal Zalewski\n");
- while ((opt = getopt(argc, argv, "+i:o:f:m:t:B:xeOQUWHh")) > 0) {
+ while ((opt = getopt(argc, argv, "+i:o:f:m:t:B:xeAOQUWHh")) > 0) {
switch (opt) {
@@ -1033,6 +1035,13 @@ int main(int argc, char **argv_orig, char **envp) {
break;
+ case 'A': /* CoreSight mode */
+
+ if (fsrv->cs_mode) { FATAL("Multiple -A options not supported"); }
+
+ fsrv->cs_mode = 1;
+ break;
+
case 'O': /* FRIDA mode */
if (fsrv->frida_mode) { FATAL("Multiple -O options not supported"); }
@@ -1152,6 +1161,11 @@ int main(int argc, char **argv_orig, char **envp) {
}
+ } else if (fsrv->cs_mode) {
+
+ use_argv =
+ get_cs_argv(argv[0], &fsrv->target_path, argc - optind, argv + optind);
+
} else {
use_argv = argv + optind;