From c8f6a313110db8db033bfbfc4eb3d7043daa430d Mon Sep 17 00:00:00 2001 From: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com> Date: Wed, 22 Sep 2021 23:05:54 +0100 Subject: Performance improvements (#1094) --- frida_mode/src/instrument/instrument_x64.c | 202 ++++++++++++++++++++++++----- 1 file changed, 172 insertions(+), 30 deletions(-) (limited to 'frida_mode/src') diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c index fec8afbb..8948c4df 100644 --- a/frida_mode/src/instrument/instrument_x64.c +++ b/frida_mode/src/instrument/instrument_x64.c @@ -1,6 +1,9 @@ +#include + #include "frida-gumjs.h" #include "config.h" +#include "debug.h" #include "instrument.h" @@ -8,38 +11,120 @@ static GumAddress current_log_impl = GUM_ADDRESS(0); -static const guint8 afl_log_code[] = { + #pragma pack(push, 1) + +typedef struct { + + /* + * pushfq + * push rdx + * mov rdx, [&previouspc] (rip relative addr) + * xor rdx, rdi (current_pc) + * shr rdi. 1 + * mov [&previouspc], rdi + * lea rsi, [&_afl_area_ptr] (rip relative) + * add rdx, rsi + * add byte ptr [rdx], 1 + * adc byte ptr [rdx], 0 + + * pop rdx + * popfq + */ + uint8_t push_fq; + uint8_t push_rdx; + uint8_t mov_rdx_rip_off[7]; + uint8_t xor_rdx_rdi[3]; + uint8_t shr_rdi[3]; + uint8_t mov_rip_off_rdi[7]; + + uint8_t lea_rdi_rip_off[7]; + uint8_t add_rdx_rdi[3]; + uint8_t add_byte_ptr_rdx[3]; + uint8_t adc_byte_ptr_rdx[3]; + + uint8_t pop_rdx; + uint8_t pop_fq; + uint8_t ret; + +} afl_log_code_asm_t; + + #pragma pack(pop) + + #pragma pack(push, 8) +typedef struct { + + afl_log_code_asm_t assembly; + uint64_t current_pc; + +} afl_log_code_t; + + #pragma pack(pop) + +typedef union { + + afl_log_code_t data; + uint8_t bytes[0]; + +} afl_log_code; + +static const afl_log_code_asm_t template = { + + .push_fq = 0x9c, + .push_rdx = 0x52, + .mov_rdx_rip_off = + { + + 0x48, 0x8b, 0x15, + /* TBC */ + + }, + + .xor_rdx_rdi = + { + + 0x48, + 0x31, + 0xfa, + + }, + + .shr_rdi = {0x48, 0xd1, 0xef}, + .mov_rip_off_rdi = {0x48, 0x89, 0x3d}, + + .lea_rdi_rip_off = + { + + 0x48, + 0x8d, + 0x3d, - 0x9c, /* pushfq */ - 0x51, /* push rcx */ - 0x52, /* push rdx */ + }, - 0x48, 0x8b, 0x0d, 0x26, - 0x00, 0x00, 0x00, /* mov rcx, sym.&previous_pc */ - 0x48, 0x8b, 0x11, /* mov rdx, qword [rcx] */ - 0x48, 0x31, 0xfa, /* xor rdx, rdi */ + .add_rdx_rdi = {0x48, 0x01, 0xfA}, - 0x48, 0x03, 0x15, 0x11, - 0x00, 0x00, 0x00, /* add rdx, sym._afl_area_ptr_ptr */ + .add_byte_ptr_rdx = + { - 0x80, 0x02, 0x01, /* add byte ptr [rdx], 1 */ - 0x80, 0x12, 0x00, /* adc byte ptr [rdx], 0 */ - 0x66, 0xd1, 0xcf, /* ror di, 1 */ - 0x48, 0x89, 0x39, /* mov qword [rcx], rdi */ + 0x80, + 0x02, + 0x01, - 0x5a, /* pop rdx */ - 0x59, /* pop rcx */ - 0x9d, /* popfq */ + }, - 0xc3, /* ret */ + .adc_byte_ptr_rdx = + { - 0x90 + 0x80, + 0x12, + 0x00, - /* Read-only data goes here: */ - /* uint8_t* __afl_area_ptr */ - /* uint64_t* &previous_pc */ + }, -}; + .pop_rdx = 0x5a, + .pop_fq = 0x9d, + .ret = 0xc3}; + +static guint8 align_pad[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90}; gboolean instrument_is_coverage_optimize_supported(void) { @@ -47,12 +132,19 @@ gboolean instrument_is_coverage_optimize_supported(void) { } -static guint8 align_pad[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90}; +static gboolean instrument_coverage_in_range(gssize offset) { + + return (offset >= G_MININT32 && offset <= G_MAXINT32); + +} static void instrument_coverate_write_function(GumStalkerOutput *output) { guint64 misalign = 0; GumX86Writer *cw = output->writer.x86; + GumAddress code_addr = 0; + afl_log_code code = {0}; + guint64 instrument_hash_zero = 0; if (current_log_impl == 0 || !gum_x86_writer_can_branch_directly_between(cw->pc, current_log_impl) || @@ -71,13 +163,63 @@ static void instrument_coverate_write_function(GumStalkerOutput *output) { } current_log_impl = cw->pc; - gum_x86_writer_put_bytes(cw, afl_log_code, sizeof(afl_log_code)); + // gum_x86_writer_put_breakpoint(cw); + code_addr = cw->pc; + + code.data.assembly = template; + code.data.current_pc = instrument_get_offset_hash(0); + + gssize current_pc_value1 = + GPOINTER_TO_SIZE(&instrument_previous_pc) - + (code_addr + offsetof(afl_log_code, data.assembly.mov_rdx_rip_off) + + sizeof(code.data.assembly.mov_rdx_rip_off)); + gssize patch_offset1 = + offsetof(afl_log_code, data.assembly.mov_rdx_rip_off) + + sizeof(code.data.assembly.mov_rdx_rip_off) - sizeof(gint); + if (!instrument_coverage_in_range(current_pc_value1)) { + + FATAL("Patch out of range (current_pc_value1): 0x%016lX", + current_pc_value1); + + } + + *((gint *)&code.bytes[patch_offset1]) = (gint)current_pc_value1; + + gssize current_pc_value2 = + GPOINTER_TO_SIZE(&instrument_previous_pc) - + (code_addr + offsetof(afl_log_code, data.assembly.mov_rip_off_rdi) + + sizeof(code.data.assembly.mov_rip_off_rdi)); + gssize patch_offset2 = + offsetof(afl_log_code, data.assembly.mov_rip_off_rdi) + + sizeof(code.data.assembly.mov_rip_off_rdi) - sizeof(gint); + + if (!instrument_coverage_in_range(current_pc_value2)) { + + FATAL("Patch out of range (current_pc_value2): 0x%016lX", + current_pc_value2); + + } + + *((gint *)&code.bytes[patch_offset2]) = (gint)current_pc_value2; + + gsize afl_area_ptr_value = + GPOINTER_TO_SIZE(__afl_area_ptr) - + (code_addr + offsetof(afl_log_code, data.assembly.lea_rdi_rip_off) + + sizeof(code.data.assembly.lea_rdi_rip_off)); + gssize afl_area_ptr_offset = + offsetof(afl_log_code, data.assembly.lea_rdi_rip_off) + + sizeof(code.data.assembly.lea_rdi_rip_off) - sizeof(gint); + + if (!instrument_coverage_in_range(afl_area_ptr_value)) { + + FATAL("Patch out of range (afl_area_ptr_value): 0x%016lX", + afl_area_ptr_value); + + } + + *((gint *)&code.bytes[afl_area_ptr_offset]) = (gint)afl_area_ptr_value; - 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, - sizeof(afl_prev_loc_ptr)); + gum_x86_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code)); gum_x86_writer_put_label(cw, after_log_impl); -- cgit 1.4.1 From e80131bef50d343e71a08cdf6ae1aa57b4475867 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sat, 2 Oct 2021 22:47:22 +0200 Subject: fix some compiler warnings in 32-bit linux --- frida_mode/src/instrument/instrument_x64.c | 11 +++++++---- frida_mode/src/prefetch.c | 8 +++++--- include/config.h | 4 ++-- src/afl-analyze.c | 2 +- src/afl-fuzz.c | 2 +- src/afl-showmap.c | 2 +- src/afl-tmin.c | 2 +- unicorn_mode/unicornafl | 2 +- 8 files changed, 19 insertions(+), 14 deletions(-) (limited to 'frida_mode/src') diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c index 8948c4df..1c2cf113 100644 --- a/frida_mode/src/instrument/instrument_x64.c +++ b/frida_mode/src/instrument/instrument_x64.c @@ -144,7 +144,7 @@ static void instrument_coverate_write_function(GumStalkerOutput *output) { GumX86Writer *cw = output->writer.x86; GumAddress code_addr = 0; afl_log_code code = {0}; - guint64 instrument_hash_zero = 0; + /*guint64 instrument_hash_zero = 0;*/ if (current_log_impl == 0 || !gum_x86_writer_can_branch_directly_between(cw->pc, current_log_impl) || @@ -183,7 +183,8 @@ static void instrument_coverate_write_function(GumStalkerOutput *output) { } - *((gint *)&code.bytes[patch_offset1]) = (gint)current_pc_value1; + gint *dst_pc_value = (gint *)&code.bytes[patch_offset1]; + *dst_pc_value = (gint)current_pc_value1; gssize current_pc_value2 = GPOINTER_TO_SIZE(&instrument_previous_pc) - @@ -200,7 +201,8 @@ static void instrument_coverate_write_function(GumStalkerOutput *output) { } - *((gint *)&code.bytes[patch_offset2]) = (gint)current_pc_value2; + dst_pc_value = (gint *)&code.bytes[patch_offset2]; + *dst_pc_value = (gint)current_pc_value2; gsize afl_area_ptr_value = GPOINTER_TO_SIZE(__afl_area_ptr) - @@ -217,7 +219,8 @@ static void instrument_coverate_write_function(GumStalkerOutput *output) { } - *((gint *)&code.bytes[afl_area_ptr_offset]) = (gint)afl_area_ptr_value; + gint *dst_afl_area_ptr_value = (gint *)&code.bytes[afl_area_ptr_offset]; + *dst_afl_area_ptr_value = (gint)afl_area_ptr_value; gum_x86_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code)); diff --git a/frida_mode/src/prefetch.c b/frida_mode/src/prefetch.c index 0efbc9bf..c30ca65c 100644 --- a/frida_mode/src/prefetch.c +++ b/frida_mode/src/prefetch.c @@ -44,8 +44,9 @@ static void gum_afl_stalker_backpatcher_notify(GumStalkerObserver *self, sizeof(prefetch_data->backpatch_data) - prefetch_data->backpatch_size; if (sizeof(gsize) + size > remaining) { return; } - *(gsize *)(&prefetch_data->backpatch_data[prefetch_data->backpatch_size]) = - size; + gsize *dst_backpatch_size = (gsize *) + &prefetch_data->backpatch_data[prefetch_data->backpatch_size]; + *dst_backpatch_size = size; prefetch_data->backpatch_size += sizeof(gsize); memcpy(&prefetch_data->backpatch_data[prefetch_data->backpatch_size], @@ -115,7 +116,8 @@ static void prefetch_read_patches(void) { remaining > sizeof(gsize); remaining = prefetch_data->backpatch_size - offset) { - gsize size = *(gsize *)(&prefetch_data->backpatch_data[offset]); + gsize *src_backpatch_data = (gsize *)&prefetch_data->backpatch_data[offset]; + gsize size = *src_backpatch_data; offset += sizeof(gsize); if (prefetch_data->backpatch_size - offset < size) { diff --git a/include/config.h b/include/config.h index da74989e..4630da0c 100644 --- a/include/config.h +++ b/include/config.h @@ -237,11 +237,11 @@ (note that if this value is changed, several areas in afl-cc.c, afl-fuzz.c and afl-fuzz-state.c have to be changed as well! */ -#define MAX_FILE (1 * 1024 * 1024U) +#define MAX_FILE (1 * 1024 * 1024L) /* The same, for the test case minimizer: */ -#define TMIN_MAX_FILE (10 * 1024 * 1024) +#define TMIN_MAX_FILE (10 * 1024 * 1024L) /* Block normalization steps for afl-tmin: */ diff --git a/src/afl-analyze.c b/src/afl-analyze.c index eef08494..8295488d 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -184,7 +184,7 @@ static void read_initial_file(void) { if (st.st_size >= TMIN_MAX_FILE) { - FATAL("Input file is too large (%u MB max)", TMIN_MAX_FILE / 1024 / 1024); + FATAL("Input file is too large (%ld MB max)", TMIN_MAX_FILE / 1024 / 1024); } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 87da9798..92a37697 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1348,7 +1348,7 @@ int main(int argc, char **argv_orig, char **envp) { } else if (afl->q_testcase_max_cache_size < 2 * MAX_FILE) { - FATAL("AFL_TESTCACHE_SIZE must be set to %u or more, or 0 to disable", + FATAL("AFL_TESTCACHE_SIZE must be set to %ld or more, or 0 to disable", (2 * MAX_FILE) % 1048576 == 0 ? (2 * MAX_FILE) / 1048576 : 1 + ((2 * MAX_FILE) / 1048576)); diff --git a/src/afl-showmap.c b/src/afl-showmap.c index e143371e..75b0ff99 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -413,7 +413,7 @@ static u32 read_file(u8 *in_file) { if (!be_quiet && !quiet_mode) { - WARNF("Input file '%s' is too large, only reading %u bytes.", in_file, + WARNF("Input file '%s' is too large, only reading %ld bytes.", in_file, MAX_FILE); } diff --git a/src/afl-tmin.c b/src/afl-tmin.c index dff51e84..4f3a6b80 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -221,7 +221,7 @@ static void read_initial_file(void) { if (st.st_size >= TMIN_MAX_FILE) { - FATAL("Input file is too large (%u MB max)", TMIN_MAX_FILE / 1024 / 1024); + FATAL("Input file is too large (%ld MB max)", TMIN_MAX_FILE / 1024 / 1024); } diff --git a/unicorn_mode/unicornafl b/unicorn_mode/unicornafl index c0e03d2c..1c47d1eb 160000 --- a/unicorn_mode/unicornafl +++ b/unicorn_mode/unicornafl @@ -1 +1 @@ -Subproject commit c0e03d2c6b55a22025324f121746b41b1e756fb8 +Subproject commit 1c47d1ebc7e904ad4efc1370f23e269fb9ac3f93 -- cgit 1.4.1 From 1a79a36762ccb5cac6da8ce09fd681166d02352b Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sun, 3 Oct 2021 00:32:59 +0200 Subject: fix compiler warning in 32-Bit --- frida_mode/src/seccomp/seccomp_callback.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'frida_mode/src') diff --git a/frida_mode/src/seccomp/seccomp_callback.c b/frida_mode/src/seccomp/seccomp_callback.c index 4af2ed0c..7e1e2070 100644 --- a/frida_mode/src/seccomp/seccomp_callback.c +++ b/frida_mode/src/seccomp/seccomp_callback.c @@ -14,8 +14,12 @@ static void seccomp_callback_filter(struct seccomp_notif * req, GumDebugSymbolDetails details = {0}; if (req->data.nr == SYS_OPENAT) { +#if UINTPTR_MAX == 0xffffffffffffffffu seccomp_print("SYS_OPENAT: (%s)\n", (char *)req->data.args[1]); - +#endif +#if UINTPTR_MAX == 0xffffffff + seccomp_print("SYS_OPENAT: (%s)\n", (char *)(__u32)req->data.args[1]); +#endif } seccomp_print( -- cgit 1.4.1 From fc48a58e64b8c5abafa83b50ea68bf8e47d00552 Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Sun, 3 Oct 2021 07:35:13 +0100 Subject: frida mode macOs warning fix, syscall being deprecated, using pthread_threadid_np available since snow leopard --- frida_mode/src/instrument/instrument.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'frida_mode/src') diff --git a/frida_mode/src/instrument/instrument.c b/frida_mode/src/instrument/instrument.c index fd0982f8..71d9bdf6 100644 --- a/frida_mode/src/instrument/instrument.c +++ b/frida_mode/src/instrument/instrument.c @@ -341,8 +341,14 @@ void instrument_init(void) { * parallel fuzzing. The seed itself, doesn't have to be random, it * just needs to be different for each instance. */ + guint64 tid; +#if defined(__APPLE__) + pthread_threadid_np(NULL, &tid); +#else + tid = syscall(SYS_gettid); +#endif instrument_hash_seed = g_get_monotonic_time() ^ - (((guint64)getpid()) << 32) ^ syscall(SYS_gettid); + (((guint64)getpid()) << 32) ^ tid; } -- cgit 1.4.1