Merge pull request #1489 from AFLplusplus/dev

push to stable
This commit is contained in:
van Hauser 2022-08-08 15:27:07 +02:00 committed by GitHub
commit 3e2986dd78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 864 additions and 222 deletions

View File

@ -2,9 +2,9 @@
<img align="right" src="https://raw.githubusercontent.com/AFLplusplus/Website/master/static/aflpp_bg.svg" alt="AFL++ logo" width="250" heigh="250"> <img align="right" src="https://raw.githubusercontent.com/AFLplusplus/Website/master/static/aflpp_bg.svg" alt="AFL++ logo" width="250" heigh="250">
Release version: [4.01c](https://github.com/AFLplusplus/AFLplusplus/releases) Release version: [4.02c](https://github.com/AFLplusplus/AFLplusplus/releases)
GitHub version: 4.02a GitHub version: 4.02c
Repository: Repository:
[https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus) [https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)

View File

@ -8,10 +8,7 @@
Want to stay in the loop on major new features? Join our mailing list by Want to stay in the loop on major new features? Join our mailing list by
sending a mail to <afl-users+subscribe@googlegroups.com>. sending a mail to <afl-users+subscribe@googlegroups.com>.
### Version ++4.02a (dev) ### Version ++4.02c (release)
- afl-fuzz:
- change post_process hook to allow returning NULL and 0 length to
tell afl-fuzz to skip this mutated input
- afl-cc: - afl-cc:
- important fix for the default pcguard mode when LLVM IR vector - important fix for the default pcguard mode when LLVM IR vector
selects are produced, thanks to @juppytt for reporting! selects are produced, thanks to @juppytt for reporting!
@ -19,6 +16,11 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
- Adacore submitted CMPLOG support to the gcc_plugin! :-) - Adacore submitted CMPLOG support to the gcc_plugin! :-)
- llvm_mode: - llvm_mode:
- laf cmp splitting fixed for more comparison types - laf cmp splitting fixed for more comparison types
- frida_mode:
- now works on Android!
- afl-fuzz:
- change post_process hook to allow returning NULL and 0 length to
tell afl-fuzz to skip this mutated input
### Version ++4.01c (release) ### Version ++4.01c (release)

View File

@ -13,6 +13,16 @@ JS_SRC:=$(BUILD_DIR)api.c
JS_OBJ:=$(BUILD_DIR)api.o JS_OBJ:=$(BUILD_DIR)api.o
SOURCES:=$(wildcard $(SRC_DIR)**/*.c) $(wildcard $(SRC_DIR)*.c) SOURCES:=$(wildcard $(SRC_DIR)**/*.c) $(wildcard $(SRC_DIR)*.c)
OBJS:=$(foreach src,$(SOURCES),$(OBJ_DIR)$(notdir $(patsubst %.c, %.o, $(src)))) OBJS:=$(foreach src,$(SOURCES),$(OBJ_DIR)$(notdir $(patsubst %.c, %.o, $(src))))
TARGET_CC?=$(CC)
TARGET_CXX?=$(CXX)
HOST_CC?=$(CC)
HOST_CXX?=$(CXX)
IS_ANDROID:=$(findstring android, $(shell $(TARGET_CC) --version 2>/dev/null))
IS_x86:=$(findstring i686, $(shell $(TARGET_CC) --version 2>/dev/null))
IS_x86_64:=$(findstring x86_64, $(shell $(TARGET_CC) --version 2>/dev/null))
IS_ARM:=$(findstring arm, $(shell $(TARGET_CC) --version 2>/dev/null))
IS_ARM64:=$(findstring aarch64, $(shell $(TARGET_CC) --version 2>/dev/null))
CFLAGS+=-fPIC \ CFLAGS+=-fPIC \
-D_GNU_SOURCE \ -D_GNU_SOURCE \
-D_FORTIFY_SOURCE=2 \ -D_FORTIFY_SOURCE=2 \
@ -21,6 +31,10 @@ CFLAGS+=-fPIC \
-funroll-loops \ -funroll-loops \
-ffunction-sections \ -ffunction-sections \
ifdef IS_ANDROID
CFLAGS+=-DANDROID
endif
AFL_CFLAGS:=-Wno-unused-parameter \ AFL_CFLAGS:=-Wno-unused-parameter \
-Wno-sign-compare \ -Wno-sign-compare \
-Wno-unused-function \ -Wno-unused-function \
@ -28,9 +42,16 @@ AFL_CFLAGS:=-Wno-unused-parameter \
-Wno-int-to-pointer-cast \ -Wno-int-to-pointer-cast \
-Wno-pointer-sign -Wno-pointer-sign
ifdef IS_ANDROID
LDFLAGS+= -static-libstdc++ \
-DANDROID \
-llog \
-shared
else
LDFLAGS+=-shared \ LDFLAGS+=-shared \
-lpthread \ -lpthread \
-lresolv -lresolv
endif
ifdef DEBUG ifdef DEBUG
CFLAGS+=-Werror \ CFLAGS+=-Werror \
@ -43,10 +64,12 @@ endif
FRIDA_BUILD_DIR:=$(BUILD_DIR)frida/ FRIDA_BUILD_DIR:=$(BUILD_DIR)frida/
FRIDA_TRACE:=$(BUILD_DIR)afl-frida-trace.so FRIDA_TRACE:=$(BUILD_DIR)afl-frida-trace.so
FRIDA_TRACE_LIB:=$(BUILD_DIR)libafl-frida-trace.a
FRIDA_TRACE_EMBEDDED:=$(BUILD_DIR)afl-frida-trace-embedded FRIDA_TRACE_EMBEDDED:=$(BUILD_DIR)afl-frida-trace-embedded
TARGET_CC?=$(CC) TARGET_CC?=$(CC)
TARGET_CXX?=$(CXX) TARGET_CXX?=$(CXX)
TARGET_AR?=$(AR)
HOST_CC?=$(CC) HOST_CC?=$(CC)
HOST_CXX?=$(CXX) HOST_CXX?=$(CXX)
@ -76,11 +99,11 @@ else
ifdef DEBUG ifdef DEBUG
AFL_CFLAGS:=$(AFL_CFLAGS) -Wno-prio-ctor-dtor AFL_CFLAGS:=$(AFL_CFLAGS) -Wno-prio-ctor-dtor
endif endif
LDFLAGS+= -z noexecstack \ LDFLAGS+= -z noexecstack \
-Wl,--gc-sections \ -Wl,--gc-sections \
-Wl,--exclude-libs,ALL \ -Wl,--exclude-libs,ALL \
-ldl \ -ldl
-lrt
LDSCRIPT:=-Wl,--version-script=$(PWD)frida.map LDSCRIPT:=-Wl,--version-script=$(PWD)frida.map
endif endif
@ -91,25 +114,28 @@ ifeq "$(shell uname)" "Linux"
endif endif
endif endif
ifneq "$(findstring android, $(shell $(CC) --version 2>/dev/null))" ""
ifdef IS_ANDROID
OS:=android OS:=android
ifneq "$(findstring aarch64, $(shell $(CC) --version 2>/dev/null))" "" ifdef IS_x86
ARCH:=arm64 ARCH:=x86
endif endif
ifneq "$(findstring arm, $(shell $(CC) --version 2>/dev/null))" "" ifdef IS_x86
ARCH:=x86_64
endif
ifdef IS_ARM
ARCH:=arm ARCH:=arm
endif endif
ifneq "$(findstring x86_64, $(shell $(CC) --version 2>/dev/null))" "" ifdef IS_ARM64
ARCH:=x86_64 ARCH:=arm64
endif
ifneq "$(findstring i686, $(shell $(CC) --version 2>/dev/null))" ""
ARCH:=x86
endif endif
endif endif
ifeq "$(ARCH)" "armhf" ifeq "$(ARCH)" "armhf"
TARGET_CC:=arm-linux-gnueabihf-gcc TARGET_CC:=arm-linux-gnueabihf-gcc
TARGET_CXX:=arm-linux-gnueabihf-g++ TARGET_CXX:=arm-linux-gnueabihf-g++
TARGET_AR:=arm-linux-gnueabihf-ar
endif endif
ifndef OS ifndef OS
@ -157,7 +183,7 @@ BIN2C_SRC:=$(PWD)util/bin2c.c
############################## ALL ############################################# ############################## ALL #############################################
all: $(FRIDA_TRACE) $(AFLPP_FRIDA_DRIVER_HOOK_OBJ) $(AFLPP_QEMU_DRIVER_HOOK_OBJ) $(ADDR_BIN) all: $(FRIDA_TRACE) $(FRIDA_TRACE_LIB) $(AFLPP_FRIDA_DRIVER_HOOK_OBJ) $(AFLPP_QEMU_DRIVER_HOOK_OBJ) $(ADDR_BIN)
32: 32:
CFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all CFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all
@ -221,10 +247,22 @@ else ifeq "$(ARCH)" "arm64"
CFLAGS+=-I $(FRIDA_DIR)build/frida_thin-$(OS)-$(ARCH)/include/frida-1.0 \ 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)/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)/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/capstone/ \
-I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/include/json-glib-1.0/ \ -I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/include/json-glib-1.0/ \
ifeq "$(OS)" "android"
CFLAGS += -static-libstdc++
endif
else
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/ \
endif
TRACE_LDFLAGS+=$(FRIDA_DIR)build/frida-$(OS)-$(ARCH)/lib/libfrida-gum-1.0.a \ 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/libsoup-2.4.a \
$(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libsqlite3.a \ $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libsqlite3.a \
@ -242,13 +280,15 @@ TRACE_LDFLAGS+=$(FRIDA_DIR)build/frida-$(OS)-$(ARCH)/lib/libfrida-gum-1.0.a \
$(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/liblzma.a \ $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/liblzma.a \
$(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libz.a \ $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libz.a \
else
CFLAGS+=-I $(FRIDA_DIR)build/frida-$(OS)-$(ARCH)/include/frida-1.0 \ 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)/include/glib-2.0/ \
-I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/glib-2.0/include/ \ -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/capstone/ \
-I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/json-glib-1.0/ \ -I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/json-glib-1.0/
ifeq "$(OS)" "android"
CFLAGS += -static-libstdc++
endif
TRACE_LDFLAGS+=$(FRIDA_DIR)build/frida-$(OS)-$(ARCH)/lib/libfrida-gum-1.0.a \ 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/libsoup-2.4.a \
@ -267,11 +307,6 @@ TRACE_LDFLAGS+=$(FRIDA_DIR)build/frida-$(OS)-$(ARCH)/lib/libfrida-gum-1.0.a \
$(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/liblzma.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/libz.a \
endif
else else
$(GUM_DEVKIT_TARBALL): | $(FRIDA_BUILD_DIR) $(GUM_DEVKIT_TARBALL): | $(FRIDA_BUILD_DIR)
@ -353,6 +388,15 @@ $(FRIDA_TRACE): $(GUM_DEVIT_LIBRARY) $(GUM_DEVIT_HEADER) $(OBJS) $(JS_OBJ) $(AFL
cp -v $(FRIDA_TRACE) $(ROOT) cp -v $(FRIDA_TRACE) $(ROOT)
$(FRIDA_TRACE_LIB): $(GUM_DEVIT_LIBRARY) $(GUM_DEVIT_HEADER) $(OBJS) $(JS_OBJ) $(AFL_COMPILER_RT_OBJ) $(AFL_PERFORMANCE_OBJ) GNUmakefile | $(BUILD_DIR)
$(TARGET_AR) \
-rcs \
$@ \
$(OBJS) \
$(JS_OBJ) \
$(AFL_COMPILER_RT_OBJ) \
$(AFL_PERFORMANCE_OBJ) \
############################# HOOK ############################################# ############################# HOOK #############################################
$(AFLPP_FRIDA_DRIVER_HOOK_OBJ): $(AFLPP_FRIDA_DRIVER_HOOK_SRC) $(GUM_DEVIT_HEADER) | $(BUILD_DIR) $(AFLPP_FRIDA_DRIVER_HOOK_OBJ): $(AFLPP_FRIDA_DRIVER_HOOK_SRC) $(GUM_DEVIT_HEADER) | $(BUILD_DIR)
@ -364,6 +408,7 @@ $(AFLPP_QEMU_DRIVER_HOOK_OBJ): $(AFLPP_QEMU_DRIVER_HOOK_SRC) | $(BUILD_DIR)
hook: $(AFLPP_FRIDA_DRIVER_HOOK_OBJ) $(AFLPP_QEMU_DRIVER_HOOK_OBJ) hook: $(AFLPP_FRIDA_DRIVER_HOOK_OBJ) $(AFLPP_QEMU_DRIVER_HOOK_OBJ)
############################# ADDR ############################################# ############################# ADDR #############################################
ifneq "$(OS)" "android"
$(ADDR_BIN): $(ADDR_SRC) | $(BUILD_DIR) $(ADDR_BIN): $(ADDR_SRC) | $(BUILD_DIR)
-$(TARGET_CC) \ -$(TARGET_CC) \
$(CFLAGS) \ $(CFLAGS) \
@ -377,7 +422,20 @@ $(ADDR_BIN): $(ADDR_SRC) | $(BUILD_DIR)
-ldl \ -ldl \
-lrt \ -lrt \
$< -o $@ $< -o $@
else
$(ADDR_BIN): $(ADDR_SRC) | $(BUILD_DIR)
-$(TARGET_CC) \
$(CFLAGS) \
-Werror \
-Wall \
-Wextra \
-Wpointer-arith \
-z noexecstack \
-Wl,--gc-sections \
-Wl,--exclude-libs,ALL \
-ldl \
$< -o $@
endif
addr: $(ADDR_BIN) addr: $(ADDR_BIN)
############################# CLEAN ############################################ ############################# CLEAN ############################################

View File

@ -146,6 +146,8 @@ instances run CMPLOG mode and instrumentation of the binary is less frequent
QEMU driver to provide a `main` loop for a user provided QEMU driver to provide a `main` loop for a user provided
`LLVMFuzzerTestOneInput`, this option configures the driver to read input from `LLVMFuzzerTestOneInput`, this option configures the driver to read input from
`stdin` rather than using in-memory test cases. `stdin` rather than using in-memory test cases.
* `AFL_FRIDA_INST_COVERAGE_ABSOLUTE` - Generate coverage files using absolute
virtual addresses rather than relative virtual addresses.
* `AFL_FRIDA_INST_COVERAGE_FILE` - File to write DynamoRIO format coverage * `AFL_FRIDA_INST_COVERAGE_FILE` - File to write DynamoRIO format coverage
information (e.g., to be loaded within IDA lighthouse). information (e.g., to be loaded within IDA lighthouse).
* `AFL_FRIDA_INST_DEBUG_FILE` - File to write raw assembly of original blocks * `AFL_FRIDA_INST_DEBUG_FILE` - File to write raw assembly of original blocks

View File

@ -13,6 +13,7 @@
js_api_set_debug_maps; js_api_set_debug_maps;
js_api_set_entrypoint; js_api_set_entrypoint;
js_api_set_instrument_cache_size; js_api_set_instrument_cache_size;
js_api_set_instrument_coverage_absolute;
js_api_set_instrument_coverage_file; js_api_set_instrument_coverage_file;
js_api_set_instrument_debug_file; js_api_set_instrument_debug_file;
js_api_set_instrument_jit; js_api_set_instrument_jit;

View File

@ -31,7 +31,7 @@ __attribute__((visibility("default"))) void afl_persistent_hook(
// do a length check matching the target! // do a length check matching the target!
void **esp = (void **)regs->esp; void **esp = (void **)regs->esp;
void * arg1 = esp[0]; void *arg1 = esp[0];
void **arg2 = &esp[1]; void **arg2 = &esp[1];
memcpy(arg1, input_buf, input_buf_len); memcpy(arg1, input_buf, input_buf_len);
*arg2 = (void *)input_buf_len; *arg2 = (void *)input_buf_len;
@ -50,6 +50,16 @@ __attribute__((visibility("default"))) void afl_persistent_hook(
} }
#elif defined(__arm__)
__attribute__((visibility("default"))) void afl_persistent_hook(
GumCpuContext *regs, uint8_t *input_buf, uint32_t input_buf_len) {
// do a length check matching the target!
memcpy((void *)regs->r[0], input_buf, input_buf_len);
regs->r[1] = input_buf_len;
}
#else #else
#pragma error "Unsupported architecture" #pragma error "Unsupported architecture"
#endif #endif

View File

@ -7,13 +7,14 @@
extern char *instrument_debug_filename; extern char *instrument_debug_filename;
extern char *instrument_coverage_filename; extern char *instrument_coverage_filename;
extern bool instrument_coverage_absolute;
extern gboolean instrument_tracing; extern gboolean instrument_tracing;
extern gboolean instrument_optimize; extern gboolean instrument_optimize;
extern gboolean instrument_unique; extern gboolean instrument_unique;
extern guint64 instrument_hash_zero; extern guint64 instrument_hash_zero;
extern char *instrument_coverage_unstable_filename; extern char *instrument_coverage_unstable_filename;
extern gboolean instrument_coverage_insn; extern gboolean instrument_coverage_insn;
extern char * instrument_regs_filename; extern char *instrument_regs_filename;
extern gboolean instrument_use_fixed_seed; extern gboolean instrument_use_fixed_seed;
extern guint64 instrument_fixed_seed; extern guint64 instrument_fixed_seed;

View File

@ -1,7 +1,7 @@
#ifndef _SECCOMP_H #ifndef _SECCOMP_H
#define _SECCOMP_H #define _SECCOMP_H
#ifndef __APPLE__ #if !defined(__APPLE__) && !defined(__ANDROID__)
#include <stdint.h> #include <stdint.h>
#include <linux/filter.h> #include <linux/filter.h>

9
frida_mode/include/shm.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef _SHM_H
#define _SHM_H
#include <stddef.h>
void *shm_create(size_t size);
#endif

View File

@ -36,6 +36,15 @@ static gboolean asan_exclude_module(const GumModuleDetails *details,
address = gum_module_find_export_by_name(details->name, symbol_name); address = gum_module_find_export_by_name(details->name, symbol_name);
if (address == 0) { return TRUE; } if (address == 0) { return TRUE; }
/* If the reported address of the symbol is outside of the range of the module
* then ignore it */
if (address < details->range->base_address) { return TRUE; }
if (address > (details->range->base_address + details->range->size)) {
return TRUE;
}
ranges_add_exclude((GumMemoryRange *)details->range); ranges_add_exclude((GumMemoryRange *)details->range);
return FALSE; return FALSE;

View File

@ -1,7 +1,5 @@
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <sys/shm.h>
#include <sys/mman.h>
#include <sys/syscall.h> #include <sys/syscall.h>
#include "frida-gumjs.h" #include "frida-gumjs.h"
@ -17,6 +15,7 @@
#include "persistent.h" #include "persistent.h"
#include "prefetch.h" #include "prefetch.h"
#include "ranges.h" #include "ranges.h"
#include "shm.h"
#include "stalker.h" #include "stalker.h"
#include "stats.h" #include "stats.h"
#include "util.h" #include "util.h"
@ -33,7 +32,7 @@ gboolean instrument_use_fixed_seed = FALSE;
guint64 instrument_fixed_seed = 0; guint64 instrument_fixed_seed = 0;
char *instrument_coverage_unstable_filename = NULL; char *instrument_coverage_unstable_filename = NULL;
gboolean instrument_coverage_insn = FALSE; gboolean instrument_coverage_insn = FALSE;
char * instrument_regs_filename = NULL; char *instrument_regs_filename = NULL;
static GumStalkerTransformer *transformer = NULL; static GumStalkerTransformer *transformer = NULL;
@ -237,9 +236,12 @@ static void instrument_basic_block(GumStalkerIterator *iterator,
} }
if (unlikely(instrument_regs_filename != NULL)) { if (unlikely(instrument_regs_filename != NULL)) {
gum_stalker_iterator_put_callout(iterator, instrument_write_regs, gum_stalker_iterator_put_callout(iterator, instrument_write_regs,
(void *)(size_t)regs_fd, NULL); (void *)(size_t)regs_fd, NULL);
} }
} }
} }
@ -274,6 +276,7 @@ static void instrument_basic_block(GumStalkerIterator *iterator,
instrument_flush(output); instrument_flush(output);
instrument_debug_end(output); instrument_debug_end(output);
instrument_coverage_end(instr->address + instr->size); instrument_coverage_end(instr->address + instr->size);
} }
void instrument_config(void) { void instrument_config(void) {
@ -344,29 +347,7 @@ void instrument_init(void) {
transformer = gum_stalker_transformer_make_from_callback( transformer = gum_stalker_transformer_make_from_callback(
instrument_basic_block, NULL, NULL); instrument_basic_block, NULL, NULL);
if (instrument_unique) { if (instrument_unique) { edges_notified = shm_create(__afl_map_size); }
int shm_id =
shmget(IPC_PRIVATE, __afl_map_size, IPC_CREAT | IPC_EXCL | 0600);
if (shm_id < 0) { FATAL("shm_id < 0 - errno: %d\n", errno); }
edges_notified = shmat(shm_id, NULL, 0);
g_assert(edges_notified != MAP_FAILED);
/*
* Configure the shared memory region to be removed once the process
* dies.
*/
if (shmctl(shm_id, IPC_RMID, NULL) < 0) {
FATAL("shmctl (IPC_RMID) < 0 - errno: %d\n", errno);
}
/* Clear it, not sure it's necessary, just seems like good practice */
memset(edges_notified, '\0', __afl_map_size);
}
if (instrument_use_fixed_seed) { if (instrument_use_fixed_seed) {
@ -404,6 +385,7 @@ void instrument_init(void) {
instrument_regs_filename == NULL ? " " : instrument_regs_filename); instrument_regs_filename == NULL ? " " : instrument_regs_filename);
if (instrument_regs_filename != NULL) { if (instrument_regs_filename != NULL) {
char *path = char *path =
g_canonicalize_filename(instrument_regs_filename, g_get_current_dir()); g_canonicalize_filename(instrument_regs_filename, g_get_current_dir());
@ -415,6 +397,7 @@ void instrument_init(void) {
if (regs_fd < 0) { FFATAL("Failed to open regs file '%s'", path); } if (regs_fd < 0) { FFATAL("Failed to open regs file '%s'", path); }
g_free(path); g_free(path);
} }
asan_init(); asan_init();
@ -444,6 +427,7 @@ void instrument_on_fork() {
} }
void instrument_regs_format(int fd, char *format, ...) { void instrument_regs_format(int fd, char *format, ...) {
va_list ap; va_list ap;
char buffer[4096] = {0}; char buffer[4096] = {0};
int ret; int ret;
@ -458,4 +442,6 @@ void instrument_regs_format(int fd, char *format, ...) {
len = strnlen(buffer, sizeof(buffer)); len = strnlen(buffer, sizeof(buffer));
IGNORED_RETURN(write(fd, buffer, len)); IGNORED_RETURN(write(fd, buffer, len));
} }

View File

@ -5,21 +5,159 @@
#if defined(__arm__) #if defined(__arm__)
#define PAGE_MASK (~(GUM_ADDRESS(0xfff)))
#define PAGE_ALIGNED(x) ((GUM_ADDRESS(x) & PAGE_MASK) == GUM_ADDRESS(x))
gboolean instrument_cache_enabled = FALSE; gboolean instrument_cache_enabled = FALSE;
gsize instrument_cache_size = 0; gsize instrument_cache_size = 0;
extern __thread guint64 instrument_previous_pc;
__attribute__((aligned(0x1000))) static guint8 area_ptr_dummy[MAP_SIZE];
#pragma pack(push, 1)
typedef struct {
// cur_location = (block_address >> 4) ^ (block_address << 8);
// shared_mem[cur_location ^ prev_location]++;
// prev_location = cur_location >> 1;
/* We can remove this branch when we add support for branch suppression */
uint32_t b_code; /* b imm */
uint8_t *shared_mem;
uint64_t *prev_location;
/* code */
/* save regs */
uint32_t str_r0_sp_rz; /* str r0, [sp - RED_ZONE] */
uint32_t str_r1_sp_rz_4; /* str r1, [sp - (RED_ZONE + 4)] */
/* load prev */
uint32_t ldr_r0_pprev; /* ldr r0, [pc-x] */
uint32_t ldrh_r1_r0; /* ldrh r1, [r0] */
/* load curr */
uint32_t mov_r0_block_id; /* mov r0, #imm16 */
/* calculate new */
uint32_t eor_r0_r0_r1; /* eor r0, r0, r1 */
/* load map */
uint32_t ldr_r1_pmap; /* ldr r1, [pc-x] */
/* calculate offset */
uint32_t add_r1_r1_r0; /* add r1, r1, r0 */
/* Load the value */
uint32_t ldrb_r0_r1; /* ldrb r0, [r1] */
/* Increment the value */
uint32_t add_r0_r0_1; /* add r0, r0, #1 */
uint32_t add_r0_r0_r0_lsr_8; /* add r0, r0, r0, lsr #8 */
/* Save the value */
uint32_t strb_r0_r1; /* strb r0, [r1] */
/* load curr shifted */
uint32_t mov_r0_block_id_shr_1; /* mov r0, #imm16 >> 1*/
/* Update prev */
uint32_t ldr_r1_pprev; /* ldr r1, [pc-x] */
uint32_t strh_r0_r1; /* strh r0, [r1] */
/* restore regs */
uint32_t ldr_r1_sp_rz_4; /* ldr r1, [sp - (RED_ZONE + 4)] */
uint32_t ldr_r0_sp_rz; /* ldr r0, [sp - RED_ZONE] */
} afl_log_code_asm_t;
typedef union {
afl_log_code_asm_t code;
uint8_t bytes[0];
} afl_log_code;
#pragma pack(pop)
static const afl_log_code_asm_t template =
{
.b_code = GUINT32_TO_LE(0xea000001),
.shared_mem = (uint8_t *)GUINT32_TO_LE(0xcefaadde),
.prev_location = (uint64_t *)GUINT32_TO_LE(0xadba0df0),
.str_r0_sp_rz = GUINT32_TO_LE(0xe50d0080),
.str_r1_sp_rz_4 = GUINT32_TO_LE(0xe50d1084),
.ldr_r0_pprev = GUINT32_TO_LE(0xe51f0014),
.ldrh_r1_r0 = GUINT32_TO_LE(0xe1d010b0),
.mov_r0_block_id = GUINT32_TO_LE(0xe3000000),
.eor_r0_r0_r1 = GUINT32_TO_LE(0xe0200001),
.ldr_r1_pmap = GUINT32_TO_LE(0xe51f1028),
.add_r1_r1_r0 = GUINT32_TO_LE(0xe0811000),
.ldrb_r0_r1 = GUINT32_TO_LE(0xe5d10000),
.add_r0_r0_1 = GUINT32_TO_LE(0xe2800001),
.add_r0_r0_r0_lsr_8 = GUINT32_TO_LE(0xe0800420),
.strb_r0_r1 = GUINT32_TO_LE(0xe5c10000),
.mov_r0_block_id_shr_1 = GUINT32_TO_LE(0xe3000000),
.ldr_r1_pprev = GUINT32_TO_LE(0xe51f1040),
.strh_r0_r1 = GUINT32_TO_LE(0xe1c100b0),
.ldr_r1_sp_rz_4 = GUINT32_TO_LE(0xe51d1084),
.ldr_r0_sp_rz = GUINT32_TO_LE(0xe51d0080),
}
;
gboolean instrument_is_coverage_optimize_supported(void) { gboolean instrument_is_coverage_optimize_supported(void) {
return false; return true;
}
static void patch_t3_insn(uint32_t *insn, uint16_t val) {
uint32_t orig = GUINT32_FROM_LE(*insn);
uint32_t imm12 = (val & 0xfff);
uint32_t imm4 = (val >> 12);
orig |= imm12;
orig |= (imm4 << 16);
*insn = GUINT32_TO_LE(orig);
} }
void instrument_coverage_optimize(const cs_insn *instr, void instrument_coverage_optimize(const cs_insn *instr,
GumStalkerOutput *output) { GumStalkerOutput *output) {
UNUSED_PARAMETER(instr); afl_log_code code = {0};
UNUSED_PARAMETER(output); GumArmWriter *cw = output->writer.arm;
FFATAL("Optimized coverage not supported on this architecture"); gpointer block_start;
guint64 area_offset = instrument_get_offset_hash(GUM_ADDRESS(instr->address));
gsize map_size_pow2;
gsize area_offset_ror;
GumAddress code_addr = 0;
// gum_arm64_writer_put_brk_imm(cw, 0x0);
code_addr = cw->pc;
block_start = GSIZE_TO_POINTER(GUM_ADDRESS(cw->code));
code.code = template;
g_assert(PAGE_ALIGNED(__afl_area_ptr));
map_size_pow2 = util_log2(__afl_map_size);
area_offset_ror = util_rotate(area_offset, 1, map_size_pow2);
code.code.shared_mem = __afl_area_ptr;
code.code.prev_location = instrument_previous_pc_addr;
patch_t3_insn(&code.code.mov_r0_block_id, (uint16_t)area_offset);
patch_t3_insn(&code.code.mov_r0_block_id_shr_1, (uint16_t)area_offset_ror);
// gum_arm_writer_put_breakpoint(cw);
gum_arm_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code));
} }
@ -28,13 +166,32 @@ void instrument_coverage_optimize_insn(const cs_insn *instr,
UNUSED_PARAMETER(instr); UNUSED_PARAMETER(instr);
UNUSED_PARAMETER(output); UNUSED_PARAMETER(output);
FFATAL("Optimized coverage not supported on this architecture");
} }
void instrument_coverage_optimize_init(void) { void instrument_coverage_optimize_init(void) {
FWARNF("Optimized coverage not supported on this architecture"); char *shm_env = getenv(SHM_ENV_VAR);
FVERBOSE("SHM_ENV_VAR: %s", shm_env);
if (shm_env == NULL) {
FWARNF("SHM_ENV_VAR not set, using dummy for debugging purposes");
__afl_area_ptr = area_ptr_dummy;
memset(area_ptr_dummy, '\0', sizeof(area_ptr_dummy));
}
FVERBOSE("__afl_area_ptr: %p", __afl_area_ptr);
if (instrument_previous_pc_addr == NULL) {
instrument_previous_pc_addr = &instrument_previous_pc;
*instrument_previous_pc_addr = instrument_hash_zero;
FVERBOSE("instrument_previous_pc_addr: %p", instrument_previous_pc_addr);
}
} }
@ -81,6 +238,7 @@ void instrument_cache(const cs_insn *instr, GumStalkerOutput *output) {
} }
void instrument_write_regs(GumCpuContext *cpu_context, gpointer user_data) { void instrument_write_regs(GumCpuContext *cpu_context, gpointer user_data) {
int fd = (int)user_data; int fd = (int)user_data;
instrument_regs_format(fd, instrument_regs_format(fd,
"r0 : 0x%08x, r1 : 0x%08x, r2 : 0x%08x, r3 : 0x%08x\n", "r0 : 0x%08x, r1 : 0x%08x, r2 : 0x%08x, r3 : 0x%08x\n",
@ -97,6 +255,7 @@ void instrument_write_regs(GumCpuContext *cpu_context, gpointer user_data) {
fd, "r12: 0x%08x, sp : 0x%08x, lr : 0x%08x, pc : 0x%08x\n", fd, "r12: 0x%08x, sp : 0x%08x, lr : 0x%08x, pc : 0x%08x\n",
cpu_context->r12, cpu_context->sp, cpu_context->lr, cpu_context->pc); cpu_context->r12, cpu_context->sp, cpu_context->lr, cpu_context->pc);
instrument_regs_format(fd, "cpsr: 0x%08x\n\n", cpu_context->cpsr); instrument_regs_format(fd, "cpsr: 0x%08x\n\n", cpu_context->cpsr);
} }
#endif #endif

View File

@ -407,6 +407,7 @@ void instrument_cache(const cs_insn *instr, GumStalkerOutput *output) {
} }
void instrument_write_regs(GumCpuContext *cpu_context, gpointer user_data) { void instrument_write_regs(GumCpuContext *cpu_context, gpointer user_data) {
int fd = (int)(size_t)user_data; int fd = (int)(size_t)user_data;
instrument_regs_format( instrument_regs_format(
fd, "x0 : 0x%016x, x1 : 0x%016x, x2 : 0x%016x, x3 : 0x%016x\n", fd, "x0 : 0x%016x, x1 : 0x%016x, x2 : 0x%016x, x3 : 0x%016x\n",
@ -440,6 +441,7 @@ void instrument_write_regs(GumCpuContext *cpu_context, gpointer user_data) {
fd, "x28: 0x%016x, fp : 0x%016x, lr : 0x%016x, sp : 0x%016x\n", fd, "x28: 0x%016x, fp : 0x%016x, lr : 0x%016x, sp : 0x%016x\n",
cpu_context->x[28], cpu_context->fp, cpu_context->lr, cpu_context->sp); cpu_context->x[28], cpu_context->fp, cpu_context->lr, cpu_context->sp);
instrument_regs_format(fd, "pc : 0x%016x\n\n", cpu_context->pc); instrument_regs_format(fd, "pc : 0x%016x\n\n", cpu_context->pc);
} }
#endif #endif

View File

@ -9,6 +9,7 @@
#include "util.h" #include "util.h"
char *instrument_coverage_filename = NULL; char *instrument_coverage_filename = NULL;
bool instrument_coverage_absolute = false;
static int normal_coverage_fd = -1; static int normal_coverage_fd = -1;
static int normal_coverage_pipes[2] = {-1, -1}; static int normal_coverage_pipes[2] = {-1, -1};
@ -237,6 +238,18 @@ static void instrument_coverage_mark(void *key, void *value, void *user_data) {
} }
static void instrument_coverage_mark_first(void *key, void *value,
void *user_data) {
UNUSED_PARAMETER(key);
coverage_range_t *module = (coverage_range_t *)user_data;
normal_coverage_data_t *val = (normal_coverage_data_t *)value;
val->module = module;
module->count++;
}
static void coverage_write(int fd, void *data, size_t size) { static void coverage_write(int fd, void *data, size_t size) {
ssize_t written; ssize_t written;
@ -404,28 +417,69 @@ static void instrument_coverage_normal_run() {
instrument_coverage_print("Coverage - Preparing\n"); instrument_coverage_print("Coverage - Preparing\n");
GArray *coverage_modules = coverage_get_modules(); if (instrument_coverage_absolute) {
guint size = g_hash_table_size(coverage_hash); guint size = g_hash_table_size(coverage_hash);
instrument_coverage_print("Coverage - Total Entries: %u\n", size); instrument_coverage_print("Coverage - Total Entries: %u\n", size);
coverage_mark_ctx_t ctx = {.modules = coverage_modules, .count = 0}; coverage_range_t module = {
g_hash_table_foreach(coverage_hash, instrument_coverage_mark, &ctx); .base_address = GUM_ADDRESS(0),
instrument_coverage_print("Coverage - Marked Entries: %u\n", ctx.count); .limit = GUM_ADDRESS(-1),
.size = GUM_ADDRESS(-1),
.path = "absolute",
.offset = 0,
.is_executable = true,
.count = size,
.id = 0,
guint coverage_marked_modules = coverage_mark_modules(coverage_modules); };
instrument_coverage_print("Coverage - Marked Modules: %u\n",
coverage_marked_modules);
coverage_write_header(normal_coverage_fd, coverage_marked_modules); instrument_coverage_print("Coverage Module - 0x%016" G_GINT64_MODIFIER
coverage_write_modules(normal_coverage_fd, coverage_modules); "X - 0x%016" G_GINT64_MODIFIER "X (%s)\n",
coverage_format(normal_coverage_fd, "BB Table: %u bbs\n", ctx.count); module.base_address, module.limit, module.path);
g_hash_table_foreach(coverage_hash, coverage_write_events,
&normal_coverage_fd); GArray *coverage_modules =
g_array_sized_new(false, false, sizeof(coverage_range_t), 1);
g_array_append_val(coverage_modules, module);
g_hash_table_foreach(coverage_hash, instrument_coverage_mark_first,
&module);
coverage_write_header(normal_coverage_fd, 1);
coverage_write_modules(normal_coverage_fd, coverage_modules);
coverage_format(normal_coverage_fd, "BB Table: %u bbs\n", size);
g_hash_table_foreach(coverage_hash, coverage_write_events,
&normal_coverage_fd);
} else {
GArray *coverage_modules = coverage_get_modules();
guint size = g_hash_table_size(coverage_hash);
instrument_coverage_print("Coverage - Total Entries: %u\n", size);
coverage_mark_ctx_t ctx = {.modules = coverage_modules, .count = 0};
/* For each coverage event in the hashtable associate it with a module and
* count the number of entries per module */
g_hash_table_foreach(coverage_hash, instrument_coverage_mark, &ctx);
instrument_coverage_print("Coverage - Marked Entries: %u\n", ctx.count);
/* For each module with coverage events assign it an incrementing number */
guint coverage_marked_modules = coverage_mark_modules(coverage_modules);
instrument_coverage_print("Coverage - Marked Modules: %u\n",
coverage_marked_modules);
coverage_write_header(normal_coverage_fd, coverage_marked_modules);
coverage_write_modules(normal_coverage_fd, coverage_modules);
coverage_format(normal_coverage_fd, "BB Table: %u bbs\n", ctx.count);
g_hash_table_foreach(coverage_hash, coverage_write_events,
&normal_coverage_fd);
}
g_hash_table_unref(coverage_hash); g_hash_table_unref(coverage_hash);
instrument_coverage_print("Coverage - Completed\n"); instrument_coverage_print("Coverage - Completed\n");
} }
@ -622,8 +676,6 @@ static void instrument_coverage_unstable_run(void) {
instrument_coverage_print("Coverage - Preparing\n"); instrument_coverage_print("Coverage - Preparing\n");
GArray *coverage_modules = coverage_get_modules();
instrument_coverage_print("Found edges: %u\n", edges); instrument_coverage_print("Found edges: %u\n", edges);
GArray *unstable_edge_ids = instrument_coverage_unstable_read_unstable_ids(); GArray *unstable_edge_ids = instrument_coverage_unstable_read_unstable_ids();
@ -634,20 +686,60 @@ static void instrument_coverage_unstable_run(void) {
guint size = g_hash_table_size(unstable_blocks); guint size = g_hash_table_size(unstable_blocks);
instrument_coverage_print("Unstable blocks: %u\n", size); instrument_coverage_print("Unstable blocks: %u\n", size);
coverage_mark_ctx_t ctx = {.modules = coverage_modules, .count = 0}; if (instrument_coverage_absolute) {
g_hash_table_foreach(unstable_blocks, instrument_coverage_mark, &ctx); instrument_coverage_print("Coverage - Total Entries: %u\n", size);
instrument_coverage_print("Coverage - Marked Entries: %u\n", ctx.count);
guint coverage_marked_modules = coverage_mark_modules(coverage_modules); coverage_range_t module = {
instrument_coverage_print("Coverage - Marked Modules: %u\n",
coverage_marked_modules);
coverage_write_header(unstable_coverage_fd, coverage_marked_modules); .base_address = GUM_ADDRESS(0),
coverage_write_modules(unstable_coverage_fd, coverage_modules); .limit = GUM_ADDRESS(-1),
coverage_format(unstable_coverage_fd, "BB Table: %u bbs\n", ctx.count); .size = GUM_ADDRESS(-1),
g_hash_table_foreach(unstable_blocks, coverage_write_events, .path = "absolute",
&unstable_coverage_fd); .offset = 0,
.is_executable = true,
.count = size,
.id = 0,
};
instrument_coverage_print("Coverage Module - 0x%016" G_GINT64_MODIFIER
"X - 0x%016" G_GINT64_MODIFIER "X (%s)\n",
module.base_address, module.limit, module.path);
GArray *coverage_modules =
g_array_sized_new(false, false, sizeof(coverage_range_t), 1);
g_array_append_val(coverage_modules, module);
g_hash_table_foreach(unstable_blocks, instrument_coverage_mark_first,
&module);
coverage_write_header(unstable_coverage_fd, 1);
coverage_write_modules(unstable_coverage_fd, coverage_modules);
coverage_format(unstable_coverage_fd, "BB Table: %u bbs\n", size);
g_hash_table_foreach(unstable_blocks, coverage_write_events,
&unstable_coverage_fd);
} else {
GArray *coverage_modules = coverage_get_modules();
coverage_mark_ctx_t ctx = {.modules = coverage_modules, .count = 0};
g_hash_table_foreach(unstable_blocks, instrument_coverage_mark, &ctx);
instrument_coverage_print("Coverage - Marked Entries: %u\n", ctx.count);
guint coverage_marked_modules = coverage_mark_modules(coverage_modules);
instrument_coverage_print("Coverage - Marked Modules: %u\n",
coverage_marked_modules);
coverage_write_header(unstable_coverage_fd, coverage_marked_modules);
coverage_write_modules(unstable_coverage_fd, coverage_modules);
coverage_format(unstable_coverage_fd, "BB Table: %u bbs\n", ctx.count);
g_hash_table_foreach(unstable_blocks, coverage_write_events,
&unstable_coverage_fd);
}
g_hash_table_unref(unstable_blocks); g_hash_table_unref(unstable_blocks);
g_array_free(unstable_edge_ids, TRUE); g_array_free(unstable_edge_ids, TRUE);
@ -660,6 +752,8 @@ static void instrument_coverage_unstable_run(void) {
void instrument_coverage_config(void) { void instrument_coverage_config(void) {
instrument_coverage_filename = getenv("AFL_FRIDA_INST_COVERAGE_FILE"); instrument_coverage_filename = getenv("AFL_FRIDA_INST_COVERAGE_FILE");
instrument_coverage_absolute =
(getenv("AFL_FRIDA_INST_COVERAGE_ABSOLUTE") != NULL);
} }

View File

@ -63,12 +63,14 @@ static void instrument_disasm(guint8 *start, guint8 *end,
count = cs_disasm(capstone, curr, size, GPOINTER_TO_SIZE(curr), 0, &insn); count = cs_disasm(capstone, curr, size, GPOINTER_TO_SIZE(curr), 0, &insn);
if (insn == NULL) { if (insn == NULL) {
instrument_debug("\t0x%" G_GINT64_MODIFIER "x\t* 0x%016" G_GSIZE_MODIFIER instrument_debug("\t0x%" G_GINT64_MODIFIER "x\t* 0x%016" G_GSIZE_MODIFIER
"x\n", "x\n",
(uint64_t)(size_t)curr, *(size_t *)curr); (uint64_t)(size_t)curr, *(size_t *)curr);
len += sizeof(size_t); len += sizeof(size_t);
continue; continue;
} }
for (i = 0; i != count; i++) { for (i = 0; i != count; i++) {

View File

@ -469,6 +469,7 @@ gpointer instrument_cur(GumStalkerOutput *output) {
} }
void instrument_write_regs(GumCpuContext *cpu_context, gpointer user_data) { void instrument_write_regs(GumCpuContext *cpu_context, gpointer user_data) {
int fd = (int)(size_t)user_data; int fd = (int)(size_t)user_data;
instrument_regs_format( instrument_regs_format(
fd, "rax: 0x%016x, rbx: 0x%016x, rcx: 0x%016x, rdx: 0x%016x\n", fd, "rax: 0x%016x, rbx: 0x%016x, rcx: 0x%016x, rdx: 0x%016x\n",
@ -483,6 +484,7 @@ void instrument_write_regs(GumCpuContext *cpu_context, gpointer user_data) {
fd, "r12: 0x%016x, r13: 0x%016x, r14: 0x%016x, r15: 0x%016x\n", fd, "r12: 0x%016x, r13: 0x%016x, r14: 0x%016x, r15: 0x%016x\n",
cpu_context->r12, cpu_context->r13, cpu_context->r14, cpu_context->r15); cpu_context->r12, cpu_context->r13, cpu_context->r14, cpu_context->r15);
instrument_regs_format(fd, "rip: 0x%016x\n\n", cpu_context->rip); instrument_regs_format(fd, "rip: 0x%016x\n\n", cpu_context->rip);
} }
#endif #endif

View File

@ -271,6 +271,7 @@ void instrument_cache(const cs_insn *instr, GumStalkerOutput *output) {
} }
void instrument_write_regs(GumCpuContext *cpu_context, gpointer user_data) { void instrument_write_regs(GumCpuContext *cpu_context, gpointer user_data) {
int fd = (int)(size_t)user_data; int fd = (int)(size_t)user_data;
instrument_regs_format( instrument_regs_format(
fd, "eax: 0x%08x, ebx: 0x%08x, ecx: 0x%08x, edx: 0x%08x\n", fd, "eax: 0x%08x, ebx: 0x%08x, ecx: 0x%08x, edx: 0x%08x\n",
@ -279,6 +280,7 @@ void instrument_write_regs(GumCpuContext *cpu_context, gpointer user_data) {
fd, "esi: 0x%08x, edi: 0x%08x, ebp: 0x%08x, esp: 0x%08x\n", fd, "esi: 0x%08x, edi: 0x%08x, ebp: 0x%08x, esp: 0x%08x\n",
cpu_context->esi, cpu_context->edi, cpu_context->ebp, cpu_context->esp); cpu_context->esi, cpu_context->edi, cpu_context->ebp, cpu_context->esp);
instrument_regs_format(fd, "eip: 0x%08x\n\n", cpu_context->eip); instrument_regs_format(fd, "eip: 0x%08x\n\n", cpu_context->eip);
} }
#endif #endif

View File

@ -104,6 +104,12 @@ class Afl {
static setInstrumentCacheSize(size) { static setInstrumentCacheSize(size) {
Afl.jsApiSetInstrumentCacheSize(size); Afl.jsApiSetInstrumentCacheSize(size);
} }
/**
* See `AFL_FRIDA_INST_COVERAGE_ABSOLUTE`.
*/
static setInstrumentCoverageAbsolute() {
Afl.jsApiSetInstrumentCoverageAbsolute();
}
/** /**
* See `AFL_FRIDA_INST_COVERAGE_FILE`. This function takes a single `string` * See `AFL_FRIDA_INST_COVERAGE_FILE`. This function takes a single `string`
* as an argument. * as an argument.
@ -324,6 +330,7 @@ Afl.jsApiSetCacheDisable = Afl.jsApiGetFunction("js_api_set_cache_disable", "voi
Afl.jsApiSetDebugMaps = Afl.jsApiGetFunction("js_api_set_debug_maps", "void", []); Afl.jsApiSetDebugMaps = Afl.jsApiGetFunction("js_api_set_debug_maps", "void", []);
Afl.jsApiSetEntryPoint = Afl.jsApiGetFunction("js_api_set_entrypoint", "void", ["pointer"]); Afl.jsApiSetEntryPoint = Afl.jsApiGetFunction("js_api_set_entrypoint", "void", ["pointer"]);
Afl.jsApiSetInstrumentCacheSize = Afl.jsApiGetFunction("js_api_set_instrument_cache_size", "void", ["size_t"]); Afl.jsApiSetInstrumentCacheSize = Afl.jsApiGetFunction("js_api_set_instrument_cache_size", "void", ["size_t"]);
Afl.jsApiSetInstrumentCoverageAbsolute = Afl.jsApiGetFunction("js_api_set_instrument_coverage_absolute", "void", []);
Afl.jsApiSetInstrumentCoverageFile = Afl.jsApiGetFunction("js_api_set_instrument_coverage_file", "void", ["pointer"]); Afl.jsApiSetInstrumentCoverageFile = Afl.jsApiGetFunction("js_api_set_instrument_coverage_file", "void", ["pointer"]);
Afl.jsApiSetInstrumentDebugFile = Afl.jsApiGetFunction("js_api_set_instrument_debug_file", "void", ["pointer"]); Afl.jsApiSetInstrumentDebugFile = Afl.jsApiGetFunction("js_api_set_instrument_debug_file", "void", ["pointer"]);
Afl.jsApiSetInstrumentInstructions = Afl.jsApiGetFunction("js_api_set_instrument_instructions", "void", []); Afl.jsApiSetInstrumentInstructions = Afl.jsApiGetFunction("js_api_set_instrument_instructions", "void", []);

View File

@ -115,6 +115,13 @@ __attribute__((visibility("default"))) void js_api_set_instrument_libraries() {
} }
__attribute__((visibility("default"))) void
js_api_set_instrument_coverage_absolute(void) {
instrument_coverage_absolute = true;
}
__attribute__((visibility("default"))) void js_api_set_instrument_coverage_file( __attribute__((visibility("default"))) void js_api_set_instrument_coverage_file(
char *path) { char *path) {
@ -158,7 +165,9 @@ __attribute__((visibility("default"))) void js_api_set_instrument_no_optimize(
__attribute__((visibility("default"))) void js_api_set_instrument_regs_file( __attribute__((visibility("default"))) void js_api_set_instrument_regs_file(
char *path) { char *path) {
instrument_regs_filename = g_strdup(path); instrument_regs_filename = g_strdup(path);
} }
__attribute__((visibility("default"))) void js_api_set_instrument_seed( __attribute__((visibility("default"))) void js_api_set_instrument_seed(

View File

@ -36,6 +36,18 @@
#ifdef __APPLE__ #ifdef __APPLE__
extern mach_port_t mach_task_self(); extern mach_port_t mach_task_self();
extern GumAddress gum_darwin_find_entrypoint(mach_port_t task); extern GumAddress gum_darwin_find_entrypoint(mach_port_t task);
#elif defined(__ANDROID__)
typedef struct {
void (**preinit_array)(void);
void (**init_array)(void);
void (**fini_array)(void);
} structors_array_t;
extern void __libc_init(void *raw_args, void (*onexit)(void) __unused,
int (*slingshot)(int, char **, char **),
structors_array_t const *const structors);
#else #else
extern int __libc_start_main(int (*main)(int, char **, char **), int argc, extern int __libc_start_main(int (*main)(int, char **, char **), int argc,
char **ubp_av, void (*init)(void), char **ubp_av, void (*init)(void),
@ -69,7 +81,11 @@ static void on_main_os(int argc, char **argv, char **envp) {
GumInterceptor *interceptor = gum_interceptor_obtain(); GumInterceptor *interceptor = gum_interceptor_obtain();
gum_interceptor_begin_transaction(interceptor); gum_interceptor_begin_transaction(interceptor);
#if defined(__ANDROID__)
gum_interceptor_revert(interceptor, __libc_init);
#else
gum_interceptor_revert(interceptor, __libc_start_main); gum_interceptor_revert(interceptor, __libc_start_main);
#endif
gum_interceptor_end_transaction(interceptor); gum_interceptor_end_transaction(interceptor);
gum_interceptor_flush(interceptor); gum_interceptor_flush(interceptor);
@ -277,6 +293,24 @@ static void intercept_main(void) {
} }
#elif defined(__ANDROID__)
static void on_libc_init(void *raw_args, void (*onexit)(void) __unused,
int (*slingshot)(int, char **, char **),
structors_array_t const *const structors) {
main_fn = slingshot;
intercept_unhook_self();
intercept_hook(slingshot, on_main, NULL);
return __libc_init(raw_args, onexit, slingshot, structors);
}
static void intercept_main(void) {
intercept_hook(__libc_init, on_libc_init, NULL);
}
#else #else
static int on_libc_start_main(int (*main)(int, char **, char **), int argc, static int on_libc_start_main(int (*main)(int, char **, char **), int argc,
char **ubp_av, void (*init)(void), char **ubp_av, void (*init)(void),

View File

@ -1,75 +1,294 @@
#include "frida-gumjs.h" #include "frida-gumjs.h"
#include "instrument.h"
#include "persistent.h" #include "persistent.h"
#include "util.h" #include "util.h"
#if defined(__arm__) #if defined(__arm__)
struct arm_regs { // struct _GumArmCpuContext {
uint32_t r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10; // guint32 pc;
// guint32 sp;
// guint32 cpsr;
union { // guint32 r8;
// guint32 r9;
// guint32 r10;
// guint32 r11;
// guint32 r12;
uint32_t r11; // GumArmVectorReg v[16];
uint32_t fp;
}; // guint32 _padding;
union { // guint32 r[8];
// guint32 lr;
// };
uint32_t r12; // r11 - fp
uint32_t ip; // r12 - ip
// r13 - sp
// r14 - lr
// r15 - pc
}; static GumCpuContext saved_regs = {0};
static gpointer saved_lr = NULL;
union {
uint32_t r13;
uint32_t sp;
};
union {
uint32_t r14;
uint32_t lr;
};
union {
uint32_t r15;
uint32_t pc;
};
uint32_t cpsr;
uint8_t vfp_zregs[32][16];
uint32_t vfp_xregs[16];
};
typedef struct arm_regs arch_api_regs;
gboolean persistent_is_supported(void) { gboolean persistent_is_supported(void) {
return false; return true;
}
static void instrument_persitent_save_regs(GumArmWriter *cw,
GumCpuContext *regs) {
/* Save Regs */
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_R0, ARM_REG_SP,
GUM_RED_ZONE_SIZE);
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_R1, ARM_REG_SP,
GUM_RED_ZONE_SIZE + sizeof(guint32));
gum_arm_writer_put_ldr_reg_address(cw, ARM_REG_R0, GUM_ADDRESS(regs));
/* Save r1-r7 */
for (size_t i = ARM_REG_R1; i < ARM_REG_R8; i++) {
gum_arm_writer_put_str_reg_reg_offset(
cw, i, ARM_REG_R0, offsetof(GumCpuContext, r[i - ARM_REG_R0]));
}
/* Save r8-r12 */
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_R8, ARM_REG_R0,
offsetof(GumCpuContext, r8));
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_R9, ARM_REG_R0,
offsetof(GumCpuContext, r9));
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_R10, ARM_REG_R0,
offsetof(GumCpuContext, r10));
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_R11, ARM_REG_R0,
offsetof(GumCpuContext, r11));
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_R12, ARM_REG_R0,
offsetof(GumCpuContext, r12));
/* Save sp & lr */
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_SP, ARM_REG_R0,
offsetof(GumCpuContext, sp));
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_LR, ARM_REG_R0,
offsetof(GumCpuContext, lr));
/* Save r0 (load from stack into r1) */
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R1, ARM_REG_SP,
GUM_RED_ZONE_SIZE);
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_R1, ARM_REG_R0,
offsetof(GumCpuContext, r[0]));
/* Save CPSR */
gum_arm_writer_put_mov_reg_cpsr(cw, ARM_REG_R1);
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_R1, ARM_REG_R0,
offsetof(GumCpuContext, cpsr));
/* Save PC */
gum_arm_writer_put_ldr_reg_address(cw, ARM_REG_R1,
GUM_ADDRESS(persistent_start));
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_R1, ARM_REG_R0,
offsetof(GumCpuContext, pc));
/* Restore Regs */
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R1, ARM_REG_SP,
GUM_RED_ZONE_SIZE + sizeof(guint32));
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R0, ARM_REG_SP,
GUM_RED_ZONE_SIZE);
}
static void instrument_persitent_restore_regs(GumArmWriter *cw,
GumCpuContext *regs) {
gum_arm_writer_put_ldr_reg_address(cw, ARM_REG_R0, GUM_ADDRESS(regs));
/* Restore CPSR */
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R1, ARM_REG_R0,
offsetof(GumCpuContext, cpsr));
gum_arm_writer_put_mov_cpsr_reg(cw, ARM_REG_R1);
/* Restore sp & lr */
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_SP, ARM_REG_R0,
offsetof(GumCpuContext, sp));
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_LR, ARM_REG_R0,
offsetof(GumCpuContext, lr));
/* Restore r8-r12 */
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R8, ARM_REG_R0,
offsetof(GumCpuContext, r8));
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R9, ARM_REG_R0,
offsetof(GumCpuContext, r9));
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R10, ARM_REG_R0,
offsetof(GumCpuContext, r10));
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R11, ARM_REG_R0,
offsetof(GumCpuContext, r11));
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R12, ARM_REG_R0,
offsetof(GumCpuContext, r12));
/* Restore r7-r0 */
for (size_t i = ARM_REG_R7; i >= ARM_REG_R0; i--) {
gum_arm_writer_put_ldr_reg_reg_offset(
cw, i, ARM_REG_R0, offsetof(GumCpuContext, r[i - ARM_REG_R0]));
}
}
static void instrument_exit(GumArmWriter *cw) {
gum_arm_writer_put_sub_reg_reg_reg(cw, ARM_REG_R0, ARM_REG_R0, ARM_REG_R0);
gum_arm_writer_put_call_address_with_arguments(cw, GUM_ADDRESS(_exit), 1,
GUM_ARG_REGISTER, ARM_REG_R0);
}
static int instrument_afl_persistent_loop_func(void) {
int ret = __afl_persistent_loop(persistent_count);
if (instrument_previous_pc_addr == NULL) {
FATAL("instrument_previous_pc_addr uninitialized");
}
*instrument_previous_pc_addr = instrument_hash_zero;
return ret;
}
static void instrument_afl_persistent_loop(GumArmWriter *cw) {
gum_arm_writer_put_sub_reg_reg_imm(cw, ARM_REG_SP, ARM_REG_SP,
GUM_RED_ZONE_SIZE);
gum_arm_writer_put_call_address_with_arguments(
cw, GUM_ADDRESS(instrument_afl_persistent_loop_func), 0);
gum_arm_writer_put_add_reg_reg_imm(cw, ARM_REG_SP, ARM_REG_SP,
GUM_RED_ZONE_SIZE);
}
static void persistent_prologue_hook(GumArmWriter *cw, GumCpuContext *regs) {
if (persistent_hook == NULL) return;
gum_arm_writer_put_sub_reg_reg_imm(cw, ARM_REG_SP, ARM_REG_SP,
GUM_RED_ZONE_SIZE);
gum_arm_writer_put_ldr_reg_address(cw, ARM_REG_R2,
GUM_ADDRESS(&__afl_fuzz_len));
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R2, ARM_REG_R2, 0);
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R2, ARM_REG_R2, 0);
gum_arm_writer_put_ldr_reg_address(cw, ARM_REG_R1,
GUM_ADDRESS(&__afl_fuzz_ptr));
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R1, ARM_REG_R1, 0);
gum_arm_writer_put_call_address_with_arguments(
cw, GUM_ADDRESS(persistent_hook), 3, GUM_ARG_ADDRESS, GUM_ADDRESS(regs),
GUM_ARG_REGISTER, ARM_REG_R1, GUM_ARG_REGISTER, ARM_REG_R2);
gum_arm_writer_put_add_reg_reg_imm(cw, ARM_REG_SP, ARM_REG_SP,
GUM_RED_ZONE_SIZE);
}
static void instrument_persitent_save_lr(GumArmWriter *cw) {
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_R0, ARM_REG_SP,
GUM_RED_ZONE_SIZE);
gum_arm_writer_put_ldr_reg_address(cw, ARM_REG_R0, GUM_ADDRESS(&saved_lr));
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_LR, ARM_REG_R0, 0);
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R0, ARM_REG_SP,
GUM_RED_ZONE_SIZE);
} }
void persistent_prologue_arch(GumStalkerOutput *output) { void persistent_prologue_arch(GumStalkerOutput *output) {
UNUSED_PARAMETER(output); /*
FFATAL("Persistent mode not supported on this architecture"); * SAVE REGS
* SAVE RET
* POP RET
* loop:
* CALL instrument_afl_persistent_loop
* TEST EAX, EAX
* JZ end:
* call hook (optionally)
* RESTORE REGS
* call original
* jmp loop:
*
* end:
* JMP SAVED RET
*
* original:
* INSTRUMENTED PERSISTENT FUNC
*/
GumArmWriter *cw = output->writer.arm;
gconstpointer loop = cw->code + 1;
FVERBOSE("Persistent loop reached");
instrument_persitent_save_regs(cw, &saved_regs);
/* loop: */
gum_arm_writer_put_label(cw, loop);
/* call instrument_prologue_func */
instrument_afl_persistent_loop(cw);
/* jz done */
gconstpointer done = cw->code + 1;
gum_arm_writer_put_cmp_reg_imm(cw, ARM_REG_R0, 0);
gum_arm_writer_put_b_cond_label(cw, ARM_CC_EQ, done);
/* Optionally call the persistent hook */
persistent_prologue_hook(cw, &saved_regs);
instrument_persitent_restore_regs(cw, &saved_regs);
gconstpointer original = cw->code + 1;
/* call original */
gum_arm_writer_put_bl_label(cw, original);
/* jmp loop */
gum_arm_writer_put_b_label(cw, loop);
/* done: */
gum_arm_writer_put_label(cw, done);
instrument_exit(cw);
/* original: */
gum_arm_writer_put_label(cw, original);
instrument_persitent_save_lr(cw);
if (persistent_debug) { gum_arm_writer_put_breakpoint(cw); }
} }
void persistent_epilogue_arch(GumStalkerOutput *output) { void persistent_epilogue_arch(GumStalkerOutput *output) {
UNUSED_PARAMETER(output); GumArmWriter *cw = output->writer.arm;
FFATAL("Persistent mode not supported on this architecture");
if (persistent_debug) { gum_arm_writer_put_breakpoint(cw); }
gum_arm_writer_put_ldr_reg_address(cw, ARM_REG_R0, GUM_ADDRESS(&saved_lr));
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R0, ARM_REG_R0, 0);
gum_arm_writer_put_bx_reg(cw, ARM_REG_R0);
} }

View File

@ -1,12 +1,11 @@
#include <errno.h> #include <errno.h>
#include <sys/shm.h>
#include <sys/mman.h>
#include "frida-gumjs.h" #include "frida-gumjs.h"
#include "entry.h" #include "entry.h"
#include "intercept.h" #include "intercept.h"
#include "prefetch.h" #include "prefetch.h"
#include "shm.h"
#include "stalker.h" #include "stalker.h"
#include "util.h" #include "util.h"
@ -285,28 +284,7 @@ void prefetch_init(void) {
* with the coverage bitmap region and fork will take care of ensuring both * with the coverage bitmap region and fork will take care of ensuring both
* the parent and child see the same consistent memory region. * the parent and child see the same consistent memory region.
*/ */
prefetch_shm_id = prefetch_data = shm_create(sizeof(prefetch_data_t));
shmget(IPC_PRIVATE, sizeof(prefetch_data_t), IPC_CREAT | IPC_EXCL | 0600);
if (prefetch_shm_id < 0) {
FFATAL("prefetch_shm_id < 0 - errno: %d\n", errno);
}
prefetch_data = shmat(prefetch_shm_id, NULL, 0);
g_assert(prefetch_data != MAP_FAILED);
/*
* Configure the shared memory region to be removed once the process dies.
*/
if (shmctl(prefetch_shm_id, IPC_RMID, NULL) < 0) {
FFATAL("shmctl (IPC_RMID) < 0 - errno: %d\n", errno);
}
/* Clear it, not sure it's necessary, just seems like good practice */
memset(prefetch_data, '\0', sizeof(prefetch_data_t));
prefetch_hook_fork(); prefetch_hook_fork();

View File

@ -11,6 +11,8 @@ void seccomp_on_fork(void) {
#ifdef __APPLE__ #ifdef __APPLE__
FFATAL("Seccomp not supported on OSX"); FFATAL("Seccomp not supported on OSX");
#elif defined(__ANDROID__)
FFATAL("Seccomp not supported on Android");
#else #else
seccomp_callback_parent(); seccomp_callback_parent();
#endif #endif
@ -32,6 +34,8 @@ void seccomp_init(void) {
#ifdef __APPLE__ #ifdef __APPLE__
FFATAL("Seccomp not supported on OSX"); FFATAL("Seccomp not supported on OSX");
#elif defined(__ANDROID__)
FFATAL("Seccomp not supported on Android");
#else #else
seccomp_callback_initialize(); seccomp_callback_initialize();
#endif #endif

87
frida_mode/src/shm.c Normal file
View File

@ -0,0 +1,87 @@
#include "shm.h"
#include "util.h"
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/mman.h>
#include <sys/shm.h>
#ifdef __ANDROID__
#include <linux/ashmem.h>
#include <sys/ioctl.h>
#endif
#ifdef __ANDROID__
#define ASHMEM_DEVICE "/dev/ashmem"
void *shm_create(size_t size) {
int fd = -1;
char ourkey[11] = {0};
void *addr = MAP_FAILED;
struct ashmem_pin pin = {0, size};
fd = open(ASHMEM_DEVICE, O_RDWR);
if (fd < 0) { FFATAL("Failed open /dev/ashmem: %d", errno); }
if (snprintf(ourkey, sizeof(ourkey) - 1, "%d", IPC_PRIVATE) < 0) {
FFATAL("Failed to generate key: %d", errno);
}
if (ioctl(fd, ASHMEM_SET_NAME, ourkey) < 0) {
FFATAL("ioctl(ASHMEM_SET_NAME) errno: %d\n", errno);
}
if (ioctl(fd, ASHMEM_SET_SIZE, size) < 0) {
FFATAL("ioctl(ASHMEM_SET_SIZE) errno: %d\n", errno);
}
addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (addr == MAP_FAILED) { FFATAL("mmap failed: %d\n", errno); }
/* Shared memory pinning has been deprecated. So if the ioctl fails, then
just assume we are running on a version where it has been. Worst case, we
will leak the shared memory region.*/
ioctl(fd, ASHMEM_UNPIN, &pin);
close(fd);
return addr;
}
#else
void *shm_create(size_t size) {
int shm_id =
shmget(IPC_PRIVATE, size, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR);
if (shm_id < 0) { FFATAL("shm_id < 0 - errno: %d\n", errno); }
void *addr = shmat(shm_id, NULL, 0);
if (addr == MAP_FAILED) { FFATAL("addr == MAP_FAILED - errno: %d\n", errno); }
/*
* Configure the shared memory region to be removed once the process
* dies.
*/
if (shmctl(shm_id, IPC_RMID, NULL) < 0) {
FFATAL("shmctl (IPC_RMID) < 0 - errno: %d\n", errno);
}
/* Clear it, not sure it's necessary, just seems like good practice */
memset(addr, '\0', size);
return addr;
}
#endif

View File

@ -2,17 +2,16 @@
#include <fcntl.h> #include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <sys/shm.h>
#include <sys/mman.h> #include <sys/mman.h>
#include "frida-gumjs.h" #include "frida-gumjs.h"
#include "config.h" #include "config.h"
#include "util.h"
#include "entry.h" #include "entry.h"
#include "shm.h"
#include "stalker.h" #include "stalker.h"
#include "stats.h" #include "stats.h"
#include "util.h"
#define MICRO_TO_SEC 1000000 #define MICRO_TO_SEC 1000000
@ -360,27 +359,10 @@ void stats_init(void) {
g_free(path); g_free(path);
int shm_id =
shmget(IPC_PRIVATE, sizeof(stats_data_t), IPC_CREAT | IPC_EXCL | 0600);
if (shm_id < 0) { FFATAL("shm_id < 0 - errno: %d\n", errno); }
stats_data = shmat(shm_id, NULL, 0);
g_assert(stats_data != MAP_FAILED);
GumStalkerObserver *observer = stalker_get_observer(); GumStalkerObserver *observer = stalker_get_observer();
stats_observer_init(observer); stats_observer_init(observer);
/* stats_data = shm_create(sizeof(stats_data_t));
* Configure the shared memory region to be removed once the process dies.
*/
if (shmctl(shm_id, IPC_RMID, NULL) < 0) {
FFATAL("shmctl (IPC_RMID) < 0 - errno: %d\n", errno);
}
/* Clear it, not sure it's necessary, just seems like good practice */
memset(stats_data, '\0', sizeof(stats_data_t));
starts_arch_init(); starts_arch_init();

View File

@ -1,9 +1,9 @@
#include <sys/shm.h>
#include <sys/mman.h> #include <sys/mman.h>
#include "frida-gumjs.h" #include "frida-gumjs.h"
#include "ranges.h" #include "ranges.h"
#include "shm.h"
#include "stats.h" #include "stats.h"
#include "util.h" #include "util.h"
@ -44,24 +44,7 @@ static stats_data_arch_t *stats_data_arch = NULL;
void starts_arch_init(void) { void starts_arch_init(void) {
int shm_id = shmget(IPC_PRIVATE, sizeof(stats_data_arch_t), stats_data_arch = shm_create(sizeof(stats_data_arch_t));
IPC_CREAT | IPC_EXCL | 0600);
if (shm_id < 0) { FFATAL("shm_id < 0 - errno: %d\n", errno); }
stats_data_arch = shmat(shm_id, NULL, 0);
g_assert(stats_data_arch != MAP_FAILED);
/*
* Configure the shared memory region to be removed once the process dies.
*/
if (shmctl(shm_id, IPC_RMID, NULL) < 0) {
FFATAL("shmctl (IPC_RMID) < 0 - errno: %d\n", errno);
}
/* Clear it, not sure it's necessary, just seems like good practice */
memset(stats_data_arch, '\0', sizeof(stats_data_arch_t));
} }

View File

@ -1,9 +1,9 @@
#include <sys/shm.h>
#include <sys/mman.h> #include <sys/mman.h>
#include "frida-gumjs.h" #include "frida-gumjs.h"
#include "ranges.h" #include "ranges.h"
#include "shm.h"
#include "stats.h" #include "stats.h"
#include "util.h" #include "util.h"
@ -46,24 +46,7 @@ static stats_data_arch_t *stats_data_arch = NULL;
void starts_arch_init(void) { void starts_arch_init(void) {
int shm_id = shmget(IPC_PRIVATE, sizeof(stats_data_arch_t), stats_data_arch = shm_create(sizeof(stats_data_arch_t));
IPC_CREAT | IPC_EXCL | 0600);
if (shm_id < 0) { FFATAL("shm_id < 0 - errno: %d\n", errno); }
stats_data_arch = shmat(shm_id, NULL, 0);
g_assert(stats_data_arch != MAP_FAILED);
/*
* Configure the shared memory region to be removed once the process dies.
*/
if (shmctl(shm_id, IPC_RMID, NULL) < 0) {
FFATAL("shmctl (IPC_RMID) < 0 - errno: %d\n", errno);
}
/* Clear it, not sure it's necessary, just seems like good practice */
memset(stats_data_arch, '\0', sizeof(stats_data_arch_t));
} }

View File

@ -14,6 +14,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/time.h>
#ifdef __APPLE__ #ifdef __APPLE__
#define TESTINSTR_SECTION #define TESTINSTR_SECTION
@ -25,8 +26,10 @@ void LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
if (size < 1) return; if (size < 1) return;
int r = rand(); struct timeval tv = {0};
if ((r % 2) == 0) { if (gettimeofday(&tv, NULL) < 0) return;
if ((tv.tv_usec % 2) == 0) {
printf ("Hooray all even\n"); printf ("Hooray all even\n");
} else { } else {
printf ("Hmm that's odd\n"); printf ("Hmm that's odd\n");

View File

@ -125,6 +125,13 @@ class Afl {
Afl.jsApiSetInstrumentCacheSize(size); Afl.jsApiSetInstrumentCacheSize(size);
} }
/**
* See `AFL_FRIDA_INST_COVERAGE_ABSOLUTE`.
*/
public static setInstrumentCoverageAbsolute(): void {
Afl.jsApiSetInstrumentCoverageAbsolute();
}
/** /**
* See `AFL_FRIDA_INST_COVERAGE_FILE`. This function takes a single `string` * See `AFL_FRIDA_INST_COVERAGE_FILE`. This function takes a single `string`
* as an argument. * as an argument.
@ -398,6 +405,12 @@ class Afl {
"void", "void",
["size_t"]); ["size_t"]);
private static readonly jsApiSetInstrumentCoverageAbsolute = Afl.jsApiGetFunction(
"js_api_set_instrument_coverage_absolute",
"void",
[]
);
private static readonly jsApiSetInstrumentCoverageFile = Afl.jsApiGetFunction( private static readonly jsApiSetInstrumentCoverageFile = Afl.jsApiGetFunction(
"js_api_set_instrument_coverage_file", "js_api_set_instrument_coverage_file",
"void", "void",

View File

@ -26,7 +26,7 @@
/* Version string: */ /* Version string: */
// c = release, a = volatile github dev, e = experimental branch // c = release, a = volatile github dev, e = experimental branch
#define VERSION "++4.02a" #define VERSION "++4.02c"
/****************************************************** /******************************************************
* * * *

View File

@ -58,6 +58,7 @@ static char *afl_environment_variables[] = {
"AFL_FRIDA_DRIVER_NO_HOOK", "AFL_FRIDA_DRIVER_NO_HOOK",
"AFL_FRIDA_EXCLUDE_RANGES", "AFL_FRIDA_EXCLUDE_RANGES",
"AFL_FRIDA_INST_CACHE_SIZE", "AFL_FRIDA_INST_CACHE_SIZE",
"AFL_FRIDA_INST_COVERAGE_ABSOLUTE",
"AFL_FRIDA_INST_COVERAGE_FILE", "AFL_FRIDA_INST_COVERAGE_FILE",
"AFL_FRIDA_INST_DEBUG_FILE", "AFL_FRIDA_INST_DEBUG_FILE",
"AFL_FRIDA_INST_INSN", "AFL_FRIDA_INST_INSN",