diff options
Diffstat (limited to 'frida_mode/src')
-rw-r--r-- | frida_mode/src/ctx/ctx_arm32.c | 2 | ||||
-rw-r--r-- | frida_mode/src/entry.c | 2 | ||||
-rw-r--r-- | frida_mode/src/instrument/instrument.c | 85 | ||||
-rw-r--r-- | frida_mode/src/instrument/instrument_arm64.c | 16 | ||||
-rw-r--r-- | frida_mode/src/instrument/instrument_x64.c | 19 | ||||
-rw-r--r-- | frida_mode/src/instrument/instrument_x86.c | 22 | ||||
-rw-r--r-- | frida_mode/src/js/api.js | 7 | ||||
-rw-r--r-- | frida_mode/src/js/js.c | 32 | ||||
-rw-r--r-- | frida_mode/src/js/js_api.c | 8 | ||||
-rw-r--r-- | frida_mode/src/persistent/persistent_arm64.c | 2 | ||||
-rw-r--r-- | frida_mode/src/persistent/persistent_x64.c | 2 | ||||
-rw-r--r-- | frida_mode/src/persistent/persistent_x86.c | 2 | ||||
-rw-r--r-- | frida_mode/src/ranges.c | 5 |
13 files changed, 141 insertions, 63 deletions
diff --git a/frida_mode/src/ctx/ctx_arm32.c b/frida_mode/src/ctx/ctx_arm32.c index a354c117..9fc70fb4 100644 --- a/frida_mode/src/ctx/ctx_arm32.c +++ b/frida_mode/src/ctx/ctx_arm32.c @@ -6,7 +6,7 @@ #if defined(__arm__) -gsize ctx_read_reg(GumIA32CpuContext *ctx, x86_reg reg) { +gsize ctx_read_reg(GumArmCpuContext *ctx, arm_reg reg) { FATAL("ctx_read_reg unimplemented for this architecture"); diff --git a/frida_mode/src/entry.c b/frida_mode/src/entry.c index f70e21fc..a0ffd028 100644 --- a/frida_mode/src/entry.c +++ b/frida_mode/src/entry.c @@ -21,7 +21,7 @@ static void entry_launch(void) { __afl_manual_init(); /* Child here */ - instrument_previous_pc = 0; + instrument_on_fork(); stats_on_fork(); } diff --git a/frida_mode/src/instrument/instrument.c b/frida_mode/src/instrument/instrument.c index 2d857716..67aafa5a 100644 --- a/frida_mode/src/instrument/instrument.c +++ b/frida_mode/src/instrument/instrument.c @@ -1,11 +1,13 @@ #include <unistd.h> #include <sys/shm.h> #include <sys/mman.h> +#include <sys/syscall.h> #include "frida-gumjs.h" #include "config.h" #include "debug.h" +#include "hash.h" #include "asan.h" #include "entry.h" @@ -22,10 +24,15 @@ gboolean instrument_tracing = false; gboolean instrument_optimize = false; gboolean instrument_unique = false; +guint64 instrument_hash_zero = 0; +guint64 instrument_hash_seed = 0; + +gboolean instrument_use_fixed_seed = FALSE; +guint64 instrument_fixed_seed = 0; static GumStalkerTransformer *transformer = NULL; -__thread uint64_t instrument_previous_pc = 0; +__thread guint64 instrument_previous_pc = 0; static GumAddress previous_rip = 0; static u8 * edges_notified = NULL; @@ -49,21 +56,18 @@ static void trace_debug(char *format, ...) { } -__attribute__((hot)) static void on_basic_block(GumCpuContext *context, - gpointer user_data) { +guint64 instrument_get_offset_hash(GumAddress current_rip) { - UNUSED_PARAMETER(context); + guint64 area_offset = hash64((unsigned char *)¤t_rip, + sizeof(GumAddress), instrument_hash_seed); + return area_offset &= MAP_SIZE - 1; - GumAddress current_rip = GUM_ADDRESS(user_data); - GumAddress current_pc; - GumAddress edge; - uint8_t * cursor; - uint64_t value; +} - current_pc = (current_rip >> 4) ^ (current_rip << 8); - current_pc &= MAP_SIZE - 1; +__attribute__((hot)) static void instrument_increment_map(GumAddress edge) { - edge = current_pc ^ instrument_previous_pc; + uint8_t *cursor; + uint64_t value; cursor = &__afl_area_ptr[edge]; value = *cursor; @@ -79,7 +83,21 @@ __attribute__((hot)) static void on_basic_block(GumCpuContext *context, } *cursor = value; - instrument_previous_pc = current_pc >> 1; + +} + +__attribute__((hot)) static void on_basic_block(GumCpuContext *context, + gpointer user_data) { + + UNUSED_PARAMETER(context); + + GumAddress current_rip = GUM_ADDRESS(user_data); + guint64 current_pc = instrument_get_offset_hash(current_rip); + guint64 edge; + + edge = current_pc ^ instrument_previous_pc; + + instrument_increment_map(edge); if (unlikely(instrument_tracing)) { @@ -98,6 +116,9 @@ __attribute__((hot)) static void on_basic_block(GumCpuContext *context, } + instrument_previous_pc = + ((current_pc & (MAP_SIZE - 1) >> 1)) | ((current_pc & 0x1) << 15); + } static void instrument_basic_block(GumStalkerIterator *iterator, @@ -203,6 +224,8 @@ 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_use_fixed_seed = (getenv("AFL_FRIDA_INST_SEED") != NULL); + instrument_fixed_seed = util_read_num("AFL_FRIDA_INST_SEED"); instrument_debug_config(); asan_config(); @@ -217,6 +240,8 @@ void instrument_init(void) { OKF("Instrumentation - optimize [%c]", instrument_optimize ? 'X' : ' '); OKF("Instrumentation - tracing [%c]", instrument_tracing ? 'X' : ' '); OKF("Instrumentation - unique [%c]", instrument_unique ? 'X' : ' '); + OKF("Instrumentation - fixed seed [%c] [0x%016" G_GINT64_MODIFIER "x]", + instrument_use_fixed_seed ? 'X' : ' ', instrument_fixed_seed); if (instrument_tracing && instrument_optimize) { @@ -252,7 +277,8 @@ void instrument_init(void) { g_assert(edges_notified != MAP_FAILED); /* - * Configure the shared memory region to be removed once the process dies. + * Configure the shared memory region to be removed once the process + * dies. */ if (shmctl(shm_id, IPC_RMID, NULL) < 0) { @@ -265,6 +291,31 @@ void instrument_init(void) { } + if (instrument_use_fixed_seed) { + + /* + * This configuration option may be useful for diagnostics or + * debugging. + */ + instrument_hash_seed = instrument_fixed_seed; + + } else { + + /* + * By using a different seed value for the hash, we can make different + * instances have edge collisions in different places when carrying out + * parallel fuzzing. The seed itself, doesn't have to be random, it + * just needs to be different for each instance. + */ + instrument_hash_seed = g_get_monotonic_time() ^ + (((guint64)getpid()) << 32) ^ syscall(SYS_gettid); + + } + + OKF("Instrumentation - seed [0x%016" G_GINT64_MODIFIER "x]", + instrument_hash_seed); + instrument_hash_zero = instrument_get_offset_hash(0); + instrument_debug_init(); asan_init(); cmplog_init(); @@ -278,3 +329,9 @@ GumStalkerTransformer *instrument_get_transformer(void) { } +void instrument_on_fork() { + + instrument_previous_pc = instrument_hash_zero; + +} + diff --git a/frida_mode/src/instrument/instrument_arm64.c b/frida_mode/src/instrument/instrument_arm64.c index 17f97c97..cf37e048 100644 --- a/frida_mode/src/instrument/instrument_arm64.c +++ b/frida_mode/src/instrument/instrument_arm64.c @@ -12,15 +12,15 @@ static GumAddress current_log_impl = GUM_ADDRESS(0); static const guint8 afl_log_code[] = { // __afl_area_ptr[current_pc ^ previous_pc]++; - // previous_pc = current_pc >> 1; + // previous_pc = current_pc ROR 1; 0xE1, 0x0B, 0xBF, 0xA9, // stp x1, x2, [sp, -0x10]! 0xE3, 0x13, 0xBF, 0xA9, // stp x3, x4, [sp, -0x10]! // x0 = current_pc - 0xe1, 0x01, 0x00, 0x58, // ldr x1, #0x3c, =&__afl_area_ptr + 0x21, 0x02, 0x00, 0x58, // ldr x1, #0x44, =&__afl_area_ptr 0x21, 0x00, 0x40, 0xf9, // ldr x1, [x1] (=__afl_area_ptr) - 0xe2, 0x01, 0x00, 0x58, // ldr x2, #0x3c, =&previous_pc + 0x22, 0x02, 0x00, 0x58, // ldr x2, #0x44, =&previous_pc 0x42, 0x00, 0x40, 0xf9, // ldr x2, [x2] (=previous_pc) // __afl_area_ptr[current_pc ^ previous_pc]++; @@ -30,8 +30,11 @@ static const guint8 afl_log_code[] = { 0x63, 0x00, 0x1f, 0x9a, // adc x3, x3, xzr 0x23, 0x68, 0x22, 0xf8, // str x3, [x1, x2] - // previous_pc = current_pc >> 1; - 0xe0, 0x07, 0x40, 0x8b, // add x0, xzr, x0, LSR #1 + // previous_pc = current_pc ROR 1; + 0xe4, 0x07, 0x40, 0x8b, // add x4, xzr, x0, LSR #1 + 0xe0, 0xff, 0x00, 0x8b, // add x0, xzr, x0, LSL #63 + 0x80, 0xc0, 0x40, 0x8b, // add x0, x4, x0, LSR #48 + 0xe2, 0x00, 0x00, 0x58, // ldr x2, #0x1c, =&previous_pc 0x40, 0x00, 0x00, 0xf9, // str x0, [x2] @@ -54,8 +57,7 @@ void instrument_coverage_optimize(const cs_insn * instr, GumStalkerOutput *output) { guint64 current_pc = instr->address; - guint64 area_offset = (current_pc >> 4) ^ (current_pc << 8); - area_offset &= MAP_SIZE - 1; + guint64 area_offset = instrument_get_offset_hash(GUM_ADDRESS(instr->address)); GumArm64Writer *cw = output->writer.arm64; if (current_log_impl == 0 || diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c index a2b54369..fec8afbb 100644 --- a/frida_mode/src/instrument/instrument_x64.c +++ b/frida_mode/src/instrument/instrument_x64.c @@ -24,7 +24,7 @@ static const guint8 afl_log_code[] = { 0x80, 0x02, 0x01, /* add byte ptr [rdx], 1 */ 0x80, 0x12, 0x00, /* adc byte ptr [rdx], 0 */ - 0x48, 0xd1, 0xef, /* shr rdi, 1 */ + 0x66, 0xd1, 0xcf, /* ror di, 1 */ 0x48, 0x89, 0x39, /* mov qword [rcx], rdi */ 0x5a, /* pop rdx */ @@ -49,13 +49,9 @@ gboolean instrument_is_coverage_optimize_supported(void) { static guint8 align_pad[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90}; -void instrument_coverage_optimize(const cs_insn * instr, - GumStalkerOutput *output) { +static void instrument_coverate_write_function(GumStalkerOutput *output) { - guint64 current_pc = instr->address; - guint64 area_offset = (current_pc >> 4) ^ (current_pc << 8); - guint64 misalign = 0; - area_offset &= MAP_SIZE - 1; + guint64 misalign = 0; GumX86Writer *cw = output->writer.x86; if (current_log_impl == 0 || @@ -87,6 +83,15 @@ void instrument_coverage_optimize(const cs_insn * instr, } +} + +void instrument_coverage_optimize(const cs_insn * instr, + GumStalkerOutput *output) { + + GumX86Writer *cw = output->writer.x86; + guint64 area_offset = instrument_get_offset_hash(GUM_ADDRESS(instr->address)); + instrument_coverate_write_function(output); + gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, -GUM_RED_ZONE_SIZE); gum_x86_writer_put_push_reg(cw, GUM_REG_RDI); diff --git a/frida_mode/src/instrument/instrument_x86.c b/frida_mode/src/instrument/instrument_x86.c index 3c3dc272..7bf48f96 100644 --- a/frida_mode/src/instrument/instrument_x86.c +++ b/frida_mode/src/instrument/instrument_x86.c @@ -30,7 +30,8 @@ static void instrument_coverage_function(GumX86Writer *cw) { uint8_t adc_byte_ptr_edx_0[] = {0x80, 0x12, 0x00}; gum_x86_writer_put_bytes(cw, adc_byte_ptr_edx_0, sizeof(adc_byte_ptr_edx_0)); - gum_x86_writer_put_shr_reg_u8(cw, GUM_REG_EDI, 1); + uint8_t ror_di_1[] = {0x66, 0xd1, 0xcf}; + gum_x86_writer_put_bytes(cw, ror_di_1, sizeof(ror_di_1)); gum_x86_writer_put_mov_reg_ptr_reg(cw, GUM_REG_ECX, GUM_REG_EDI); gum_x86_writer_put_pop_reg(cw, GUM_REG_EDX); @@ -46,15 +47,8 @@ gboolean instrument_is_coverage_optimize_supported(void) { } -void instrument_coverage_optimize(const cs_insn * instr, - GumStalkerOutput *output) { - - UNUSED_PARAMETER(instr); - UNUSED_PARAMETER(output); +static void instrument_coverate_write_function(GumStalkerOutput *output) { - guint64 current_pc = instr->address; - guint64 area_offset = (current_pc >> 4) ^ (current_pc << 8); - area_offset &= MAP_SIZE - 1; GumX86Writer *cw = output->writer.x86; if (current_log_impl == 0 || @@ -73,7 +67,15 @@ void instrument_coverage_optimize(const cs_insn * instr, } - // gum_x86_writer_put_breakpoint(cw); +} + +void instrument_coverage_optimize(const cs_insn * instr, + GumStalkerOutput *output) { + + GumX86Writer *cw = output->writer.x86; + guint64 area_offset = instrument_get_offset_hash(GUM_ADDRESS(instr->address)); + instrument_coverate_write_function(output); + gum_x86_writer_put_push_reg(cw, GUM_REG_EDI); gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EDI, area_offset); gum_x86_writer_put_call_address(cw, current_log_impl); diff --git a/frida_mode/src/js/api.js b/frida_mode/src/js/api.js index 1d843024..b8f2d39a 100644 --- a/frida_mode/src/js/api.js +++ b/frida_mode/src/js/api.js @@ -117,6 +117,12 @@ class Afl { static setInstrumentNoOptimize() { Afl.jsApiSetInstrumentNoOptimize(); } + /* + * See `AFL_FRIDA_INST_SEED` + */ + static setInstrumentSeed(seed) { + Afl.jsApiSetInstrumentSeed(seed); + } /** * See `AFL_FRIDA_INST_TRACE_UNIQUE`. */ @@ -231,6 +237,7 @@ Afl.jsApiSetInstrumentDebugFile = Afl.jsApiGetFunction("js_api_set_instrument_de Afl.jsApiSetInstrumentJit = Afl.jsApiGetFunction("js_api_set_instrument_jit", "void", []); Afl.jsApiSetInstrumentLibraries = Afl.jsApiGetFunction("js_api_set_instrument_libraries", "void", []); Afl.jsApiSetInstrumentNoOptimize = Afl.jsApiGetFunction("js_api_set_instrument_no_optimize", "void", []); +Afl.jsApiSetInstrumentSeed = Afl.jsApiGetFunction("js_api_set_instrument_seed", "void", ["uint64"]); Afl.jsApiSetInstrumentTrace = Afl.jsApiGetFunction("js_api_set_instrument_trace", "void", []); Afl.jsApiSetInstrumentTraceUnique = Afl.jsApiGetFunction("js_api_set_instrument_trace_unique", "void", []); Afl.jsApiSetPersistentAddress = Afl.jsApiGetFunction("js_api_set_persistent_address", "void", ["pointer"]); diff --git a/frida_mode/src/js/js.c b/frida_mode/src/js/js.c index cf98ff3e..e3cd4933 100644 --- a/frida_mode/src/js/js.c +++ b/frida_mode/src/js/js.c @@ -83,21 +83,27 @@ static void js_print_script(gchar *source) { } -static void create_cb(GObject *source_object, GAsyncResult *result, - gpointer user_data) { +static void load_cb(GObject *source_object, GAsyncResult *result, + gpointer user_data) { UNUSED_PARAMETER(source_object); UNUSED_PARAMETER(user_data); - script = gum_script_backend_create_finish(backend, result, &error); + gum_script_load_finish(script, result); + if (error != NULL) { FATAL("Failed to load script - %s", error->message); } } -static void load_cb(GObject *source_object, GAsyncResult *result, - gpointer user_data) { +static void create_cb(GObject *source_object, GAsyncResult *result, + gpointer user_data) { UNUSED_PARAMETER(source_object); UNUSED_PARAMETER(user_data); - gum_script_load_finish(script, result); + script = gum_script_backend_create_finish(backend, result, &error); + if (error != NULL) { FATAL("Failed to create script: %s", error->message); } + + gum_script_set_message_handler(script, js_msg, NULL, NULL); + + gum_script_load(script, cancellable, load_cb, NULL); } @@ -122,20 +128,6 @@ void js_start(void) { while (g_main_context_pending(context)) g_main_context_iteration(context, FALSE); - if (error != NULL) { - - g_printerr("%s\n", error->message); - FATAL("Error processing script"); - - } - - gum_script_load(script, cancellable, load_cb, NULL); - - while (g_main_context_pending(context)) - g_main_context_iteration(context, FALSE); - - gum_script_set_message_handler(script, js_msg, NULL, NULL); - 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 index fd8128c5..930a6dc0 100644 --- a/frida_mode/src/js/js_api.c +++ b/frida_mode/src/js/js_api.c @@ -127,6 +127,14 @@ __attribute__((visibility("default"))) void js_api_set_instrument_no_optimize( } +__attribute__((visibility("default"))) void js_api_set_instrument_seed( + guint64 seed) { + + instrument_use_fixed_seed = TRUE; + instrument_fixed_seed = seed; + +} + __attribute__((visibility("default"))) void js_api_set_instrument_trace(void) { instrument_tracing = TRUE; diff --git a/frida_mode/src/persistent/persistent_arm64.c b/frida_mode/src/persistent/persistent_arm64.c index 4ab7b283..3cd61cd5 100644 --- a/frida_mode/src/persistent/persistent_arm64.c +++ b/frida_mode/src/persistent/persistent_arm64.c @@ -237,7 +237,7 @@ static void instrument_exit(GumArm64Writer *cw) { static int instrument_afl_persistent_loop_func(void) { int ret = __afl_persistent_loop(persistent_count); - instrument_previous_pc = 0; + instrument_previous_pc = instrument_hash_zero; return ret; } diff --git a/frida_mode/src/persistent/persistent_x64.c b/frida_mode/src/persistent/persistent_x64.c index ce3017e4..c0bd9a09 100644 --- a/frida_mode/src/persistent/persistent_x64.c +++ b/frida_mode/src/persistent/persistent_x64.c @@ -174,7 +174,7 @@ static void instrument_exit(GumX86Writer *cw) { static int instrument_afl_persistent_loop_func(void) { int ret = __afl_persistent_loop(persistent_count); - instrument_previous_pc = 0; + instrument_previous_pc = instrument_hash_zero; return ret; } diff --git a/frida_mode/src/persistent/persistent_x86.c b/frida_mode/src/persistent/persistent_x86.c index cc1f1a4f..b911676a 100644 --- a/frida_mode/src/persistent/persistent_x86.c +++ b/frida_mode/src/persistent/persistent_x86.c @@ -130,7 +130,7 @@ static void instrument_exit(GumX86Writer *cw) { static int instrument_afl_persistent_loop_func(void) { int ret = __afl_persistent_loop(persistent_count); - instrument_previous_pc = 0; + instrument_previous_pc = instrument_hash_zero; return ret; } diff --git a/frida_mode/src/ranges.c b/frida_mode/src/ranges.c index 5e78fa60..6fdd65a7 100644 --- a/frida_mode/src/ranges.c +++ b/frida_mode/src/ranges.c @@ -582,6 +582,11 @@ void ranges_init(void) { print_ranges("AFL_FRIDA_INST_RANGES", include_ranges); print_ranges("AFL_FRIDA_EXCLUDE_RANGES", exclude_ranges); + 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(); jit_ranges = collect_jit_ranges(); |