mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-18 20:48:07 +00:00
Perf regression4 (#979)
* Added test for libjpeg * Added proj4 test * Added missing members to x86/64 context * Changes to use memfd and hashtable cache * Removed redundant check Co-authored-by: Your Name <you@example.com>
This commit is contained in:
committed by
GitHub
parent
35153e9b49
commit
58747f9f4f
@ -10,18 +10,20 @@
|
||||
#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 int fd_tmp = -1;
|
||||
static ssize_t fd_tmp_size = 0;
|
||||
static GHashTable * hash = NULL;
|
||||
|
||||
static int memfd = -1;
|
||||
static size_t memfd_size = 0;
|
||||
static u8 scratch[MAX_MEMFD_SIZE] = {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,37 +37,22 @@ 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) {
|
||||
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);
|
||||
|
||||
FATAL("Failed to create temp file: %s, errno: %d", fname, errno);
|
||||
for (guint i = 0; i < cmplog_ranges->len; i++) {
|
||||
|
||||
GumMemoryRange *range = &g_array_index(cmplog_ranges, GumMemoryRange, i);
|
||||
|
||||
}
|
||||
|
||||
if (unlink(fname) < 0) {
|
||||
|
||||
FATAL("Failed to unlink temp file: %s (%d), errno: %d", fname, fd, errno);
|
||||
|
||||
}
|
||||
|
||||
if (ftruncate(fd, 0) < 0) {
|
||||
|
||||
FATAL("Failed to ftruncate temp file: %s (%d), errno: %d", fname, fd,
|
||||
errno);
|
||||
|
||||
}
|
||||
|
||||
g_free(fname);
|
||||
|
||||
return fd;
|
||||
g_array_free(cmplog_ranges, TRUE);
|
||||
|
||||
}
|
||||
|
||||
@ -73,25 +60,28 @@ void cmplog_init(void) {
|
||||
|
||||
if (__afl_cmp_map != NULL) { OKF("CMPLOG mode enabled"); }
|
||||
|
||||
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);
|
||||
cmplog_get_ranges();
|
||||
|
||||
for (guint i = 0; i < cmplog_ranges->len; i++) {
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* We can't use /dev/null or /dev/zero for this since it appears that they
|
||||
* don't validate the input buffer. Persumably as an optimization because they
|
||||
* don't actually write any data. The file will be deleted on close.
|
||||
*/
|
||||
fd_tmp = cmplog_create_temp();
|
||||
memfd = syscall(__NR_memfd_create, "cmplog_memfd", 0);
|
||||
if (memfd < 0) {
|
||||
|
||||
FATAL("Failed to create_memfd, errno: %d", errno);
|
||||
|
||||
}
|
||||
|
||||
hash = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||
if (hash == NULL) {
|
||||
FATAL("Failed to g_hash_table_new, errno: %d", errno);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -102,6 +92,42 @@ 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, (gpointer)addr)) { return true; }
|
||||
|
||||
if (memfd_size > MAX_MEMFD_SIZE) {
|
||||
if (lseek(memfd, 0, SEEK_SET) < 0) {
|
||||
FATAL("CMPLOG - Failed lseek, errno: %d", errno);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Our address map can change (e.g. stack growth), use write as a fallback to
|
||||
* validate our address.
|
||||
*/
|
||||
ssize_t written = syscall(__NR_write, memfd, (void *)addr, size);
|
||||
if (written < 0 && errno != EFAULT && errno != 0) {
|
||||
FATAL("CMPLOG - Failed __NR_write, errno: %d", errno);
|
||||
}
|
||||
/*
|
||||
* If the write succeeds, then the buffer must be valid otherwise it would
|
||||
* return EFAULT
|
||||
*/
|
||||
if (written > 0) { memfd_size += written; }
|
||||
|
||||
if ((size_t)written == size) {
|
||||
if (!g_hash_table_add (hash, (gpointer)addr)) {
|
||||
FATAL("Failed - g_hash_table_add");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
gboolean cmplog_is_readable(guint64 addr, size_t size) {
|
||||
|
||||
if (cmplog_ranges == NULL) FATAL("CMPLOG not initialized");
|
||||
@ -125,6 +151,7 @@ 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;
|
||||
|
||||
@ -133,37 +160,7 @@ gboolean cmplog_is_readable(guint64 addr, size_t size) {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
172
frida_mode/test/jpeg/GNUmakefile
Normal file
172
frida_mode/test/jpeg/GNUmakefile
Normal file
@ -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
|
19
frida_mode/test/jpeg/Makefile
Normal file
19
frida_mode/test/jpeg/Makefile
Normal file
@ -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
|
97
frida_mode/test/jpeg/aflpp_qemu_driver_hook.c
Normal file
97
frida_mode/test/jpeg/aflpp_qemu_driver_hook.c
Normal file
@ -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;
|
||||
|
||||
}
|
||||
|
36
frida_mode/test/jpeg/get_symbol_addr.py
Executable file
36
frida_mode/test/jpeg/get_symbol_addr.py
Executable file
@ -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)
|
172
frida_mode/test/proj4/GNUmakefile
Normal file
172
frida_mode/test/proj4/GNUmakefile
Normal file
@ -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
|
19
frida_mode/test/proj4/Makefile
Normal file
19
frida_mode/test/proj4/Makefile
Normal file
@ -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
|
97
frida_mode/test/proj4/aflpp_qemu_driver_hook.c
Normal file
97
frida_mode/test/proj4/aflpp_qemu_driver_hook.c
Normal file
@ -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;
|
||||
|
||||
}
|
||||
|
36
frida_mode/test/proj4/get_symbol_addr.py
Executable file
36
frida_mode/test/proj4/get_symbol_addr.py
Executable file
@ -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)
|
Reference in New Issue
Block a user