diff options
Diffstat (limited to 'frida_mode/src')
42 files changed, 822 insertions, 234 deletions
diff --git a/frida_mode/src/asan/asan.c b/frida_mode/src/asan/asan.c index f78f690c..b2e763ca 100644 --- a/frida_mode/src/asan/asan.c +++ b/frida_mode/src/asan/asan.c @@ -1,18 +1,18 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" #include "asan.h" -gboolean asan_initialized = FALSE; +static gboolean asan_enabled = FALSE; +gboolean asan_initialized = FALSE; -void asan_init(void) { +void asan_config(void) { if (getenv("AFL_USE_FASAN") != NULL) { OKF("Frida ASAN mode enabled"); - asan_arch_init(); - asan_initialized = TRUE; + asan_enabled = TRUE; } else { @@ -22,3 +22,14 @@ void asan_init(void) { } +void asan_init(void) { + + if (asan_enabled) { + + asan_arch_init(); + asan_initialized = TRUE; + + } + +} + diff --git a/frida_mode/src/asan/asan_arm32.c b/frida_mode/src/asan/asan_arm32.c index 79475ced..f5fa4713 100644 --- a/frida_mode/src/asan/asan_arm32.c +++ b/frida_mode/src/asan/asan_arm32.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" diff --git a/frida_mode/src/asan/asan_arm64.c b/frida_mode/src/asan/asan_arm64.c index 66138e42..65524e03 100644 --- a/frida_mode/src/asan/asan_arm64.c +++ b/frida_mode/src/asan/asan_arm64.c @@ -1,5 +1,5 @@ #include <dlfcn.h> -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" diff --git a/frida_mode/src/asan/asan_x64.c b/frida_mode/src/asan/asan_x64.c index a2eabe3c..5c12669f 100644 --- a/frida_mode/src/asan/asan_x64.c +++ b/frida_mode/src/asan/asan_x64.c @@ -1,5 +1,5 @@ #include <dlfcn.h> -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" diff --git a/frida_mode/src/asan/asan_x86.c b/frida_mode/src/asan/asan_x86.c index 8490b490..6d2f9e2b 100644 --- a/frida_mode/src/asan/asan_x86.c +++ b/frida_mode/src/asan/asan_x86.c @@ -1,5 +1,5 @@ #include <dlfcn.h> -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" diff --git a/frida_mode/src/cmplog/cmplog.c b/frida_mode/src/cmplog/cmplog.c index 8814f7f3..a2609c8e 100644 --- a/frida_mode/src/cmplog/cmplog.c +++ b/frida_mode/src/cmplog/cmplog.c @@ -5,7 +5,7 @@ #include <sys/syscall.h> #include <unistd.h> -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" @@ -50,6 +50,10 @@ static void cmplog_get_ranges(void) { } +void cmplog_config(void) { + +} + void cmplog_init(void) { if (__afl_cmp_map != NULL) { OKF("CMPLOG mode enabled"); } @@ -94,10 +98,10 @@ static gboolean cmplog_contains(GumAddress inner_base, GumAddress inner_limit, gboolean cmplog_test_addr(guint64 addr, size_t size) { - if (g_hash_table_contains(hash_yes, (gpointer)addr)) { return true; } - if (g_hash_table_contains(hash_no, (gpointer)addr)) { return false; } + if (g_hash_table_contains(hash_yes, GSIZE_TO_POINTER(addr))) { return true; } + if (g_hash_table_contains(hash_no, GSIZE_TO_POINTER(addr))) { return false; } - void * page_addr = (void *)(addr & page_mask); + void * page_addr = GSIZE_TO_POINTER(addr & page_mask); size_t page_offset = addr & page_offset_mask; /* If it spans a page, then bail */ @@ -109,7 +113,7 @@ gboolean cmplog_test_addr(guint64 addr, size_t size) { */ if (msync(page_addr, page_offset + size, MS_ASYNC) < 0) { - if (!g_hash_table_add(hash_no, (gpointer)addr)) { + if (!g_hash_table_add(hash_no, GSIZE_TO_POINTER(addr))) { FATAL("Failed - g_hash_table_add"); @@ -119,7 +123,7 @@ gboolean cmplog_test_addr(guint64 addr, size_t size) { } else { - if (!g_hash_table_add(hash_yes, (gpointer)addr)) { + if (!g_hash_table_add(hash_yes, GSIZE_TO_POINTER(addr))) { FATAL("Failed - g_hash_table_add"); diff --git a/frida_mode/src/cmplog/cmplog_arm32.c b/frida_mode/src/cmplog/cmplog_arm32.c index 5af28f3f..ac703408 100644 --- a/frida_mode/src/cmplog/cmplog_arm32.c +++ b/frida_mode/src/cmplog/cmplog_arm32.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" diff --git a/frida_mode/src/cmplog/cmplog_arm64.c b/frida_mode/src/cmplog/cmplog_arm64.c index 04631ff8..dd97f38d 100644 --- a/frida_mode/src/cmplog/cmplog_arm64.c +++ b/frida_mode/src/cmplog/cmplog_arm64.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" #include "cmplog.h" diff --git a/frida_mode/src/cmplog/cmplog_x64.c b/frida_mode/src/cmplog/cmplog_x64.c index ba16445d..0d18767a 100644 --- a/frida_mode/src/cmplog/cmplog_x64.c +++ b/frida_mode/src/cmplog/cmplog_x64.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" #include "cmplog.h" diff --git a/frida_mode/src/cmplog/cmplog_x86.c b/frida_mode/src/cmplog/cmplog_x86.c index a27df0af..dd666c34 100644 --- a/frida_mode/src/cmplog/cmplog_x86.c +++ b/frida_mode/src/cmplog/cmplog_x86.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" #include "cmplog.h" diff --git a/frida_mode/src/ctx/ctx_arm32.c b/frida_mode/src/ctx/ctx_arm32.c index a5c6f6d4..a354c117 100644 --- a/frida_mode/src/ctx/ctx_arm32.c +++ b/frida_mode/src/ctx/ctx_arm32.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" diff --git a/frida_mode/src/ctx/ctx_arm64.c b/frida_mode/src/ctx/ctx_arm64.c index d09896af..a735401b 100644 --- a/frida_mode/src/ctx/ctx_arm64.c +++ b/frida_mode/src/ctx/ctx_arm64.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" diff --git a/frida_mode/src/ctx/ctx_x64.c b/frida_mode/src/ctx/ctx_x64.c index 1772a252..da5cb13a 100644 --- a/frida_mode/src/ctx/ctx_x64.c +++ b/frida_mode/src/ctx/ctx_x64.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" diff --git a/frida_mode/src/ctx/ctx_x86.c b/frida_mode/src/ctx/ctx_x86.c index 9b50cb52..1a587702 100644 --- a/frida_mode/src/ctx/ctx_x86.c +++ b/frida_mode/src/ctx/ctx_x86.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" diff --git a/frida_mode/src/entry.c b/frida_mode/src/entry.c index e71386a0..186d5098 100644 --- a/frida_mode/src/entry.c +++ b/frida_mode/src/entry.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" @@ -9,27 +9,32 @@ extern void __afl_manual_init(); -guint64 entry_start = 0; +guint64 entry_point = 0; static void entry_launch(void) { __afl_manual_init(); /* Child here */ - previous_pc = 0; + instrument_previous_pc = 0; + +} + +void entry_config(void) { + + entry_point = util_read_address("AFL_ENTRYPOINT"); } void entry_init(void) { - entry_start = util_read_address("AFL_ENTRYPOINT"); - OKF("entry_point: 0x%016" G_GINT64_MODIFIER "X", entry_start); + OKF("entry_point: 0x%016" G_GINT64_MODIFIER "X", entry_point); } -void entry_run(void) { +void entry_start(void) { - if (entry_start == 0) { entry_launch(); } + if (entry_point == 0) { entry_launch(); } } diff --git a/frida_mode/src/instrument/instrument.c b/frida_mode/src/instrument/instrument.c index ba82b89f..d6ae505d 100644 --- a/frida_mode/src/instrument/instrument.c +++ b/frida_mode/src/instrument/instrument.c @@ -2,7 +2,7 @@ #include <sys/shm.h> #include <sys/mman.h> -#include "frida-gum.h" +#include "frida-gumjs.h" #include "config.h" #include "debug.h" @@ -18,12 +18,13 @@ #include "stats.h" #include "util.h" -static gboolean tracing = false; -static gboolean optimize = false; -static gboolean unique = false; +gboolean instrument_tracing = false; +gboolean instrument_optimize = false; +gboolean instrument_unique = false; + static GumStalkerTransformer *transformer = NULL; -__thread uint64_t previous_pc = 0; +__thread uint64_t instrument_previous_pc = 0; static GumAddress previous_rip = 0; static u8 * edges_notified = NULL; @@ -61,7 +62,7 @@ __attribute__((hot)) static void on_basic_block(GumCpuContext *context, current_pc = (current_rip >> 4) ^ (current_rip << 8); current_pc &= MAP_SIZE - 1; - edge = current_pc ^ previous_pc; + edge = current_pc ^ instrument_previous_pc; cursor = &__afl_area_ptr[edge]; value = *cursor; @@ -77,11 +78,11 @@ __attribute__((hot)) static void on_basic_block(GumCpuContext *context, } *cursor = value; - previous_pc = current_pc >> 1; + instrument_previous_pc = current_pc >> 1; - if (unlikely(tracing)) { + if (unlikely(instrument_tracing)) { - if (!unique || edges_notified[edge] == 0) { + if (!instrument_unique || edges_notified[edge] == 0) { trace_debug("TRACE: edge: %10" G_GINT64_MODIFIER "d, current_rip: 0x%016" G_GINT64_MODIFIER @@ -90,7 +91,7 @@ __attribute__((hot)) static void on_basic_block(GumCpuContext *context, } - if (unique) { edges_notified[edge] = 1; } + if (instrument_unique) { edges_notified[edge] = 1; } previous_rip = current_rip; @@ -98,8 +99,9 @@ __attribute__((hot)) static void on_basic_block(GumCpuContext *context, } -static void instr_basic_block(GumStalkerIterator *iterator, - GumStalkerOutput *output, gpointer user_data) { +static void instrument_basic_block(GumStalkerIterator *iterator, + GumStalkerOutput * output, + gpointer user_data) { UNUSED_PARAMETER(user_data); @@ -111,7 +113,7 @@ static void instr_basic_block(GumStalkerIterator *iterator, if (unlikely(begin)) { instrument_debug_start(instr->address, output); } - if (instr->address == entry_start) { entry_prologue(iterator, output); } + if (instr->address == entry_point) { entry_prologue(iterator, output); } if (instr->address == persistent_start) { persistent_prologue(output); } if (instr->address == persistent_ret) { persistent_epilogue(output); } @@ -150,7 +152,7 @@ static void instr_basic_block(GumStalkerIterator *iterator, if (likely(!excluded)) { - if (likely(optimize)) { + if (likely(instrument_optimize)) { instrument_coverage_optimize(instr, output); @@ -185,31 +187,39 @@ static void instr_basic_block(GumStalkerIterator *iterator, } -void instrument_init(void) { +void instrument_config(void) { + + instrument_optimize = (getenv("AFL_FRIDA_INST_NO_OPTIMIZE") == NULL); + instrument_tracing = (getenv("AFL_FRIDA_INST_TRACE") != NULL); + instrument_unique = (getenv("AFL_FRIDA_INST_TRACE_UNIQUE") != NULL); + + instrument_debug_config(); + asan_config(); + cmplog_config(); - optimize = (getenv("AFL_FRIDA_INST_NO_OPTIMIZE") == NULL); - tracing = (getenv("AFL_FRIDA_INST_TRACE") != NULL); - unique = (getenv("AFL_FRIDA_INST_TRACE_UNIQUE") != NULL); +} + +void instrument_init(void) { - if (!instrument_is_coverage_optimize_supported()) optimize = false; + if (!instrument_is_coverage_optimize_supported()) instrument_optimize = false; - OKF("Instrumentation - optimize [%c]", optimize ? 'X' : ' '); - OKF("Instrumentation - tracing [%c]", tracing ? 'X' : ' '); - OKF("Instrumentation - unique [%c]", unique ? 'X' : ' '); + OKF("Instrumentation - optimize [%c]", instrument_optimize ? 'X' : ' '); + OKF("Instrumentation - tracing [%c]", instrument_tracing ? 'X' : ' '); + OKF("Instrumentation - unique [%c]", instrument_unique ? 'X' : ' '); - if (tracing && optimize) { + if (instrument_tracing && instrument_optimize) { FATAL("AFL_FRIDA_INST_TRACE requires AFL_FRIDA_INST_NO_OPTIMIZE"); } - if (unique && optimize) { + if (instrument_unique && instrument_optimize) { FATAL("AFL_FRIDA_INST_TRACE_UNIQUE requires AFL_FRIDA_INST_NO_OPTIMIZE"); } - if (unique) { tracing = TRUE; } + if (instrument_unique) { instrument_tracing = TRUE; } if (__afl_map_size != 0x10000) { @@ -217,10 +227,10 @@ void instrument_init(void) { } - transformer = - gum_stalker_transformer_make_from_callback(instr_basic_block, NULL, NULL); + transformer = gum_stalker_transformer_make_from_callback( + instrument_basic_block, NULL, NULL); - if (unique) { + if (instrument_unique) { int shm_id = shmget(IPC_PRIVATE, MAP_SIZE, IPC_CREAT | IPC_EXCL | 0600); if (shm_id < 0) { FATAL("shm_id < 0 - errno: %d\n", errno); } diff --git a/frida_mode/src/instrument/instrument_arm32.c b/frida_mode/src/instrument/instrument_arm32.c index 450a69a3..0e15940a 100644 --- a/frida_mode/src/instrument/instrument_arm32.c +++ b/frida_mode/src/instrument/instrument_arm32.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" diff --git a/frida_mode/src/instrument/instrument_arm64.c b/frida_mode/src/instrument/instrument_arm64.c index 49ee86a2..17f97c97 100644 --- a/frida_mode/src/instrument/instrument_arm64.c +++ b/frida_mode/src/instrument/instrument_arm64.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "config.h" #include "debug.h" @@ -72,7 +72,7 @@ void instrument_coverage_optimize(const cs_insn * instr, gum_arm64_writer_put_bytes(cw, afl_log_code, sizeof(afl_log_code)); uint8_t **afl_area_ptr_ptr = &__afl_area_ptr; - uint64_t *afl_prev_loc_ptr = &previous_pc; + uint64_t *afl_prev_loc_ptr = &instrument_previous_pc; gum_arm64_writer_put_bytes(cw, (const guint8 *)&afl_area_ptr_ptr, sizeof(afl_area_ptr_ptr)); gum_arm64_writer_put_bytes(cw, (const guint8 *)&afl_prev_loc_ptr, diff --git a/frida_mode/src/instrument/instrument_debug.c b/frida_mode/src/instrument/instrument_debug.c index 0ce26a1c..b8cca634 100644 --- a/frida_mode/src/instrument/instrument_debug.c +++ b/frida_mode/src/instrument/instrument_debug.c @@ -3,7 +3,7 @@ #include <stdio.h> #include <unistd.h> -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" @@ -13,6 +13,8 @@ static int debugging_fd = -1; static gpointer instrument_gen_start = NULL; +char *instrument_debug_filename = NULL; + static void instrument_debug(char *format, ...) { va_list ap; @@ -79,18 +81,25 @@ static void instrument_disasm(guint8 *start, guint8 *end) { } +void instrument_debug_config(void) { + + instrument_debug_filename = getenv("AFL_FRIDA_INST_DEBUG_FILE"); + +} + void instrument_debug_init(void) { - char *filename = getenv("AFL_FRIDA_INST_DEBUG_FILE"); - OKF("Instrumentation debugging - enabled [%c]", filename == NULL ? ' ' : 'X'); + OKF("Instrumentation debugging - enabled [%c]", + instrument_debug_filename == NULL ? ' ' : 'X'); - if (filename == NULL) { return; } + if (instrument_debug_filename == NULL) { return; } - OKF("Instrumentation debugging - file [%s]", filename); + OKF("Instrumentation debugging - file [%s]", instrument_debug_filename); - if (filename == NULL) { return; } + if (instrument_debug_filename == NULL) { return; } - char *path = g_canonicalize_filename(filename, g_get_current_dir()); + char *path = + g_canonicalize_filename(instrument_debug_filename, g_get_current_dir()); OKF("Instrumentation debugging - path [%s]", path); diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c index 7000e65d..a38b5b14 100644 --- a/frida_mode/src/instrument/instrument_x64.c +++ b/frida_mode/src/instrument/instrument_x64.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "config.h" @@ -68,7 +68,7 @@ void instrument_coverage_optimize(const cs_insn * instr, current_log_impl = cw->pc; gum_x86_writer_put_bytes(cw, afl_log_code, sizeof(afl_log_code)); - uint64_t *afl_prev_loc_ptr = &previous_pc; + uint64_t *afl_prev_loc_ptr = &instrument_previous_pc; gum_x86_writer_put_bytes(cw, (const guint8 *)&__afl_area_ptr, sizeof(__afl_area_ptr)); gum_x86_writer_put_bytes(cw, (const guint8 *)&afl_prev_loc_ptr, diff --git a/frida_mode/src/instrument/instrument_x86.c b/frida_mode/src/instrument/instrument_x86.c index 04a19e08..3c3dc272 100644 --- a/frida_mode/src/instrument/instrument_x86.c +++ b/frida_mode/src/instrument/instrument_x86.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" @@ -16,7 +16,7 @@ static void instrument_coverage_function(GumX86Writer *cw) { gum_x86_writer_put_push_reg(cw, GUM_REG_EDX); gum_x86_writer_put_mov_reg_address(cw, GUM_REG_ECX, - GUM_ADDRESS(&previous_pc)); + GUM_ADDRESS(&instrument_previous_pc)); gum_x86_writer_put_mov_reg_reg_ptr(cw, GUM_REG_EDX, GUM_REG_ECX); gum_x86_writer_put_xor_reg_reg(cw, GUM_REG_EDX, GUM_REG_EDI); diff --git a/frida_mode/src/interceptor.c b/frida_mode/src/intercept.c index d2802752..ed8d27bd 100644 --- a/frida_mode/src/interceptor.c +++ b/frida_mode/src/intercept.c @@ -1,10 +1,10 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" -#include "interceptor.h" +#include "intercept.h" -void intercept(void *address, gpointer replacement, gpointer user_data) { +void intercept_hook(void *address, gpointer replacement, gpointer user_data) { GumInterceptor *interceptor = gum_interceptor_obtain(); gum_interceptor_begin_transaction(interceptor); @@ -15,7 +15,7 @@ void intercept(void *address, gpointer replacement, gpointer user_data) { } -void unintercept(void *address) { +void intercept_unhook(void *address) { GumInterceptor *interceptor = gum_interceptor_obtain(); @@ -26,10 +26,10 @@ void unintercept(void *address) { } -void unintercept_self(void) { +void intercept_unhook_self(void) { GumInvocationContext *ctx = gum_interceptor_get_current_invocation(); - unintercept(ctx->function); + intercept_unhook(ctx->function); } diff --git a/frida_mode/src/js/api.js b/frida_mode/src/js/api.js new file mode 100644 index 00000000..983f1efa --- /dev/null +++ b/frida_mode/src/js/api.js @@ -0,0 +1,201 @@ +const write = new NativeFunction( + Module.getExportByName(null, 'write'), + 'int', + ['int', 'pointer', 'int'] +); + +const afl_frida_trace = Process.findModuleByName('afl-frida-trace.so'); + +function get_api(name, ret, args) { + const addr = afl_frida_trace.findExportByName(name); + return new NativeFunction(addr, ret, args); +} + +const js_api_done = get_api( + 'js_api_done', + 'void', + []); + +const js_api_error = get_api( + 'js_api_error', + 'void', + ['pointer']); + +const js_api_set_entrypoint = get_api( + 'js_api_set_entrypoint', + 'void', + ['pointer']); + +const js_api_set_persistent_address = get_api( + 'js_api_set_persistent_address', + 'void', + ['pointer']); + +const js_api_set_persistent_return = get_api( + 'js_api_set_persistent_return', + 'void', + ['pointer']); + +const js_api_set_persistent_count = get_api( + 'js_api_set_persistent_count', + 'void', + ['uint64']); + +const js_api_set_persistent_debug = get_api( + 'js_api_set_persistent_debug', + 'void', + []); + +const js_api_set_debug_maps = get_api( + 'js_api_set_debug_maps', + 'void', + []); + +const js_api_add_include_range = get_api( + 'js_api_add_include_range', + 'void', + ['pointer', 'size_t']); + +const js_api_add_exclude_range = get_api( + 'js_api_add_exclude_range', + 'void', + ['pointer', 'size_t']); + +const js_api_set_instrument_libraries = get_api( + 'js_api_set_instrument_libraries', + 'void', + []); + +const js_api_set_instrument_debug_file = get_api( + 'js_api_set_instrument_debug_file', + 'void', + ['pointer']); + +const js_api_set_prefetch_disable = get_api( + 'js_api_set_prefetch_disable', + 'void', + []); + +const js_api_set_instrument_no_optimize = get_api( + 'js_api_set_instrument_no_optimize', + 'void', + []); + +const js_api_set_instrument_trace = get_api( + 'js_api_set_instrument_trace', + 'void', + []); + +const js_api_set_instrument_trace_unique = get_api( + 'js_api_set_instrument_trace_unique', + 'void', + []); + +const js_api_set_stdout = get_api( + 'js_api_set_stdout', + 'void', + ['pointer']); + +const js_api_set_stderr = get_api( + 'js_api_set_stderr', + 'void', + ['pointer']); + +const js_api_set_stats_file = get_api( + 'js_api_set_stats_file', + 'void', + ['pointer']); + +const js_api_set_stats_interval = get_api( + 'js_api_set_stats_interval', + 'void', + ['uint64']); + +const js_api_set_stats_transitions = get_api( + 'js_api_set_stats_transitions', + 'void', + []); + +const afl = { + print: function (msg) { + const STDOUT_FILENO = 2; + const log = `${msg}\n`; + const buf = Memory.allocUtf8String(log); + write(STDOUT_FILENO, buf, log.length); + }, + done: function() { + js_api_done(); + }, + error: function(msg) { + const buf = Memory.allocUtf8String(msg); + js_api_error(buf); + }, + setEntryPoint: function(addr) { + js_api_set_entrypoint(addr); + }, + setPersistentAddress: function(addr) { + js_api_set_persistent_address(addr); + }, + setPersistentReturn: function(addr) { + js_api_set_persistent_return(addr); + }, + setPersistentCount: function(addr) { + js_api_set_persistent_count(addr); + }, + setPersistentDebug: function() { + js_api_set_persistent_debug(); + }, + setDebugMaps: function() { + js_api_set_debug_maps(); + }, + addIncludedRange: function(address, size) { + js_api_add_include_range(address, size); + }, + addExcludedRange: function(address, size) { + js_api_add_exclude_range(address, size); + }, + setInstrumentLibraries: function() { + js_api_set_instrument_libraries(); + }, + setInstrumentDebugFile: function(file) { + const buf = Memory.allocUtf8String(file); + js_api_set_instrument_debug_file(buf) + }, + setPrefetchDisable: function() { + js_api_set_prefetch_disable(); + }, + setInstrumentNoOptimize: function() { + js_api_set_instrument_no_optimize(); + }, + setInstrumentEnableTracing: function() { + js_api_set_instrument_trace(); + }, + setInstrumentTracingUnique: function() { + js_api_set_instrument_trace_unique(); + }, + setStdOut: function(file) { + const buf = Memory.allocUtf8String(file); + js_api_set_stdout(buf) + }, + setStdErr: function(file) { + const buf = Memory.allocUtf8String(file); + js_api_set_stderr(buf) + }, + setStatsFile: function(file) { + const buf = Memory.allocUtf8String(file); + js_api_set_stats_file(buf) + }, + setStatsInterval: function(interval) { + js_api_set_stats_interval(interval); + }, + setStatsTransitions: function() { + js_api_set_stats_transitions(); + } + +}; + +Object.defineProperty(global, 'Afl', {value: afl, writeable: false}); + +//////////////////////////////////////////////////////////////////////////////// +// END OF API // +//////////////////////////////////////////////////////////////////////////////// diff --git a/frida_mode/src/js/js.c b/frida_mode/src/js/js.c new file mode 100644 index 00000000..79e716ad --- /dev/null +++ b/frida_mode/src/js/js.c @@ -0,0 +1,113 @@ +#include "frida-gumjs.h" + +#include "debug.h" + +#include "js.h" +#include "util.h" + +static char *js_script = NULL; +gboolean js_done = FALSE; + +static gchar * filename = "afl.js"; +static gchar * contents; +static GumScriptBackend *backend; +static GCancellable * cancellable = NULL; +static GError * error = NULL; +static GumScript * script; + +static void js_msg(GumScript *script, const gchar *message, GBytes *data, + gpointer user_data) { + + UNUSED_PARAMETER(script); + UNUSED_PARAMETER(data); + UNUSED_PARAMETER(user_data); + OKF("%s", message); + +} + +void js_config(void) { + + js_script = getenv("AFL_FRIDA_JS_SCRIPT"); + +} + +static gchar *js_get_script() { + + gsize length; + if (js_script != NULL) { filename = js_script; } + + filename = g_canonicalize_filename(filename, g_get_current_dir()); + + if (!g_file_get_contents(filename, &contents, &length, NULL)) { + + if (js_script == NULL) { + + return NULL; + + } else { + + FATAL("Could not load script file: %s", filename); + + } + + } else { + + OKF("Loaded AFL script: %s, %" G_GSIZE_MODIFIER "d bytes", filename, + length); + + gchar *source = g_malloc0(api_js_len + length + 1); + memcpy(source, api_js, api_js_len); + memcpy(&source[api_js_len], contents, length); + + return source; + + } + +} + +static void js_print_script(gchar *source) { + + gchar **split = g_strsplit(source, "\n", 0); + + for (size_t i = 0; split[i] != NULL; i++) { + + OKF("%3" G_GSIZE_MODIFIER "d. %s", i + 1, split[i]); + + } + + g_strfreev(split); + +} + +void js_start(void) { + + GMainContext *context; + + gchar *source = js_get_script(); + if (source == NULL) { return; } + js_print_script(source); + + backend = gum_script_backend_obtain_qjs(); + + script = gum_script_backend_create_sync(backend, "example", source, + cancellable, &error); + + if (error != NULL) { + + g_printerr("%s\n", error->message); + FATAL("Error processing script"); + + } + + gum_script_set_message_handler(script, js_msg, NULL, NULL); + + gum_script_load_sync(script, cancellable); + + context = g_main_context_get_thread_default(); + while (g_main_context_pending(context)) + g_main_context_iteration(context, FALSE); + + if (!js_done) { FATAL("Script didn't call Afl.done()"); } + +} + diff --git a/frida_mode/src/js/js_api.c b/frida_mode/src/js/js_api.c new file mode 100644 index 00000000..018c0b9a --- /dev/null +++ b/frida_mode/src/js/js_api.c @@ -0,0 +1,142 @@ +#include "debug.h" + +#include "entry.h" +#include "instrument.h" +#include "js.h" +#include "output.h" +#include "persistent.h" +#include "prefetch.h" +#include "ranges.h" +#include "stats.h" +#include "util.h" + +void js_api_done() { + + js_done = TRUE; + +} + +void js_api_error(char *msg) { + + FATAL("%s", msg); + +} + +void js_api_set_entrypoint(void *address) { + + entry_point = GPOINTER_TO_SIZE(address); + +} + +void js_api_set_persistent_address(void *address) { + + persistent_start = GPOINTER_TO_SIZE(address); + +} + +void js_api_set_persistent_return(void *address) { + + persistent_ret = GPOINTER_TO_SIZE(address); + +} + +void js_api_set_persistent_count(uint64_t count) { + + persistent_count = count; + +} + +void js_api_set_persistent_debug() { + + persistent_debug = TRUE; + +} + +void js_api_set_debug_maps() { + + ranges_debug_maps = TRUE; + +} + +void js_api_add_include_range(void *address, gsize size) { + + GumMemoryRange range = {.base_address = GUM_ADDRESS(address), .size = size}; + ranges_add_include(&range); + +} + +void js_api_add_exclude_range(void *address, gsize size) { + + GumMemoryRange range = {.base_address = GUM_ADDRESS(address), .size = size}; + ranges_add_exclude(&range); + +} + +void js_api_set_instrument_libraries() { + + ranges_inst_libs = TRUE; + +} + +void js_api_set_instrument_debug_file(char *path) { + + instrument_debug_filename = g_strdup(path); + +} + +void js_api_set_prefetch_disable(void) { + + prefetch_enable = FALSE; + +} + +void js_api_set_instrument_no_optimize(void) { + + instrument_optimize = FALSE; + +} + +void js_api_set_instrument_trace(void) { + + instrument_tracing = TRUE; + +} + +void js_api_set_instrument_trace_unique(void) { + + instrument_unique = TRUE; + +} + +void js_api_set_stdout(char *file) { + + output_stdout = g_strdup(file); + +} + +void js_api_set_stderr(char *file) { + + output_stderr = g_strdup(file); + +} + +void js_api_set_stats_file(char *file) { + + stats_filename = g_strdup(file); + +} + +void js_api_set_stats_interval(uint64_t interval) { + + stats_interval = interval; + +} + +void js_api_set_stats_transitions() { + + stats_transitions = TRUE; + +} + +// "AFL_FRIDA_PERSISTENT_HOOK", + diff --git a/frida_mode/src/lib/lib.c b/frida_mode/src/lib/lib.c index 13a7d1e7..59a3fcf9 100644 --- a/frida_mode/src/lib/lib.c +++ b/frida_mode/src/lib/lib.c @@ -6,7 +6,7 @@ #include <sys/mman.h> #include <unistd.h> - #include "frida-gum.h" + #include "frida-gumjs.h" #include "debug.h" @@ -151,6 +151,10 @@ static void lib_get_text_section(lib_details_t *details) { } +void lib_config(void) { + +} + void lib_init(void) { lib_details_t lib_details; diff --git a/frida_mode/src/lib/lib_apple.c b/frida_mode/src/lib/lib_apple.c index 8f863861..2aa48a13 100644 --- a/frida_mode/src/lib/lib_apple.c +++ b/frida_mode/src/lib/lib_apple.c @@ -1,5 +1,5 @@ #ifdef __APPLE__ - #include "frida-gum.h" + #include "frida-gumjs.h" #include "debug.h" @@ -56,6 +56,10 @@ gboolean lib_get_text_section(const GumDarwinSectionDetails *details, } +void lib_config(void) { + +} + void lib_init(void) { GumDarwinModule *module = NULL; diff --git a/frida_mode/src/main.c b/frida_mode/src/main.c index b17d9f49..85b0bbf3 100644 --- a/frida_mode/src/main.c +++ b/frida_mode/src/main.c @@ -11,14 +11,15 @@ #include <sys/personality.h> #endif -#include "frida-gum.h" +#include "frida-gumjs.h" #include "config.h" #include "debug.h" #include "entry.h" #include "instrument.h" -#include "interceptor.h" +#include "intercept.h" +#include "js.h" #include "lib.h" #include "output.h" #include "persistent.h" @@ -44,13 +45,6 @@ typedef int *(*main_fn_t)(int argc, char **argv, char **envp); static main_fn_t main_fn = NULL; -static int on_fork(void) { - - prefetch_read(); - return fork(); - -} - #ifdef __APPLE__ static void on_main_os(int argc, char **argv, char **envp) { @@ -174,23 +168,36 @@ void afl_frida_start(void) { afl_print_cmdline(); afl_print_env(); + /* Configure */ + entry_config(); + instrument_config(); + js_config(); + lib_config(); + output_config(); + persistent_config(); + prefetch_config(); + ranges_config(); + stalker_config(); + stats_config(); + + js_start(); + + /* Initialize */ + output_init(); + embedded_init(); - stalker_init(); - lib_init(); entry_init(); instrument_init(); - output_init(); + lib_init(); persistent_init(); prefetch_init(); + stalker_init(); ranges_init(); stats_init(); - void *fork_addr = - GSIZE_TO_POINTER(gum_module_find_export_by_name(NULL, "fork")); - intercept(fork_addr, on_fork, NULL); - + /* Start */ stalker_start(); - entry_run(); + entry_start(); } @@ -198,7 +205,7 @@ static int *on_main(int argc, char **argv, char **envp) { on_main_os(argc, argv, envp); - unintercept_self(); + intercept_unhook_self(); afl_frida_start(); @@ -212,7 +219,7 @@ extern int *main(int argc, char **argv, char **envp); static void intercept_main(void) { main_fn = main; - intercept(main, on_main, NULL); + intercept_hook(main, on_main, NULL); } @@ -225,7 +232,7 @@ static void intercept_main(void) { OKF("Entry Point: 0x%016" G_GINT64_MODIFIER "x", entry); void *main = GSIZE_TO_POINTER(entry); main_fn = main; - intercept(main, on_main, NULL); + intercept_hook(main, on_main, NULL); } @@ -236,8 +243,8 @@ static int on_libc_start_main(int *(main)(int, char **, char **), int argc, void(*stack_end)) { main_fn = main; - unintercept_self(); - intercept(main, on_main, NULL); + intercept_unhook_self(); + intercept_hook(main, on_main, NULL); return __libc_start_main(main, argc, ubp_av, init, fini, rtld_fini, stack_end); @@ -245,7 +252,7 @@ static int on_libc_start_main(int *(main)(int, char **, char **), int argc, static void intercept_main(void) { - intercept(__libc_start_main, on_libc_start_main, NULL); + intercept_hook(__libc_start_main, on_libc_start_main, NULL); } diff --git a/frida_mode/src/output.c b/frida_mode/src/output.c index 8a222b25..e2b744e7 100644 --- a/frida_mode/src/output.c +++ b/frida_mode/src/output.c @@ -2,17 +2,17 @@ #include <fcntl.h> #include <unistd.h> -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" #include "output.h" -static int output_fd = -1; +char *output_stdout = NULL; +char *output_stderr = NULL; -static void output_redirect(int fd, char *variable) { +static void output_redirect(int fd, char *filename) { - char *filename = getenv(variable); char *path = NULL; if (filename == NULL) { return; } @@ -21,8 +21,8 @@ static void output_redirect(int fd, char *variable) { OKF("Redirect %d -> '%s'", fd, path); - output_fd = open(path, O_RDWR | O_CREAT | O_TRUNC, - S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + int output_fd = open(path, O_RDWR | O_CREAT | O_TRUNC, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); g_free(path); @@ -34,12 +34,24 @@ static void output_redirect(int fd, char *variable) { } + close(output_fd); + +} + +void output_config(void) { + + output_stdout = getenv("AFL_FRIDA_OUTPUT_STDOUT"); + output_stderr = getenv("AFL_FRIDA_OUTPUT_STDERR"); + } void output_init(void) { - output_redirect(STDOUT_FILENO, "AFL_FRIDA_OUTPUT_STDOUT"); - output_redirect(STDERR_FILENO, "AFL_FRIDA_OUTPUT_STDERR"); + OKF("Output - StdOut: %s", output_stdout); + OKF("Output - StdErr: %s", output_stderr); + + output_redirect(STDOUT_FILENO, output_stdout); + output_redirect(STDERR_FILENO, output_stderr); } diff --git a/frida_mode/src/persistent/persistent.c b/frida_mode/src/persistent/persistent.c index 243d501d..e3e0b0ca 100644 --- a/frida_mode/src/persistent/persistent.c +++ b/frida_mode/src/persistent/persistent.c @@ -1,6 +1,6 @@ #include <dlfcn.h> -#include "frida-gum.h" +#include "frida-gumjs.h" #include "config.h" #include "debug.h" @@ -8,17 +8,18 @@ #include "persistent.h" #include "util.h" -int __afl_sharedmem_fuzzing = 0; -afl_persistent_hook_fn hook = NULL; +int __afl_sharedmem_fuzzing = 0; +static char *hook_name = NULL; + +afl_persistent_hook_fn persistent_hook = NULL; guint64 persistent_start = 0; guint64 persistent_count = 0; guint64 persistent_ret = 0; gboolean persistent_debug = FALSE; -void persistent_init(void) { - - char *hook_name = getenv("AFL_FRIDA_PERSISTENT_HOOK"); +void persistent_config(void) { + 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"); persistent_ret = util_read_address("AFL_FRIDA_PERSISTENT_RET"); @@ -33,6 +34,11 @@ void persistent_init(void) { } + if (persistent_start != 0 && persistent_count == 0) persistent_count = 1000; + + if (persistent_start != 0 && !persistent_is_supported()) + FATAL("Persistent mode not supported on this architecture"); + if (persistent_ret != 0 && persistent_start == 0) { FATAL( @@ -41,13 +47,9 @@ void persistent_init(void) { } - 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_start != 0 && !persistent_is_supported()) - FATAL("Persistent mode not supported on this architecture"); +void persistent_init(void) { OKF("Instrumentation - persistent mode [%c] (0x%016" G_GINT64_MODIFIER "X)", persistent_start == 0 ? ' ' : 'X', persistent_start); @@ -58,27 +60,26 @@ void persistent_init(void) { OKF("Instrumentation - persistent ret [%c] (0x%016" G_GINT64_MODIFIER "X)", persistent_ret == 0 ? ' ' : 'X', persistent_ret); - if (hook_name != NULL) { + if (hook_name == NULL) { return; } - void *hook_obj = dlopen(hook_name, RTLD_NOW); - if (hook_obj == NULL) - FATAL("Failed to load AFL_FRIDA_PERSISTENT_HOOK (%s)", hook_name); + 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); + 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"); + 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); + persistent_hook = + (afl_persistent_hook_fn)dlsym(hook_obj, "afl_persistent_hook"); + if (persistent_hook == NULL) + FATAL("Failed to find afl_persistent_hook in %s", hook_name); - __afl_sharedmem_fuzzing = 1; - - } + __afl_sharedmem_fuzzing = 1; } diff --git a/frida_mode/src/persistent/persistent_arm32.c b/frida_mode/src/persistent/persistent_arm32.c index 6a3c06fa..f12f1af8 100644 --- a/frida_mode/src/persistent/persistent_arm32.c +++ b/frida_mode/src/persistent/persistent_arm32.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" diff --git a/frida_mode/src/persistent/persistent_arm64.c b/frida_mode/src/persistent/persistent_arm64.c index d7c6c76b..e618fbac 100644 --- a/frida_mode/src/persistent/persistent_arm64.c +++ b/frida_mode/src/persistent/persistent_arm64.c @@ -1,5 +1,5 @@ #include <unistd.h> -#include "frida-gum.h" +#include "frida-gumjs.h" #include "config.h" #include "debug.h" @@ -318,7 +318,7 @@ static void instrument_exit(GumArm64Writer *cw) { static int instrument_afl_persistent_loop_func(void) { int ret = __afl_persistent_loop(persistent_count); - previous_pc = 0; + instrument_previous_pc = 0; return ret; } @@ -337,7 +337,7 @@ static void instrument_afl_persistent_loop(GumArm64Writer *cw) { static void persistent_prologue_hook(GumArm64Writer * cw, struct arm64_regs *regs) { - if (hook == NULL) return; + if (persistent_hook == NULL) return; gum_arm64_writer_put_sub_reg_reg_imm(cw, ARM64_REG_SP, ARM64_REG_SP, GUM_RED_ZONE_SIZE); @@ -354,7 +354,7 @@ static void persistent_prologue_hook(GumArm64Writer * cw, gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X2, 0); gum_arm64_writer_put_call_address_with_arguments( - cw, GUM_ADDRESS(hook), 4, GUM_ARG_ADDRESS, GUM_ADDRESS(regs), + cw, GUM_ADDRESS(persistent_hook), 4, GUM_ARG_ADDRESS, GUM_ADDRESS(regs), GUM_ARG_ADDRESS, GUM_ADDRESS(0), GUM_ARG_REGISTER, ARM64_REG_X2, GUM_ARG_REGISTER, ARM64_REG_X3); diff --git a/frida_mode/src/persistent/persistent_x64.c b/frida_mode/src/persistent/persistent_x64.c index 653acefe..a91abc1c 100644 --- a/frida_mode/src/persistent/persistent_x64.c +++ b/frida_mode/src/persistent/persistent_x64.c @@ -1,5 +1,5 @@ #include <unistd.h> -#include "frida-gum.h" +#include "frida-gumjs.h" #include "config.h" #include "debug.h" @@ -199,7 +199,7 @@ static void instrument_exit(GumX86Writer *cw) { static int instrument_afl_persistent_loop_func(void) { int ret = __afl_persistent_loop(persistent_count); - previous_pc = 0; + instrument_previous_pc = 0; return ret; } @@ -220,7 +220,7 @@ static void instrument_afl_persistent_loop(GumX86Writer *cw) { static void persistent_prologue_hook(GumX86Writer * cw, struct x86_64_regs *regs) { - if (hook == NULL) return; + if (persistent_hook == NULL) return; gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, -(GUM_RED_ZONE_SIZE)); @@ -236,7 +236,7 @@ static void persistent_prologue_hook(GumX86Writer * cw, gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RDX, GUM_REG_RDX, 0); gum_x86_writer_put_call_address_with_arguments( - cw, GUM_CALL_CAPI, GUM_ADDRESS(hook), 4, GUM_ARG_ADDRESS, + cw, GUM_CALL_CAPI, GUM_ADDRESS(persistent_hook), 4, GUM_ARG_ADDRESS, GUM_ADDRESS(regs), GUM_ARG_ADDRESS, GUM_ADDRESS(0), GUM_ARG_REGISTER, GUM_REG_RDX, GUM_ARG_REGISTER, GUM_REG_RCX); diff --git a/frida_mode/src/persistent/persistent_x86.c b/frida_mode/src/persistent/persistent_x86.c index 7add6e99..1d01d8e4 100644 --- a/frida_mode/src/persistent/persistent_x86.c +++ b/frida_mode/src/persistent/persistent_x86.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "config.h" @@ -152,7 +152,7 @@ static void instrument_exit(GumX86Writer *cw) { static int instrument_afl_persistent_loop_func(void) { int ret = __afl_persistent_loop(persistent_count); - previous_pc = 0; + instrument_previous_pc = 0; return ret; } @@ -167,7 +167,7 @@ static void instrument_afl_persistent_loop(GumX86Writer *cw) { static void persistent_prologue_hook(GumX86Writer *cw, struct x86_regs *regs) { - if (hook == NULL) return; + if (persistent_hook == NULL) return; gum_x86_writer_put_mov_reg_address(cw, GUM_REG_ECX, GUM_ADDRESS(&__afl_fuzz_len)); @@ -180,7 +180,7 @@ static void persistent_prologue_hook(GumX86Writer *cw, struct x86_regs *regs) { /* Base address is 64-bits (hence two zero arguments) */ gum_x86_writer_put_call_address_with_arguments( - cw, GUM_CALL_CAPI, GUM_ADDRESS(hook), 5, GUM_ARG_ADDRESS, + cw, GUM_CALL_CAPI, GUM_ADDRESS(persistent_hook), 5, GUM_ARG_ADDRESS, GUM_ADDRESS(regs), GUM_ARG_ADDRESS, GUM_ADDRESS(0), GUM_ARG_ADDRESS, GUM_ADDRESS(0), GUM_ARG_REGISTER, GUM_REG_EDX, GUM_ARG_REGISTER, GUM_REG_ECX); diff --git a/frida_mode/src/prefetch.c b/frida_mode/src/prefetch.c index 65c09fba..50d10c9e 100644 --- a/frida_mode/src/prefetch.c +++ b/frida_mode/src/prefetch.c @@ -2,10 +2,11 @@ #include <sys/shm.h> #include <sys/mman.h> -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" +#include "intercept.h" #include "prefetch.h" #include "stalker.h" @@ -20,9 +21,10 @@ typedef struct { } prefetch_data_t; -static prefetch_data_t *prefetch_data = NULL; +gboolean prefetch_enable = TRUE; -static int prefetch_shm_id = -1; +static prefetch_data_t *prefetch_data = NULL; +static int prefetch_shm_id = -1; /* * We do this from the transformer since we need one anyway for coverage, this @@ -72,14 +74,33 @@ void prefetch_read(void) { } +void prefetch_config(void) { + + prefetch_enable = (getenv("AFL_FRIDA_INST_NO_PREFETCH") == NULL); + +} + +static int prefetch_on_fork(void) { + + prefetch_read(); + return fork(); + +} + +static void prefetch_hook_fork(void) { + + void *fork_addr = + GSIZE_TO_POINTER(gum_module_find_export_by_name(NULL, "fork")); + intercept_hook(fork_addr, prefetch_on_fork, NULL); + +} + void prefetch_init(void) { g_assert_cmpint(sizeof(prefetch_data_t), ==, PREFETCH_SIZE); - gboolean prefetch = (getenv("AFL_FRIDA_INST_NO_PREFETCH") == NULL); + OKF("Instrumentation - prefetch [%c]", prefetch_enable ? 'X' : ' '); - OKF("Instrumentation - prefetch [%c]", prefetch ? 'X' : ' '); - - if (!prefetch) { return; } + if (!prefetch_enable) { return; } /* * Make our shared memory, we can attach before we fork, just like AFL does * with the coverage bitmap region and fork will take care of ensuring both @@ -108,5 +129,7 @@ void prefetch_init(void) { /* Clear it, not sure it's necessary, just seems like good practice */ memset(prefetch_data, '\0', sizeof(prefetch_data_t)); + prefetch_hook_fork(); + } diff --git a/frida_mode/src/ranges.c b/frida_mode/src/ranges.c index ef25b371..534f202b 100644 --- a/frida_mode/src/ranges.c +++ b/frida_mode/src/ranges.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" @@ -17,11 +17,14 @@ typedef struct { } convert_name_ctx_t; -GArray *module_ranges = NULL; -GArray *libs_ranges = NULL; -GArray *include_ranges = NULL; -GArray *exclude_ranges = NULL; -GArray *ranges = NULL; +gboolean ranges_debug_maps = FALSE; +gboolean ranges_inst_libs = FALSE; + +static GArray *module_ranges = NULL; +static GArray *libs_ranges = NULL; +static GArray *include_ranges = NULL; +static GArray *exclude_ranges = NULL; +static GArray *ranges = NULL; static void convert_address_token(gchar *token, GumMemoryRange *range) { @@ -225,6 +228,43 @@ static GArray *collect_module_ranges(void) { } +static void check_for_overlaps(GArray *array) { + + for (guint i = 1; i < array->len; i++) { + + GumMemoryRange *prev = &g_array_index(array, GumMemoryRange, i - 1); + GumMemoryRange *curr = &g_array_index(array, GumMemoryRange, i); + GumAddress prev_limit = prev->base_address + prev->size; + GumAddress curr_limit = curr->base_address + curr->size; + if (prev_limit > curr->base_address) { + + FATAL("OVerlapping ranges 0x%016" G_GINT64_MODIFIER + "x-0x%016" G_GINT64_MODIFIER "x 0x%016" G_GINT64_MODIFIER + "x-0x%016" G_GINT64_MODIFIER "x", + prev->base_address, prev_limit, curr->base_address, curr_limit); + + } + + } + +} + +void ranges_add_include(GumMemoryRange *range) { + + g_array_append_val(include_ranges, *range); + g_array_sort(include_ranges, range_sort); + check_for_overlaps(include_ranges); + +} + +void ranges_add_exclude(GumMemoryRange *range) { + + g_array_append_val(exclude_ranges, *range); + g_array_sort(exclude_ranges, range_sort); + check_for_overlaps(exclude_ranges); + +} + static GArray *collect_ranges(char *env_key) { char * env_val; @@ -253,23 +293,7 @@ static GArray *collect_ranges(char *env_key) { g_array_sort(result, range_sort); - /* Check for overlaps */ - for (i = 1; i < token_count; i++) { - - GumMemoryRange *prev = &g_array_index(result, GumMemoryRange, i - 1); - GumMemoryRange *curr = &g_array_index(result, GumMemoryRange, i); - GumAddress prev_limit = prev->base_address + prev->size; - GumAddress curr_limit = curr->base_address + curr->size; - if (prev_limit > curr->base_address) { - - FATAL("OVerlapping ranges 0x%016" G_GINT64_MODIFIER - "x-0x%016" G_GINT64_MODIFIER "x 0x%016" G_GINT64_MODIFIER - "x-0x%016" G_GINT64_MODIFIER "x", - prev->base_address, prev_limit, curr->base_address, curr_limit); - - } - - } + check_for_overlaps(result); print_ranges(env_key, result); @@ -285,15 +309,15 @@ static GArray *collect_libs_ranges(void) { GumMemoryRange range; result = g_array_new(false, false, sizeof(GumMemoryRange)); - if (getenv("AFL_INST_LIBS") == NULL) { + if (ranges_inst_libs) { - range.base_address = lib_get_text_base(); - range.size = lib_get_text_limit() - lib_get_text_base(); + range.base_address = 0; + range.size = G_MAXULONG; } else { - range.base_address = 0; - range.size = G_MAXULONG; + range.base_address = lib_get_text_base(); + range.size = lib_get_text_limit() - lib_get_text_base(); } @@ -480,30 +504,13 @@ static GArray *merge_ranges(GArray *a) { } -static gboolean exclude_ranges_callback(const GumRangeDetails *details, - gpointer user_data) { +void ranges_config(void) { - UNUSED_PARAMETER(user_data); - gchar * name; - gboolean found; - GumStalker *stalker; - if (details->file == NULL) { return TRUE; } - name = g_path_get_basename(details->file->path); - - found = (g_strcmp0(name, "afl-frida-trace.so") == 0); - g_free(name); - if (!found) { return TRUE; } - - stalker = stalker_get(); - gum_stalker_exclude(stalker, details->range); - - return FALSE; + if (getenv("AFL_FRIDA_DEBUG_MAPS") != NULL) { ranges_debug_maps = TRUE; } + if (getenv("AFL_INST_LIBS") != NULL) { ranges_inst_libs = TRUE; } -} - -static void ranges_exclude_self(void) { - - gum_process_enumerate_ranges(GUM_PAGE_EXECUTE, exclude_ranges_callback, NULL); + include_ranges = collect_ranges("AFL_FRIDA_INST_RANGES"); + exclude_ranges = collect_ranges("AFL_FRIDA_EXCLUDE_RANGES"); } @@ -515,16 +522,20 @@ void ranges_init(void) { GArray * step3; GArray * step4; - if (getenv("AFL_FRIDA_DEBUG_MAPS") != NULL) { + if (ranges_debug_maps) { gum_process_enumerate_ranges(GUM_PAGE_NO_ACCESS, print_ranges_callback, NULL); } + OKF("Ranges - Instrument libraries [%c]", ranges_inst_libs ? 'X' : ' '); + + print_ranges("AFL_FRIDA_INST_RANGES", include_ranges); + print_ranges("AFL_FRIDA_EXCLUDE_RANGES", exclude_ranges); + module_ranges = collect_module_ranges(); libs_ranges = collect_libs_ranges(); - include_ranges = collect_ranges("AFL_FRIDA_INST_RANGES"); /* If include ranges is empty, then assume everything is included */ if (include_ranges->len == 0) { @@ -535,8 +546,6 @@ void ranges_init(void) { } - exclude_ranges = collect_ranges("AFL_FRIDA_EXCLUDE_RANGES"); - /* Intersect with .text section of main executable unless AFL_INST_LIBS */ step1 = intersect_ranges(module_ranges, libs_ranges); print_ranges("step1", step1); @@ -565,9 +574,6 @@ void ranges_init(void) { g_array_free(step2, TRUE); g_array_free(step1, TRUE); - /* *NEVER* stalk the stalker, only bad things will ever come of this! */ - ranges_exclude_self(); - ranges_exclude(); } diff --git a/frida_mode/src/stalker.c b/frida_mode/src/stalker.c index 63f3c529..98483cde 100644 --- a/frida_mode/src/stalker.c +++ b/frida_mode/src/stalker.c @@ -2,18 +2,47 @@ #include "instrument.h" #include "stalker.h" +#include "util.h" static GumStalker *stalker = NULL; -void stalker_init(void) { +void stalker_config(void) { if (!gum_stalker_is_supported()) { FATAL("Failed to initialize embedded"); } +} + +static gboolean stalker_exclude_self(const GumRangeDetails *details, + gpointer user_data) { + + UNUSED_PARAMETER(user_data); + gchar * name; + gboolean found; + GumStalker *stalker; + if (details->file == NULL) { return TRUE; } + name = g_path_get_basename(details->file->path); + + found = (g_strcmp0(name, "afl-frida-trace.so") == 0); + g_free(name); + if (!found) { return TRUE; } + + stalker = stalker_get(); + gum_stalker_exclude(stalker, details->range); + + return FALSE; + +} + +void stalker_init(void) { + stalker = gum_stalker_new(); if (stalker == NULL) { FATAL("Failed to initialize stalker"); } gum_stalker_set_trust_threshold(stalker, 0); + /* *NEVER* stalk the stalker, only bad things will ever come of this! */ + gum_process_enumerate_ranges(GUM_PAGE_EXECUTE, stalker_exclude_self, NULL); + } GumStalker *stalker_get(void) { diff --git a/frida_mode/src/stats/stats.c b/frida_mode/src/stats/stats.c index 0d7b9fb0..0dd8be70 100644 --- a/frida_mode/src/stats/stats.c +++ b/frida_mode/src/stats/stats.c @@ -5,7 +5,7 @@ #include <sys/shm.h> #include <sys/mman.h> -#include "frida-gum.h" +#include "frida-gumjs.h" #include "config.h" #include "debug.h" @@ -17,15 +17,16 @@ stats_data_header_t *stats_data = NULL; -static int stats_parent_pid = -1; -static int stats_fd = -1; -static gboolean stats_transitions = FALSE; -static guint64 stats_interval = 0; +static int stats_parent_pid = -1; +static int stats_fd = -1; -void stats_init(void) { +char * stats_filename = NULL; +guint64 stats_interval = 0; +gboolean stats_transitions = FALSE; - stats_parent_pid = getpid(); - char *filename = getenv("AFL_FRIDA_STATS_FILE"); +void stats_config(void) { + + stats_filename = getenv("AFL_FRIDA_STATS_FILE"); stats_interval = util_read_num("AFL_FRIDA_STATS_INTERVAL"); if (getenv("AFL_FRIDA_STATS_TRANSITIONS") != NULL) { @@ -33,10 +34,16 @@ void stats_init(void) { } - OKF("Stats - file [%s]", filename); +} + +void stats_init(void) { + + stats_parent_pid = getpid(); + + OKF("Stats - file [%s]", stats_filename); OKF("Stats - interval [%" G_GINT64_MODIFIER "u]", stats_interval); - if (stats_interval != 0 && filename == NULL) { + if (stats_interval != 0 && stats_filename == NULL) { FATAL( "AFL_FRIDA_STATS_FILE must be specified if " @@ -46,7 +53,7 @@ void stats_init(void) { if (stats_interval == 0) { stats_interval = 10; } - if (filename == NULL) { return; } + if (stats_filename == NULL) { return; } if (!stats_is_supported_arch()) { @@ -56,11 +63,11 @@ void stats_init(void) { char *path = NULL; - if (filename == NULL) { return; } + if (stats_filename == NULL) { return; } if (stats_transitions) { gum_stalker_set_counters_enabled(TRUE); } - path = g_canonicalize_filename(filename, g_get_current_dir()); + path = g_canonicalize_filename(stats_filename, g_get_current_dir()); OKF("Stats - path [%s]", path); diff --git a/frida_mode/src/stats/stats_arm32.c b/frida_mode/src/stats/stats_arm32.c index 7eea7f91..71953af3 100644 --- a/frida_mode/src/stats/stats_arm32.c +++ b/frida_mode/src/stats/stats_arm32.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" diff --git a/frida_mode/src/stats/stats_arm64.c b/frida_mode/src/stats/stats_arm64.c index 592af87a..d9d374a4 100644 --- a/frida_mode/src/stats/stats_arm64.c +++ b/frida_mode/src/stats/stats_arm64.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" diff --git a/frida_mode/src/stats/stats_x64.c b/frida_mode/src/stats/stats_x64.c index c3e8742a..7c3a90d7 100644 --- a/frida_mode/src/stats/stats_x64.c +++ b/frida_mode/src/stats/stats_x64.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" diff --git a/frida_mode/src/stats/stats_x86.c b/frida_mode/src/stats/stats_x86.c index 1906e809..d9c4f652 100644 --- a/frida_mode/src/stats/stats_x86.c +++ b/frida_mode/src/stats/stats_x86.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" |