From 39ad3b89467d6de12cbb9d08ccd77d331c0d1f9e Mon Sep 17 00:00:00 2001 From: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com> Date: Wed, 28 Apr 2021 09:25:26 +0100 Subject: Frida persistent (#880) * Added x64 support for persistent mode (function call only), in-memory teest cases and complog * Review changes, fix NeverZero and code to parse the .text section of the main executable. Excluded ranges TBC * Various minor fixes and finished support for AFL_INST_LIBS * Review changes Co-authored-by: Your Name --- frida_mode/src/persistent/persistent.c | 68 ++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 frida_mode/src/persistent/persistent.c (limited to 'frida_mode/src/persistent/persistent.c') diff --git a/frida_mode/src/persistent/persistent.c b/frida_mode/src/persistent/persistent.c new file mode 100644 index 00000000..fe3a1d20 --- /dev/null +++ b/frida_mode/src/persistent/persistent.c @@ -0,0 +1,68 @@ +#include + +#include "frida-gum.h" + +#include "config.h" +#include "debug.h" + +#include "persistent.h" +#include "util.h" + +int __afl_sharedmem_fuzzing = 0; +afl_persistent_hook_fn hook = NULL; +guint64 persistent_start = 0; +guint64 persistent_count = 0; + +void persistent_init(void) { + + char *hook_name = getenv("AFL_FRIDA_PERSISTENT_HOOK"); + + persistent_start = util_read_address("AFL_FRIDA_PERSISTENT_ADDR"); + persistent_count = util_read_num("AFL_FRIDA_PERSISTENT_CNT"); + + if (persistent_count != 0 && persistent_start == 0) + FATAL( + "AFL_FRIDA_PERSISTENT_ADDR must be specified if " + "AFL_FRIDA_PERSISTENT_CNT is"); + + if (persistent_start != 0 && persistent_count == 0) persistent_count = 1000; + + if (persistent_count != 0 && persistent_count < 100) + WARNF("Persistent count out of recommended range (<100)"); + + if (persistent_count > 10000) + WARNF("Persistent count out of recommended range (<10000)"); + + if (persistent_start != 0 && !persistent_is_supported()) + FATAL("Persistent mode not supported on this architecture"); + + OKF("Instrumentation - persistent mode [%c] (0x%016lX)", + persistent_start == 0 ? ' ' : 'X', persistent_start); + OKF("Instrumentation - persistent count [%c] (%ld)", + persistent_start == 0 ? ' ' : 'X', persistent_count); + OKF("Instrumentation - hook [%s]", hook_name); + + if (hook_name != NULL) { + + void *hook_obj = dlopen(hook_name, RTLD_NOW); + if (hook_obj == NULL) + FATAL("Failed to load AFL_FRIDA_PERSISTENT_HOOK (%s)", hook_name); + + int (*afl_persistent_hook_init_ptr)(void) = + dlsym(hook_obj, "afl_persistent_hook_init"); + if (afl_persistent_hook_init_ptr == NULL) + FATAL("Failed to find afl_persistent_hook_init in %s", hook_name); + + if (afl_persistent_hook_init_ptr() == 0) + FATAL("afl_persistent_hook_init returned a failure"); + + hook = (afl_persistent_hook_fn)dlsym(hook_obj, "afl_persistent_hook"); + if (hook == NULL) + FATAL("Failed to find afl_persistent_hook in %s", hook_name); + + __afl_sharedmem_fuzzing = 1; + + } + +} + -- cgit 1.4.1 From da65eef57279dae7b652c40bdb31bc6cd749f63d Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 28 Apr 2021 12:57:29 +0200 Subject: fix frida mode --- frida_mode/GNUmakefile | 6 +++--- frida_mode/include/persistent.h | 7 ++++++- frida_mode/src/lib.c | 2 +- frida_mode/src/persistent/persistent.c | 3 --- 4 files changed, 10 insertions(+), 8 deletions(-) (limited to 'frida_mode/src/persistent/persistent.c') diff --git a/frida_mode/GNUmakefile b/frida_mode/GNUmakefile index 51107910..6b193806 100644 --- a/frida_mode/GNUmakefile +++ b/frida_mode/GNUmakefile @@ -5,7 +5,7 @@ SRC_DIR:=$(PWD)src/ INCLUDES:=$(wildcard $(INC_DIR)*.h) SOURCES:=$(wildcard $(SRC_DIR)**/*.c) $(wildcard $(SRC_DIR)*.c) BUILD_DIR:=$(PWD)build/ -CFLAGS+=-fPIC -D_GNU_SOURCE -Wno-prio-ctor-dtor +CFLAGS+=-fPIC -D_GNU_SOURCE -Wno-prio-ctor-dtor -fcommon -Wl,--allow-multiple-definition FRIDA_BUILD_DIR:=$(BUILD_DIR)frida/ FRIDA_TRACE:=$(BUILD_DIR)afl-frida-trace.so @@ -71,8 +71,8 @@ $(FRIDA_TRACE): $(GUM_DEVIT_LIBRARY) $(GUM_DEVIT_HEADER) $(SOURCES) $(QEMU_INC_A -I $(ROOT) \ -I $(ROOT)include \ -I $(INC_DIR) \ - $(ROOT)instrumentation/afl-compiler-rt.o.c \ - -lpthread -ldl -lresolv -lelf + $(ROOT)instrumentation/afl-compiler-rt.o.c +# -lpthread -ldl -lresolv -lelf cp -v $(FRIDA_TRACE) $(ROOT) diff --git a/frida_mode/include/persistent.h b/frida_mode/include/persistent.h index 14c8a268..017c26c7 100644 --- a/frida_mode/include/persistent.h +++ b/frida_mode/include/persistent.h @@ -1,5 +1,9 @@ -#include "frida-gum.h" +#ifndef _PERSISTENT_H + +#define _PERSISTENT_H + +#include "frida-gum.h" #include "config.h" typedef struct arch_api_regs api_regs; @@ -24,3 +28,4 @@ gboolean persistent_is_supported(void); void persistent_prologue(GumStalkerOutput *output); +#endif diff --git a/frida_mode/src/lib.c b/frida_mode/src/lib.c index 326d4819..6e27c170 100644 --- a/frida_mode/src/lib.c +++ b/frida_mode/src/lib.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include #include diff --git a/frida_mode/src/persistent/persistent.c b/frida_mode/src/persistent/persistent.c index fe3a1d20..34e4093e 100644 --- a/frida_mode/src/persistent/persistent.c +++ b/frida_mode/src/persistent/persistent.c @@ -9,9 +9,6 @@ #include "util.h" int __afl_sharedmem_fuzzing = 0; -afl_persistent_hook_fn hook = NULL; -guint64 persistent_start = 0; -guint64 persistent_count = 0; void persistent_init(void) { -- cgit 1.4.1 From 3a0d4fe0d0a585d152a59ca4601d1981cedbf113 Mon Sep 17 00:00:00 2001 From: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com> Date: Wed, 28 Apr 2021 18:26:19 +0100 Subject: Bumped warnings up to the max and fixed remaining issues (#890) Co-authored-by: Your Name --- frida_mode/GNUmakefile | 64 +++++++++++++++++++++++++----- frida_mode/include/complog.h | 5 +++ frida_mode/include/instrument.h | 11 +++-- frida_mode/include/interceptor.h | 5 +++ frida_mode/include/lib.h | 5 +++ frida_mode/include/persistent.h | 8 ++-- frida_mode/include/prefetch.h | 5 +++ frida_mode/include/ranges.h | 5 +++ frida_mode/include/stalker.h | 5 +++ frida_mode/include/util.h | 8 ++++ frida_mode/src/complog/complog.c | 3 ++ frida_mode/src/complog/complog_x64.c | 50 ++++++++++------------- frida_mode/src/instrument/instrument.c | 9 +++-- frida_mode/src/interceptor.c | 2 +- frida_mode/src/main.c | 7 ++-- frida_mode/src/persistent/persistent.c | 3 ++ frida_mode/src/persistent/persistent_x64.c | 2 +- frida_mode/src/ranges.c | 19 ++++----- frida_mode/test/png/GNUmakefile | 1 - 19 files changed, 153 insertions(+), 64 deletions(-) (limited to 'frida_mode/src/persistent/persistent.c') diff --git a/frida_mode/GNUmakefile b/frida_mode/GNUmakefile index 6b193806..e317237a 100644 --- a/frida_mode/GNUmakefile +++ b/frida_mode/GNUmakefile @@ -3,9 +3,25 @@ ROOT:=$(shell realpath $(PWD)..)/ INC_DIR:=$(PWD)include/ SRC_DIR:=$(PWD)src/ INCLUDES:=$(wildcard $(INC_DIR)*.h) -SOURCES:=$(wildcard $(SRC_DIR)**/*.c) $(wildcard $(SRC_DIR)*.c) BUILD_DIR:=$(PWD)build/ -CFLAGS+=-fPIC -D_GNU_SOURCE -Wno-prio-ctor-dtor -fcommon -Wl,--allow-multiple-definition +OBJ_DIR:=$(BUILD_DIR)obj/ +SOURCES:=$(wildcard $(SRC_DIR)**/*.c) $(wildcard $(SRC_DIR)*.c) +OBJS:=$(foreach src,$(SOURCES),$(OBJ_DIR)$(notdir $(patsubst %.c, %.o, $(src)))) +CFLAGS+=-fPIC \ + -D_GNU_SOURCE \ + -D_FORTIFY_SOURCE=2 \ + -Werror \ + -Wall \ + -Wextra \ + -Wpointer-arith \ + -g \ + -O3 \ + -funroll-loops \ + +LDFLAGS+=-shared \ + -lpthread \ + -lresolv \ + -ldl \ FRIDA_BUILD_DIR:=$(BUILD_DIR)frida/ FRIDA_TRACE:=$(BUILD_DIR)afl-frida-trace.so @@ -36,7 +52,8 @@ GUM_DEVKIT_TARBALL:=$(FRIDA_BUILD_DIR)$(GUM_DEVKIT_FILENAME) GUM_DEVIT_LIBRARY=$(FRIDA_BUILD_DIR)libfrida-gum.a GUM_DEVIT_HEADER=$(FRIDA_BUILD_DIR)frida-gum.h -TEST_BUILD_DIR:=$(BUILD_DIR)test/ +AFL_COMPILER_RT_SRC:=$(ROOT)instrumentation/afl-compiler-rt.o.c +AFL_COMPILER_RT_OBJ:=$(OBJ_DIR)afl-compiler-rt.o .PHONY: all clean format @@ -49,6 +66,9 @@ all: $(FRIDA_TRACE) $(BUILD_DIR): mkdir -p $(BUILD_DIR) +$(OBJ_DIR): | $(BUILD_DIR) + mkdir -p $@ + $(FRIDA_BUILD_DIR): | $(BUILD_DIR) mkdir -p $@ @@ -61,18 +81,40 @@ $(GUM_DEVIT_LIBRARY): | $(GUM_DEVKIT_TARBALL) $(GUM_DEVIT_HEADER): | $(GUM_DEVKIT_TARBALL) tar Jxvf $(GUM_DEVKIT_TARBALL) -C $(FRIDA_BUILD_DIR) -$(FRIDA_TRACE): $(GUM_DEVIT_LIBRARY) $(GUM_DEVIT_HEADER) $(SOURCES) $(QEMU_INC_API) Makefile | $(BUILD_DIR) - $(CC) -shared \ +$(AFL_COMPILER_RT_OBJ): $(AFL_COMPILER_RT_SRC) + $(CC) \ $(CFLAGS) \ - -o $@ \ - $(SOURCES) \ - $(GUM_DEVIT_LIBRARY) \ - -I $(FRIDA_BUILD_DIR) \ -I $(ROOT) \ -I $(ROOT)include \ + -Wno-unused-parameter \ + -Wno-sign-compare \ + -Wno-unused-function \ + -Wno-prio-ctor-dtor \ + -Wno-unused-result \ + -o $@ \ + -c $< + + +define BUILD_SOURCE = +$(2): $(1) GNUmakefile | $(OBJ_DIR) + $(CC) \ + $(CFLAGS) \ + -I $(ROOT)include \ + -I $(FRIDA_BUILD_DIR) \ -I $(INC_DIR) \ - $(ROOT)instrumentation/afl-compiler-rt.o.c -# -lpthread -ldl -lresolv -lelf + -c $1 \ + -o $2 +endef + +$(foreach src,$(SOURCES),$(eval $(call BUILD_SOURCE,$(src),$(OBJ_DIR)$(notdir $(patsubst %.c, %.o, $(src)))))) + +$(FRIDA_TRACE): $(GUM_DEVIT_LIBRARY) $(GUM_DEVIT_HEADER) $(OBJS) $(AFL_COMPILER_RT_OBJ) GNUmakefile | $(BUILD_DIR) + $(CC) \ + -o $@ \ + $(OBJS) \ + $(GUM_DEVIT_LIBRARY) \ + $(AFL_COMPILER_RT_OBJ) \ + $(LDFLAGS) \ cp -v $(FRIDA_TRACE) $(ROOT) diff --git a/frida_mode/include/complog.h b/frida_mode/include/complog.h index 094b7b93..1c1adb6d 100644 --- a/frida_mode/include/complog.h +++ b/frida_mode/include/complog.h @@ -1,3 +1,6 @@ +#ifndef _COMPLOG_H +#define _COMPLOG_H + extern struct cmp_map *__afl_cmp_map; void complog_init(void); @@ -7,3 +10,5 @@ void complog_instrument(const cs_insn *instr, GumStalkerIterator *iterator); gboolean complog_is_readable(void *addr, size_t size); +#endif + diff --git a/frida_mode/include/instrument.h b/frida_mode/include/instrument.h index 1b6c6bba..03fd33e5 100644 --- a/frida_mode/include/instrument.h +++ b/frida_mode/include/instrument.h @@ -1,10 +1,13 @@ +#ifndef _INSTRUMENT_H +#define _INSTRUMENT_H + #include "frida-gum.h" #include "config.h" -extern uint64_t __thread previous_pc; -extern uint8_t *__afl_area_ptr; -extern uint32_t __afl_map_size; +extern __thread uint64_t previous_pc; +extern uint8_t * __afl_area_ptr; +extern uint32_t __afl_map_size; void instrument_init(void); @@ -16,3 +19,5 @@ gboolean instrument_is_coverage_optimize_supported(void); void instrument_coverage_optimize(const cs_insn * instr, GumStalkerOutput *output); +#endif + diff --git a/frida_mode/include/interceptor.h b/frida_mode/include/interceptor.h index 49c0630a..0ff754a4 100644 --- a/frida_mode/include/interceptor.h +++ b/frida_mode/include/interceptor.h @@ -1,6 +1,11 @@ +#ifndef _INTERCEPTOR_H +#define _INTERCEPTOR_H + #include "frida-gum.h" void intercept(void *address, gpointer replacement, gpointer user_data); void unintercept(void *address); void unintercept_self(void); +#endif + diff --git a/frida_mode/include/lib.h b/frida_mode/include/lib.h index 1dc426a2..237aecb0 100644 --- a/frida_mode/include/lib.h +++ b/frida_mode/include/lib.h @@ -1,3 +1,6 @@ +#ifndef _LIB_H +#define _LIB_H + #include "frida-gum.h" void lib_init(void); @@ -6,3 +9,5 @@ guint64 lib_get_text_base(void); guint64 lib_get_text_limit(void); +#endif + diff --git a/frida_mode/include/persistent.h b/frida_mode/include/persistent.h index 017c26c7..e58c5301 100644 --- a/frida_mode/include/persistent.h +++ b/frida_mode/include/persistent.h @@ -1,6 +1,5 @@ #ifndef _PERSISTENT_H - #define _PERSISTENT_H #include "frida-gum.h" @@ -17,9 +16,9 @@ extern int __afl_persistent_loop(unsigned int max_cnt); extern unsigned int * __afl_fuzz_len; extern unsigned char *__afl_fuzz_ptr; -guint64 persistent_start; -guint64 persistent_count; -afl_persistent_hook_fn hook; +extern guint64 persistent_start; +extern guint64 persistent_count; +extern afl_persistent_hook_fn hook; void persistent_init(void); @@ -29,3 +28,4 @@ gboolean persistent_is_supported(void); void persistent_prologue(GumStalkerOutput *output); #endif + diff --git a/frida_mode/include/prefetch.h b/frida_mode/include/prefetch.h index 110f717f..8f0cee68 100644 --- a/frida_mode/include/prefetch.h +++ b/frida_mode/include/prefetch.h @@ -1,6 +1,11 @@ +#ifndef _PREFETCH_H +#define _PREFETCH_H + #include "frida-gum.h" void prefetch_init(void); void prefetch_write(void *addr); void prefetch_read(void); +#endif + diff --git a/frida_mode/include/ranges.h b/frida_mode/include/ranges.h index a021f35c..f652eb8a 100644 --- a/frida_mode/include/ranges.h +++ b/frida_mode/include/ranges.h @@ -1,6 +1,11 @@ +#ifndef _RANGES_H +#define _RANGES_H + #include "frida-gum.h" void ranges_init(void); gboolean range_is_excluded(gpointer address); +#endif + diff --git a/frida_mode/include/stalker.h b/frida_mode/include/stalker.h index 1962eec9..1f1abb6b 100644 --- a/frida_mode/include/stalker.h +++ b/frida_mode/include/stalker.h @@ -1,3 +1,6 @@ +#ifndef _STALKER_H +#define _STALKER_H + #include "frida-gum.h" void stalker_init(void); @@ -6,3 +9,5 @@ void stalker_start(void); void stalker_pause(void); void stalker_resume(void); +#endif + diff --git a/frida_mode/include/util.h b/frida_mode/include/util.h index 5b4ea76b..afd0b9c1 100644 --- a/frida_mode/include/util.h +++ b/frida_mode/include/util.h @@ -1,6 +1,14 @@ +#ifndef _UTIL_H +#define _UTIL_H + #include "frida-gum.h" +#define UNUSED_PARAMETER(x) (void)(x) +#define IGNORED_RERURN(x) (void)!(x) + guint64 util_read_address(char *key); guint64 util_read_num(char *key); +#endif + diff --git a/frida_mode/src/complog/complog.c b/frida_mode/src/complog/complog.c index 3b679a5c..1857ea3b 100644 --- a/frida_mode/src/complog/complog.c +++ b/frida_mode/src/complog/complog.c @@ -2,6 +2,7 @@ #include "debug.h" #include "cmplog.h" +#include "util.h" extern struct cmp_map *__afl_cmp_map; @@ -10,8 +11,10 @@ static GArray *complog_ranges = NULL; static gboolean complog_range(const GumRangeDetails *details, gpointer user_data) { + UNUSED_PARAMETER(user_data); GumMemoryRange range = *details->range; g_array_append_val(complog_ranges, range); + return TRUE; } diff --git a/frida_mode/src/complog/complog_x64.c b/frida_mode/src/complog/complog_x64.c index 253ec041..28010e7f 100644 --- a/frida_mode/src/complog/complog_x64.c +++ b/frida_mode/src/complog/complog_x64.c @@ -4,6 +4,7 @@ #include "cmplog.h" #include "complog.h" +#include "util.h" #if defined(__x86_64__) @@ -148,7 +149,27 @@ static guint64 complog_read_mem(GumX64CpuContext *ctx, x86_op_mem *mem) { } -static void complog_handle_call(GumCpuContext *context, guint64 target) { +static guint64 cmplog_get_operand_value(GumCpuContext *context, + complog_ctx_t *ctx) { + + switch (ctx->type) { + + case X86_OP_REG: + return complog_read_reg(context, ctx->reg); + case X86_OP_IMM: + return ctx->imm; + case X86_OP_MEM: + return complog_read_mem(context, &ctx->mem); + default: + FATAL("Invalid operand type: %d\n", ctx->type); + + } + +} + +static void complog_call_callout(GumCpuContext *context, gpointer user_data) { + + UNUSED_PARAMETER(user_data); guint64 address = complog_read_reg(context, X86_REG_RIP); guint64 rdi = complog_read_reg(context, X86_REG_RDI); @@ -179,33 +200,6 @@ static void complog_handle_call(GumCpuContext *context, guint64 target) { } -static guint64 cmplog_get_operand_value(GumCpuContext *context, - complog_ctx_t *ctx) { - - switch (ctx->type) { - - case X86_OP_REG: - return complog_read_reg(context, ctx->reg); - case X86_OP_IMM: - return ctx->imm; - case X86_OP_MEM: - return complog_read_mem(context, &ctx->mem); - default: - FATAL("Invalid operand type: %d\n", ctx->type); - - } - -} - -static void complog_call_callout(GumCpuContext *context, gpointer user_data) { - - complog_ctx_t *ctx = (complog_ctx_t *)user_data; - - guint64 target = cmplog_get_operand_value(context, ctx); - complog_handle_call(context, target); - -} - static void complog_instrument_put_operand(complog_ctx_t *ctx, cs_x86_op * operand) { diff --git a/frida_mode/src/instrument/instrument.c b/frida_mode/src/instrument/instrument.c index 81080bee..3806136a 100644 --- a/frida_mode/src/instrument/instrument.c +++ b/frida_mode/src/instrument/instrument.c @@ -11,17 +11,18 @@ #include "prefetch.h" #include "ranges.h" #include "stalker.h" +#include "util.h" static gboolean tracing = false; static gboolean optimize = false; -static gboolean strict = false; static GumStalkerTransformer *transformer = NULL; -uint64_t __thread previous_pc = 0; +__thread uint64_t previous_pc = 0; __attribute__((hot)) static void on_basic_block(GumCpuContext *context, gpointer user_data) { + UNUSED_PARAMETER(context); /* * This function is performance critical as it is called to instrument every * basic block. By moving our print buffer to a global, we avoid it affecting @@ -44,7 +45,7 @@ __attribute__((hot)) static void on_basic_block(GumCpuContext *context, "x, previous_pc: 0x%016" G_GINT64_MODIFIER "x\n", current_pc, previous_pc); - write(STDOUT_FILENO, buffer, len + 1); + IGNORED_RERURN(write(STDOUT_FILENO, buffer, len + 1)); } @@ -72,6 +73,8 @@ __attribute__((hot)) static void on_basic_block(GumCpuContext *context, static void instr_basic_block(GumStalkerIterator *iterator, GumStalkerOutput *output, gpointer user_data) { + UNUSED_PARAMETER(user_data); + const cs_insn *instr; gboolean begin = TRUE; while (gum_stalker_iterator_next(iterator, &instr)) { diff --git a/frida_mode/src/interceptor.c b/frida_mode/src/interceptor.c index 8d41b075..d2802752 100644 --- a/frida_mode/src/interceptor.c +++ b/frida_mode/src/interceptor.c @@ -10,7 +10,7 @@ void intercept(void *address, gpointer replacement, gpointer user_data) { gum_interceptor_begin_transaction(interceptor); GumReplaceReturn ret = gum_interceptor_replace(interceptor, address, replacement, user_data); - if (ret != GUM_ATTACH_OK) { FATAL("gum_interceptor_attach: %d", ret); } + if (ret != GUM_REPLACE_OK) { FATAL("gum_interceptor_attach: %d", ret); } gum_interceptor_end_transaction(interceptor); } diff --git a/frida_mode/src/main.c b/frida_mode/src/main.c index f712a8c0..11cf041c 100644 --- a/frida_mode/src/main.c +++ b/frida_mode/src/main.c @@ -21,6 +21,7 @@ #include "prefetch.h" #include "ranges.h" #include "stalker.h" +#include "util.h" #ifdef __APPLE__ extern mach_port_t mach_task_self(); @@ -36,8 +37,6 @@ typedef int *(*main_fn_t)(int argc, char **argv, char **envp); static main_fn_t main_fn = NULL; -static GumMemoryRange code_range = {0}; - extern void __afl_manual_init(); static int on_fork(void) { @@ -55,6 +54,8 @@ static void on_main_os(int argc, char **argv, char **envp) { #else static void on_main_os(int argc, char **argv, char **envp) { + UNUSED_PARAMETER(argc); + /* Personality doesn't affect the current process, it only takes effect on * evec */ int persona = personality(ADDR_NO_RANDOMIZE); @@ -97,7 +98,7 @@ static int *on_main(int argc, char **argv, char **envp) { /* Child here */ previous_pc = 0; stalker_resume(); - main_fn(argc, argv, envp); + return main_fn(argc, argv, envp); } diff --git a/frida_mode/src/persistent/persistent.c b/frida_mode/src/persistent/persistent.c index 34e4093e..fe3a1d20 100644 --- a/frida_mode/src/persistent/persistent.c +++ b/frida_mode/src/persistent/persistent.c @@ -9,6 +9,9 @@ #include "util.h" int __afl_sharedmem_fuzzing = 0; +afl_persistent_hook_fn hook = NULL; +guint64 persistent_start = 0; +guint64 persistent_count = 0; void persistent_init(void) { diff --git a/frida_mode/src/persistent/persistent_x64.c b/frida_mode/src/persistent/persistent_x64.c index 0cabbf24..5b8493b2 100644 --- a/frida_mode/src/persistent/persistent_x64.c +++ b/frida_mode/src/persistent/persistent_x64.c @@ -231,7 +231,7 @@ static int instrument_afl_persistent_loop_func(void) { } -static int instrument_afl_persistent_loop(GumX86Writer *cw) { +static void instrument_afl_persistent_loop(GumX86Writer *cw) { gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, -(GUM_RED_ZONE_SIZE)); diff --git a/frida_mode/src/ranges.c b/frida_mode/src/ranges.c index 6fcbd258..e3f09f9e 100644 --- a/frida_mode/src/ranges.c +++ b/frida_mode/src/ranges.c @@ -5,6 +5,7 @@ #include "lib.h" #include "ranges.h" #include "stalker.h" +#include "util.h" #define MAX_RANGES 20 @@ -167,6 +168,7 @@ gint range_sort(gconstpointer a, gconstpointer b) { static gboolean print_ranges_callback(const GumRangeDetails *details, gpointer user_data) { + UNUSED_PARAMETER(user_data); if (details->file == NULL) { OKF("MAP - 0x%016" G_GINT64_MODIFIER "x - 0x%016" G_GINT64_MODIFIER "X", @@ -190,7 +192,7 @@ static gboolean print_ranges_callback(const GumRangeDetails *details, static void print_ranges(char *key, GArray *ranges) { OKF("Range: %s Length: %d", key, ranges->len); - for (int i = 0; i < ranges->len; i++) { + for (guint i = 0; i < ranges->len; i++) { GumMemoryRange *curr = &g_array_index(ranges, GumMemoryRange, i); GumAddress curr_limit = curr->base_address + curr->size; @@ -345,10 +347,10 @@ static GArray *intersect_ranges(GArray *a, GArray *b) { result = g_array_new(false, false, sizeof(GumMemoryRange)); - for (int i = 0; i < a->len; i++) { + for (guint i = 0; i < a->len; i++) { ra = &g_array_index(a, GumMemoryRange, i); - for (int j = 0; j < b->len; j++) { + for (guint j = 0; j < b->len; j++) { rb = &g_array_index(b, GumMemoryRange, j); @@ -377,11 +379,11 @@ static GArray *subtract_ranges(GArray *a, GArray *b) { result = g_array_new(false, false, sizeof(GumMemoryRange)); - for (int i = 0; i < a->len; i++) { + for (guint i = 0; i < a->len; i++) { ra = &g_array_index(a, GumMemoryRange, i); ral = ra->base_address + ra->size; - for (int j = 0; j < b->len; j++) { + for (guint j = 0; j < b->len; j++) { rb = &g_array_index(b, GumMemoryRange, j); @@ -453,7 +455,7 @@ static GArray *merge_ranges(GArray *a) { rp = g_array_index(a, GumMemoryRange, 0); - for (int i = 1; i < a->len; i++) { + for (guint i = 1; i < a->len; i++) { r = &g_array_index(a, GumMemoryRange, i); @@ -535,7 +537,7 @@ void ranges_init(void) { stalker = stalker_get(); - for (int i = 0; i < ranges->len; i++) { + for (guint i = 0; i < ranges->len; i++) { r = &g_array_index(ranges, GumMemoryRange, i); gum_stalker_exclude(stalker, r); @@ -551,12 +553,11 @@ void ranges_init(void) { gboolean range_is_excluded(gpointer address) { - int i; GumAddress test = GUM_ADDRESS(address); if (ranges == NULL) { return false; } - for (i = 0; i < ranges->len; i++) { + for (guint i = 0; i < ranges->len; i++) { GumMemoryRange *curr = &g_array_index(ranges, GumMemoryRange, i); GumAddress curr_limit = curr->base_address + curr->size; diff --git a/frida_mode/test/png/GNUmakefile b/frida_mode/test/png/GNUmakefile index c381f5ab..7de3e85a 100644 --- a/frida_mode/test/png/GNUmakefile +++ b/frida_mode/test/png/GNUmakefile @@ -80,7 +80,6 @@ $(TEST_BIN): $(HARNESS_OBJ) $(PNGTEST_OBJ) $(LIBPNG_LIB) -o $@ \ $(HARNESS_OBJ) $(PNGTEST_OBJ) $(LIBPNG_LIB) \ -lz \ - $(TEST_LDFLAGS) clean: rm -rf $(BUILD_DIR) -- cgit 1.4.1 From 423c32969c0111f5fdc666a159497dff805bff89 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 28 Apr 2021 22:48:43 +0200 Subject: nit --- frida_mode/src/persistent/persistent.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'frida_mode/src/persistent/persistent.c') diff --git a/frida_mode/src/persistent/persistent.c b/frida_mode/src/persistent/persistent.c index fe3a1d20..5aad3724 100644 --- a/frida_mode/src/persistent/persistent.c +++ b/frida_mode/src/persistent/persistent.c @@ -30,9 +30,6 @@ void persistent_init(void) { if (persistent_count != 0 && persistent_count < 100) WARNF("Persistent count out of recommended range (<100)"); - if (persistent_count > 10000) - WARNF("Persistent count out of recommended range (<10000)"); - if (persistent_start != 0 && !persistent_is_supported()) FATAL("Persistent mode not supported on this architecture"); -- cgit 1.4.1 From 26b84e3521936ec11b7615bb833310d62795020e Mon Sep 17 00:00:00 2001 From: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com> Date: Thu, 29 Apr 2021 08:06:14 +0100 Subject: Fixes for aarch64, OSX and other minor issues (#891) Co-authored-by: Your Name --- frida_mode/GNUmakefile | 28 +++-- frida_mode/src/complog/complog.c | 5 +- frida_mode/src/complog/complog_arm.c | 6 +- frida_mode/src/complog/complog_arm64.c | 6 +- frida_mode/src/complog/complog_x86.c | 6 +- frida_mode/src/lib.c | 169 ------------------------- frida_mode/src/lib/lib | Bin 0 -> 4144 bytes frida_mode/src/lib/lib.c | 176 +++++++++++++++++++++++++++ frida_mode/src/lib/lib_apple.c | 82 +++++++++++++ frida_mode/src/main.c | 4 + frida_mode/src/persistent/persistent.c | 4 +- frida_mode/src/persistent/persistent_arm32.c | 2 + frida_mode/src/persistent/persistent_arm64.c | 2 + frida_mode/src/persistent/persistent_x86.c | 2 + frida_mode/test/exe/GNUmakefile | 50 ++++++++ frida_mode/test/exe/Makefile | 12 ++ frida_mode/test/exe/testinstr.c | 112 +++++++++++++++++ frida_mode/test/png/GNUmakefile | 4 + 18 files changed, 487 insertions(+), 183 deletions(-) delete mode 100644 frida_mode/src/lib.c create mode 100755 frida_mode/src/lib/lib create mode 100644 frida_mode/src/lib/lib.c create mode 100644 frida_mode/src/lib/lib_apple.c create mode 100644 frida_mode/test/exe/GNUmakefile create mode 100644 frida_mode/test/exe/Makefile create mode 100644 frida_mode/test/exe/testinstr.c (limited to 'frida_mode/src/persistent/persistent.c') diff --git a/frida_mode/GNUmakefile b/frida_mode/GNUmakefile index 65a7a1c3..d2f5ba4b 100644 --- a/frida_mode/GNUmakefile +++ b/frida_mode/GNUmakefile @@ -10,16 +10,29 @@ OBJS:=$(foreach src,$(SOURCES),$(OBJ_DIR)$(notdir $(patsubst %.c, %.o, $(src)))) CFLAGS+=-fPIC \ -D_GNU_SOURCE \ -D_FORTIFY_SOURCE=2 \ - -Wno-pointer-arith \ -g \ -O3 \ -funroll-loops \ +RT_CFLAGS:=-Wno-unused-parameter \ + -Wno-sign-compare \ + -Wno-unused-function \ + -Wno-unused-result \ + LDFLAGS+=-shared \ -lpthread \ -lresolv \ -ldl \ +ifdef DEBUG +CFLAGS+=-Werror \ + -Wall \ + -Wextra \ + -Wpointer-arith +else +CFLAGS+=-Wno-pointer-arith +endif + FRIDA_BUILD_DIR:=$(BUILD_DIR)frida/ FRIDA_TRACE:=$(BUILD_DIR)afl-frida-trace.so FRIDA_TRACE_EMBEDDED:=$(BUILD_DIR)afl-frida-trace-embedded @@ -31,7 +44,11 @@ endif ifeq "$(shell uname)" "Darwin" OS:=macos - CFLAGS:=$(CFLAGS) -Wno-deprecated-declarations + RT_CFLAGS:=$(RT_CFLAGS) -Wno-deprecated-declarations +else +ifdef DEBUG + RT_CFLAGS:=$(RT_CFLAGS) -Wno-prio-ctor-dtor +endif endif ifeq "$(shell uname)" "Linux" @@ -81,17 +98,14 @@ $(GUM_DEVIT_HEADER): | $(GUM_DEVKIT_TARBALL) $(AFL_COMPILER_RT_OBJ): $(AFL_COMPILER_RT_SRC) $(CC) \ $(CFLAGS) \ + $(RT_CFLAGS) \ -I $(ROOT) \ -I $(ROOT)include \ - -Wno-unused-parameter \ - -Wno-sign-compare \ - -Wno-unused-function \ - -Wno-unused-result \ -o $@ \ -c $< -define BUILD_SOURCE = +define BUILD_SOURCE $(2): $(1) GNUmakefile | $(OBJ_DIR) $(CC) \ $(CFLAGS) \ diff --git a/frida_mode/src/complog/complog.c b/frida_mode/src/complog/complog.c index 1857ea3b..ce8a3f62 100644 --- a/frida_mode/src/complog/complog.c +++ b/frida_mode/src/complog/complog.c @@ -36,8 +36,9 @@ void complog_init(void) { for (guint i = 0; i < complog_ranges->len; i++) { GumMemoryRange *range = &g_array_index(complog_ranges, GumMemoryRange, i); - OKF("CompLog Range - 0x%016lX - 0x%016lX", range->base_address, - range->base_address + range->size); + OKF("CompLog Range - 0x%016" G_GINT64_MODIFIER + "X - 0x%016" G_GINT64_MODIFIER "X", + range->base_address, range->base_address + range->size); } diff --git a/frida_mode/src/complog/complog_arm.c b/frida_mode/src/complog/complog_arm.c index 82cc2557..1b8eb8f1 100644 --- a/frida_mode/src/complog/complog_arm.c +++ b/frida_mode/src/complog/complog_arm.c @@ -3,10 +3,14 @@ #include "debug.h" #include "complog.h" +#include "util.h" -#if defined(__arm64__) +#if defined(__arm__) void complog_instrument(const cs_insn *instr, GumStalkerIterator *iterator) { + UNUSED_PARAMETER(instr); + UNUSED_PARAMETER(iterator); + if (__afl_cmp_map == NULL) { return; } FATAL("Complog mode not supported on this architecture"); } diff --git a/frida_mode/src/complog/complog_arm64.c b/frida_mode/src/complog/complog_arm64.c index e4dbf322..ce62f6fd 100644 --- a/frida_mode/src/complog/complog_arm64.c +++ b/frida_mode/src/complog/complog_arm64.c @@ -3,10 +3,14 @@ #include "debug.h" #include "complog.h" +#include "util.h" -#if defined(__i386__) +#if defined(__aarch64__) void complog_instrument(const cs_insn *instr, GumStalkerIterator *iterator) { + UNUSED_PARAMETER(instr); + UNUSED_PARAMETER(iterator); + if (__afl_cmp_map == NULL) { return; } FATAL("Complog mode not supported on this architecture"); } diff --git a/frida_mode/src/complog/complog_x86.c b/frida_mode/src/complog/complog_x86.c index df7b7cc1..b2e5ddcf 100644 --- a/frida_mode/src/complog/complog_x86.c +++ b/frida_mode/src/complog/complog_x86.c @@ -3,10 +3,14 @@ #include "debug.h" #include "complog.h" +#include "util.h" -#if defined(__arm__) +#if defined(__i386__) void complog_instrument(const cs_insn *instr, GumStalkerIterator *iterator) { + UNUSED_PARAMETER(instr); + UNUSED_PARAMETER(iterator); + if (__afl_cmp_map == NULL) { return; } FATAL("Complog mode not supported on this architecture"); } diff --git a/frida_mode/src/lib.c b/frida_mode/src/lib.c deleted file mode 100644 index e50163ac..00000000 --- a/frida_mode/src/lib.c +++ /dev/null @@ -1,169 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "frida-gum.h" - -#include "debug.h" - -#include "lib.h" - -#if defined(__arm__) || defined(__i386__) - #define ELFCLASS ELFCLASS32 -typedef Elf32_Ehdr Elf_Ehdr; -typedef Elf32_Phdr Elf_Phdr; -typedef Elf32_Shdr Elf_Shdr; -#elif defined(__aarch64__) || defined(__x86_64__) - #define ELFCLASS ELFCLASS64 -typedef Elf64_Ehdr Elf_Ehdr; -typedef Elf64_Phdr Elf_Phdr; -typedef Elf64_Shdr Elf_Shdr; -#else - #error "Unsupported platform" -#endif - -typedef struct { - - gchar name[PATH_MAX + 1]; - gchar path[PATH_MAX + 1]; - GumAddress base_address; - gsize size; - -} lib_details_t; - -static guint64 text_base = 0; -static guint64 text_limit = 0; - -static gboolean lib_find_exe(const GumModuleDetails *details, - gpointer user_data) { - - lib_details_t *lib_details = (lib_details_t *)user_data; - - memcpy(lib_details->name, details->name, PATH_MAX); - memcpy(lib_details->path, details->path, PATH_MAX); - lib_details->base_address = details->range->base_address; - lib_details->size = details->range->size; - return FALSE; - -} - -static gboolean lib_is_little_endian(void) { - - int probe = 1; - return *(char *)&probe; - -} - -static void lib_validate_hdr(Elf_Ehdr *hdr) { - - if (hdr->e_ident[0] != ELFMAG0) FATAL("Invalid e_ident[0]"); - if (hdr->e_ident[1] != ELFMAG1) FATAL("Invalid e_ident[1]"); - if (hdr->e_ident[2] != ELFMAG2) FATAL("Invalid e_ident[2]"); - if (hdr->e_ident[3] != ELFMAG3) FATAL("Invalid e_ident[3]"); - if (hdr->e_ident[4] != ELFCLASS) FATAL("Invalid class"); -/* - if (hdr->e_ident[5] != (lib_is_little_endian() ? ELFDATA2LSB : ELFDATA2MSB)) - FATAL("Invalid endian"); - if (hdr->e_ident[6] != EV_CURRENT) FATAL("Invalid version"); - if (hdr->e_type != ET_DYN) FATAL("Invalid type"); - if (hdr->e_version != EV_CURRENT) FATAL("Invalid e_version"); - if (hdr->e_phoff != sizeof(Elf_Ehdr)) FATAL("Invalid e_phoff"); - if (hdr->e_ehsize != sizeof(Elf_Ehdr)) FATAL("Invalid e_ehsize"); - if (hdr->e_phentsize != sizeof(Elf_Phdr)) FATAL("Invalid e_phentsize"); - if (hdr->e_shentsize != sizeof(Elf_Shdr)) FATAL("Invalid e_shentsize"); -*/ - -} - -static void lib_read_text_section(lib_details_t *lib_details, Elf_Ehdr *hdr) { - - Elf_Shdr *shdr; - Elf_Shdr *shstrtab; - char * shstr; - char * section_name; - Elf_Shdr *curr; - char text_name[] = ".text"; - - shdr = (Elf_Shdr *)((char *)hdr + hdr->e_shoff); - shstrtab = &shdr[hdr->e_shstrndx]; - shstr = (char *)hdr + shstrtab->sh_offset; - - OKF("shdr: %p", shdr); - OKF("shstrtab: %p", shstrtab); - OKF("shstr: %p", shstr); - - for (size_t i = 0; i < hdr->e_shnum; i++) { - - curr = &shdr[i]; - - if (curr->sh_name == 0) continue; - - section_name = &shstr[curr->sh_name]; - OKF("Section: %2lu - base: 0x%016lX size: 0x%016lX %s", i, curr->sh_addr, - curr->sh_size, section_name); - if (memcmp(section_name, text_name, sizeof(text_name)) == 0 && - text_base == 0) { - - text_base = lib_details->base_address + curr->sh_addr; - text_limit = lib_details->base_address + curr->sh_addr + curr->sh_size; - OKF("> text_addr: 0x%016lX", text_base); - OKF("> text_limit: 0x%016lX", text_limit); - - } - - } - -} - -static void lib_get_text_section(lib_details_t *details) { - - int fd = -1; - off_t len; - Elf_Ehdr *hdr; - - fd = open(details->path, O_RDONLY); - if (fd < 0) { FATAL("Failed to open %s", details->path); } - - len = lseek(fd, 0, SEEK_END); - - if (len == (off_t)-1) { FATAL("Failed to lseek %s", details->path); } - - OKF("len: %ld", len); - - hdr = (Elf_Ehdr *)mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0); - if (hdr == MAP_FAILED) { FATAL("Failed to map %s", details->path); } - - lib_validate_hdr(hdr); - lib_read_text_section(details, hdr); - - munmap(hdr, len); - close(fd); - -} - -void lib_init(void) { - - lib_details_t lib_details; - gum_process_enumerate_modules(lib_find_exe, &lib_details); - OKF("Executable: 0x%016lx - %s", lib_details.base_address, lib_details.path); - lib_get_text_section(&lib_details); - -} - -guint64 lib_get_text_base(void) { - - if (text_base == 0) FATAL("Lib not initialized"); - return text_base; - -} - -guint64 lib_get_text_limit(void) { - - if (text_limit == 0) FATAL("Lib not initialized"); - return text_limit; - -} - diff --git a/frida_mode/src/lib/lib b/frida_mode/src/lib/lib new file mode 100755 index 00000000..8f09a3b1 Binary files /dev/null and b/frida_mode/src/lib/lib differ diff --git a/frida_mode/src/lib/lib.c b/frida_mode/src/lib/lib.c new file mode 100644 index 00000000..c5045533 --- /dev/null +++ b/frida_mode/src/lib/lib.c @@ -0,0 +1,176 @@ +#ifndef __APPLE__ + #include + #include + #include + #include + #include + #include + + #include "frida-gum.h" + + #include "debug.h" + + #include "lib.h" + + #if defined(__arm__) || defined(__i386__) + #define ELFCLASS ELFCLASS32 +typedef Elf32_Ehdr Elf_Ehdr; +typedef Elf32_Phdr Elf_Phdr; +typedef Elf32_Shdr Elf_Shdr; +typedef Elf32_Addr Elf_Addr; + #elif defined(__aarch64__) || defined(__x86_64__) + #define ELFCLASS ELFCLASS64 +typedef Elf64_Ehdr Elf_Ehdr; +typedef Elf64_Phdr Elf_Phdr; +typedef Elf64_Shdr Elf_Shdr; +typedef Elf64_Addr Elf_Addr; + #else + #error "Unsupported platform" + #endif + +typedef struct { + + gchar name[PATH_MAX + 1]; + gchar path[PATH_MAX + 1]; + GumAddress base_address; + gsize size; + +} lib_details_t; + +static guint64 text_base = 0; +static guint64 text_limit = 0; + +static gboolean lib_find_exe(const GumModuleDetails *details, + gpointer user_data) { + + lib_details_t *lib_details = (lib_details_t *)user_data; + + memcpy(lib_details->name, details->name, PATH_MAX); + memcpy(lib_details->path, details->path, PATH_MAX); + lib_details->base_address = details->range->base_address; + lib_details->size = details->range->size; + return FALSE; + +} + +static void lib_validate_hdr(Elf_Ehdr *hdr) { + + if (hdr->e_ident[0] != ELFMAG0) FATAL("Invalid e_ident[0]"); + if (hdr->e_ident[1] != ELFMAG1) FATAL("Invalid e_ident[1]"); + if (hdr->e_ident[2] != ELFMAG2) FATAL("Invalid e_ident[2]"); + if (hdr->e_ident[3] != ELFMAG3) FATAL("Invalid e_ident[3]"); + if (hdr->e_ident[4] != ELFCLASS) FATAL("Invalid class"); + +} + +static void lib_read_text_section(lib_details_t *lib_details, Elf_Ehdr *hdr) { + + Elf_Phdr *phdr; + gboolean found_preferred_base = FALSE; + Elf_Addr preferred_base; + Elf_Shdr *shdr; + Elf_Shdr *shstrtab; + char * shstr; + char * section_name; + Elf_Shdr *curr; + char text_name[] = ".text"; + + phdr = (Elf_Phdr *)((char *)hdr + hdr->e_phoff); + for (size_t i = 0; i < hdr->e_phnum; i++) { + + if (phdr[i].p_type == PT_LOAD) { + + preferred_base = phdr[i].p_vaddr; + found_preferred_base = TRUE; + break; + + } + + } + + if (!found_preferred_base) { FATAL("Failed to find preferred load address"); } + + OKF("Image preferred load address 0x%016lx", preferred_base); + + shdr = (Elf_Shdr *)((char *)hdr + hdr->e_shoff); + shstrtab = &shdr[hdr->e_shstrndx]; + shstr = (char *)hdr + shstrtab->sh_offset; + + OKF("shdr: %p", shdr); + OKF("shstrtab: %p", shstrtab); + OKF("shstr: %p", shstr); + + for (size_t i = 0; i < hdr->e_shnum; i++) { + + curr = &shdr[i]; + + if (curr->sh_name == 0) continue; + + section_name = &shstr[curr->sh_name]; + OKF("Section: %2lu - base: 0x%016lX size: 0x%016lX %s", i, curr->sh_addr, + curr->sh_size, section_name); + if (memcmp(section_name, text_name, sizeof(text_name)) == 0 && + text_base == 0) { + + text_base = lib_details->base_address + curr->sh_addr - preferred_base; + text_limit = text_base + curr->sh_size; + OKF("> text_addr: 0x%016lX", text_base); + OKF("> text_limit: 0x%016lX", text_limit); + + } + + } + +} + +static void lib_get_text_section(lib_details_t *details) { + + int fd = -1; + off_t len; + Elf_Ehdr *hdr; + + fd = open(details->path, O_RDONLY); + if (fd < 0) { FATAL("Failed to open %s", details->path); } + + len = lseek(fd, 0, SEEK_END); + + if (len == (off_t)-1) { FATAL("Failed to lseek %s", details->path); } + + OKF("len: %ld", len); + + hdr = (Elf_Ehdr *)mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0); + if (hdr == MAP_FAILED) { FATAL("Failed to map %s", details->path); } + + lib_validate_hdr(hdr); + lib_read_text_section(details, hdr); + + munmap(hdr, len); + close(fd); + +} + +void lib_init(void) { + + lib_details_t lib_details; + gum_process_enumerate_modules(lib_find_exe, &lib_details); + OKF("Executable: 0x%016lx - %s", lib_details.base_address, lib_details.path); + lib_get_text_section(&lib_details); + +} + +guint64 lib_get_text_base(void) { + + if (text_base == 0) FATAL("Lib not initialized"); + return text_base; + +} + +guint64 lib_get_text_limit(void) { + + if (text_limit == 0) FATAL("Lib not initialized"); + return text_limit; + +} + +#endif + diff --git a/frida_mode/src/lib/lib_apple.c b/frida_mode/src/lib/lib_apple.c new file mode 100644 index 00000000..8f863861 --- /dev/null +++ b/frida_mode/src/lib/lib_apple.c @@ -0,0 +1,82 @@ +#ifdef __APPLE__ + #include "frida-gum.h" + + #include "debug.h" + + #include "lib.h" + #include "util.h" + +extern mach_port_t mach_task_self(); +extern void gum_darwin_enumerate_modules(mach_port_t task, + GumFoundModuleFunc func, + gpointer user_data); + +static guint64 text_base = 0; +static guint64 text_limit = 0; + +static gboolean lib_get_main_module(const GumModuleDetails *details, + gpointer user_data) { + + GumDarwinModule **ret = (GumDarwinModule **)user_data; + GumDarwinModule * module = gum_darwin_module_new_from_memory( + details->path, mach_task_self(), details->range->base_address, + GUM_DARWIN_MODULE_FLAGS_NONE, NULL); + + OKF("Found main module: %s", module->name); + + *ret = module; + + return FALSE; + +} + +gboolean lib_get_text_section(const GumDarwinSectionDetails *details, + gpointer user_data) { + + UNUSED_PARAMETER(user_data); + static size_t idx = 0; + char text_name[] = "__text"; + + OKF("Section: %2lu - base: 0x%016" G_GINT64_MODIFIER + "X size: 0x%016" G_GINT64_MODIFIER "X %s", + idx++, details->vm_address, details->vm_address + details->size, + details->section_name); + + if (memcmp(details->section_name, text_name, sizeof(text_name)) == 0 && + text_base == 0) { + + text_base = details->vm_address; + text_limit = details->vm_address + details->size; + OKF("> text_addr: 0x%016" G_GINT64_MODIFIER "X", text_base); + OKF("> text_limit: 0x%016" G_GINT64_MODIFIER "X", text_limit); + + } + + return TRUE; + +} + +void lib_init(void) { + + GumDarwinModule *module = NULL; + gum_darwin_enumerate_modules(mach_task_self(), lib_get_main_module, &module); + gum_darwin_module_enumerate_sections(module, lib_get_text_section, NULL); + +} + +guint64 lib_get_text_base(void) { + + if (text_base == 0) FATAL("Lib not initialized"); + return text_base; + +} + +guint64 lib_get_text_limit(void) { + + if (text_limit == 0) FATAL("Lib not initialized"); + return text_limit; + +} + +#endif + diff --git a/frida_mode/src/main.c b/frida_mode/src/main.c index 11cf041c..5c64d192 100644 --- a/frida_mode/src/main.c +++ b/frida_mode/src/main.c @@ -49,6 +49,10 @@ static int on_fork(void) { #ifdef __APPLE__ static void on_main_os(int argc, char **argv, char **envp) { + UNUSED_PARAMETER(argc); + UNUSED_PARAMETER(argv); + UNUSED_PARAMETER(envp); + } #else diff --git a/frida_mode/src/persistent/persistent.c b/frida_mode/src/persistent/persistent.c index 5aad3724..918ff153 100644 --- a/frida_mode/src/persistent/persistent.c +++ b/frida_mode/src/persistent/persistent.c @@ -33,9 +33,9 @@ void persistent_init(void) { if (persistent_start != 0 && !persistent_is_supported()) FATAL("Persistent mode not supported on this architecture"); - OKF("Instrumentation - persistent mode [%c] (0x%016lX)", + OKF("Instrumentation - persistent mode [%c] (0x%016" G_GINT64_MODIFIER "X)", persistent_start == 0 ? ' ' : 'X', persistent_start); - OKF("Instrumentation - persistent count [%c] (%ld)", + OKF("Instrumentation - persistent count [%c] (%" G_GINT64_MODIFIER "d)", persistent_start == 0 ? ' ' : 'X', persistent_count); OKF("Instrumentation - hook [%s]", hook_name); diff --git a/frida_mode/src/persistent/persistent_arm32.c b/frida_mode/src/persistent/persistent_arm32.c index 10dab3b2..bc021ff3 100644 --- a/frida_mode/src/persistent/persistent_arm32.c +++ b/frida_mode/src/persistent/persistent_arm32.c @@ -3,6 +3,7 @@ #include "debug.h" #include "persistent.h" +#include "util.h" #if defined(__arm__) @@ -62,6 +63,7 @@ gboolean persistent_is_supported(void) { void persistent_prologue(GumStalkerOutput *output) { + UNUSED_PARAMETER(output); FATAL("Persistent mode not supported on this architecture"); } diff --git a/frida_mode/src/persistent/persistent_arm64.c b/frida_mode/src/persistent/persistent_arm64.c index 5a18ac2c..c198da69 100644 --- a/frida_mode/src/persistent/persistent_arm64.c +++ b/frida_mode/src/persistent/persistent_arm64.c @@ -4,6 +4,7 @@ #include "debug.h" #include "instrument.h" +#include "util.h" #if defined(__aarch64__) @@ -105,6 +106,7 @@ gboolean persistent_is_supported(void) { void persistent_prologue(GumStalkerOutput *output) { + UNUSED_PARAMETER(output); FATAL("Persistent mode not supported on this architecture"); } diff --git a/frida_mode/src/persistent/persistent_x86.c b/frida_mode/src/persistent/persistent_x86.c index 4daa61a9..9d39c4e9 100644 --- a/frida_mode/src/persistent/persistent_x86.c +++ b/frida_mode/src/persistent/persistent_x86.c @@ -3,6 +3,7 @@ #include "debug.h" #include "persistent.h" +#include "util.h" #if defined(__i386__) @@ -45,6 +46,7 @@ gboolean persistent_is_supported(void) { void persistent_prologue(GumStalkerOutput *output) { + UNUSED_PARAMETER(output); FATAL("Persistent mode not supported on this architecture"); } diff --git a/frida_mode/test/exe/GNUmakefile b/frida_mode/test/exe/GNUmakefile new file mode 100644 index 00000000..7719ad2b --- /dev/null +++ b/frida_mode/test/exe/GNUmakefile @@ -0,0 +1,50 @@ +PWD:=$(shell pwd)/ +ROOT:=$(shell realpath $(PWD)../../..)/ +BUILD_DIR:=$(PWD)build/ +TESTINSTR_DATA_DIR:=$(BUILD_DIR)in/ +TESTINSTR_DATA_FILE:=$(TESTINSTR_DATA_DIR)in + +TESTINSTBIN:=$(BUILD_DIR)testinstr +TESTINSTSRC:=$(PWD)testinstr.c + +QEMU_OUT:=$(BUILD_DIR)qemu-out +FRIDA_OUT:=$(BUILD_DIR)frida-out + +.PHONY: all clean qemu frida + +all: $(TESTINSTBIN) + make -C $(ROOT)frida_mode/ + +$(BUILD_DIR): + mkdir -p $@ + +$(TESTINSTR_DATA_DIR): | $(BUILD_DIR) + mkdir -p $@ + +$(TESTINSTR_DATA_FILE): | $(TESTINSTR_DATA_DIR) + echo -n "000" > $@ + +$(TESTINSTBIN): $(TESTINSTSRC) | $(BUILD_DIR) + $(CC) -o $@ $< -no-pie + +clean: + rm -rf $(BUILD_DIR) + + +qemu: $(TESTINSTBIN) $(TESTINSTR_DATA_FILE) + $(ROOT)afl-fuzz \ + -D \ + -Q \ + -i $(TESTINSTR_DATA_DIR) \ + -o $(QEMU_OUT) \ + -- \ + $(TESTINSTBIN) @@ + +frida: $(FRIDA_TRACE) $(TESTINSTBIN) $(TESTINSTR_DATA_FILE) + $(ROOT)afl-fuzz \ + -D \ + -O \ + -i $(TESTINSTR_DATA_DIR) \ + -o $(FRIDA_OUT) \ + -- \ + $(TESTINSTBIN) @@ \ No newline at end of file diff --git a/frida_mode/test/exe/Makefile b/frida_mode/test/exe/Makefile new file mode 100644 index 00000000..f322d1f5 --- /dev/null +++ b/frida_mode/test/exe/Makefile @@ -0,0 +1,12 @@ +all: + @echo trying to use GNU make... + @gmake all || echo please install GNUmake + +clean: + @gmake clean + +qemu: + @gmake qemu + +frida: + @gmake frida \ No newline at end of file diff --git a/frida_mode/test/exe/testinstr.c b/frida_mode/test/exe/testinstr.c new file mode 100644 index 00000000..5e26fc46 --- /dev/null +++ b/frida_mode/test/exe/testinstr.c @@ -0,0 +1,112 @@ +/* + american fuzzy lop++ - a trivial program to test the build + -------------------------------------------------------- + Originally written by Michal Zalewski + Copyright 2014 Google Inc. All rights reserved. + Copyright 2019-2020 AFLplusplus Project. All rights reserved. + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at: + http://www.apache.org/licenses/LICENSE-2.0 + */ + +#include +#include +#include +#include +#include + +#ifdef __APPLE__ + #define TESTINSTR_SECTION +#else + #define TESTINSTR_SECTION __attribute__((section(".testinstr"))) +#endif + +void testinstr(char *buf, int len) { + + if (len < 1) return; + buf[len] = 0; + + // we support three input cases + if (buf[0] == '0') + printf("Looks like a zero to me!\n"); + else if (buf[0] == '1') + printf("Pretty sure that is a one!\n"); + else + printf("Neither one or zero? How quaint!\n"); + +} + +TESTINSTR_SECTION int main(int argc, char **argv) { + + char * file; + int fd = -1; + off_t len; + char * buf = NULL; + size_t n_read; + int result = -1; + + if (argc != 2) { return 1; } + + do { + + file = argv[1]; + + dprintf(STDERR_FILENO, "Running: %s\n", file); + + fd = open(file, O_RDONLY); + if (fd < 0) { + + perror("open"); + break; + + } + + len = lseek(fd, 0, SEEK_END); + if (len < 0) { + + perror("lseek (SEEK_END)"); + break; + + } + + if (lseek(fd, 0, SEEK_SET) != 0) { + + perror("lseek (SEEK_SET)"); + break; + + } + + buf = malloc(len); + if (buf == NULL) { + + perror("malloc"); + break; + + } + + n_read = read(fd, buf, len); + if (n_read != len) { + + perror("read"); + break; + + } + + dprintf(STDERR_FILENO, "Running: %s: (%zd bytes)\n", file, n_read); + + testinstr(buf, len); + dprintf(STDERR_FILENO, "Done: %s: (%zd bytes)\n", file, n_read); + + result = 0; + + } while (false); + + if (buf != NULL) { free(buf); } + + if (fd != -1) { close(fd); } + + return result; + +} + diff --git a/frida_mode/test/png/GNUmakefile b/frida_mode/test/png/GNUmakefile index 7de3e85a..515728c4 100644 --- a/frida_mode/test/png/GNUmakefile +++ b/frida_mode/test/png/GNUmakefile @@ -21,6 +21,9 @@ PNGTEST_OBJ:=$(PNGTEST_BUILD_DIR)target.o PNGTEST_URL:="https://raw.githubusercontent.com/google/fuzzbench/master/benchmarks/libpng-1.2.56/target.cc" TEST_BIN:=$(BUILD_DIR)test +ifeq "$(shell uname)" "Darwin" +TEST_BIN_LDFLAGS:=-undefined dynamic_lookup +endif TEST_DATA_DIR:=$(LIBPNG_DIR)contrib/pngsuite/ @@ -80,6 +83,7 @@ $(TEST_BIN): $(HARNESS_OBJ) $(PNGTEST_OBJ) $(LIBPNG_LIB) -o $@ \ $(HARNESS_OBJ) $(PNGTEST_OBJ) $(LIBPNG_LIB) \ -lz \ + $(TEST_BIN_LDFLAGS) \ clean: rm -rf $(BUILD_DIR) -- cgit 1.4.1 From f677be5e86a096edbba74cb8c739e8b10850a379 Mon Sep 17 00:00:00 2001 From: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com> Date: Thu, 27 May 2021 21:33:44 +0100 Subject: Support for AFL_FRIDA_PERSISTENT_RET (#941) Co-authored-by: Your Name --- frida_mode/GNUmakefile | 7 +- frida_mode/include/persistent.h | 4 + frida_mode/src/instrument/instrument.c | 1 + frida_mode/src/persistent/persistent.c | 34 +++++- frida_mode/src/persistent/persistent_arm32.c | 7 ++ frida_mode/src/persistent/persistent_arm64.c | 7 ++ frida_mode/src/persistent/persistent_x64.c | 19 +++- frida_mode/src/persistent/persistent_x86.c | 15 +++ frida_mode/src/util.c | 13 +-- frida_mode/test/persistent_ret/GNUmakefile | 105 +++++++++++++++++++ frida_mode/test/persistent_ret/Makefile | 22 ++++ frida_mode/test/persistent_ret/get_symbol_addr.py | 36 +++++++ frida_mode/test/persistent_ret/testinstr.c | 120 ++++++++++++++++++++++ include/envs.h | 3 + 14 files changed, 382 insertions(+), 11 deletions(-) create mode 100644 frida_mode/test/persistent_ret/GNUmakefile create mode 100644 frida_mode/test/persistent_ret/Makefile create mode 100755 frida_mode/test/persistent_ret/get_symbol_addr.py create mode 100644 frida_mode/test/persistent_ret/testinstr.c (limited to 'frida_mode/src/persistent/persistent.c') diff --git a/frida_mode/GNUmakefile b/frida_mode/GNUmakefile index 20fbb544..f9c0f1f7 100644 --- a/frida_mode/GNUmakefile +++ b/frida_mode/GNUmakefile @@ -36,6 +36,10 @@ else CFLAGS+=-Wno-pointer-arith endif +ifdef FRIDA_DEBUG +CFLAGS += -DFRIDA_DEBUG +endif + FRIDA_BUILD_DIR:=$(BUILD_DIR)frida/ FRIDA_TRACE:=$(BUILD_DIR)afl-frida-trace.so FRIDA_TRACE_EMBEDDED:=$(BUILD_DIR)afl-frida-trace-embedded @@ -94,9 +98,6 @@ AFL_COMPILER_RT_OBJ:=$(OBJ_DIR)afl-compiler-rt.o all: $(FRIDA_TRACE) -32: - CFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all - 32: CFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all diff --git a/frida_mode/include/persistent.h b/frida_mode/include/persistent.h index e58c5301..25b44ab0 100644 --- a/frida_mode/include/persistent.h +++ b/frida_mode/include/persistent.h @@ -18,6 +18,9 @@ extern unsigned char *__afl_fuzz_ptr; extern guint64 persistent_start; extern guint64 persistent_count; +extern guint64 persistent_ret; +extern guint64 persistent_ret_offset; +extern gboolean persistent_debug; extern afl_persistent_hook_fn hook; void persistent_init(void); @@ -26,6 +29,7 @@ void persistent_init(void); gboolean persistent_is_supported(void); void persistent_prologue(GumStalkerOutput *output); +void persistent_epilogue(GumStalkerOutput *output); #endif diff --git a/frida_mode/src/instrument/instrument.c b/frida_mode/src/instrument/instrument.c index f21849a6..c4f18797 100644 --- a/frida_mode/src/instrument/instrument.c +++ b/frida_mode/src/instrument/instrument.c @@ -85,6 +85,7 @@ static void instr_basic_block(GumStalkerIterator *iterator, if (instr->address == entry_start) { entry_prologue(iterator, output); } if (instr->address == persistent_start) { persistent_prologue(output); } + if (instr->address == persistent_ret) { persistent_epilogue(output); } /* * Until we reach AFL_ENTRYPOINT (assumed to be main if not specified) or diff --git a/frida_mode/src/persistent/persistent.c b/frida_mode/src/persistent/persistent.c index 918ff153..2ec5b9cc 100644 --- a/frida_mode/src/persistent/persistent.c +++ b/frida_mode/src/persistent/persistent.c @@ -12,6 +12,9 @@ int __afl_sharedmem_fuzzing = 0; afl_persistent_hook_fn hook = NULL; guint64 persistent_start = 0; guint64 persistent_count = 0; +guint64 persistent_ret = 0; +guint64 persistent_ret_offset = 0; +gboolean persistent_debug = FALSE; void persistent_init(void) { @@ -19,12 +22,36 @@ void persistent_init(void) { persistent_start = util_read_address("AFL_FRIDA_PERSISTENT_ADDR"); persistent_count = util_read_num("AFL_FRIDA_PERSISTENT_CNT"); + persistent_ret = util_read_address("AFL_FRIDA_PERSISTENT_RET"); + persistent_ret_offset = + util_read_address("AFL_FRIDA_PERSISTENT_RETADDR_OFFSET"); + + if (getenv("AFL_FRIDA_PERSISTENT_DEBUG") != NULL) { persistent_debug = TRUE; } + + if (persistent_count != 0 && persistent_start == 0) { - if (persistent_count != 0 && persistent_start == 0) FATAL( "AFL_FRIDA_PERSISTENT_ADDR must be specified if " "AFL_FRIDA_PERSISTENT_CNT is"); + } + + if (persistent_ret != 0 && persistent_start == 0) { + + FATAL( + "AFL_FRIDA_PERSISTENT_ADDR must be specified if " + "AFL_FRIDA_PERSISTENT_RET is"); + + } + + if (persistent_ret_offset != 0 && persistent_ret == 0) { + + FATAL( + "AFL_FRIDA_PERSISTENT_RET must be specified if " + "AFL_FRIDA_PERSISTENT_RETADDR_OFFSET is"); + + } + if (persistent_start != 0 && persistent_count == 0) persistent_count = 1000; if (persistent_count != 0 && persistent_count < 100) @@ -39,6 +66,11 @@ void persistent_init(void) { persistent_start == 0 ? ' ' : 'X', persistent_count); OKF("Instrumentation - hook [%s]", hook_name); + OKF("Instrumentation - persistent ret [%c] (0x%016" G_GINT64_MODIFIER "X)", + persistent_ret == 0 ? ' ' : 'X', persistent_ret); + OKF("Instrumentation - persistent ret offset [%c] (%" G_GINT64_MODIFIER "d)", + persistent_ret_offset == 0 ? ' ' : 'X', persistent_ret_offset); + if (hook_name != NULL) { void *hook_obj = dlopen(hook_name, RTLD_NOW); diff --git a/frida_mode/src/persistent/persistent_arm32.c b/frida_mode/src/persistent/persistent_arm32.c index bc021ff3..6a3c06fa 100644 --- a/frida_mode/src/persistent/persistent_arm32.c +++ b/frida_mode/src/persistent/persistent_arm32.c @@ -68,5 +68,12 @@ void persistent_prologue(GumStalkerOutput *output) { } +void persistent_epilogue(GumStalkerOutput *output) { + + UNUSED_PARAMETER(output); + FATAL("Persistent mode not supported on this architecture"); + +} + #endif diff --git a/frida_mode/src/persistent/persistent_arm64.c b/frida_mode/src/persistent/persistent_arm64.c index c198da69..1215d8da 100644 --- a/frida_mode/src/persistent/persistent_arm64.c +++ b/frida_mode/src/persistent/persistent_arm64.c @@ -111,5 +111,12 @@ void persistent_prologue(GumStalkerOutput *output) { } +void persistent_epilogue(GumStalkerOutput *output) { + + UNUSED_PARAMETER(output); + FATAL("Persistent mode not supported on this architecture"); + +} + #endif diff --git a/frida_mode/src/persistent/persistent_x64.c b/frida_mode/src/persistent/persistent_x64.c index aa772b7f..4c495d47 100644 --- a/frida_mode/src/persistent/persistent_x64.c +++ b/frida_mode/src/persistent/persistent_x64.c @@ -1,9 +1,11 @@ #include "frida-gum.h" #include "config.h" +#include "debug.h" #include "instrument.h" #include "persistent.h" +#include "util.h" #if defined(__x86_64__) @@ -264,7 +266,6 @@ void persistent_prologue(GumStalkerOutput *output) { GumX86Writer *cw = output->writer.x86; gconstpointer loop = cw->code + 1; - // gum_x86_writer_put_breakpoint(cw); /* Stack must be 16-byte aligned per ABI */ instrument_persitent_save_regs(cw, &saved_regs); @@ -288,7 +289,9 @@ void persistent_prologue(GumStalkerOutput *output) { instrument_persitent_restore_regs(cw, &saved_regs); gconstpointer original = cw->code + 1; /* call original */ + gum_x86_writer_put_call_near_label(cw, original); + /* jmp loop */ gum_x86_writer_put_jmp_near_label(cw, loop); @@ -300,9 +303,23 @@ void persistent_prologue(GumStalkerOutput *output) { /* original: */ gum_x86_writer_put_label(cw, original); + if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); } + gum_x86_writer_flush(cw); } +void persistent_epilogue(GumStalkerOutput *output) { + + GumX86Writer *cw = output->writer.x86; + + if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); } + + gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, + persistent_ret_offset); + gum_x86_writer_put_ret(cw); + +} + #endif diff --git a/frida_mode/src/persistent/persistent_x86.c b/frida_mode/src/persistent/persistent_x86.c index 20a3dc42..b30dfadf 100644 --- a/frida_mode/src/persistent/persistent_x86.c +++ b/frida_mode/src/persistent/persistent_x86.c @@ -244,9 +244,24 @@ void persistent_prologue(GumStalkerOutput *output) { /* original: */ gum_x86_writer_put_label(cw, original); + if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); } + gum_x86_writer_flush(cw); } +void persistent_epilogue(GumStalkerOutput *output) { + + GumX86Writer *cw = output->writer.x86; + + if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); } + + gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_ESP, GUM_REG_ESP, + persistent_ret_offset); + + gum_x86_writer_put_ret(cw); + +} + #endif diff --git a/frida_mode/src/util.c b/frida_mode/src/util.c index 86b94970..09e8a58b 100644 --- a/frida_mode/src/util.c +++ b/frida_mode/src/util.c @@ -10,7 +10,7 @@ guint64 util_read_address(char *key) { if (!g_str_has_prefix(value_str, "0x")) { - FATAL("Invalid address should have 0x prefix: %s\n", value_str); + FATAL("Invalid address should have 0x prefix: %s=%s\n", key, value_str); } @@ -20,8 +20,8 @@ guint64 util_read_address(char *key) { if (!g_ascii_isxdigit(*c)) { - FATAL("Invalid address not formed of hex digits: %s ('%c')\n", value_str, - *c); + FATAL("Invalid address not formed of hex digits: %s=%s ('%c')\n", key, + value_str, *c); } @@ -30,7 +30,7 @@ guint64 util_read_address(char *key) { guint64 value = g_ascii_strtoull(value_str2, NULL, 16); if (value == 0) { - FATAL("Invalid address failed hex conversion: %s\n", value_str2); + FATAL("Invalid address failed hex conversion: %s=%s\n", key, value_str2); } @@ -48,7 +48,8 @@ guint64 util_read_num(char *key) { if (!g_ascii_isdigit(*c)) { - FATAL("Invalid address not formed of decimal digits: %s\n", value_str); + FATAL("Invalid address not formed of decimal digits: %s=%s\n", key, + value_str); } @@ -57,7 +58,7 @@ guint64 util_read_num(char *key) { guint64 value = g_ascii_strtoull(value_str, NULL, 10); if (value == 0) { - FATAL("Invalid address failed numeric conversion: %s\n", value_str); + FATAL("Invalid address failed numeric conversion: %s=%s\n", key, value_str); } diff --git a/frida_mode/test/persistent_ret/GNUmakefile b/frida_mode/test/persistent_ret/GNUmakefile new file mode 100644 index 00000000..df48d065 --- /dev/null +++ b/frida_mode/test/persistent_ret/GNUmakefile @@ -0,0 +1,105 @@ +PWD:=$(shell pwd)/ +ROOT:=$(shell realpath $(PWD)../../..)/ +BUILD_DIR:=$(PWD)build/ +TESTINSTR_DATA_DIR:=$(BUILD_DIR)in/ +TESTINSTR_DATA_FILE:=$(TESTINSTR_DATA_DIR)in + +TESTINSTBIN:=$(BUILD_DIR)testinstr +TESTINSTSRC:=$(PWD)testinstr.c + +QEMU_OUT:=$(BUILD_DIR)qemu-out +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 + +ARCH=$(shell uname -m) +ifeq "$(ARCH)" "aarch64" + AFL_FRIDA_PERSISTENT_ADDR=$(shell $(PWD)get_symbol_addr.py -f $(TESTINSTBIN) -s main -b 0x0000aaaaaaaaa000) + AFL_FRIDA_PERSISTENT_RET=$(shell $(PWD)get_symbol_addr.py -f $(TESTINSTBIN) -s slow -b 0x0000aaaaaaaaa000) +endif + +ifeq "$(ARCH)" "x86_64" + AFL_FRIDA_PERSISTENT_ADDR=$(shell $(PWD)get_symbol_addr.py -f $(TESTINSTBIN) -s main -b 0x0000555555554000) + AFL_FRIDA_PERSISTENT_RET=$(shell $(PWD)get_symbol_addr.py -f $(TESTINSTBIN) -s slow -b 0x0000555555554000) +endif + +ifeq "$(ARCH)" "x86" + AFL_FRIDA_PERSISTENT_ADDR=$(shell $(PWD)get_symbol_addr.py -f $(TESTINSTBIN) -s main -b 0x56555000) + AFL_FRIDA_PERSISTENT_RET=$(shell $(PWD)get_symbol_addr.py -f $(TESTINSTBIN) -s slow -b 0x56555000) +endif + +AFL_FRIDA_PERSISTENT_RETADDR_OFFSET:=0x50 + +.PHONY: all 32 clean qemu frida + +all: $(TESTINSTBIN) + make -C $(ROOT)frida_mode/ + +32: + CFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all + +$(BUILD_DIR): + mkdir -p $@ + +$(TESTINSTR_DATA_DIR): | $(BUILD_DIR) + mkdir -p $@ + +$(TESTINSTR_DATA_FILE): | $(TESTINSTR_DATA_DIR) + echo -n "000" > $@ + +$(TESTINSTBIN): $(TESTINSTSRC) | $(BUILD_DIR) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< + +clean: + rm -rf $(BUILD_DIR) + +frida: $(TESTINSTBIN) $(TESTINSTR_DATA_FILE) + AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR) \ + $(ROOT)afl-fuzz \ + -D \ + -O \ + -i $(TESTINSTR_DATA_DIR) \ + -o $(FRIDA_OUT) \ + -- \ + $(TESTINSTBIN) @@ + +frida_ret: $(TESTINSTBIN) $(TESTINSTR_DATA_FILE) + AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR) \ + AFL_FRIDA_PERSISTENT_RET=$(AFL_FRIDA_PERSISTENT_RET) \ + AFL_FRIDA_PERSISTENT_RETADDR_OFFSET=$(AFL_FRIDA_PERSISTENT_RETADDR_OFFSET) \ + $(ROOT)afl-fuzz \ + -D \ + -O \ + -i $(TESTINSTR_DATA_DIR) \ + -o $(FRIDA_OUT) \ + -- \ + $(TESTINSTBIN) @@ + +debug: $(TESTINSTR_DATA_FILE) + gdb \ + --ex 'set environment AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR)' \ + --ex 'set environment AFL_FRIDA_PERSISTENT_RET=$(AFL_FRIDA_PERSISTENT_RET)' \ + --ex 'set environment AFL_FRIDA_PERSISTENT_RETADDR_OFFSET=$(AFL_FRIDA_PERSISTENT_RETADDR_OFFSET)' \ + --ex 'set environment AFL_FRIDA_PERSISTENT_DEBUG=1' \ + --ex 'set environment AFL_DEBUG_CHILD=1' \ + --ex 'set environment LD_PRELOAD=$(ROOT)afl-frida-trace.so' \ + --ex 'set disassembly-flavor intel' \ + --args $(TESTINSTBIN) $(TESTINSTR_DATA_FILE) + +run: $(TESTINSTR_DATA_FILE) + AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR) \ + AFL_FRIDA_PERSISTENT_RET=$(AFL_FRIDA_PERSISTENT_RET) \ + AFL_FRIDA_PERSISTENT_RETADDR_OFFSET=$(AFL_FRIDA_PERSISTENT_RETADDR_OFFSET) \ + AFL_DEBUG_CHILD=1 \ + LD_PRELOAD=$(ROOT)afl-frida-trace.so \ + $(TESTINSTBIN) $(TESTINSTR_DATA_FILE) diff --git a/frida_mode/test/persistent_ret/Makefile b/frida_mode/test/persistent_ret/Makefile new file mode 100644 index 00000000..e3deddbd --- /dev/null +++ b/frida_mode/test/persistent_ret/Makefile @@ -0,0 +1,22 @@ +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 + +frida_ret: + @gmake frida_ret + +debug: + @gmake debug + +run: + @gmake run diff --git a/frida_mode/test/persistent_ret/get_symbol_addr.py b/frida_mode/test/persistent_ret/get_symbol_addr.py new file mode 100755 index 00000000..1c46e010 --- /dev/null +++ b/frida_mode/test/persistent_ret/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/persistent_ret/testinstr.c b/frida_mode/test/persistent_ret/testinstr.c new file mode 100644 index 00000000..6cb88a50 --- /dev/null +++ b/frida_mode/test/persistent_ret/testinstr.c @@ -0,0 +1,120 @@ +/* + american fuzzy lop++ - a trivial program to test the build + -------------------------------------------------------- + Originally written by Michal Zalewski + Copyright 2014 Google Inc. All rights reserved. + Copyright 2019-2020 AFLplusplus Project. All rights reserved. + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at: + http://www.apache.org/licenses/LICENSE-2.0 + */ + +#include +#include +#include +#include +#include + +#ifdef __APPLE__ + #define TESTINSTR_SECTION +#else + #define TESTINSTR_SECTION __attribute__((section(".testinstr"))) +#endif + +void testinstr(char *buf, int len) { + + if (len < 1) return; + buf[len] = 0; + + // we support three input cases + if (buf[0] == '0') + printf("Looks like a zero to me!\n"); + else if (buf[0] == '1') + printf("Pretty sure that is a one!\n"); + else + printf("Neither one or zero? How quaint!\n"); + +} + +void slow() { + + usleep(100000); + +} + +TESTINSTR_SECTION int main(int argc, char **argv) { + + char * file; + int fd = -1; + off_t len; + char * buf = NULL; + size_t n_read; + int result = -1; + + if (argc != 2) { return 1; } + + do { + + file = argv[1]; + + dprintf(STDERR_FILENO, "Running: %s\n", file); + + fd = open(file, O_RDONLY); + if (fd < 0) { + + perror("open"); + break; + + } + + len = lseek(fd, 0, SEEK_END); + if (len < 0) { + + perror("lseek (SEEK_END)"); + break; + + } + + if (lseek(fd, 0, SEEK_SET) != 0) { + + perror("lseek (SEEK_SET)"); + break; + + } + + buf = malloc(len); + if (buf == NULL) { + + perror("malloc"); + break; + + } + + n_read = read(fd, buf, len); + if (n_read != len) { + + perror("read"); + break; + + } + + dprintf(STDERR_FILENO, "Running: %s: (%zd bytes)\n", file, n_read); + + testinstr(buf, len); + dprintf(STDERR_FILENO, "Done: %s: (%zd bytes)\n", file, n_read); + + slow(); + + result = 0; + + } while (false); + + if (buf != NULL) { free(buf); } + + if (fd != -1) { close(fd); } + + return result; + +} + diff --git a/include/envs.h b/include/envs.h index e7162c0f..73cd82a8 100644 --- a/include/envs.h +++ b/include/envs.h @@ -62,7 +62,10 @@ static char *afl_environment_variables[] = { "AFL_FRIDA_INST_TRACE", "AFL_FRIDA_PERSISTENT_ADDR", "AFL_FRIDA_PERSISTENT_CNT", + "AFL_FRIDA_PERSISTENT_DEBUG", "AFL_FRIDA_PERSISTENT_HOOK", + "AFL_FRIDA_PERSISTENT_RET", + "AFL_FRIDA_PERSISTENT_RETADDR_OFFSET", "AFL_FUZZER_ARGS", // oss-fuzz "AFL_GDB", "AFL_GCC_ALLOWLIST", -- cgit 1.4.1