aboutsummaryrefslogtreecommitdiff
path: root/frida_mode/src
diff options
context:
space:
mode:
authorllzmb <46303940+llzmb@users.noreply.github.com>2021-10-10 16:32:43 +0200
committerGitHub <noreply@github.com>2021-10-10 16:32:43 +0200
commit79d87f8544a0f67537b2169e3f6821f459659f61 (patch)
tree15bfaef53f95696583ea12396a7e8e98b73f77e1 /frida_mode/src
parent228f6c5dad1a593b4113006e587e9885459a53c2 (diff)
parentda865cbb9d289d0f782a1c33d85261903c60d624 (diff)
downloadafl++-79d87f8544a0f67537b2169e3f6821f459659f61.tar.gz
Merge branch 'dev' into docs_edit_readme_fix_links
Diffstat (limited to 'frida_mode/src')
-rw-r--r--frida_mode/src/instrument/instrument.c8
-rw-r--r--frida_mode/src/instrument/instrument_x64.c205
-rw-r--r--frida_mode/src/prefetch.c8
-rw-r--r--frida_mode/src/seccomp/seccomp_callback.c6
4 files changed, 192 insertions, 35 deletions
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;
}
diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c
index fec8afbb..1c2cf113 100644
--- a/frida_mode/src/instrument/instrument_x64.c
+++ b/frida_mode/src/instrument/instrument_x64.c
@@ -1,6 +1,9 @@
+#include <stddef.h>
+
#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,66 @@ 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 *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) -
+ (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);
+
+ }
+
+ 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) -
+ (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 *dst_afl_area_ptr_value = (gint *)&code.bytes[afl_area_ptr_offset];
+ *dst_afl_area_ptr_value = (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);
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/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(