From dd9003e59b87b00c8e1ea62612c88599b7eaa14c Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 31 Jan 2022 09:00:01 +0100 Subject: nits for nyx build script --- nyx_mode/build_nyx_support.sh | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/nyx_mode/build_nyx_support.sh b/nyx_mode/build_nyx_support.sh index 3cb13cf1..8fa12ceb 100755 --- a/nyx_mode/build_nyx_support.sh +++ b/nyx_mode/build_nyx_support.sh @@ -13,6 +13,13 @@ if [ ! "`uname -s`" = "Linux" ]; then fi +if [ ! "`uname -m`" = "x86_64" ]; then + + echo "[-] Error: Nyx mode is only available on x86_64 (yet)." + exit 0 + +fi + echo "[*] Making sure all Nyx is checked out" git status 1>/dev/null 2>/dev/null @@ -34,9 +41,9 @@ else fi -test -d QEMU-Nyx/.git || { echo "[-] Not checked out, please install git or check your internet connection." ; exit 1 ; } -test -d packer/.git || { echo "[-] Not checked out, please install git or check your internet connection." ; exit 1 ; } -test -d libnyx/.git || { echo "[-] Not checked out, please install git or check your internet connection." ; exit 1 ; } +test -d packer/.git || { echo "[-] packer not checked out, please install git or check your internet connection." ; exit 1 ; } +test -d libnyx/.git || { echo "[-] libnyx not checked out, please install git or check your internet connection." ; exit 1 ; } +test -d 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 -- cgit 1.4.1 From 60e126c615a892b329d494ddcc5b84a8e560ca4b Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 31 Jan 2022 09:24:04 +0100 Subject: mention arm64 docker image --- Dockerfile | 4 +--- README.md | 8 ++++---- docs/INSTALL.md | 5 +++-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Dockerfile b/Dockerfile index 53189657..522e801a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,6 @@ # # This Dockerfile for AFLplusplus uses Ubuntu 20.04 focal and # installs LLVM 11 from llvm.org for afl-clang-lto support :-) -# It also installs gcc/g++ 10 from the Ubuntu development platform -# since focal has gcc-10 but not g++-10 ... # FROM ubuntu:20.04 AS aflplusplus @@ -77,6 +75,6 @@ RUN echo 'alias joe="joe --wordwrap --joe_state -nobackup"' >> ~/.bashrc RUN echo "export PS1='"'[afl++ \h] \w$(__git_ps1) \$ '"'" >> ~/.bashrc ENV IS_DOCKER="1" -# Disabled until we have the container ready +# Disabled as there are now better alternatives #COPY --from=aflplusplus/afl-dyninst /usr/local/lib/libdyninstAPI_RT.so /usr/local/lib/libdyninstAPI_RT.so #COPY --from=aflplusplus/afl-dyninst /afl-dyninst/libAflDyninst.so /usr/local/lib/libAflDyninst.so diff --git a/README.md b/README.md index af4c6abd..66b884e2 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ Here is some information to get you started: ## Building and installing AFL++ To have AFL++ easily available with everything compiled, pull the image directly -from the Docker Hub: +from the Docker Hub (available for x86_64 and arm64): ```shell docker pull aflplusplus/aflplusplus @@ -58,10 +58,10 @@ docker run -ti -v /location/of/your/target:/src aflplusplus/aflplusplus ``` This image is automatically generated when a push to the stable repo happens -(see [branches](#branches)). You will find your target source code in `/src` in -the container. +(see [branches](#branches)). If you use the command above, you will find your +target source code in `/src` in the container. -To build AFL++ yourself - which we recommend - continue at +To build AFL++ yourself - *which we recommend* - continue at [docs/INSTALL.md](docs/INSTALL.md). ## Quick start: Fuzzing with AFL++ diff --git a/docs/INSTALL.md b/docs/INSTALL.md index e2bc8420..b0090e77 100644 --- a/docs/INSTALL.md +++ b/docs/INSTALL.md @@ -3,8 +3,9 @@ ## 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-11 - -hence afl-clang-lto is available!) or just pull directly from the Docker Hub: +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): ```shell docker pull aflplusplus/aflplusplus -- cgit 1.4.1 From bb186a2ece40ae112e072dce195bf80cd8f41bec Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 1 Feb 2022 08:13:18 +0000 Subject: Bump FRIDA version --- frida_mode/GNUmakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frida_mode/GNUmakefile b/frida_mode/GNUmakefile index 010c12d9..cda9ab57 100644 --- a/frida_mode/GNUmakefile +++ b/frida_mode/GNUmakefile @@ -113,7 +113,7 @@ ifndef OS $(error "Operating system unsupported") endif -GUM_DEVKIT_VERSION=15.1.13 +GUM_DEVKIT_VERSION=15.1.15 GUM_DEVKIT_FILENAME=frida-gumjs-devkit-$(GUM_DEVKIT_VERSION)-$(OS)-$(ARCH).tar.xz GUM_DEVKIT_URL="https://github.com/frida/frida/releases/download/$(GUM_DEVKIT_VERSION)/$(GUM_DEVKIT_FILENAME)" -- cgit 1.4.1 From c38b05c80a51284b72e8dffb6fb1f703b237ff15 Mon Sep 17 00:00:00 2001 From: jon Date: Tue, 1 Feb 2022 08:13:28 +0000 Subject: Fixed build from source on OSX --- frida_mode/GNUmakefile | 130 ++++++++++++++++++++++++++++++------------------- 1 file changed, 80 insertions(+), 50 deletions(-) diff --git a/frida_mode/GNUmakefile b/frida_mode/GNUmakefile index cda9ab57..b96526f9 100644 --- a/frida_mode/GNUmakefile +++ b/frida_mode/GNUmakefile @@ -66,9 +66,12 @@ ifeq "$(ARCH)" "i686" endif endif +GUM_ARCH="-$(ARCH)" + ifeq "$(shell uname)" "Darwin" OS:=macos AFL_CFLAGS:=$(AFL_CFLAGS) -Wno-deprecated-declarations + GUM_ARCH:="" else ifdef DEBUG AFL_CFLAGS:=$(AFL_CFLAGS) -Wno-prio-ctor-dtor @@ -119,7 +122,7 @@ GUM_DEVKIT_URL="https://github.com/frida/frida/releases/download/$(GUM_DEVKIT_VE GUM_DEVKIT_TARBALL:=$(FRIDA_BUILD_DIR)$(GUM_DEVKIT_FILENAME) ifdef FRIDA_SOURCE -GUM_DEVIT_LIBRARY=$(FRIDA_DIR)build/frida-linux-$(ARCH)/lib/libfrida-gumjs-1.0.a +GUM_DEVIT_LIBRARY=$(FRIDA_DIR)build/frida-$(OS)-$(ARCH)/lib/libfrida-gumjs-1.0.a else GUM_DEVIT_LIBRARY=$(FRIDA_BUILD_DIR)libfrida-gumjs.a endif @@ -177,7 +180,7 @@ $(FRIDA_MAKEFILE): | $(BUILD_DIR) .PHONY: $(GUM_DEVIT_LIBRARY) $(GUM_DEVIT_LIBRARY): $(FRIDA_MAKEFILE) - cd $(FRIDA_DIR) && make gum-linux-$(ARCH) + cd $(FRIDA_DIR) && make gum-$(OS)$(GUM_ARCH) $(GUM_DEVIT_HEADER): $(FRIDA_MAKEFILE) | $(FRIDA_BUILD_DIR) echo "#include " > $@ @@ -189,62 +192,89 @@ $(GUM_DEVIT_HEADER): $(FRIDA_MAKEFILE) | $(FRIDA_BUILD_DIR) echo "#include " >> $@ echo "#include " >> $@ -ifeq "$(ARCH)" "arm64" - -CFLAGS+=-I $(FRIDA_DIR)build/frida_thin-linux-$(ARCH)/include/frida-1.0 \ - -I $(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/include/glib-2.0/ \ - -I $(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/glib-2.0/include/ \ - -I $(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/include/capstone/ \ - -I $(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/include/json-glib-1.0/ \ - -TRACE_LDFLAGS+=$(FRIDA_DIR)build/frida-linux-$(ARCH)/lib/libfrida-gum-1.0.a \ - $(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/libsoup-2.4.a \ - $(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/libsqlite3.a \ - $(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/libtcc.a \ - $(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/libjson-glib-1.0.a \ - $(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/libquickjs.a \ - $(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/libcapstone.a \ - $(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/libunwind-*.a \ - $(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/libunwind.a \ - $(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/libffi.a \ - $(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/libdwarf.a \ - $(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/libelf.a \ - $(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/libgio-2.0.a \ - $(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/libgobject-2.0.a \ - $(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/libglib-2.0.a \ - $(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/liblzma.a \ - $(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/libz.a \ +ifeq "$(OS)" "macos" + +CFLAGS+=-I $(FRIDA_DIR)build/frida-$(OS)-$(ARCH)/include/frida-1.0 \ + -I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/glib-2.0/ \ + -I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/glib-2.0/include/ \ + -I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/capstone/ \ + -I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/json-glib-1.0/ \ + +TRACE_LDFLAGS+=$(FRIDA_DIR)build/frida-$(OS)-$(ARCH)/lib/libfrida-gum-1.0.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libsoup-2.4.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libsqlite3.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libtcc.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libjson-glib-1.0.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libquickjs.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libcapstone.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libffi.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libgio-2.0.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libgobject-2.0.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libglib-2.0.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/liblzma.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libz.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libiconv.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libv8-8.0.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libgmodule-2.0.a \ + +else ifeq "$(ARCH)" "arm64" + +CFLAGS+=-I $(FRIDA_DIR)build/frida_thin-$(OS)-$(ARCH)/include/frida-1.0 \ + -I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/include/glib-2.0/ \ + -I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/glib-2.0/include/ \ + -I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/include/capstone/ \ + -I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/include/json-glib-1.0/ \ + +TRACE_LDFLAGS+=$(FRIDA_DIR)build/frida-$(OS)-$(ARCH)/lib/libfrida-gum-1.0.a \ + $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libsoup-2.4.a \ + $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libsqlite3.a \ + $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libtcc.a \ + $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libjson-glib-1.0.a \ + $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libquickjs.a \ + $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libcapstone.a \ + $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libunwind-*.a \ + $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libunwind.a \ + $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libffi.a \ + $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libdwarf.a \ + $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libelf.a \ + $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libgio-2.0.a \ + $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libgobject-2.0.a \ + $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libglib-2.0.a \ + $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/liblzma.a \ + $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libz.a \ else -CFLAGS+=-I $(FRIDA_DIR)build/frida-linux-$(ARCH)/include/frida-1.0 \ - -I $(FRIDA_DIR)build/sdk-linux-$(ARCH)/include/glib-2.0/ \ - -I $(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/glib-2.0/include/ \ - -I $(FRIDA_DIR)build/sdk-linux-$(ARCH)/include/capstone/ \ - -I $(FRIDA_DIR)build/sdk-linux-$(ARCH)/include/json-glib-1.0/ \ - -TRACE_LDFLAGS+=$(FRIDA_DIR)build/frida-linux-$(ARCH)/lib/libfrida-gum-1.0.a \ - $(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/libsoup-2.4.a \ - $(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/libsqlite3.a \ - $(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/libtcc.a \ - $(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/libjson-glib-1.0.a \ - $(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/libquickjs.a \ - $(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/libcapstone.a \ - $(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/libunwind-*.a \ - $(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/libunwind.a \ - $(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/libffi.a \ - $(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/libdwarf.a \ - $(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/libelf.a \ - $(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/libgio-2.0.a \ - $(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/libgobject-2.0.a \ - $(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/libglib-2.0.a \ - $(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/liblzma.a \ - $(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/libz.a \ +CFLAGS+=-I $(FRIDA_DIR)build/frida-$(OS)-$(ARCH)/include/frida-1.0 \ + -I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/glib-2.0/ \ + -I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/glib-2.0/include/ \ + -I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/capstone/ \ + -I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/json-glib-1.0/ \ + +TRACE_LDFLAGS+=$(FRIDA_DIR)build/frida-$(OS)-$(ARCH)/lib/libfrida-gum-1.0.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libsoup-2.4.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libsqlite3.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libtcc.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libjson-glib-1.0.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libquickjs.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libcapstone.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libunwind-*.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libunwind.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libffi.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libdwarf.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libelf.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libgio-2.0.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libgobject-2.0.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libglib-2.0.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/liblzma.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libz.a \ endif + + else $(GUM_DEVKIT_TARBALL): | $(FRIDA_BUILD_DIR) wget -O $@ $(GUM_DEVKIT_URL) || curl -L -o $@ $(GUM_DEVKIT_URL) -- cgit 1.4.1 From 1c79b82ab85da06686bd00f65099d7553d05a802 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 1 Feb 2022 08:13:28 +0000 Subject: Add AARCH64 support for setting ic_entries --- frida_mode/src/stalker.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frida_mode/src/stalker.c b/frida_mode/src/stalker.c index 3a421867..80e4e707 100644 --- a/frida_mode/src/stalker.c +++ b/frida_mode/src/stalker.c @@ -100,7 +100,7 @@ void stalker_init(void) { FOKF(cBLU "Stalker" cRST " - " cGRN "adjacent_blocks:" cYEL " [%u]", stalker_adjacent_blocks); -#if !(defined(__x86_64__) || defined(__i386__)) +#if !(defined(__x86_64__) || defined(__i386__) || defined(__aarch64__)) if (getenv("AFL_FRIDA_STALKER_IC_ENTRIES") != NULL) { FFATAL("AFL_FRIDA_STALKER_IC_ENTRIES not supported"); @@ -134,6 +134,9 @@ void stalker_init(void) { #if defined(__x86_64__) || defined(__i386__) stalker = g_object_new(GUM_TYPE_STALKER, "ic-entries", stalker_ic_entries, "adjacent-blocks", stalker_adjacent_blocks, NULL); +#elif defined(__aarch64__) + stalker = + g_object_new(GUM_TYPE_STALKER, "ic-entries", stalker_ic_entries, NULL); #else stalker = gum_stalker_new(); #endif -- cgit 1.4.1 From e2f76dd41e908d37caa6ab41bfe0f1c62f9b501f Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 1 Feb 2022 08:13:28 +0000 Subject: AARCH64 branch suppression --- frida_mode/src/instrument/instrument_arm64.c | 123 +++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/frida_mode/src/instrument/instrument_arm64.c b/frida_mode/src/instrument/instrument_arm64.c index 57b60317..e1dc2441 100644 --- a/frida_mode/src/instrument/instrument_arm64.c +++ b/frida_mode/src/instrument/instrument_arm64.c @@ -14,9 +14,12 @@ #define PAGE_MASK (~(GUM_ADDRESS(0xfff))) #define PAGE_ALIGNED(x) ((GUM_ADDRESS(x) & PAGE_MASK) == GUM_ADDRESS(x)) +#define GUM_RESTORATION_PROLOG_SIZE 4 #if defined(__aarch64__) +static GHashTable *coverage_blocks = NULL; + __attribute__((aligned(0x1000))) static guint8 area_ptr_dummy[MAP_SIZE]; #pragma pack(push, 1) @@ -120,6 +123,101 @@ gboolean instrument_is_coverage_optimize_supported(void) { } +static void instrument_coverage_switch(GumStalkerObserver *self, + gpointer start_address, + const cs_insn * from_insn, + gpointer * target) { + + UNUSED_PARAMETER(self); + UNUSED_PARAMETER(start_address); + + cs_arm64 * arm64; + arm64_cc cc; + gsize fixup_offset; + + if (from_insn == NULL) { return; } + + arm64 = &from_insn->detail->arm64; + cc = arm64->cc; + + if (!g_hash_table_contains(coverage_blocks, GSIZE_TO_POINTER(*target))) { + + return; + + } + + switch (from_insn->id) { + + case ARM64_INS_B: + case ARM64_INS_BL: + if (cc != ARM64_CC_INVALID) { return; } + break; + + case ARM64_INS_RET: + case ARM64_INS_RETAA: + case ARM64_INS_RETAB: + if (arm64->op_count != 0) { return; } + break; + default: + return; + + } + + /* + * Since each block is prefixed with a restoration prologue, we need to be + * able to begin execution at an offset into the block and execute both this + * restoration prologue and the instrumented block without the coverage code. + * We therefore layout our block as follows: + * + * +-----+--------------------------+------------------+-----+-------------+ + * | LDP | COVERAGE INSTRUMENTATION | BR | LDP | TARGET CODE | + * +-----+--------------------------+------------------+-----+-------------+ + * + * ^ ^ ^ ^ + * | | | | + * A B C D + * + * Without instrumentation suppression, the block is either executed at point + * (A) if it is reached by an indirect branch (and registers need to be + * restored) or point (B) if it is reached by an direct branch (and hence the + * registers don't need restoration). Similarly, we can start execution of the + * block at points (C) or (D) to achieve the same functionality, but without + * executing the coverage instrumentation. + * + * In either case, Stalker will call us back with the address of the target + * block to be executed as the destination. It is not until later that Stalker + * will determine which branch type is required given the location of its + * instrumented code and add the `GUM_RESTORATION_PROLOG_SIZE` to the target + * address. Therefore, we need to map the address of point (A) to that of + * point (C) and also ensure that the offset between (A)->(B) and (C)->(D) is + * identical so that if Stalker can use an immediate call, it still branches + * to a valid offset. + */ + fixup_offset = GUM_RESTORATION_PROLOG_SIZE + + G_STRUCT_OFFSET(afl_log_code_asm_t, restoration_prolog); + *target += fixup_offset; + +} + +static void instrument_coverage_suppress_init(void) { + + static gboolean initialized = false; + if (initialized) { return; } + initialized = true; + + GumStalkerObserver * observer = stalker_get_observer(); + GumStalkerObserverInterface *iface = GUM_STALKER_OBSERVER_GET_IFACE(observer); + iface->switch_callback = instrument_coverage_switch; + + coverage_blocks = g_hash_table_new(g_direct_hash, g_direct_equal); + if (coverage_blocks == NULL) { + + FATAL("Failed to g_hash_table_new, errno: %d", errno); + + } + +} + static gboolean instrument_coverage_in_range(gssize offset) { return (offset >= G_MININT33 && offset <= G_MAXINT33); @@ -151,6 +249,7 @@ void instrument_coverage_optimize(const cs_insn * instr, afl_log_code code = {0}; GumArm64Writer *cw = output->writer.arm64; + gpointer block_start; guint64 area_offset = instrument_get_offset_hash(GUM_ADDRESS(instr->address)); gsize map_size_pow2; gsize area_offset_ror; @@ -171,8 +270,32 @@ void instrument_coverage_optimize(const cs_insn * instr, // gum_arm64_writer_put_brk_imm(cw, 0x0); + instrument_coverage_suppress_init(); + code_addr = cw->pc; + /* + * On AARCH64, immediate branches can only be encoded with a 28-bit offset. To + * make a longer branch, it is necessary to load a register with the target + * address, this register must be saved beyond the red-zone before the branch + * is taken. To restore this register each block is prefixed by Stalker with + * an instruction to load x16,x17 from beyond the red-zone on the stack. A + * pair of registers are saved/restored because on AARCH64, the stack pointer + * must be 16 byte aligned. This instruction is emitted into the block before + * the tranformer (from which we are called) is executed. If is is possible + * for Stalker to make a direct branch (the target block is close enough), it + * can forego pushing the registers and instead branch at an offset into the + * block to skip this restoration prolog. + */ + block_start = + GSIZE_TO_POINTER(GUM_ADDRESS(cw->code) - GUM_RESTORATION_PROLOG_SIZE); + + if (!g_hash_table_add(coverage_blocks, block_start)) { + + FATAL("Failed - g_hash_table_add"); + + } + code.code = template; /* -- cgit 1.4.1 From 055af8202613e8dbaa288facdf159add10ffa593 Mon Sep 17 00:00:00 2001 From: jon Date: Tue, 1 Feb 2022 08:13:28 +0000 Subject: Make default coverage code branchless --- frida_mode/src/instrument/instrument_arm64.c | 95 +++++++++++++++------------- 1 file changed, 52 insertions(+), 43 deletions(-) diff --git a/frida_mode/src/instrument/instrument_arm64.c b/frida_mode/src/instrument/instrument_arm64.c index e1dc2441..1a704585 100644 --- a/frida_mode/src/instrument/instrument_arm64.c +++ b/frida_mode/src/instrument/instrument_arm64.c @@ -47,6 +47,9 @@ typedef struct { // b 0x7fb6f0dee4 // ldp x16, x17, [sp], #144 + uint32_t b_imm8; /* br #68 */ + uint32_t restoration_prolog; /* ldp x16, x17, [sp], #0x90 */ + uint32_t stp_x0_x1; /* stp x0, x1, [sp, #-0xa0] */ uint32_t adrp_x0_prev_loc1; /* adrp x0, #0xXXXX */ @@ -69,9 +72,6 @@ typedef struct { uint32_t ldp_x0_x1; /* ldp x0, x1, [sp, #-0xa0] */ - uint32_t b_imm8; /* br #8 */ - uint32_t restoration_prolog; /* ldp x16, x17, [sp], #0x90 */ - } afl_log_code_asm_t; #pragma pack(pop) @@ -86,6 +86,9 @@ typedef union { static const afl_log_code_asm_t template = { + .b_imm8 = 0x14000011, + + .restoration_prolog = 0xa8c947f0, .stp_x0_x1 = 0xa93607e0, .adrp_x0_prev_loc1 = 0x90000000, @@ -110,9 +113,6 @@ static const afl_log_code_asm_t template = .ldp_x0_x1 = 0xa97607e0, - .b_imm8 = 0x14000002, - .restoration_prolog = 0xa8c947f0, - } ; @@ -123,75 +123,84 @@ gboolean instrument_is_coverage_optimize_supported(void) { } -static void instrument_coverage_switch(GumStalkerObserver *self, - gpointer start_address, - const cs_insn * from_insn, - gpointer * target) { - - UNUSED_PARAMETER(self); - UNUSED_PARAMETER(start_address); +static gboolean instrument_is_deterministic(const cs_insn *from_insn) { - cs_arm64 * arm64; - arm64_cc cc; - gsize fixup_offset; + cs_arm64 *arm64; + arm64_cc cc; - if (from_insn == NULL) { return; } + if (from_insn == NULL) { return FALSE; } arm64 = &from_insn->detail->arm64; cc = arm64->cc; - if (!g_hash_table_contains(coverage_blocks, GSIZE_TO_POINTER(*target))) { - - return; - - } - switch (from_insn->id) { case ARM64_INS_B: case ARM64_INS_BL: - if (cc != ARM64_CC_INVALID) { return; } + if (cc == ARM64_CC_INVALID) { return TRUE; } break; case ARM64_INS_RET: case ARM64_INS_RETAA: case ARM64_INS_RETAB: - if (arm64->op_count != 0) { return; } + if (arm64->op_count == 0) { return TRUE; } break; default: - return; + return FALSE; } + return FALSE; + +} + +static void instrument_coverage_switch(GumStalkerObserver *self, + gpointer start_address, + const cs_insn * from_insn, + gpointer * target) { + + UNUSED_PARAMETER(self); + UNUSED_PARAMETER(start_address); + + gsize fixup_offset; + + if (!g_hash_table_contains(coverage_blocks, GSIZE_TO_POINTER(*target)) && + !g_hash_table_contains(coverage_blocks, GSIZE_TO_POINTER(*target + 4))) { + + return; + + } + + if (instrument_is_deterministic(from_insn)) { return; } + /* * Since each block is prefixed with a restoration prologue, we need to be * able to begin execution at an offset into the block and execute both this * restoration prologue and the instrumented block without the coverage code. * We therefore layout our block as follows: * - * +-----+--------------------------+------------------+-----+-------------+ - * | LDP | COVERAGE INSTRUMENTATION | BR | LDP | TARGET CODE | - * +-----+--------------------------+------------------+-----+-------------+ + * +-----+------------------+-----+--------------------------+-------------+ + * | LDP | BR | LDP | COVERAGE INSTRUMENTATION | TARGET CODE | + * +-----+------------------+-----+--------------------------+-------------+ * - * ^ ^ ^ ^ - * | | | | - * A B C D + * ^ ^ ^ ^ + * | | | | + * A B C D * * Without instrumentation suppression, the block is either executed at point - * (A) if it is reached by an indirect branch (and registers need to be - * restored) or point (B) if it is reached by an direct branch (and hence the + * (C) if it is reached by an indirect branch (and registers need to be + * restored) or point (D) if it is reached by an direct branch (and hence the * registers don't need restoration). Similarly, we can start execution of the - * block at points (C) or (D) to achieve the same functionality, but without + * block at points (A) or (B) to achieve the same functionality, but without * executing the coverage instrumentation. * * In either case, Stalker will call us back with the address of the target - * block to be executed as the destination. It is not until later that Stalker - * will determine which branch type is required given the location of its - * instrumented code and add the `GUM_RESTORATION_PROLOG_SIZE` to the target - * address. Therefore, we need to map the address of point (A) to that of - * point (C) and also ensure that the offset between (A)->(B) and (C)->(D) is - * identical so that if Stalker can use an immediate call, it still branches - * to a valid offset. + * block to be executed as the destination. We can then check if the branch is + * a deterministic one and if so branch to point (C) or (D) rather than (A) + * or (B). We lay the code out in this fashion so that in the event we can't + * suppress coverage (the most likely), we can vector directly to the coverage + * instrumentation code and execute entirely without any branches. If we + * suppress the coverage, we simply branch beyond it instead. */ fixup_offset = GUM_RESTORATION_PROLOG_SIZE + G_STRUCT_OFFSET(afl_log_code_asm_t, restoration_prolog); @@ -249,7 +258,7 @@ void instrument_coverage_optimize(const cs_insn * instr, afl_log_code code = {0}; GumArm64Writer *cw = output->writer.arm64; - gpointer block_start; + gpointer block_start; guint64 area_offset = instrument_get_offset_hash(GUM_ADDRESS(instr->address)); gsize map_size_pow2; gsize area_offset_ror; -- cgit 1.4.1 From 17fc44d995bd97e53cce4c30b167078b77d39862 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 1 Feb 2022 08:13:28 +0000 Subject: Fix libunwind libraries when building from source --- frida_mode/GNUmakefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/frida_mode/GNUmakefile b/frida_mode/GNUmakefile index b96526f9..0b5f52cb 100644 --- a/frida_mode/GNUmakefile +++ b/frida_mode/GNUmakefile @@ -232,7 +232,6 @@ TRACE_LDFLAGS+=$(FRIDA_DIR)build/frida-$(OS)-$(ARCH)/lib/libfrida-gum-1.0.a \ $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libjson-glib-1.0.a \ $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libquickjs.a \ $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libcapstone.a \ - $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libunwind-*.a \ $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libunwind.a \ $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libffi.a \ $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libdwarf.a \ @@ -258,7 +257,6 @@ TRACE_LDFLAGS+=$(FRIDA_DIR)build/frida-$(OS)-$(ARCH)/lib/libfrida-gum-1.0.a \ $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libjson-glib-1.0.a \ $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libquickjs.a \ $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libcapstone.a \ - $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libunwind-*.a \ $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libunwind.a \ $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libffi.a \ $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libdwarf.a \ -- cgit 1.4.1 From 5f6bbc7dea04cf3ef8fc37c9876e000fb35e9f86 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 1 Feb 2022 08:13:28 +0000 Subject: Changes to fix persistent_ret demo --- frida_mode/test/persistent_ret/testinstr.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/frida_mode/test/persistent_ret/testinstr.c b/frida_mode/test/persistent_ret/testinstr.c index d383c340..b2bc19ef 100644 --- a/frida_mode/test/persistent_ret/testinstr.c +++ b/frida_mode/test/persistent_ret/testinstr.c @@ -16,12 +16,6 @@ #include #include -#ifdef __APPLE__ - #define MAIN_SECTION -#else - #define MAIN_SECTION __attribute__((section(".main"))) -#endif - void LLVMFuzzerTestOneInput(char *buf, int len) { printf (">>> LLVMFuzzerTestOneInput >>>\n"); @@ -44,7 +38,7 @@ void slow() { } -MAIN_SECTION int main(int argc, char **argv) { +int main(int argc, char **argv) { char * file; int fd = -1; -- cgit 1.4.1 From 119a0e0dcebe93f8c3e7ca4d23429519aca317e2 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 1 Feb 2022 14:16:49 +0100 Subject: fix build scripts --- nyx_mode/build_nyx_support.sh | 6 +++--- qemu_mode/build_qemu_support.sh | 2 +- unicorn_mode/build_unicorn_support.sh | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/nyx_mode/build_nyx_support.sh b/nyx_mode/build_nyx_support.sh index 8fa12ceb..83e0ae32 100755 --- a/nyx_mode/build_nyx_support.sh +++ b/nyx_mode/build_nyx_support.sh @@ -41,9 +41,9 @@ else fi -test -d packer/.git || { echo "[-] packer not checked out, please install git or check your internet connection." ; exit 1 ; } -test -d libnyx/.git || { echo "[-] libnyx not checked out, please install git or check your internet connection." ; exit 1 ; } -test -d QEMU-Nyx/.git || { echo "[-] QEMU-Nyx not checked out, please install git or check your internet connection." ; exit 1 ; } +test -e packer/.git || { echo "[-] packer not checked out, please install git or check your internet connection." ; exit 1 ; } +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 diff --git a/qemu_mode/build_qemu_support.sh b/qemu_mode/build_qemu_support.sh index 8822770c..5dbd9d44 100755 --- a/qemu_mode/build_qemu_support.sh +++ b/qemu_mode/build_qemu_support.sh @@ -87,7 +87,7 @@ else } fi -test -d qemuafl/.git || { echo "[-] Not checked out, please install git or check your internet connection." ; exit 1 ; } +test -e qemuafl/.git || { echo "[-] Not checked out, please install git or check your internet connection." ; exit 1 ; } echo "[+] Got qemuafl." cd "qemuafl" || exit 1 diff --git a/unicorn_mode/build_unicorn_support.sh b/unicorn_mode/build_unicorn_support.sh index 80961599..a846fd1c 100755 --- a/unicorn_mode/build_unicorn_support.sh +++ b/unicorn_mode/build_unicorn_support.sh @@ -171,7 +171,7 @@ else } fi -test -d unicornafl/.git || { echo "[-] not checked out, please install git or check your internet connection." ; exit 1 ; } +test -e unicornafl/.git || { echo "[-] not checked out, please install git or check your internet connection." ; exit 1 ; } echo "[+] Got unicornafl." cd "unicornafl" || exit 1 -- cgit 1.4.1 From 7d366097226717edb20bb6f09c5eb39f30e88d85 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Tue, 1 Feb 2022 15:53:05 +0100 Subject: libafl custom mut readme --- custom_mutators/libafl_base/README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 custom_mutators/libafl_base/README.md diff --git a/custom_mutators/libafl_base/README.md b/custom_mutators/libafl_base/README.md new file mode 100644 index 00000000..0849e6da --- /dev/null +++ b/custom_mutators/libafl_base/README.md @@ -0,0 +1,10 @@ +# custum mutator: libafl basic havoc mutator + +This uses the libafl StdScheduledMutator with `havoc_mutations` and `token_mutations`. + +Make sure to have [cargo installed](https://rustup.rs/) and just type `make` to build. + +Run with: + +```AFL_CUSTOM_MUTATOR_LIBRARY=custom_mutators/libafl_base/libafl_base.so afl-fuzz ...``` +``` -- cgit 1.4.1 From 104c0e29e9dd72014f925e8e92d77d2b7779e9a3 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 1 Feb 2022 20:14:41 +0100 Subject: small doc update --- custom_mutators/libafl_base/README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/custom_mutators/libafl_base/README.md b/custom_mutators/libafl_base/README.md index 0849e6da..9f49260f 100644 --- a/custom_mutators/libafl_base/README.md +++ b/custom_mutators/libafl_base/README.md @@ -1,10 +1,11 @@ -# custum mutator: libafl basic havoc mutator +# libafl basic havoc + token mutator -This uses the libafl StdScheduledMutator with `havoc_mutations` and `token_mutations`. +This uses the [libafl](https://github.com/AFLplusplus/libafl) StdScheduledMutator with `havoc_mutations` and `token_mutations`. Make sure to have [cargo installed](https://rustup.rs/) and just type `make` to build. Run with: -```AFL_CUSTOM_MUTATOR_LIBRARY=custom_mutators/libafl_base/libafl_base.so afl-fuzz ...``` +``` +AFL_CUSTOM_MUTATOR_LIBRARY=custom_mutators/libafl_base/libafl_base.so AFL_CUSTOM_MUTATOR_ONLY=1 afl-fuzz ... ``` -- cgit 1.4.1 From 80543a809ec5a8f6bea45a5d20090a078daa6393 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 1 Feb 2022 20:15:45 +0100 Subject: small doc update --- docs/Changelog.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/Changelog.md b/docs/Changelog.md index a420dcc2..2f037c8e 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -11,7 +11,8 @@ sending a mail to . ### Version ++4.01a (dev) - fix */build_...sh scripts to work outside of git - new custom_mutator: libafl with token fuzzing :) - (still needs README) + - frida_mode: + - update to new frida release, handles now c++ throw/catch ### Version ++4.00c (release) -- cgit 1.4.1 From d4c01c057bb8e6741e6652567f168e9bdd00f9cd Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 4 Feb 2022 12:09:07 +0100 Subject: test support for forced persistent mode --- include/forkserver.h | 1 + src/afl-forkserver.c | 13 +++++++++---- src/afl-fuzz-init.c | 3 +-- src/afl-fuzz.c | 13 ++++++++++++- 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/include/forkserver.h b/include/forkserver.h index 01f45587..fd4d283c 100644 --- a/include/forkserver.h +++ b/include/forkserver.h @@ -162,6 +162,7 @@ typedef struct afl_forkserver { void (*add_extra_func)(void *afl_ptr, u8 *mem, u32 len); u8 kill_signal; + u8 persistent_mode; #ifdef __linux__ nyx_plugin_handler_t *nyx_handlers; diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index ce554170..fdaf7d0d 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -59,7 +59,11 @@ static list_t fsrv_list = {.element_prealloc_count = 0}; static void fsrv_exec_child(afl_forkserver_t *fsrv, char **argv) { - if (fsrv->qemu_mode) { setenv("AFL_DISABLE_LLVM_INSTRUMENTATION", "1", 0); } + if (fsrv->qemu_mode || fsrv->frida_mode || fsrv->cs_mode) { + + setenv("AFL_DISABLE_LLVM_INSTRUMENTATION", "1", 0); + + } execv(fsrv->target_path, argv); @@ -281,13 +285,13 @@ static void afl_fauxsrv_execv(afl_forkserver_t *fsrv, char **argv) { sigaction(SIGPIPE, &sa, NULL); signal(SIGCHLD, old_sigchld_handler); + // FORKSRV_FD is for communication with AFL, we don't need it in the - // child. + // child close(FORKSRV_FD); close(FORKSRV_FD + 1); - // TODO: exec... - + // finally: exec... execv(fsrv->target_path, argv); /* Use a distinctive bitmap signature to tell the parent about execv() @@ -567,6 +571,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, } + if (!be_quiet) { ACTF("Using AFL++ faux forkserver..."); } fsrv->init_child_func = afl_fauxsrv_execv; } diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 5449460e..9e74079b 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -2818,7 +2818,7 @@ void check_binary(afl_state_t *afl, u8 *fname) { OKF(cPIN "Persistent mode binary detected."); setenv(PERSIST_ENV_VAR, "1", 1); afl->persistent_mode = 1; - + afl->fsrv.persistent_mode = 1; afl->shmem_testcase_mode = 1; } else if (getenv("AFL_PERSISTENT")) { @@ -2830,7 +2830,6 @@ void check_binary(afl_state_t *afl, u8 *fname) { OKF("FRIDA Persistent mode configuration options detected."); setenv(PERSIST_ENV_VAR, "1", 1); afl->persistent_mode = 1; - afl->shmem_testcase_mode = 1; } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 9ef2669a..80059783 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -198,7 +198,7 @@ static void usage(u8 *argv0, int more_help) { " -I command - execute this command/script when a new crash is " "found\n" //" -B bitmap.txt - mutate a specific test case, use the - //out/default/fuzz_bitmap file\n" + // out/default/fuzz_bitmap file\n" " -C - crash exploration mode (the peruvian rabbit thing)\n" " -b cpu_id - bind the fuzzing process to the specified CPU core " "(0-...)\n" @@ -1897,6 +1897,17 @@ int main(int argc, char **argv_orig, char **envp) { check_binary(afl, argv[optind]); + if (getenv(PERSIST_ENV_VAR) && !afl->persistent_mode) { + + WARNF( + "Persistent mode environment variable detected, forcing persitent " + "mode!"); + afl->persistent_mode = 1; + afl->fsrv.persistent_mode = 1; + afl->shmem_testcase_mode = 1; + + } + #ifdef AFL_PERSISTENT_RECORD if (unlikely(afl->fsrv.persistent_record)) { -- cgit 1.4.1 From 1a89d428c9ec65653cc049d8106f1a7e329d7302 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 4 Feb 2022 12:12:23 +0100 Subject: same for defered forkserver --- src/afl-fuzz.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 80059783..c083c446 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1908,6 +1908,15 @@ int main(int argc, char **argv_orig, char **envp) { } + if (getenv(DEFER_ENV_VAR) && !afl->deferred_mode) { + + WARNF( + "Deferred forkserver mode environment variable detected, forcing " + "defered forkserver!"); + afl->deferred_mode = 1; + + } + #ifdef AFL_PERSISTENT_RECORD if (unlikely(afl->fsrv.persistent_record)) { -- cgit 1.4.1 From 9b72fe488062da33718fac2533891f862fb753fa Mon Sep 17 00:00:00 2001 From: hexcoder Date: Fri, 4 Feb 2022 13:59:11 +0100 Subject: typo --- docs/Changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Changelog.md b/docs/Changelog.md index 2f037c8e..94e854e4 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -60,7 +60,7 @@ sending a mail to . - fix bug where targets are not killed on timeouts - moved hidden afl-showmap -A option to -H to be used for coresight_mode - - Prevent accidentaly killing non-afl/fuzz services when aborting + - Prevent accidentally killing non-afl/fuzz services when aborting afl-showmap and other tools. - afl-cc: - detect overflow reads on initial input buffer for asan -- cgit 1.4.1 From 9eb66cccf4443e1ee7bcfe8f4e81c9836b39d834 Mon Sep 17 00:00:00 2001 From: hexcoder Date: Fri, 4 Feb 2022 15:06:53 +0100 Subject: typo --- src/afl-fuzz.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index c083c446..d8610df9 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1900,7 +1900,7 @@ int main(int argc, char **argv_orig, char **envp) { if (getenv(PERSIST_ENV_VAR) && !afl->persistent_mode) { WARNF( - "Persistent mode environment variable detected, forcing persitent " + "Persistent mode environment variable detected, forcing persistent " "mode!"); afl->persistent_mode = 1; afl->fsrv.persistent_mode = 1; -- cgit 1.4.1 From 04d693721bbfe181a8d1c6361d46baa74388e6f2 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sat, 5 Feb 2022 07:25:12 +0100 Subject: force persistent and deferred also for tools --- src/afl-common.c | 6 ++++-- src/afl-fuzz-init.c | 1 + src/afl-fuzz.c | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/afl-common.c b/src/afl-common.c index 7ba3bb74..e684302a 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -63,7 +63,8 @@ u32 check_binary_signatures(u8 *fn) { if (f_data == MAP_FAILED) { PFATAL("Unable to mmap file '%s'", fn); } close(fd); - if (memmem(f_data, f_len, PERSIST_SIG, strlen(PERSIST_SIG) + 1)) { + if (memmem(f_data, f_len, PERSIST_SIG, strlen(PERSIST_SIG) + 1) || + getenv(PERSIST_ENV_VAR)) { if (!be_quiet) { OKF(cPIN "Persistent mode binary detected."); } setenv(PERSIST_ENV_VAR, "1", 1); @@ -90,7 +91,8 @@ u32 check_binary_signatures(u8 *fn) { } - if (memmem(f_data, f_len, DEFER_SIG, strlen(DEFER_SIG) + 1)) { + if (memmem(f_data, f_len, DEFER_SIG, strlen(DEFER_SIG) + 1) || + getenv(DEFER_ENV_VAR)) { if (!be_quiet) { OKF(cPIN "Deferred forkserver binary detected."); } setenv(DEFER_ENV_VAR, "1", 1); diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 9e74079b..eb73b120 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -2830,6 +2830,7 @@ void check_binary(afl_state_t *afl, u8 *fname) { OKF("FRIDA Persistent mode configuration options detected."); setenv(PERSIST_ENV_VAR, "1", 1); afl->persistent_mode = 1; + afl->fsrv.persistent_mode = 1; afl->shmem_testcase_mode = 1; } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index d8610df9..7a74fc7e 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1912,7 +1912,7 @@ int main(int argc, char **argv_orig, char **envp) { WARNF( "Deferred forkserver mode environment variable detected, forcing " - "defered forkserver!"); + "deferred forkserver!"); afl->deferred_mode = 1; } -- cgit 1.4.1 From ce5032cc2949366260db12a7d52699b23ff9cda4 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sat, 5 Feb 2022 07:32:20 +0100 Subject: debug CI --- test/test-frida-mode.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test-frida-mode.sh b/test/test-frida-mode.sh index 501ef70a..59b8e307 100755 --- a/test/test-frida-mode.sh +++ b/test/test-frida-mode.sh @@ -22,7 +22,7 @@ test -e ../afl-frida-trace.so && { echo 00000 > in/in $ECHO "$GREY[*] running afl-fuzz for frida_mode, this will take approx 10 seconds" { - ../afl-fuzz -m ${MEM_LIMIT} -V10 -O -i in -o out -- ./test-instr >>errors 2>&1 + AFL_DEBUG=1 AFL_FRIDA_VERBOSE=1 ../afl-fuzz -m ${MEM_LIMIT} -V10 -O -i in -o out -- ./test-instr >>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 frida_mode" -- cgit 1.4.1 From d5b9cd4b73253c2fbbc7da88015ae0eac303eb32 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sat, 5 Feb 2022 08:27:17 +0100 Subject: add afl-fuzz -y fuzz length support --- docs/Changelog.md | 3 +++ include/afl-fuzz.h | 9 ++++++--- src/afl-fuzz-bitmap.c | 2 +- src/afl-fuzz-cmplog.c | 2 +- src/afl-fuzz-init.c | 5 ++--- src/afl-fuzz-mutators.c | 2 +- src/afl-fuzz-run.c | 35 +++++++++++++++++++++++++++++------ src/afl-fuzz-state.c | 2 ++ src/afl-fuzz.c | 42 ++++++++++++++++++++++++++++++++++++++++-- 9 files changed, 85 insertions(+), 17 deletions(-) diff --git a/docs/Changelog.md b/docs/Changelog.md index 94e854e4..153369b7 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -11,6 +11,9 @@ sending a mail to . ### Version ++4.01a (dev) - fix */build_...sh scripts to work outside of git - new custom_mutator: libafl with token fuzzing :) + - afl-fuzz: + - new commandline option -y to set min and max length of generated + fuzz inputs - frida_mode: - update to new frida release, handles now c++ throw/catch diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index e225211f..3712fc4f 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -726,6 +726,9 @@ typedef struct afl_state { /* queue entries ready for splicing count (len > 4) */ u32 ready_for_splicing_count; + /* min/max length for generated fuzzing inputs */ + u32 min_length, max_length; + /* This is the user specified maximum size to use for the testcase cache */ u64 q_testcase_max_cache_size; @@ -1090,12 +1093,12 @@ int statsd_format_metric(afl_state_t *afl, char *buff, size_t bufflen); /* Run */ -fsrv_run_result_t fuzz_run_target(afl_state_t *, afl_forkserver_t *fsrv, u32); -void write_to_testcase(afl_state_t *, void *, u32); -u8 calibrate_case(afl_state_t *, struct queue_entry *, u8 *, u32, u8); void sync_fuzzers(afl_state_t *); +u32 write_to_testcase(afl_state_t *, void *, u32, u32); +u8 calibrate_case(afl_state_t *, struct queue_entry *, u8 *, u32, u8); u8 trim_case(afl_state_t *, struct queue_entry *, u8 *); u8 common_fuzz_stuff(afl_state_t *, u8 *, u32); +fsrv_run_result_t fuzz_run_target(afl_state_t *, afl_forkserver_t *fsrv, u32); /* Fuzz one */ diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 8d044959..b963caf8 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -633,7 +633,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { if (afl->fsrv.exec_tmout < afl->hang_tmout) { u8 new_fault; - write_to_testcase(afl, mem, len); + len = write_to_testcase(afl, mem, len, 0); new_fault = fuzz_run_target(afl, &afl->fsrv, afl->hang_tmout); classify_counts(&afl->fsrv); diff --git a/src/afl-fuzz-cmplog.c b/src/afl-fuzz-cmplog.c index ce8f1a83..1a8052a0 100644 --- a/src/afl-fuzz-cmplog.c +++ b/src/afl-fuzz-cmplog.c @@ -49,7 +49,7 @@ u8 common_fuzz_cmplog_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { u8 fault; - write_to_testcase(afl, out_buf, len); + len = write_to_testcase(afl, out_buf, len, 0); fault = fuzz_run_target(afl, &afl->cmplog_fsrv, afl->fsrv.exec_tmout); diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index eb73b120..45f28d4b 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -617,11 +617,10 @@ void read_foreign_testcases(afl_state_t *afl, int first) { } - write_to_testcase(afl, mem, st.st_size); + u32 len = write_to_testcase(afl, mem, st.st_size, 1); fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout); afl->syncing_party = foreign_name; - afl->queued_imported += - save_if_interesting(afl, mem, st.st_size, fault); + afl->queued_imported += save_if_interesting(afl, mem, len, fault); afl->syncing_party = 0; munmap(mem, st.st_size); close(fd); diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index 51a43dbd..e78e2dc4 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -428,7 +428,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf, if (likely(retlen)) { - write_to_testcase(afl, retbuf, retlen); + retlen = write_to_testcase(afl, retbuf, retlen, 0); fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout); ++afl->trim_execs; diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index eaa82b19..5da0e583 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -73,8 +73,8 @@ fuzz_run_target(afl_state_t *afl, afl_forkserver_t *fsrv, u32 timeout) { old file is unlinked and a new one is created. Otherwise, afl->fsrv.out_fd is rewound and truncated. */ -void __attribute__((hot)) -write_to_testcase(afl_state_t *afl, void *mem, u32 len) { +u32 __attribute__((hot)) +write_to_testcase(afl_state_t *afl, void *mem, u32 len, u32 fix) { #ifdef _AFL_DOCUMENT_MUTATIONS s32 doc_fd; @@ -120,16 +120,39 @@ write_to_testcase(afl_state_t *afl, void *mem, u32 len) { }); + if (unlikely(new_size < afl->min_length && !fix)) { + + new_size = afl->min_length; + + } else if (unlikely(new_size > afl->max_length)) { + + new_size = afl->max_length; + + } + /* everything as planned. use the potentially new data. */ afl_fsrv_write_to_testcase(&afl->fsrv, new_mem, new_size); + len = new_size; } else { + if (unlikely(len < afl->min_length && !fix)) { + + len = afl->min_length; + + } else if (unlikely(len > afl->max_length)) { + + len = afl->max_length; + + } + /* boring uncustom. */ afl_fsrv_write_to_testcase(&afl->fsrv, mem, len); } + return len; + } /* The same, but with an adjustable gap. Used for trimming. */ @@ -346,7 +369,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, /* we need a dummy run if this is LTO + cmplog */ if (unlikely(afl->shm.cmplog_mode)) { - write_to_testcase(afl, use_mem, q->len); + (void)write_to_testcase(afl, use_mem, q->len, 1); fault = fuzz_run_target(afl, &afl->fsrv, use_tmout); @@ -389,7 +412,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, u64 cksum; - write_to_testcase(afl, use_mem, q->len); + (void)write_to_testcase(afl, use_mem, q->len, 1); fault = fuzz_run_target(afl, &afl->fsrv, use_tmout); @@ -700,7 +723,7 @@ void sync_fuzzers(afl_state_t *afl) { /* See what happens. We rely on save_if_interesting() to catch major errors and save the test case. */ - write_to_testcase(afl, mem, st.st_size); + (void)write_to_testcase(afl, mem, st.st_size, 1); fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout); @@ -943,7 +966,7 @@ common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { u8 fault; - write_to_testcase(afl, out_buf, len); + len = write_to_testcase(afl, out_buf, len, 0); fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout); diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 69ffa8cf..24bd28dd 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -102,6 +102,8 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->stats_avg_exec = 0; afl->skip_deterministic = 1; afl->cmplog_lvl = 2; + afl->min_length = 1; + afl->max_length = MAX_FILE; #ifndef NO_SPLICING afl->use_splicing = 1; #endif diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 7a74fc7e..6ca9be33 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -155,6 +155,9 @@ static void usage(u8 *argv0, int more_help) { "\n" "Mutator settings:\n" + " -y [min-]max - set minimum and maximum length of generated fuzzing " + "input.\n" + " default: 1-%lu\n" " -D - enable deterministic fuzzing (once per queue entry)\n" " -L minutes - use MOpt(imize) mode and set the time limit for " "entering the\n" @@ -204,7 +207,7 @@ static void usage(u8 *argv0, int more_help) { "(0-...)\n" " -e ext - file extension for the fuzz test input file (if " "needed)\n\n", - argv0, EXEC_TIMEOUT, MEM_LIMIT, FOREIGN_SYNCS_MAX); + argv0, EXEC_TIMEOUT, MEM_LIMIT, MAX_FILE, FOREIGN_SYNCS_MAX); if (more_help > 1) { @@ -529,11 +532,36 @@ int main(int argc, char **argv_orig, char **envp) { while ((opt = getopt( argc, argv, - "+Ab:B:c:CdDe:E:hi:I:f:F:l:L:m:M:nNOXYo:p:RQs:S:t:T:UV:Wx:Z")) > + "+Ab:B:c:CdDe:E:hi:I:f:F:l:L:m:M:nNOo:p:RQs:S:t:T:UV:WXx:Yy:Z")) > 0) { switch (opt) { + case 'y': { + + u8 *sep; + if (!(sep = strchr(optarg, '-')) && !(sep = strchr(optarg, ':'))) { + + afl->max_length = atoi(optarg); + + } else { + + afl->min_length = atoi(optarg); + afl->max_length = atoi(sep + 1); + + } + + if (afl->min_length < 1 || afl->max_length > MAX_FILE || + afl->min_length > afl->max_length) { + + FATAL("Illegal min/max length values: %s", optarg); + + } + + break; + + } + case 'Z': afl->old_seed_selection = 1; break; @@ -1622,6 +1650,16 @@ int main(int argc, char **argv_orig, char **envp) { } + OKF("Generating fuzz data with a a length of min=%u max=%u", afl->min_length, + afl->max_length); + u32 min_alloc = MAX(64U, afl->min_length); + afl_realloc(AFL_BUF_PARAM(in_scratch), min_alloc); + afl_realloc(AFL_BUF_PARAM(in), min_alloc); + afl_realloc(AFL_BUF_PARAM(out_scratch), min_alloc); + afl_realloc(AFL_BUF_PARAM(out), min_alloc); + afl_realloc(AFL_BUF_PARAM(eff), min_alloc); + afl_realloc(AFL_BUF_PARAM(ex), min_alloc); + afl->fsrv.use_fauxsrv = afl->non_instrumented_mode == 1 || afl->no_forkserver; #ifdef __linux__ -- cgit 1.4.1 From fa3c0d8a3756c1d80356690796877d94959f305c Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sat, 5 Feb 2022 10:36:37 +0100 Subject: change -y to -g/-G and add env var alternatives --- docs/env_variables.md | 4 ++++ include/envs.h | 2 ++ src/afl-fuzz-state.c | 14 ++++++++++++++ src/afl-fuzz.c | 43 ++++++++++++++----------------------------- 4 files changed, 34 insertions(+), 29 deletions(-) diff --git a/docs/env_variables.md b/docs/env_variables.md index 2a8fbcb7..f7ad4ff9 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -400,6 +400,10 @@ checks or alter some of the more exotic semantics of the tool: This makes the "own finds" counter in the UI more accurate. Beyond counter aesthetics, not much else should change. + - 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 + of fuzzing input generated. + - `AFL_KILL_SIGNAL`: Set the signal ID to be delivered to child processes on timeout. Unless you implement your own targets or instrumentation, you likely don't have to set it. By default, on timeout and on exit, `SIGKILL` diff --git a/include/envs.h b/include/envs.h index 3bacc380..538ea3a8 100644 --- a/include/envs.h +++ b/include/envs.h @@ -98,6 +98,8 @@ static char *afl_environment_variables[] = { "AFL_IGNORE_PROBLEMS", "AFL_IGNORE_UNKNOWN_ENVS", "AFL_IMPORT_FIRST", + "AFL_INPUT_LEN_MIN", + "AFL_INPUT_LEN_MAX", "AFL_INST_LIBS", "AFL_INST_RATIO", "AFL_KILL_SIGNAL", diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 24bd28dd..115e62de 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -482,6 +482,20 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_target_env = (u8 *)get_afl_env(afl_environment_variables[i]); + } else if (!strncmp(env, "AFL_INPUT_LEN_MIN", + + afl_environment_variable_len)) { + + afl->min_length = atoi( + (u8 *)get_afl_env(afl_environment_variables[i])); + + } else if (!strncmp(env, "AFL_INPUT_LEN_MAX", + + afl_environment_variable_len)) { + + afl->max_length = atoi( + (u8 *)get_afl_env(afl_environment_variables[i])); + } } else { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 6ca9be33..ffa991ae 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -155,9 +155,9 @@ static void usage(u8 *argv0, int more_help) { "\n" "Mutator settings:\n" - " -y [min-]max - set minimum and maximum length of generated fuzzing " - "input.\n" - " default: 1-%lu\n" + " -g minlength - set min length of generated fuzz input (default: 1)\n" + " -G minlength - set max length of generated fuzz input (default: " + "%lu)\n" " -D - enable deterministic fuzzing (once per queue entry)\n" " -L minutes - use MOpt(imize) mode and set the time limit for " "entering the\n" @@ -256,6 +256,7 @@ static void usage(u8 *argv0, int more_help) { "AFL_IGNORE_UNKNOWN_ENVS: don't warn on unknown env vars\n" "AFL_IGNORE_PROBLEMS: do not abort fuzzing if an incorrect setup is detected during a run\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_KILL_SIGNAL: Signal ID delivered to child processes on timeout, etc. (default: SIGKILL)\n" "AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n" " the target was compiled for\n" @@ -530,37 +531,21 @@ int main(int argc, char **argv_orig, char **envp) { afl->shmem_testcase_mode = 1; // we always try to perform shmem fuzzing - while ((opt = getopt( - argc, argv, - "+Ab:B:c:CdDe:E:hi:I:f:F:l:L:m:M:nNOo:p:RQs:S:t:T:UV:WXx:Yy:Z")) > - 0) { + while ( + (opt = getopt( + argc, argv, + "+Ab:B:c:CdDe:E:hi:I:f:F:g:G:l:L:m:M:nNOo:p:RQs:S:t:T:UV:WXx:YZ")) > + 0) { switch (opt) { - case 'y': { - - u8 *sep; - if (!(sep = strchr(optarg, '-')) && !(sep = strchr(optarg, ':'))) { - - afl->max_length = atoi(optarg); - - } else { - - afl->min_length = atoi(optarg); - afl->max_length = atoi(sep + 1); - - } - - if (afl->min_length < 1 || afl->max_length > MAX_FILE || - afl->min_length > afl->max_length) { - - FATAL("Illegal min/max length values: %s", optarg); - - } - + case 'g': + afl->min_length = atoi(optarg); break; - } + case 'G': + afl->max_length = atoi(optarg); + break; case 'Z': afl->old_seed_selection = 1; -- cgit 1.4.1 From 077a3e32e03ae3506a34394e7a53d5daaec909ce Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sat, 5 Feb 2022 10:57:58 +0100 Subject: fix accidental broken frida mode --- src/afl-forkserver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index fdaf7d0d..971edaa4 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -59,7 +59,7 @@ static list_t fsrv_list = {.element_prealloc_count = 0}; static void fsrv_exec_child(afl_forkserver_t *fsrv, char **argv) { - if (fsrv->qemu_mode || fsrv->frida_mode || fsrv->cs_mode) { + if (fsrv->qemu_mode || fsrv->cs_mode) { setenv("AFL_DISABLE_LLVM_INSTRUMENTATION", "1", 0); -- cgit 1.4.1 From d178b325ab76f07b78388f905dc14da24afd43b8 Mon Sep 17 00:00:00 2001 From: yuawn Date: Sun, 6 Feb 2022 05:34:44 +0000 Subject: fix -G description --- src/afl-fuzz.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index ffa991ae..7e3b3c94 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -156,7 +156,7 @@ static void usage(u8 *argv0, int more_help) { "Mutator settings:\n" " -g minlength - set min length of generated fuzz input (default: 1)\n" - " -G minlength - set max length of generated fuzz input (default: " + " -G maxlength - set max length of generated fuzz input (default: " "%lu)\n" " -D - enable deterministic fuzzing (once per queue entry)\n" " -L minutes - use MOpt(imize) mode and set the time limit for " -- cgit 1.4.1 From 958a0594772fb69f9d61283cbb56695b2956e6dd Mon Sep 17 00:00:00 2001 From: yuawn Date: Sun, 6 Feb 2022 08:54:14 +0000 Subject: add GCC hot attribute to hot functions --- src/afl-forkserver.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 971edaa4..310d3643 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -1270,7 +1270,7 @@ u32 afl_fsrv_get_mapsize(afl_forkserver_t *fsrv, char **argv, /* Delete the current testcase and write the buf to the testcase file */ -void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) { +void __attribute__((hot)) afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) { #ifdef __linux__ if (unlikely(fsrv->nyx_mode)) { @@ -1388,8 +1388,8 @@ void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) { /* Execute target application, monitoring for timeouts. Return status information. The called program will update afl->fsrv->trace_bits. */ -fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, - volatile u8 *stop_soon_p) { +fsrv_run_result_t __attribute__((hot)) afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, + volatile u8 *stop_soon_p) { s32 res; u32 exec_ms; -- cgit 1.4.1 From bcd802e6fd9a15a6f39a89a862fb39de281dabd6 Mon Sep 17 00:00:00 2001 From: yuawn Date: Sun, 6 Feb 2022 08:54:30 +0000 Subject: code format --- src/afl-forkserver.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 310d3643..8997781d 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -1270,7 +1270,8 @@ u32 afl_fsrv_get_mapsize(afl_forkserver_t *fsrv, char **argv, /* Delete the current testcase and write the buf to the testcase file */ -void __attribute__((hot)) afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) { +void __attribute__((hot)) +afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) { #ifdef __linux__ if (unlikely(fsrv->nyx_mode)) { @@ -1388,7 +1389,8 @@ void __attribute__((hot)) afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 /* Execute target application, monitoring for timeouts. Return status information. The called program will update afl->fsrv->trace_bits. */ -fsrv_run_result_t __attribute__((hot)) afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, +fsrv_run_result_t __attribute__((hot)) +afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, volatile u8 *stop_soon_p) { s32 res; -- cgit 1.4.1 From a5dc0673317b32aee68e773e2c4f86190092b373 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 7 Feb 2022 12:22:57 +0100 Subject: nits --- docs/Changelog.md | 2 +- nyx_mode/README.md | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/Changelog.md b/docs/Changelog.md index 153369b7..bdb2dda3 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -12,7 +12,7 @@ sending a mail to . - fix */build_...sh scripts to work outside of git - new custom_mutator: libafl with token fuzzing :) - afl-fuzz: - - new commandline option -y to set min and max length of generated + - new commandline options -g/G to set min/max length of generated fuzz inputs - frida_mode: - update to new frida release, handles now c++ throw/catch diff --git a/nyx_mode/README.md b/nyx_mode/README.md index 09421f27..1afedd9b 100644 --- a/nyx_mode/README.md +++ b/nyx_mode/README.md @@ -114,6 +114,14 @@ afl-fuzz -i in -o out -Y -S 1 -- ./PACKAGE-DIRECTORY afl-fuzz -i in -o out -Y -S 2 -- ./PACKAGE-DIRECTORY ``` +## AFL++ companion tools (afl-showmap etc.) + +Please note that AFL++ companion tools like afl-cmin, afl-showmap, etc. are +not supported with Nyx mode, only afl-fuzz. + +For source based instrumentation just use these tools normally, for +binary-only targets use with -Q for qemu_mode. + ## Real-world examples ### Fuzzing libxml2 with AFL++ in Nyx-mode -- cgit 1.4.1 From 452eb9f75bd37954f3944e4391c3b11663668583 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 8 Feb 2022 08:58:35 +0000 Subject: Fix initialization in non-persistent mode --- frida_mode/src/entry.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/frida_mode/src/entry.c b/frida_mode/src/entry.c index 995f765f..5d9bcaaf 100644 --- a/frida_mode/src/entry.c +++ b/frida_mode/src/entry.c @@ -78,6 +78,12 @@ void entry_init(void) { void entry_start(void) { + if (persistent_start == 0) { + + ranges_exclude(); + stalker_trust(); + + } if (entry_point == 0) { entry_launch(); } } -- cgit 1.4.1 From 64cc345ec2f78cf7542536fc86e201e44f9f946f Mon Sep 17 00:00:00 2001 From: David Carlier Date: Tue, 8 Feb 2022 10:46:54 +0000 Subject: afl-system-config update proposal for OpenBSD. The vast majority of security features can t be disabled but we can act of allocation config. --- afl-system-config | 3 +++ 1 file changed, 3 insertions(+) diff --git a/afl-system-config b/afl-system-config index b222b2ad..ef343704 100755 --- a/afl-system-config +++ b/afl-system-config @@ -76,6 +76,9 @@ EOF DONE=1 fi if [ "$PLATFORM" = "OpenBSD" ] ; then + doas sysctl vm.malloc_conf= + echo 'Freecheck on allocation in particular can be detrimental to performance.' + echo 'Also we might not want necessarily to abort at any allocation failure.' echo 'System security features cannot be disabled on OpenBSD.' echo DONE=1 -- cgit 1.4.1 From 05a36f10ba99a461647a41433f199dd4ebc95e57 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 8 Feb 2022 18:33:59 +0100 Subject: import mozilla afl-cc patch --- instrumentation/afl-compiler-rt.o.c | 25 +++++----- src/afl-cc.c | 93 ++++++++++++++++++++++++------------- 2 files changed, 72 insertions(+), 46 deletions(-) diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index 59839750..9a12831e 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -282,11 +282,9 @@ static void __afl_map_shm(void) { char *id_str = getenv(SHM_ENV_VAR); - if (__afl_final_loc) { ++__afl_final_loc; } // as we count starting 0 - if (__afl_final_loc) { - __afl_map_size = __afl_final_loc; + __afl_map_size = ++__afl_final_loc; // as we count starting 0 if (__afl_final_loc > MAP_SIZE) { @@ -333,14 +331,14 @@ static void __afl_map_shm(void) { if (__afl_debug) { - fprintf(stderr, - "DEBUG: (1) id_str %s, __afl_area_ptr %p, __afl_area_initial %p, " - "__afl_area_ptr_dummy %p, __afl_map_addr 0x%llx, MAP_SIZE %u, " - "__afl_final_loc %u, " - "max_size_forkserver %u/0x%x\n", - id_str == NULL ? "" : id_str, __afl_area_ptr, - __afl_area_initial, __afl_area_ptr_dummy, __afl_map_addr, MAP_SIZE, - __afl_final_loc, FS_OPT_MAX_MAPSIZE, FS_OPT_MAX_MAPSIZE); + fprintf( + stderr, + "DEBUG: (1) id_str %s, __afl_area_ptr %p, __afl_area_initial %p, " + "__afl_area_ptr_dummy %p, __afl_map_addr 0x%llx, MAP_SIZE %u, " + "__afl_final_loc %u, __afl_map_size %u, max_size_forkserver %u/0x%x\n", + id_str == NULL ? "" : id_str, __afl_area_ptr, __afl_area_initial, + __afl_area_ptr_dummy, __afl_map_addr, MAP_SIZE, __afl_final_loc, + __afl_map_size, FS_OPT_MAX_MAPSIZE, FS_OPT_MAX_MAPSIZE); } @@ -487,11 +485,12 @@ static void __afl_map_shm(void) { fprintf(stderr, "DEBUG: (2) id_str %s, __afl_area_ptr %p, __afl_area_initial %p, " "__afl_area_ptr_dummy %p, __afl_map_addr 0x%llx, MAP_SIZE " - "%u, __afl_final_loc %u, " + "%u, __afl_final_loc %u, __afl_map_size %u," "max_size_forkserver %u/0x%x\n", id_str == NULL ? "" : id_str, __afl_area_ptr, __afl_area_initial, __afl_area_ptr_dummy, __afl_map_addr, MAP_SIZE, - __afl_final_loc, FS_OPT_MAX_MAPSIZE, FS_OPT_MAX_MAPSIZE); + __afl_final_loc, __afl_map_size, FS_OPT_MAX_MAPSIZE, + FS_OPT_MAX_MAPSIZE); } diff --git a/src/afl-cc.c b/src/afl-cc.c index 9197c74b..1f28b1f9 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -315,7 +315,7 @@ 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; + have_c = 0, partial_linking = 0, wasm_linking = 0; cc_params = ck_alloc((argc + 128) * sizeof(u8 *)); @@ -671,22 +671,6 @@ static void edit_params(u32 argc, char **argv, char **envp) { // cc_params[cc_par_cnt++] = "-Qunused-arguments"; - // 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++] = "-rpath"; - cc_params[cc_par_cnt++] = libdir; - - } else { - - free(libdir); - - } - if (lto_mode && argc > 1) { u32 idx; @@ -766,14 +750,21 @@ static void edit_params(u32 argc, char **argv, char **envp) { u8 *afllib = find_object("libAFLDriver.a", argv[0]); - if (!be_quiet) + if (!be_quiet) { + OKF("Found '-fsanitize=fuzzer', replacing with libAFLDriver.a"); + } + if (!afllib) { - WARNF( - "Cannot find 'libAFLDriver.a' to replace '-fsanitize=fuzzer' in " - "the flags - this will fail!"); + if (!be_quiet) { + + WARNF( + "Cannot find 'libAFLDriver.a' to replace '-fsanitize=fuzzer' in " + "the flags - this will fail!"); + + } } else { @@ -805,6 +796,13 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (!strcmp(cur, "-x")) x_set = 1; if (!strcmp(cur, "-E")) preprocessor_only = 1; if (!strcmp(cur, "-shared")) shared_linking = 1; + if (!strcmp(cur, "--target=wasm32-wasi")) { + + if (!be_quiet) { WARNF("Found '%s'!", cur); } + wasm_linking = 1; + + } + if (!strcmp(cur, "-dynamiclib")) shared_linking = 1; if (!strcmp(cur, "-Wl,-r")) partial_linking = 1; if (!strcmp(cur, "-Wl,-i")) partial_linking = 1; @@ -820,6 +818,22 @@ static void edit_params(u32 argc, char **argv, char **envp) { } + // 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 && !wasm_linking && strlen(libdir) && + strncmp(libdir, "/usr", 4) && strncmp(libdir, "/lib", 4)) { + + cc_params[cc_par_cnt++] = "-rpath"; + cc_params[cc_par_cnt++] = libdir; + + } else { + + free(libdir); + + } + if (getenv("AFL_HARDEN")) { cc_params[cc_par_cnt++] = "-fstack-protector-all"; @@ -1056,7 +1070,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { switch (bit_mode) { case 0: - if (!shared_linking && !partial_linking) + if (!shared_linking && !partial_linking && !wasm_linking) cc_params[cc_par_cnt++] = alloc_printf("%s/afl-compiler-rt.o", obj_path); if (lto_mode) @@ -1065,7 +1079,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { break; case 32: - if (!shared_linking && !partial_linking) { + if (!shared_linking && !partial_linking && !wasm_linking) { cc_params[cc_par_cnt++] = alloc_printf("%s/afl-compiler-rt-32.o", obj_path); @@ -1086,7 +1100,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { break; case 64: - if (!shared_linking && !partial_linking) { + if (!shared_linking && !partial_linking && !wasm_linking) { cc_params[cc_par_cnt++] = alloc_printf("%s/afl-compiler-rt-64.o", obj_path); @@ -1109,7 +1123,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { } #if !defined(__APPLE__) && !defined(__sun) - if (!shared_linking && !partial_linking) + if (!shared_linking && !partial_linking && !wasm_linking) cc_params[cc_par_cnt++] = alloc_printf("-Wl,--dynamic-list=%s/dynamic_list.txt", obj_path); #endif @@ -1248,10 +1262,14 @@ int main(int argc, char **argv, char **envp) { if (compiler_mode) { - WARNF( - "\"AFL_CC_COMPILER\" is set but a specific compiler was already " - "selected by command line parameter or symlink, ignoring the " - "environment variable!"); + if (!be_quiet) { + + WARNF( + "\"AFL_CC_COMPILER\" is set but a specific compiler was already " + "selected by command line parameter or symlink, ignoring the " + "environment variable!"); + + } } else { @@ -1304,11 +1322,14 @@ int main(int argc, char **argv, char **envp) { } - if (compiler_mode) + if (compiler_mode && !be_quiet) { + WARNF( "--afl-... compiler mode supersedes the AFL_CC_COMPILER and " "symlink compiler selection!"); + } + ptr = argv[i]; ptr += 5; while (*ptr == '-') @@ -1390,7 +1411,7 @@ int main(int argc, char **argv, char **envp) { } - if (have_instr_env && getenv("AFL_DONT_OPTIMIZE")) { + if (have_instr_env && getenv("AFL_DONT_OPTIMIZE") && !be_quiet) { WARNF( "AFL_LLVM_ALLOWLIST/DENYLIST and AFL_DONT_OPTIMIZE cannot be combined " @@ -1970,10 +1991,13 @@ int main(int argc, char **argv, char **envp) { } else { - if (!be_quiet) + if (!be_quiet) { + WARNF("afl-clang-lto called with mode %s, using that mode instead", instrument_mode_string[instrument_mode]); + } + } } @@ -1985,11 +2009,14 @@ int main(int argc, char **argv, char **envp) { if (have_instr_env) { instrument_mode = INSTRUMENT_AFL; - if (!be_quiet) + if (!be_quiet) { + WARNF( "Switching to classic instrumentation because " "AFL_LLVM_ALLOWLIST/DENYLIST does not work with PCGUARD < 10.0.1."); + } + } else #endif -- cgit 1.4.1 From fa628865c1d3b8d0cc4bc04efc516fc7b48b6a69 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 8 Feb 2022 18:43:23 +0100 Subject: remove debug msg --- src/afl-cc.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/afl-cc.c b/src/afl-cc.c index 1f28b1f9..2d7e3d91 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -796,14 +796,8 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (!strcmp(cur, "-x")) x_set = 1; if (!strcmp(cur, "-E")) preprocessor_only = 1; if (!strcmp(cur, "-shared")) shared_linking = 1; - if (!strcmp(cur, "--target=wasm32-wasi")) { - - if (!be_quiet) { WARNF("Found '%s'!", cur); } - wasm_linking = 1; - - } - if (!strcmp(cur, "-dynamiclib")) shared_linking = 1; + if (!strcmp(cur, "--target=wasm32-wasi")) wasm_linking = 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; -- cgit 1.4.1 From cf853fb2494912a1c4b531ffcf302843266639b7 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 8 Feb 2022 20:15:48 +0100 Subject: reintroduce AFL_PERSISTENT and AFL_DEFER_FORKSRV --- docs/Changelog.md | 3 +++ docs/env_variables.md | 10 +++++++--- frida_mode/src/entry.c | 1 + src/afl-common.c | 22 ++++++++-------------- src/afl-fuzz-init.c | 10 ++++++++-- src/afl-fuzz-state.c | 8 ++++---- src/afl-fuzz.c | 24 ++---------------------- 7 files changed, 33 insertions(+), 45 deletions(-) diff --git a/docs/Changelog.md b/docs/Changelog.md index bdb2dda3..142b85b3 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -14,6 +14,9 @@ sending a mail to . - afl-fuzz: - new commandline options -g/G to set min/max length of generated fuzz inputs + - reintroduced AFL_PERSISTENT and AFL_DEFER_FORKSRV to allow + persistent mode and manual forkserver support if these are not + in the target binary (e.g. are in a shared library) - frida_mode: - update to new frida release, handles now c++ throw/catch diff --git a/docs/env_variables.md b/docs/env_variables.md index f7ad4ff9..06c08f31 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -532,9 +532,13 @@ checks or alter some of the more exotic semantics of the tool: - Setting `AFL_TRY_AFFINITY` tries to attempt binding to a specific CPU core on Linux systems, but will not terminate if that fails. - - Outdated environment variables that are not supported anymore: - - `AFL_DEFER_FORKSRV` - - `AFL_PERSISTENT` + - The following environment variables are only needed if you implemented + your own forkserver or persistent mode, or if __AFL_LOOP or __AFL_INIT + are in a shared library and not the main binary: + - `AFL_DEFER_FORKSRV` enforces a deferred forkserver even if none was + detected in the target binary + - `AFL_PERSISTENT` enforces persistent mode even if none was detected + in the target binary ## 5) Settings for afl-qemu-trace diff --git a/frida_mode/src/entry.c b/frida_mode/src/entry.c index 5d9bcaaf..05af7ebb 100644 --- a/frida_mode/src/entry.c +++ b/frida_mode/src/entry.c @@ -84,6 +84,7 @@ void entry_start(void) { stalker_trust(); } + if (entry_point == 0) { entry_launch(); } } diff --git a/src/afl-common.c b/src/afl-common.c index e684302a..7c074acc 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -63,8 +63,7 @@ u32 check_binary_signatures(u8 *fn) { if (f_data == MAP_FAILED) { PFATAL("Unable to mmap file '%s'", fn); } close(fd); - if (memmem(f_data, f_len, PERSIST_SIG, strlen(PERSIST_SIG) + 1) || - getenv(PERSIST_ENV_VAR)) { + if (memmem(f_data, f_len, PERSIST_SIG, strlen(PERSIST_SIG) + 1)) { if (!be_quiet) { OKF(cPIN "Persistent mode binary detected."); } setenv(PERSIST_ENV_VAR, "1", 1); @@ -72,11 +71,9 @@ u32 check_binary_signatures(u8 *fn) { } else if (getenv("AFL_PERSISTENT")) { - if (!be_quiet) { - - WARNF("AFL_PERSISTENT is no longer supported and may misbehave!"); - - } + if (!be_quiet) { OKF(cPIN "Persistent mode enforced."); } + setenv(PERSIST_ENV_VAR, "1", 1); + ret = 1; } else if (getenv("AFL_FRIDA_PERSISTENT_ADDR")) { @@ -91,8 +88,7 @@ u32 check_binary_signatures(u8 *fn) { } - if (memmem(f_data, f_len, DEFER_SIG, strlen(DEFER_SIG) + 1) || - getenv(DEFER_ENV_VAR)) { + if (memmem(f_data, f_len, DEFER_SIG, strlen(DEFER_SIG) + 1)) { if (!be_quiet) { OKF(cPIN "Deferred forkserver binary detected."); } setenv(DEFER_ENV_VAR, "1", 1); @@ -100,11 +96,9 @@ u32 check_binary_signatures(u8 *fn) { } else if (getenv("AFL_DEFER_FORKSRV")) { - if (!be_quiet) { - - WARNF("AFL_DEFER_FORKSRV is no longer supported and may misbehave!"); - - } + if (!be_quiet) { OKF(cPIN "Deferred forkserver enforced."); } + setenv(DEFER_ENV_VAR, "1", 1); + ret += 2; } diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 45f28d4b..05a654c8 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -2822,7 +2822,11 @@ void check_binary(afl_state_t *afl, u8 *fname) { } else if (getenv("AFL_PERSISTENT")) { - WARNF("AFL_PERSISTENT is no longer supported and may misbehave!"); + OKF(cPIN "Persistent mode enforced."); + setenv(PERSIST_ENV_VAR, "1", 1); + afl->persistent_mode = 1; + afl->fsrv.persistent_mode = 1; + afl->shmem_testcase_mode = 1; } else if (getenv("AFL_FRIDA_PERSISTENT_ADDR")) { @@ -2843,7 +2847,9 @@ void check_binary(afl_state_t *afl, u8 *fname) { } else if (getenv("AFL_DEFER_FORKSRV")) { - WARNF("AFL_DEFER_FORKSRV is no longer supported and may misbehave!"); + OKF(cPIN "Deferred forkserver enforced."); + setenv(DEFER_ENV_VAR, "1", 1); + afl->deferred_mode = 1; } diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 115e62de..129e4c8b 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -486,15 +486,15 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl_environment_variable_len)) { - afl->min_length = atoi( - (u8 *)get_afl_env(afl_environment_variables[i])); + afl->min_length = + atoi((u8 *)get_afl_env(afl_environment_variables[i])); } else if (!strncmp(env, "AFL_INPUT_LEN_MAX", afl_environment_variable_len)) { - afl->max_length = atoi( - (u8 *)get_afl_env(afl_environment_variables[i])); + afl->max_length = + atoi((u8 *)get_afl_env(afl_environment_variables[i])); } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 7e3b3c94..c923cc9d 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -294,8 +294,8 @@ static void usage(u8 *argv0, int more_help) { " 'signalfx' and 'influxdb'\n" "AFL_TESTCACHE_SIZE: use a cache for testcases, improves performance (in MB)\n" "AFL_TMPDIR: directory to use for input file generation (ramdisk recommended)\n" - //"AFL_PERSISTENT: not supported anymore -> no effect, just a warning\n" - //"AFL_DEFER_FORKSRV: not supported anymore -> no effect, just a warning\n" + "AFL_PERSISTENT: enforce persistent mode (if __AFL_LOOP is in a shared lib\n" + "AFL_DEFER_FORKSRV: enforced deferred forkserver (__AFL_INIT is in a .so\n" "\n" ); @@ -1920,26 +1920,6 @@ int main(int argc, char **argv_orig, char **envp) { check_binary(afl, argv[optind]); - if (getenv(PERSIST_ENV_VAR) && !afl->persistent_mode) { - - WARNF( - "Persistent mode environment variable detected, forcing persistent " - "mode!"); - afl->persistent_mode = 1; - afl->fsrv.persistent_mode = 1; - afl->shmem_testcase_mode = 1; - - } - - if (getenv(DEFER_ENV_VAR) && !afl->deferred_mode) { - - WARNF( - "Deferred forkserver mode environment variable detected, forcing " - "deferred forkserver!"); - afl->deferred_mode = 1; - - } - #ifdef AFL_PERSISTENT_RECORD if (unlikely(afl->fsrv.persistent_record)) { -- cgit 1.4.1 From 056ebbff15bb6ebef6664776dee05217cebdc7fe Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 8 Feb 2022 20:36:06 +0100 Subject: add AFL_EARLY_FORKSERVER support --- docs/Changelog.md | 3 +++ docs/env_variables.md | 4 ++++ include/envs.h | 1 + instrumentation/afl-compiler-rt.o.c | 14 ++++++++++++++ src/afl-fuzz.c | 2 ++ 5 files changed, 24 insertions(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index 142b85b3..f4ae0e43 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -17,6 +17,9 @@ sending a mail to . - reintroduced AFL_PERSISTENT and AFL_DEFER_FORKSRV to allow persistent mode and manual forkserver support if these are not in the target binary (e.g. are in a shared library) + - add AFL_EARY_FORKSERVER to install the forkserver as earliest as + possible in the target (for afl-gcc-fast/afl-clang-fast/ + afl-clang-lto) - frida_mode: - update to new frida release, handles now c++ throw/catch diff --git a/docs/env_variables.md b/docs/env_variables.md index 06c08f31..4fa3f051 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -540,6 +540,10 @@ checks or alter some of the more exotic semantics of the tool: - `AFL_PERSISTENT` enforces persistent mode even if none was detected in the target binary + - If you need an early forkserver in your target because of early + constructors in your target you can set `AFL_EARLY_FORKSERVER`. + Note that is is not a compile time option but a runtime option :-) + ## 5) Settings for afl-qemu-trace The QEMU wrapper used to instrument binary-only code supports several settings: diff --git a/include/envs.h b/include/envs.h index 538ea3a8..f4327d8c 100644 --- a/include/envs.h +++ b/include/envs.h @@ -47,6 +47,7 @@ static char *afl_environment_variables[] = { "AFL_DONT_OPTIMIZE", "AFL_DRIVER_STDERR_DUPLICATE_FILENAME", "AFL_DUMB_FORKSRV", + "AFL_EARLY_FORKSERVER", "AFL_ENTRYPOINT", "AFL_EXIT_WHEN_DONE", "AFL_EXIT_ON_TIME", diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index 9a12831e..db7ac7b0 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -68,6 +68,7 @@ #endif #define CTOR_PRIO 3 +#define EARLY_FS_PRIO 5 #include #include @@ -145,6 +146,7 @@ u32 __afl_already_initialized_shm; u32 __afl_already_initialized_forkserver; u32 __afl_already_initialized_first; u32 __afl_already_initialized_second; +u32 __afl_already_initialized_init; /* Dummy pipe for area_is_valid() */ @@ -1253,6 +1255,8 @@ void __afl_manual_init(void) { __attribute__((constructor())) void __afl_auto_init(void) { + if (__afl_already_initialized_init) { return; } + #ifdef __ANDROID__ // Disable handlers in linker/debuggerd, check include/debuggerd/handler.h signal(SIGABRT, SIG_DFL); @@ -1265,6 +1269,8 @@ __attribute__((constructor())) void __afl_auto_init(void) { signal(SIGTRAP, SIG_DFL); #endif + __afl_already_initialized_init = 1; + if (getenv("AFL_DISABLE_LLVM_INSTRUMENTATION")) return; if (getenv(DEFER_ENV_VAR)) return; @@ -1273,6 +1279,14 @@ __attribute__((constructor())) void __afl_auto_init(void) { } +/* Optionally run an early forkserver */ + +__attribute__((constructor(EARLY_FS_PRIO))) void __early_forkserver(void) { + + if (getenv("AFL_EARLY_FORKSERVER")) { __afl_auto_init(); } + +} + /* Initialization of the shmem - earliest possible because of LTO fixed mem. */ __attribute__((constructor(CTOR_PRIO))) void __afl_auto_early(void) { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index c923cc9d..c73ab38b 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -294,6 +294,8 @@ static void usage(u8 *argv0, int more_help) { " 'signalfx' and 'influxdb'\n" "AFL_TESTCACHE_SIZE: use a cache for testcases, improves performance (in MB)\n" "AFL_TMPDIR: directory to use for input file generation (ramdisk recommended)\n" + "AFL_EARLY_FORKSERVER: force an early forkserver in an afl-clang-fast/\n" + " afl-clang-lto/afl-gcc-fast target\n" "AFL_PERSISTENT: enforce persistent mode (if __AFL_LOOP is in a shared lib\n" "AFL_DEFER_FORKSRV: enforced deferred forkserver (__AFL_INIT is in a .so\n" "\n" -- cgit 1.4.1 From 5e8da2b85c13eeaac245f94ef9232c674cd2e146 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 9 Feb 2022 20:36:16 +0100 Subject: Adapt to my MacOS --- GNUmakefile | 10 ++++++++-- src/afl-cc.c | 4 ++-- utils/aflpp_driver/GNUmakefile | 8 +++++++- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 1c5d992e..6392fceb 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -97,6 +97,12 @@ ifneq "$(SYS)" "Darwin" endif endif +ifeq "$(SYS)" "Darwin" + # On some odd MacOS system configurations, the Xcode sdk path is not set correctly + SDK_LD = -L$(shell xcrun --show-sdk-path)/usr/lib + LDFLAGS += $(SDK_LD) +endif + ifeq "$(SYS)" "SunOS" CFLAGS_OPT += -Wno-format-truncation LDFLAGS = -lkstat -lrt @@ -384,7 +390,7 @@ test_x86: @echo "[*] Testing the PATH environment variable..." @test "$${PATH}" != "$${PATH#.:}" && { echo "Please remove current directory '.' from PATH to avoid recursion of 'as', thanks!"; echo; exit 1; } || : @echo "[*] Checking for the ability to compile x86 code..." - @echo 'main() { __asm__("xorb %al, %al"); }' | $(CC) $(CFLAGS) -w -x c - -o .test1 || ( echo; echo "Oops, looks like your compiler can't generate x86 code."; echo; echo "Don't panic! You can use the LLVM or QEMU mode, but see docs/INSTALL first."; echo "(To ignore this error, set AFL_NO_X86=1 and try again.)"; echo; exit 1 ) + @echo 'main() { __asm__("xorb %al, %al"); }' | $(CC) $(CFLAGS) $(LDFLAGS) -w -x c - -o .test1 || ( echo; echo "Oops, looks like your compiler can't generate x86 code."; echo; echo "Don't panic! You can use the LLVM or QEMU mode, but see docs/INSTALL first."; echo "(To ignore this error, set AFL_NO_X86=1 and try again.)"; echo; exit 1 ) @rm -f .test1 else test_x86: @@ -528,7 +534,7 @@ code-format: ifndef AFL_NO_X86 test_build: afl-cc afl-gcc afl-as afl-showmap @echo "[*] Testing the CC wrapper afl-cc and its instrumentation output..." - @unset AFL_MAP_SIZE AFL_USE_UBSAN AFL_USE_CFISAN AFL_USE_LSAN AFL_USE_ASAN AFL_USE_MSAN; ASAN_OPTIONS=detect_leaks=0 AFL_INST_RATIO=100 AFL_PATH=. ./afl-cc test-instr.c -o test-instr 2>&1 || (echo "Oops, afl-cc failed"; exit 1 ) + @unset AFL_MAP_SIZE AFL_USE_UBSAN AFL_USE_CFISAN AFL_USE_LSAN AFL_USE_ASAN AFL_USE_MSAN; ASAN_OPTIONS=detect_leaks=0 AFL_INST_RATIO=100 AFL_PATH=. ./afl-cc test-instr.c $(LDFLAGS) -o test-instr 2>&1 || (echo "Oops, afl-cc failed"; exit 1 ) ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr0 ./test-instr < /dev/null echo 1 | ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr1 ./test-instr @rm -f test-instr diff --git a/src/afl-cc.c b/src/afl-cc.c index 2d7e3d91..ed57ca1e 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -931,7 +931,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { } -#if defined(USEMMAP) && !defined(__HAIKU__) +#if defined(USEMMAP) && !defined(__HAIKU__) && !__APPLE__ if (!have_c) cc_params[cc_par_cnt++] = "-lrt"; #endif @@ -1136,7 +1136,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { } - #if defined(USEMMAP) && !defined(__HAIKU__) + #if defined(USEMMAP) && !defined(__HAIKU__) && !__APPLE__ cc_params[cc_par_cnt++] = "-lrt"; #endif diff --git a/utils/aflpp_driver/GNUmakefile b/utils/aflpp_driver/GNUmakefile index c282a9f3..234a1c31 100644 --- a/utils/aflpp_driver/GNUmakefile +++ b/utils/aflpp_driver/GNUmakefile @@ -2,6 +2,12 @@ ifeq "" "$(LLVM_CONFIG)" LLVM_CONFIG=llvm-config endif +ifeq "$(shell uname -s)" "Darwin" + # On some odd MacOS system configurations, the Xcode sdk path is not set correctly + SDK_LD = -L$(shell xcrun --show-sdk-path)/usr/lib + LDFLAGS += $(SDK_LD) +endif + LLVM_BINDIR = $(shell $(LLVM_CONFIG) --bindir 2>/dev/null) ifneq "" "$(LLVM_BINDIR)" LLVM_BINDIR := $(LLVM_BINDIR)/ @@ -33,7 +39,7 @@ libAFLQemuDriver.a: aflpp_qemu_driver.o @-cp -vf libAFLQemuDriver.a ../../ aflpp_qemu_driver_hook.so: aflpp_qemu_driver_hook.o - @-test -e aflpp_qemu_driver_hook.o && $(LLVM_BINDIR)clang -shared aflpp_qemu_driver_hook.o -o aflpp_qemu_driver_hook.so || echo "Note: Optional aflpp_qemu_driver_hook.so not built." + @-test -e aflpp_qemu_driver_hook.o && $(LLVM_BINDIR)clang $(LDFLAGS) -shared aflpp_qemu_driver_hook.o -o aflpp_qemu_driver_hook.so || echo "Note: Optional aflpp_qemu_driver_hook.so not built." aflpp_qemu_driver_hook.o: aflpp_qemu_driver_hook.c @-test -e ../../qemu_mode/qemuafl/qemuafl/api.h && $(LLVM_BINDIR)clang $(CFLAGS) -funroll-loops -c aflpp_qemu_driver_hook.c || echo "Note: Optional aflpp_qemu_driver_hook.o not built." -- cgit 1.4.1 From de7058b75b629011246be12b4ae7df1e504925b1 Mon Sep 17 00:00:00 2001 From: hexcoder Date: Thu, 10 Feb 2022 10:40:11 +0100 Subject: typo --- docs/env_variables.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/env_variables.md b/docs/env_variables.md index 4fa3f051..4626a9b6 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -542,7 +542,7 @@ checks or alter some of the more exotic semantics of the tool: - If you need an early forkserver in your target because of early constructors in your target you can set `AFL_EARLY_FORKSERVER`. - Note that is is not a compile time option but a runtime option :-) + Note that this is not a compile time option but a runtime option :-) ## 5) Settings for afl-qemu-trace -- cgit 1.4.1