mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-14 11:08:06 +00:00
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>
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@ -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
|
||||
|
6
.gitmodules
vendored
6
.gitmodules
vendored
@ -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
|
||||
|
16
GNUmakefile
16
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"
|
||||
|
2
coresight_mode/.gitignore
vendored
Normal file
2
coresight_mode/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
.local
|
||||
glibc*
|
59
coresight_mode/GNUmakefile
Normal file
59
coresight_mode/GNUmakefile
Normal file
@ -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
|
21
coresight_mode/Makefile
Normal file
21
coresight_mode/Makefile
Normal file
@ -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
|
58
coresight_mode/README.md
Normal file
58
coresight_mode/README.md
Normal file
@ -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).
|
1
coresight_mode/coresight-trace
Submodule
1
coresight_mode/coresight-trace
Submodule
Submodule coresight_mode/coresight-trace added at ec0fd61047
1
coresight_mode/patchelf
Submodule
1
coresight_mode/patchelf
Submodule
Submodule coresight_mode/patchelf added at 7ec8edbe09
117
coresight_mode/patches/0001-Add-AFL-forkserver.patch
Normal file
117
coresight_mode/patches/0001-Add-AFL-forkserver.patch
Normal file
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user