diff options
Diffstat (limited to 'frida_mode')
| -rw-r--r-- | frida_mode/GNUmakefile | 4 | ||||
| -rw-r--r-- | frida_mode/src/cmplog/cmplog.c | 149 | ||||
| -rw-r--r-- | frida_mode/src/cmplog/cmplog_x64.c | 22 | ||||
| -rw-r--r-- | frida_mode/src/ctx/ctx_x64.c | 22 | ||||
| -rw-r--r-- | frida_mode/src/ctx/ctx_x86.c | 6 | ||||
| -rw-r--r-- | frida_mode/src/main.c | 6 | ||||
| -rw-r--r-- | frida_mode/test/jpeg/GNUmakefile | 172 | ||||
| -rw-r--r-- | frida_mode/test/jpeg/Makefile | 19 | ||||
| -rw-r--r-- | frida_mode/test/jpeg/aflpp_qemu_driver_hook.c | 97 | ||||
| -rwxr-xr-x | frida_mode/test/jpeg/get_symbol_addr.py | 36 | ||||
| -rw-r--r-- | frida_mode/test/proj4/GNUmakefile | 172 | ||||
| -rw-r--r-- | frida_mode/test/proj4/Makefile | 19 | ||||
| -rw-r--r-- | frida_mode/test/proj4/aflpp_qemu_driver_hook.c | 97 | ||||
| -rwxr-xr-x | frida_mode/test/proj4/get_symbol_addr.py | 36 |
14 files changed, 768 insertions, 89 deletions
diff --git a/frida_mode/GNUmakefile b/frida_mode/GNUmakefile index 329d9f7f..2f637412 100644 --- a/frida_mode/GNUmakefile +++ b/frida_mode/GNUmakefile @@ -25,8 +25,7 @@ RT_CFLAGS:=-Wno-unused-parameter \ LDFLAGS+=-shared \ -lpthread \ -lresolv \ - -ldl \ - -z noexecstack \ + -ldl ifdef DEBUG CFLAGS+=-Werror \ @@ -60,6 +59,7 @@ else ifdef DEBUG RT_CFLAGS:=$(RT_CFLAGS) -Wno-prio-ctor-dtor endif +LDFLAGS+=-z noexecstack endif ifeq "$(shell uname)" "Linux" diff --git a/frida_mode/src/cmplog/cmplog.c b/frida_mode/src/cmplog/cmplog.c index 3df7d13d..0e3fbe53 100644 --- a/frida_mode/src/cmplog/cmplog.c +++ b/frida_mode/src/cmplog/cmplog.c @@ -1,7 +1,9 @@ #include <errno.h> #include <fcntl.h> #include <limits.h> -#include <syscall.h> +#include <sys/mman.h> +#include <sys/syscall.h> +#include <unistd.h> #include "frida-gum.h" @@ -10,18 +12,21 @@ #include "util.h" #define DEFAULT_MMAP_MIN_ADDR (32UL << 10) -#define FD_TMP_MAX_SIZE 65536 +#define MAX_MEMFD_SIZE (64UL << 10) extern struct cmp_map *__afl_cmp_map; +static GArray * cmplog_ranges = NULL; +static GHashTable * hash_yes = NULL; +static GHashTable * hash_no = NULL; -static GArray *cmplog_ranges = NULL; -static int fd_tmp = -1; -static ssize_t fd_tmp_size = 0; +static long page_size = 0; +static long page_offset_mask = 0; +static long page_mask = 0; static gboolean cmplog_range(const GumRangeDetails *details, gpointer user_data) { - UNUSED_PARAMETER(user_data); + GArray * cmplog_ranges = (GArray *)user_data; GumMemoryRange range = *details->range; g_array_append_val(cmplog_ranges, range); return TRUE; @@ -35,54 +40,46 @@ static gint cmplog_sort(gconstpointer a, gconstpointer b) { } -static int cmplog_create_temp(void) { +static void cmplog_get_ranges(void) { - const char *tmpdir = g_get_tmp_dir(); - OKF("CMPLOG Temporary directory: %s", tmpdir); - gchar *fname = g_strdup_printf("%s/frida-cmplog-XXXXXX", tmpdir); - OKF("CMPLOG Temporary file template: %s", fname); - int fd = mkstemp(fname); - OKF("CMPLOG Temporary file: %s", fname); + OKF("CMPLOG - Collecting ranges"); - if (fd < 0) { - - FATAL("Failed to create temp file: %s, errno: %d", fname, errno); + cmplog_ranges = g_array_sized_new(false, false, sizeof(GumMemoryRange), 100); + gum_process_enumerate_ranges(GUM_PAGE_READ, cmplog_range, cmplog_ranges); + g_array_sort(cmplog_ranges, cmplog_sort); - } +} - if (unlink(fname) < 0) { +void cmplog_init(void) { - FATAL("Failed to unlink temp file: %s (%d), errno: %d", fname, fd, errno); + if (__afl_cmp_map != NULL) { OKF("CMPLOG mode enabled"); } - } + cmplog_get_ranges(); - if (ftruncate(fd, 0) < 0) { + for (guint i = 0; i < cmplog_ranges->len; i++) { - FATAL("Failed to ftruncate temp file: %s (%d), errno: %d", fname, fd, - errno); + GumMemoryRange *range = &g_array_index(cmplog_ranges, GumMemoryRange, i); + OKF("CMPLOG Range - %3u: 0x%016" G_GINT64_MODIFIER + "X - 0x%016" G_GINT64_MODIFIER "X", + i, range->base_address, range->base_address + range->size); } - g_free(fname); + page_size = sysconf(_SC_PAGE_SIZE); + page_offset_mask = page_size - 1; + page_mask = ~(page_offset_mask); - return fd; - -} + hash_yes = g_hash_table_new(g_direct_hash, g_direct_equal); + if (hash_yes == NULL) { -void cmplog_init(void) { - - if (__afl_cmp_map != NULL) { OKF("CMPLOG mode enabled"); } + FATAL("Failed to g_hash_table_new, errno: %d", errno); - cmplog_ranges = g_array_sized_new(false, false, sizeof(GumMemoryRange), 100); - gum_process_enumerate_ranges(GUM_PAGE_READ, cmplog_range, NULL); - g_array_sort(cmplog_ranges, cmplog_sort); + } - for (guint i = 0; i < cmplog_ranges->len; i++) { + hash_no = g_hash_table_new(g_direct_hash, g_direct_equal); + if (hash_no == NULL) { - GumMemoryRange *range = &g_array_index(cmplog_ranges, GumMemoryRange, i); - OKF("CMPLOG Range - 0x%016" G_GINT64_MODIFIER "X - 0x%016" G_GINT64_MODIFIER - "X", - range->base_address, range->base_address + range->size); + FATAL("Failed to g_hash_table_new, errno: %d", errno); } @@ -102,6 +99,45 @@ static gboolean cmplog_contains(GumAddress inner_base, GumAddress inner_limit, } +gboolean cmplog_test_addr(guint64 addr, size_t size) { + + if (g_hash_table_contains(hash_yes, (gpointer)addr)) { return true; } + if (g_hash_table_contains(hash_no, (gpointer)addr)) { return false; } + + void * page_addr = (void *)(addr & page_mask); + size_t page_offset = addr & page_offset_mask; + + /* If it spans a page, then bail */ + if (page_size - page_offset < size) { return false; } + + /* + * Our address map can change (e.g. stack growth), use msync as a fallback to + * validate our address. + */ + if (msync(page_addr, page_offset + size, MS_ASYNC) < 0) { + + if (!g_hash_table_add(hash_no, (gpointer)addr)) { + + FATAL("Failed - g_hash_table_add"); + + } + + return false; + + } else { + + if (!g_hash_table_add(hash_yes, (gpointer)addr)) { + + FATAL("Failed - g_hash_table_add"); + + } + + return true; + + } + +} + gboolean cmplog_is_readable(guint64 addr, size_t size) { if (cmplog_ranges == NULL) FATAL("CMPLOG not initialized"); @@ -125,45 +161,16 @@ gboolean cmplog_is_readable(guint64 addr, size_t size) { for (guint i = 0; i < cmplog_ranges->len; i++) { GumMemoryRange *range = &g_array_index(cmplog_ranges, GumMemoryRange, i); - GumAddress outer_base = range->base_address; - GumAddress outer_limit = outer_base + range->size; + + GumAddress outer_base = range->base_address; + GumAddress outer_limit = outer_base + range->size; if (cmplog_contains(inner_base, inner_limit, outer_base, outer_limit)) return true; } - /* - * Our address map can change (e.g. stack growth), use write as a fallback to - * validate our address. - */ - ssize_t written = syscall(__NR_write, fd_tmp, (void *)addr, size); - - /* - * If the write succeeds, then the buffer must be valid otherwise it would - * return EFAULT - */ - if (written > 0) { - - fd_tmp_size += written; - if (fd_tmp_size > FD_TMP_MAX_SIZE) { - - /* - * Truncate the file, we don't want our temp file to continue growing! - */ - if (ftruncate(fd_tmp, 0) < 0) { - - FATAL("Failed to truncate fd_tmp (%d), errno: %d", fd_tmp, errno); - - } - - fd_tmp_size = 0; - - } - - if ((size_t)written == size) { return true; } - - } + if (cmplog_test_addr(addr, size)) { return true; } return false; diff --git a/frida_mode/src/cmplog/cmplog_x64.c b/frida_mode/src/cmplog/cmplog_x64.c index 9f56c32a..ba16445d 100644 --- a/frida_mode/src/cmplog/cmplog_x64.c +++ b/frida_mode/src/cmplog/cmplog_x64.c @@ -177,7 +177,7 @@ static void cmplog_handle_cmp_sub(GumCpuContext *context, gsize operand1, register uintptr_t k = (uintptr_t)address; k = (k >> 4) ^ (k << 8); - k &= CMP_MAP_W - 1; + k &= CMP_MAP_W - 7; __afl_cmp_map->headers[k].type = CMP_TYPE_INS; @@ -198,8 +198,6 @@ static void cmplog_cmp_sub_callout(GumCpuContext *context, gpointer user_data) { gsize operand1; gsize operand2; - if (ctx->operand1.size != ctx->operand2.size) FATAL("Operand size mismatch"); - if (!cmplog_get_operand_value(context, &ctx->operand1, &operand1)) { return; } if (!cmplog_get_operand_value(context, &ctx->operand2, &operand2)) { return; } @@ -233,6 +231,15 @@ static void cmplog_instrument_cmp_sub(const cs_insn * instr, case X86_INS_CMP: case X86_INS_SUB: + case X86_INS_SCASB: + case X86_INS_SCASD: + case X86_INS_SCASQ: + case X86_INS_SCASW: + case X86_INS_CMPSB: + case X86_INS_CMPSD: + case X86_INS_CMPSQ: + case X86_INS_CMPSS: + case X86_INS_CMPSW: break; default: return; @@ -247,13 +254,8 @@ static void cmplog_instrument_cmp_sub(const cs_insn * instr, if (operand1->type == X86_OP_INVALID) return; if (operand2->type == X86_OP_INVALID) return; - if ((operand1->type == X86_OP_MEM) && - (operand1->mem.segment != X86_REG_INVALID)) - return; - - if ((operand2->type == X86_OP_MEM) && - (operand2->mem.segment != X86_REG_INVALID)) - return; + /* Both operands are the same size */ + if (operand1->size == 1) { return; } cmplog_instrument_cmp_sub_put_callout(iterator, operand1, operand2); diff --git a/frida_mode/src/ctx/ctx_x64.c b/frida_mode/src/ctx/ctx_x64.c index c5900533..1772a252 100644 --- a/frida_mode/src/ctx/ctx_x64.c +++ b/frida_mode/src/ctx/ctx_x64.c @@ -49,9 +49,18 @@ gsize ctx_read_reg(GumX64CpuContext *ctx, x86_reg reg) { X86_REG_8L(X86_REG_BL, ctx->rbx) X86_REG_8L(X86_REG_CL, ctx->rcx) X86_REG_8L(X86_REG_DL, ctx->rdx) + X86_REG_8L(X86_REG_SPL, ctx->rsp) X86_REG_8L(X86_REG_BPL, ctx->rbp) X86_REG_8L(X86_REG_SIL, ctx->rsi) X86_REG_8L(X86_REG_DIL, ctx->rdi) + X86_REG_8L(X86_REG_R8B, ctx->r8) + X86_REG_8L(X86_REG_R9B, ctx->r9) + X86_REG_8L(X86_REG_R10B, ctx->r10) + X86_REG_8L(X86_REG_R11B, ctx->r11) + X86_REG_8L(X86_REG_R12B, ctx->r12) + X86_REG_8L(X86_REG_R13B, ctx->r13) + X86_REG_8L(X86_REG_R14B, ctx->r14) + X86_REG_8L(X86_REG_R15B, ctx->r15) X86_REG_8H(X86_REG_AH, ctx->rax) X86_REG_8H(X86_REG_BH, ctx->rbx) @@ -62,14 +71,23 @@ gsize ctx_read_reg(GumX64CpuContext *ctx, x86_reg reg) { X86_REG_16(X86_REG_BX, ctx->rbx) X86_REG_16(X86_REG_CX, ctx->rcx) X86_REG_16(X86_REG_DX, ctx->rdx) + X86_REG_16(X86_REG_SP, ctx->rsp) + X86_REG_16(X86_REG_BP, ctx->rbp) X86_REG_16(X86_REG_DI, ctx->rdi) X86_REG_16(X86_REG_SI, ctx->rsi) - X86_REG_16(X86_REG_BP, ctx->rbp) + X86_REG_16(X86_REG_R8W, ctx->r8) + X86_REG_16(X86_REG_R9W, ctx->r9) + X86_REG_16(X86_REG_R10W, ctx->r10) + X86_REG_16(X86_REG_R11W, ctx->r11) + X86_REG_16(X86_REG_R12W, ctx->r12) + X86_REG_16(X86_REG_R13W, ctx->r13) + X86_REG_16(X86_REG_R14W, ctx->r14) + X86_REG_16(X86_REG_R15W, ctx->r15) X86_REG_32(X86_REG_EAX, ctx->rax) + X86_REG_32(X86_REG_EBX, ctx->rbx) X86_REG_32(X86_REG_ECX, ctx->rcx) X86_REG_32(X86_REG_EDX, ctx->rdx) - X86_REG_32(X86_REG_EBX, ctx->rbx) X86_REG_32(X86_REG_ESP, ctx->rsp) X86_REG_32(X86_REG_EBP, ctx->rbp) X86_REG_32(X86_REG_ESI, ctx->rsi) diff --git a/frida_mode/src/ctx/ctx_x86.c b/frida_mode/src/ctx/ctx_x86.c index 45308272..9b50cb52 100644 --- a/frida_mode/src/ctx/ctx_x86.c +++ b/frida_mode/src/ctx/ctx_x86.c @@ -42,6 +42,7 @@ gsize ctx_read_reg(GumIA32CpuContext *ctx, x86_reg reg) { X86_REG_8L(X86_REG_BL, ctx->ebx) X86_REG_8L(X86_REG_CL, ctx->ecx) X86_REG_8L(X86_REG_DL, ctx->edx) + X86_REG_8L(X86_REG_SPL, ctx->esp) X86_REG_8L(X86_REG_BPL, ctx->ebp) X86_REG_8L(X86_REG_SIL, ctx->esi) X86_REG_8L(X86_REG_DIL, ctx->edi) @@ -55,14 +56,15 @@ gsize ctx_read_reg(GumIA32CpuContext *ctx, x86_reg reg) { X86_REG_16(X86_REG_BX, ctx->ebx) X86_REG_16(X86_REG_CX, ctx->ecx) X86_REG_16(X86_REG_DX, ctx->edx) + X86_REG_16(X86_REG_SP, ctx->esp) + X86_REG_16(X86_REG_BP, ctx->ebp) X86_REG_16(X86_REG_DI, ctx->edi) X86_REG_16(X86_REG_SI, ctx->esi) - X86_REG_16(X86_REG_BP, ctx->ebp) X86_REG_32(X86_REG_EAX, ctx->eax) + X86_REG_32(X86_REG_EBX, ctx->ebx) X86_REG_32(X86_REG_ECX, ctx->ecx) X86_REG_32(X86_REG_EDX, ctx->edx) - X86_REG_32(X86_REG_EBX, ctx->ebx) X86_REG_32(X86_REG_ESP, ctx->esp) X86_REG_32(X86_REG_EBP, ctx->ebp) X86_REG_32(X86_REG_ESI, ctx->esi) diff --git a/frida_mode/src/main.c b/frida_mode/src/main.c index 7ff23755..b17d9f49 100644 --- a/frida_mode/src/main.c +++ b/frida_mode/src/main.c @@ -101,7 +101,8 @@ static void afl_print_cmdline(void) { if (fd < 0) { - FATAL("Failed to open /proc/self/cmdline, errno: (%d)", errno); + WARNF("Failed to open /proc/self/cmdline, errno: (%d)", errno); + return; } @@ -138,7 +139,8 @@ static void afl_print_env(void) { if (fd < 0) { - FATAL("Failed to open /proc/self/cmdline, errno: (%d)", errno); + WARNF("Failed to open /proc/self/cmdline, errno: (%d)", errno); + return; } diff --git a/frida_mode/test/jpeg/GNUmakefile b/frida_mode/test/jpeg/GNUmakefile new file mode 100644 index 00000000..689fce3d --- /dev/null +++ b/frida_mode/test/jpeg/GNUmakefile @@ -0,0 +1,172 @@ +PWD:=$(shell pwd)/ +ROOT:=$(shell realpath $(PWD)../../..)/ +BUILD_DIR:=$(PWD)build/ + +AFLPP_DRIVER_HOOK_SRC=$(PWD)aflpp_qemu_driver_hook.c +AFLPP_DRIVER_HOOK_OBJ=$(BUILD_DIR)aflpp_qemu_driver_hook.so + +LIBJPEG_BUILD_DIR:=$(BUILD_DIR)libjpeg/ +HARNESS_BUILD_DIR:=$(BUILD_DIR)harness/ +JPEGTEST_BUILD_DIR:=$(BUILD_DIR)jpegtest/ + +LIBJPEG_URL:=https://github.com/libjpeg-turbo/libjpeg-turbo.git +LIBJPEG_DIR:=$(LIBJPEG_BUILD_DIR)libjpeg/ +LIBJPEG_CONFIGURE:=$(LIBJPEG_DIR)configure.ac +LIBJPEG_MAKEFILE:=$(LIBJPEG_DIR)Makefile +LIBJPEG_LIB:=$(LIBJPEG_DIR).libs/libturbojpeg.a + +HARNESS_FILE:=$(HARNESS_BUILD_DIR)StandaloneFuzzTargetMain.c +HARNESS_OBJ:=$(HARNESS_BUILD_DIR)StandaloneFuzzTargetMain.o +HARNESS_URL:="https://raw.githubusercontent.com/AFLplusplus/AFLplusplus/stable/utils/aflpp_driver/aflpp_qemu_driver.c" + +JPEGTEST_FILE:=$(JPEGTEST_BUILD_DIR)target.cc +JPEGTEST_OBJ:=$(JPEGTEST_BUILD_DIR)target.o +JPEGTEST_URL:="https://raw.githubusercontent.com/google/fuzzbench/master/benchmarks/libjpeg-turbo-07-2017/libjpeg_turbo_fuzzer.cc" + +LDFLAGS += -lpthread + +TEST_BIN:=$(BUILD_DIR)test +ifeq "$(shell uname)" "Darwin" +TEST_BIN_LDFLAGS:=-undefined dynamic_lookup +endif + +TEST_DATA_DIR:=$(BUILD_DIR)in/ +TEST_DATA_FILE:=$(TEST_DATA_DIR)default_seed + +FRIDA_OUT:=$(BUILD_DIR)frida-out + +ifndef ARCH + +ARCH=$(shell uname -m) +ifeq "$(ARCH)" "aarch64" + ARCH:=arm64 +endif + +ifeq "$(ARCH)" "i686" + ARCH:=x86 +endif +endif + +ifeq "$(ARCH)" "aarch64" + AFL_FRIDA_PERSISTENT_ADDR=$(shell $(PWD)get_symbol_addr.py -f $(TEST_BIN) -s LLVMFuzzerTestOneInput -b 0x0000aaaaaaaaa000) +endif + +ifeq "$(ARCH)" "x86_64" + AFL_FRIDA_PERSISTENT_ADDR=$(shell $(PWD)get_symbol_addr.py -f $(TEST_BIN) -s LLVMFuzzerTestOneInput -b 0x0000555555554000) +endif + +ifeq "$(ARCH)" "x86" + AFL_FRIDA_PERSISTENT_ADDR=$(shell $(PWD)get_symbol_addr.py -f $(TEST_BIN) -s LLVMFuzzerTestOneInput -b 0x56555000) +endif + +.PHONY: all clean frida hook + +all: $(TEST_BIN) + make -C $(ROOT)frida_mode/ + +32: + CXXFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all + +$(BUILD_DIR): + mkdir -p $@ + +######### HARNESS ######## +$(HARNESS_BUILD_DIR): | $(BUILD_DIR) + mkdir -p $@ + +$(HARNESS_FILE): | $(HARNESS_BUILD_DIR) + wget -O $@ $(HARNESS_URL) + +$(HARNESS_OBJ): $(HARNESS_FILE) + $(CC) $(CXXFLAGS) $(LDFLAGS) -o $@ -c $< + +######### JPEGTEST ######## + +$(JPEGTEST_BUILD_DIR): | $(BUILD_DIR) + mkdir -p $@ + +$(JPEGTEST_FILE): | $(JPEGTEST_BUILD_DIR) + wget -O $@ $(JPEGTEST_URL) + +$(JPEGTEST_OBJ): $(JPEGTEST_FILE) | $(LIBJPEG_MAKEFILE) + $(CXX) $(CXXFLAGS) $(LDFLAGS) -std=c++11 -I $(LIBJPEG_DIR) -o $@ -c $< + +######### LIBJPEG ######## + +$(LIBJPEG_BUILD_DIR): | $(BUILD_DIR) + mkdir -p $@ + +$(LIBJPEG_CONFIGURE): $(LIBJPEG_BUILD_DIR) + git clone $(LIBJPEG_URL) $(LIBJPEG_DIR) + cd $(LIBJPEG_DIR) && git checkout b0971e47d76fdb81270e93bbf11ff5558073350d + +$(LIBJPEG_MAKEFILE): $(LIBJPEG_CONFIGURE) + cd $(LIBJPEG_DIR) && autoreconf -fiv + cd $(LIBJPEG_DIR) && ./configure + +$(LIBJPEG_LIB): $(LIBJPEG_MAKEFILE) + make -C $(LIBJPEG_DIR) -j $(shell nproc) + +######### TEST ######## + +$(TEST_BIN): $(HARNESS_OBJ) $(JPEGTEST_OBJ) $(LIBJPEG_LIB) + $(CXX) \ + $(CFLAGS) \ + -o $@ \ + $(HARNESS_OBJ) $(JPEGTEST_OBJ) $(LIBJPEG_LIB) \ + -lz \ + $(LDFLAGS) \ + $(TEST_BIN_LDFLAGS) \ + +########## HOOK ######## + +$(AFLPP_DRIVER_HOOK_OBJ): $(AFLPP_DRIVER_HOOK_SRC) | $(BUILD_DIR) + $(CC) -shared $(CFLAGS) $(LDFLAGS) $< -o $@ + +########## DUMMY ####### + +$(TEST_DATA_DIR): | $(BUILD_DIR) + mkdir -p $@ + +$(TEST_DATA_FILE): | $(TEST_DATA_DIR) + echo "hi" > $(TEST_DATA_FILE) + +###### TEST DATA ####### + +hook: $(AFLPP_DRIVER_HOOK_OBJ) + +clean: + rm -rf $(BUILD_DIR) + +frida: $(TEST_BIN) $(AFLPP_DRIVER_HOOK_OBJ) $(TEST_DATA_FILE) + AFL_DEBUG_CHILD=1 \ + AFL_DISABLE_TRIM=1 \ + AFL_FRIDA_PERSISTENT_CNT=1000000 \ + AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 \ + AFL_NO_AFFINITY=1 \ + X__AFL_NO_UI=1 \ + AFL_PATH=/out \ + AFL_SHUFFLE_QUEUE=1 \ + AFL_SKIP_CPUFREQ=1 \ + AFL_SKIP_CRASHES=1 \ + AFL_TESTCACHE_SIZE=2 \ + AFL_FRIDA_PERSISTENT_HOOK=$(AFLPP_DRIVER_HOOK_OBJ) \ + AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR) \ + AFL_ENTRYPOINT=$(AFL_FRIDA_PERSISTENT_ADDR) \ + $(ROOT)afl-fuzz \ + -i $(TEST_DATA_DIR) \ + -o $(FRIDA_OUT) \ + -m none \ + -t 1000+ \ + -d \ + -O \ + -c 0\ + -V 30 \ + -- \ + $(TEST_BIN) 2147483647 + +debug: + gdb \ + --ex 'set environment LD_PRELOAD=$(ROOT)afl-frida-trace.so' \ + --ex 'set disassembly-flavor intel' \ + --args $(TEST_BIN) $(TEST_DATA_DIR)basn0g01.jpeg diff --git a/frida_mode/test/jpeg/Makefile b/frida_mode/test/jpeg/Makefile new file mode 100644 index 00000000..863438cf --- /dev/null +++ b/frida_mode/test/jpeg/Makefile @@ -0,0 +1,19 @@ +all: + @echo trying to use GNU make... + @gmake all || echo please install GNUmake + +32: + @echo trying to use GNU make... + @gmake 32 || echo please install GNUmake + +clean: + @gmake clean + +frida: + @gmake frida + +debug: + @gmake debug + +hook: + @gmake hook diff --git a/frida_mode/test/jpeg/aflpp_qemu_driver_hook.c b/frida_mode/test/jpeg/aflpp_qemu_driver_hook.c new file mode 100644 index 00000000..059d438d --- /dev/null +++ b/frida_mode/test/jpeg/aflpp_qemu_driver_hook.c @@ -0,0 +1,97 @@ +#include <stdint.h> +#include <string.h> + +#if defined(__x86_64__) + +struct x86_64_regs { + + uint64_t rax, rbx, rcx, rdx, rdi, rsi, rbp, r8, r9, r10, r11, r12, r13, r14, + r15; + + union { + + uint64_t rip; + uint64_t pc; + + }; + + union { + + uint64_t rsp; + uint64_t sp; + + }; + + union { + + uint64_t rflags; + uint64_t flags; + + }; + + uint8_t zmm_regs[32][64]; + +}; + +void afl_persistent_hook(struct x86_64_regs *regs, uint64_t guest_base, + uint8_t *input_buf, uint32_t input_buf_len) { + + memcpy((void *)regs->rdi, input_buf, input_buf_len); + regs->rsi = input_buf_len; + +} + +#elif defined(__i386__) + +struct x86_regs { + + uint32_t eax, ebx, ecx, edx, edi, esi, ebp; + + union { + + uint32_t eip; + uint32_t pc; + + }; + + union { + + uint32_t esp; + uint32_t sp; + + }; + + union { + + uint32_t eflags; + uint32_t flags; + + }; + + uint8_t xmm_regs[8][16]; + +}; + +void afl_persistent_hook(struct x86_regs *regs, uint64_t guest_base, + uint8_t *input_buf, uint32_t input_buf_len) { + + void **esp = (void **)regs->esp; + void * arg1 = esp[1]; + void **arg2 = &esp[2]; + memcpy(arg1, input_buf, input_buf_len); + *arg2 = (void *)input_buf_len; + +} + +#else + #pragma error "Unsupported architecture" +#endif + +int afl_persistent_hook_init(void) { + + // 1 for shared memory input (faster), 0 for normal input (you have to use + // read(), input_buf will be NULL) + return 1; + +} + diff --git a/frida_mode/test/jpeg/get_symbol_addr.py b/frida_mode/test/jpeg/get_symbol_addr.py new file mode 100755 index 00000000..1c46e010 --- /dev/null +++ b/frida_mode/test/jpeg/get_symbol_addr.py @@ -0,0 +1,36 @@ +#!/usr/bin/python3 +import argparse +from elftools.elf.elffile import ELFFile + +def process_file(file, symbol, base): + with open(file, 'rb') as f: + elf = ELFFile(f) + symtab = elf.get_section_by_name('.symtab') + mains = symtab.get_symbol_by_name(symbol) + if len(mains) != 1: + print ("Failed to find main") + return 1 + + main_addr = mains[0]['st_value'] + main = base + main_addr + print ("0x%016x" % main) + return 0 + +def hex_value(x): + return int(x, 16) + +def main(): + parser = argparse.ArgumentParser(description='Process some integers.') + parser.add_argument('-f', '--file', dest='file', type=str, + help='elf file name', required=True) + parser.add_argument('-s', '--symbol', dest='symbol', type=str, + help='symbol name', required=True) + parser.add_argument('-b', '--base', dest='base', type=hex_value, + help='elf base address', required=True) + + args = parser.parse_args() + return process_file (args.file, args.symbol, args.base) + +if __name__ == "__main__": + ret = main() + exit(ret) diff --git a/frida_mode/test/proj4/GNUmakefile b/frida_mode/test/proj4/GNUmakefile new file mode 100644 index 00000000..09112cd5 --- /dev/null +++ b/frida_mode/test/proj4/GNUmakefile @@ -0,0 +1,172 @@ +PWD:=$(shell pwd)/ +ROOT:=$(shell realpath $(PWD)../../..)/ +BUILD_DIR:=$(PWD)build/ + +AFLPP_DRIVER_HOOK_SRC=$(PWD)aflpp_qemu_driver_hook.c +AFLPP_DRIVER_HOOK_OBJ=$(BUILD_DIR)aflpp_qemu_driver_hook.so + +LIBPROJ4_BUILD_DIR:=$(BUILD_DIR)libproj4/ +HARNESS_BUILD_DIR:=$(BUILD_DIR)harness/ +PROJ4TEST_BUILD_DIR:=$(BUILD_DIR)proj4test/ + +LIBPROJ4_URL:=https://github.com/OSGeo/PROJ +LIBPROJ4_DIR:=$(LIBPROJ4_BUILD_DIR)libproj4/ +LIBPROJ4_CONFIGURE:=$(LIBPROJ4_DIR)configure.ac +LIBPROJ4_MAKEFILE:=$(LIBPROJ4_DIR)Makefile +LIBPROJ4_LIB:=$(LIBPROJ4_DIR)src/.libs/libproj.a + +HARNESS_FILE:=$(HARNESS_BUILD_DIR)StandaloneFuzzTargetMain.c +HARNESS_OBJ:=$(HARNESS_BUILD_DIR)StandaloneFuzzTargetMain.o +HARNESS_URL:="https://raw.githubusercontent.com/AFLplusplus/AFLplusplus/stable/utils/aflpp_driver/aflpp_qemu_driver.c" + +PROJ4TEST_FILE:=$(PROJ4TEST_BUILD_DIR)target.cc +PROJ4TEST_OBJ:=$(PROJ4TEST_BUILD_DIR)target.o +PROJ4TEST_URL:="https://raw.githubusercontent.com/OSGeo/PROJ/d00501750b210a73f9fb107ac97a683d4e3d8e7a/test/fuzzers/standard_fuzzer.cpp" + +LDFLAGS += -lpthread + +TEST_BIN:=$(BUILD_DIR)test +ifeq "$(shell uname)" "Darwin" +TEST_BIN_LDFLAGS:=-undefined dynamic_lookup +endif + +TEST_DATA_DIR:=$(BUILD_DIR)in/ +TEST_DATA_FILE:=$(TEST_DATA_DIR)default_seed + +FRIDA_OUT:=$(BUILD_DIR)frida-out + +ifndef ARCH + +ARCH=$(shell uname -m) +ifeq "$(ARCH)" "aarch64" + ARCH:=arm64 +endif + +ifeq "$(ARCH)" "i686" + ARCH:=x86 +endif +endif + +ifeq "$(ARCH)" "aarch64" + AFL_FRIDA_PERSISTENT_ADDR=$(shell $(PWD)get_symbol_addr.py -f $(TEST_BIN) -s LLVMFuzzerTestOneInput -b 0x0000aaaaaaaaa000) +endif + +ifeq "$(ARCH)" "x86_64" + AFL_FRIDA_PERSISTENT_ADDR=$(shell $(PWD)get_symbol_addr.py -f $(TEST_BIN) -s LLVMFuzzerTestOneInput -b 0x0000555555554000) +endif + +ifeq "$(ARCH)" "x86" + AFL_FRIDA_PERSISTENT_ADDR=$(shell $(PWD)get_symbol_addr.py -f $(TEST_BIN) -s LLVMFuzzerTestOneInput -b 0x56555000) +endif + +.PHONY: all clean frida hook + +all: $(TEST_BIN) + make -C $(ROOT)frida_mode/ + +32: + CXXFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all + +$(BUILD_DIR): + mkdir -p $@ + +######### HARNESS ######## +$(HARNESS_BUILD_DIR): | $(BUILD_DIR) + mkdir -p $@ + +$(HARNESS_FILE): | $(HARNESS_BUILD_DIR) + wget -O $@ $(HARNESS_URL) + +$(HARNESS_OBJ): $(HARNESS_FILE) + $(CC) $(CXXFLAGS) $(LDFLAGS) -o $@ -c $< + +######### PROJ4TEST ######## + +$(PROJ4TEST_BUILD_DIR): | $(BUILD_DIR) + mkdir -p $@ + +$(PROJ4TEST_FILE): | $(PROJ4TEST_BUILD_DIR) + wget -O $@ $(PROJ4TEST_URL) + +$(PROJ4TEST_OBJ): $(PROJ4TEST_FILE) | $(LIBPROJ4_MAKEFILE) + $(CXX) $(CXXFLAGS) $(LDFLAGS) -std=c++11 -I $(LIBPROJ4_DIR)src/ -o $@ -c $< + +######### LIBPROJ4 ######## + +$(LIBPROJ4_BUILD_DIR): | $(BUILD_DIR) + mkdir -p $@ + +$(LIBPROJ4_CONFIGURE): $(LIBPROJ4_BUILD_DIR) + git clone $(LIBPROJ4_URL) $(LIBPROJ4_DIR) + cd $(LIBPROJ4_DIR) && git checkout d00501750b210a73f9fb107ac97a683d4e3d8e7a + +$(LIBPROJ4_MAKEFILE): $(LIBPROJ4_CONFIGURE) + cd $(LIBPROJ4_DIR) && ./autogen.sh + cd $(LIBPROJ4_DIR) && ./configure + +$(LIBPROJ4_LIB): $(LIBPROJ4_MAKEFILE) + make -C $(LIBPROJ4_DIR) -j $(shell nproc) + +######### TEST ######## + +$(TEST_BIN): $(HARNESS_OBJ) $(PROJ4TEST_OBJ) $(LIBPROJ4_LIB) + $(CXX) \ + $(CFLAGS) \ + -o $@ \ + $(HARNESS_OBJ) $(PROJ4TEST_OBJ) $(LIBPROJ4_LIB) \ + -lz \ + $(LDFLAGS) \ + $(TEST_BIN_LDFLAGS) \ + +########## HOOK ######## + +$(AFLPP_DRIVER_HOOK_OBJ): $(AFLPP_DRIVER_HOOK_SRC) | $(BUILD_DIR) + $(CC) -shared $(CFLAGS) $(LDFLAGS) $< -o $@ + +########## DUMMY ####### + +$(TEST_DATA_DIR): | $(BUILD_DIR) + mkdir -p $@ + +$(TEST_DATA_FILE): | $(TEST_DATA_DIR) + echo "hi" > $(TEST_DATA_FILE) + +###### TEST DATA ####### + +hook: $(AFLPP_DRIVER_HOOK_OBJ) + +clean: + rm -rf $(BUILD_DIR) + +frida: $(TEST_BIN) $(AFLPP_DRIVER_HOOK_OBJ) $(TEST_DATA_FILE) + AFL_DEBUG_CHILD=1 \ + AFL_DISABLE_TRIM=1 \ + AFL_FRIDA_PERSISTENT_CNT=1000000 \ + AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 \ + AFL_NO_AFFINITY=1 \ + X__AFL_NO_UI=1 \ + AFL_PATH=/out \ + AFL_SHUFFLE_QUEUE=1 \ + AFL_SKIP_CPUFREQ=1 \ + AFL_SKIP_CRASHES=1 \ + AFL_TESTCACHE_SIZE=2 \ + AFL_FRIDA_PERSISTENT_HOOK=$(AFLPP_DRIVER_HOOK_OBJ) \ + AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR) \ + AFL_ENTRYPOINT=$(AFL_FRIDA_PERSISTENT_ADDR) \ + $(ROOT)afl-fuzz \ + -i $(TEST_DATA_DIR) \ + -o $(FRIDA_OUT) \ + -m none \ + -t 1000+ \ + -d \ + -O \ + -c 0\ + -V 30 \ + -- \ + $(TEST_BIN) 2147483647 + +debug: + gdb \ + --ex 'set environment LD_PRELOAD=$(ROOT)afl-frida-trace.so' \ + --ex 'set disassembly-flavor intel' \ + --args $(TEST_BIN) $(TEST_DATA_DIR)basn0g01.proj4 diff --git a/frida_mode/test/proj4/Makefile b/frida_mode/test/proj4/Makefile new file mode 100644 index 00000000..863438cf --- /dev/null +++ b/frida_mode/test/proj4/Makefile @@ -0,0 +1,19 @@ +all: + @echo trying to use GNU make... + @gmake all || echo please install GNUmake + +32: + @echo trying to use GNU make... + @gmake 32 || echo please install GNUmake + +clean: + @gmake clean + +frida: + @gmake frida + +debug: + @gmake debug + +hook: + @gmake hook diff --git a/frida_mode/test/proj4/aflpp_qemu_driver_hook.c b/frida_mode/test/proj4/aflpp_qemu_driver_hook.c new file mode 100644 index 00000000..059d438d --- /dev/null +++ b/frida_mode/test/proj4/aflpp_qemu_driver_hook.c @@ -0,0 +1,97 @@ +#include <stdint.h> +#include <string.h> + +#if defined(__x86_64__) + +struct x86_64_regs { + + uint64_t rax, rbx, rcx, rdx, rdi, rsi, rbp, r8, r9, r10, r11, r12, r13, r14, + r15; + + union { + + uint64_t rip; + uint64_t pc; + + }; + + union { + + uint64_t rsp; + uint64_t sp; + + }; + + union { + + uint64_t rflags; + uint64_t flags; + + }; + + uint8_t zmm_regs[32][64]; + +}; + +void afl_persistent_hook(struct x86_64_regs *regs, uint64_t guest_base, + uint8_t *input_buf, uint32_t input_buf_len) { + + memcpy((void *)regs->rdi, input_buf, input_buf_len); + regs->rsi = input_buf_len; + +} + +#elif defined(__i386__) + +struct x86_regs { + + uint32_t eax, ebx, ecx, edx, edi, esi, ebp; + + union { + + uint32_t eip; + uint32_t pc; + + }; + + union { + + uint32_t esp; + uint32_t sp; + + }; + + union { + + uint32_t eflags; + uint32_t flags; + + }; + + uint8_t xmm_regs[8][16]; + +}; + +void afl_persistent_hook(struct x86_regs *regs, uint64_t guest_base, + uint8_t *input_buf, uint32_t input_buf_len) { + + void **esp = (void **)regs->esp; + void * arg1 = esp[1]; + void **arg2 = &esp[2]; + memcpy(arg1, input_buf, input_buf_len); + *arg2 = (void *)input_buf_len; + +} + +#else + #pragma error "Unsupported architecture" +#endif + +int afl_persistent_hook_init(void) { + + // 1 for shared memory input (faster), 0 for normal input (you have to use + // read(), input_buf will be NULL) + return 1; + +} + diff --git a/frida_mode/test/proj4/get_symbol_addr.py b/frida_mode/test/proj4/get_symbol_addr.py new file mode 100755 index 00000000..1c46e010 --- /dev/null +++ b/frida_mode/test/proj4/get_symbol_addr.py @@ -0,0 +1,36 @@ +#!/usr/bin/python3 +import argparse +from elftools.elf.elffile import ELFFile + +def process_file(file, symbol, base): + with open(file, 'rb') as f: + elf = ELFFile(f) + symtab = elf.get_section_by_name('.symtab') + mains = symtab.get_symbol_by_name(symbol) + if len(mains) != 1: + print ("Failed to find main") + return 1 + + main_addr = mains[0]['st_value'] + main = base + main_addr + print ("0x%016x" % main) + return 0 + +def hex_value(x): + return int(x, 16) + +def main(): + parser = argparse.ArgumentParser(description='Process some integers.') + parser.add_argument('-f', '--file', dest='file', type=str, + help='elf file name', required=True) + parser.add_argument('-s', '--symbol', dest='symbol', type=str, + help='symbol name', required=True) + parser.add_argument('-b', '--base', dest='base', type=hex_value, + help='elf base address', required=True) + + args = parser.parse_args() + return process_file (args.file, args.symbol, args.base) + +if __name__ == "__main__": + ret = main() + exit(ret) |
