aboutsummaryrefslogtreecommitdiff
path: root/frida_mode/src
diff options
context:
space:
mode:
Diffstat (limited to 'frida_mode/src')
-rw-r--r--frida_mode/src/asan/asan.c21
-rw-r--r--frida_mode/src/asan/asan_arm32.c2
-rw-r--r--frida_mode/src/asan/asan_arm64.c2
-rw-r--r--frida_mode/src/asan/asan_x64.c2
-rw-r--r--frida_mode/src/asan/asan_x86.c2
-rw-r--r--frida_mode/src/cmplog/cmplog.c156
-rw-r--r--frida_mode/src/cmplog/cmplog_arm32.c2
-rw-r--r--frida_mode/src/cmplog/cmplog_arm64.c2
-rw-r--r--frida_mode/src/cmplog/cmplog_x64.c24
-rw-r--r--frida_mode/src/cmplog/cmplog_x86.c2
-rw-r--r--frida_mode/src/ctx/ctx_arm32.c2
-rw-r--r--frida_mode/src/ctx/ctx_arm64.c2
-rw-r--r--frida_mode/src/ctx/ctx_x64.c24
-rw-r--r--frida_mode/src/ctx/ctx_x86.c8
-rw-r--r--frida_mode/src/entry.c20
-rw-r--r--frida_mode/src/instrument/instrument.c77
-rw-r--r--frida_mode/src/instrument/instrument_arm32.c2
-rw-r--r--frida_mode/src/instrument/instrument_arm64.c4
-rw-r--r--frida_mode/src/instrument/instrument_debug.c23
-rw-r--r--frida_mode/src/instrument/instrument_x64.c4
-rw-r--r--frida_mode/src/instrument/instrument_x86.c4
-rw-r--r--frida_mode/src/intercept.c (renamed from frida_mode/src/interceptor.c)12
-rw-r--r--frida_mode/src/js/api.js243
-rw-r--r--frida_mode/src/js/js.c122
-rw-r--r--frida_mode/src/js/js_api.c152
-rw-r--r--frida_mode/src/lib/lib.c6
-rw-r--r--frida_mode/src/lib/lib_apple.c6
-rw-r--r--frida_mode/src/main.c59
-rw-r--r--frida_mode/src/output.c28
-rw-r--r--frida_mode/src/persistent/persistent.c65
-rw-r--r--frida_mode/src/persistent/persistent_arm32.c2
-rw-r--r--frida_mode/src/persistent/persistent_arm64.c405
-rw-r--r--frida_mode/src/persistent/persistent_x64.c180
-rw-r--r--frida_mode/src/persistent/persistent_x86.c117
-rw-r--r--frida_mode/src/prefetch.c37
-rw-r--r--frida_mode/src/ranges.c120
-rw-r--r--frida_mode/src/stalker.c31
-rw-r--r--frida_mode/src/stats/stats.c33
-rw-r--r--frida_mode/src/stats/stats_arm32.c2
-rw-r--r--frida_mode/src/stats/stats_arm64.c2
-rw-r--r--frida_mode/src/stats/stats_x64.c2
-rw-r--r--frida_mode/src/stats/stats_x86.c2
42 files changed, 1283 insertions, 728 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 3df7d13d..a2609c8e 100644
--- a/frida_mode/src/cmplog/cmplog.c
+++ b/frida_mode/src/cmplog/cmplog.c
@@ -1,27 +1,32 @@
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
-#include <syscall.h>
+#include <sys/mman.h>
+#include <sys/syscall.h>
+#include <unistd.h>
-#include "frida-gum.h"
+#include "frida-gumjs.h"
#include "debug.h"
#include "util.h"
#define DEFAULT_MMAP_MIN_ADDR (32UL << 10)
-#define FD_TMP_MAX_SIZE 65536
+#define MAX_MEMFD_SIZE (64UL << 10)
extern struct cmp_map *__afl_cmp_map;
+static GArray * cmplog_ranges = NULL;
+static GHashTable * hash_yes = NULL;
+static GHashTable * hash_no = NULL;
-static GArray *cmplog_ranges = NULL;
-static int fd_tmp = -1;
-static ssize_t fd_tmp_size = 0;
+static long page_size = 0;
+static long page_offset_mask = 0;
+static long page_mask = 0;
static gboolean cmplog_range(const GumRangeDetails *details,
gpointer user_data) {
- UNUSED_PARAMETER(user_data);
+ GArray * cmplog_ranges = (GArray *)user_data;
GumMemoryRange range = *details->range;
g_array_append_val(cmplog_ranges, range);
return TRUE;
@@ -35,70 +40,98 @@ static gint cmplog_sort(gconstpointer a, gconstpointer b) {
}
-static int cmplog_create_temp(void) {
+static void cmplog_get_ranges(void) {
- const char *tmpdir = g_get_tmp_dir();
- OKF("CMPLOG Temporary directory: %s", tmpdir);
- gchar *fname = g_strdup_printf("%s/frida-cmplog-XXXXXX", tmpdir);
- OKF("CMPLOG Temporary file template: %s", fname);
- int fd = mkstemp(fname);
- OKF("CMPLOG Temporary file: %s", fname);
+ OKF("CMPLOG - Collecting ranges");
- if (fd < 0) {
+ cmplog_ranges = g_array_sized_new(false, false, sizeof(GumMemoryRange), 100);
+ gum_process_enumerate_ranges(GUM_PAGE_READ, cmplog_range, cmplog_ranges);
+ g_array_sort(cmplog_ranges, cmplog_sort);
- FATAL("Failed to create temp file: %s, errno: %d", fname, errno);
+}
- }
+void cmplog_config(void) {
- if (unlink(fname) < 0) {
+}
+
+void cmplog_init(void) {
- FATAL("Failed to unlink temp file: %s (%d), errno: %d", fname, fd, errno);
+ if (__afl_cmp_map != NULL) { OKF("CMPLOG mode enabled"); }
+
+ cmplog_get_ranges();
+
+ for (guint i = 0; i < cmplog_ranges->len; i++) {
+
+ GumMemoryRange *range = &g_array_index(cmplog_ranges, GumMemoryRange, i);
+ OKF("CMPLOG Range - %3u: 0x%016" G_GINT64_MODIFIER
+ "X - 0x%016" G_GINT64_MODIFIER "X",
+ i, range->base_address, range->base_address + range->size);
}
- if (ftruncate(fd, 0) < 0) {
+ page_size = sysconf(_SC_PAGE_SIZE);
+ page_offset_mask = page_size - 1;
+ page_mask = ~(page_offset_mask);
+
+ hash_yes = g_hash_table_new(g_direct_hash, g_direct_equal);
+ if (hash_yes == NULL) {
- FATAL("Failed to ftruncate temp file: %s (%d), errno: %d", fname, fd,
- errno);
+ FATAL("Failed to g_hash_table_new, errno: %d", errno);
}
- g_free(fname);
+ hash_no = g_hash_table_new(g_direct_hash, g_direct_equal);
+ if (hash_no == NULL) {
+
+ FATAL("Failed to g_hash_table_new, errno: %d", errno);
- return fd;
+ }
}
-void cmplog_init(void) {
+static gboolean cmplog_contains(GumAddress inner_base, GumAddress inner_limit,
+ GumAddress outer_base, GumAddress outer_limit) {
- if (__afl_cmp_map != NULL) { OKF("CMPLOG mode enabled"); }
+ return (inner_base >= outer_base && inner_limit <= outer_limit);
- cmplog_ranges = g_array_sized_new(false, false, sizeof(GumMemoryRange), 100);
- gum_process_enumerate_ranges(GUM_PAGE_READ, cmplog_range, NULL);
- g_array_sort(cmplog_ranges, cmplog_sort);
+}
- for (guint i = 0; i < cmplog_ranges->len; i++) {
+gboolean cmplog_test_addr(guint64 addr, size_t size) {
- GumMemoryRange *range = &g_array_index(cmplog_ranges, GumMemoryRange, i);
- OKF("CMPLOG Range - 0x%016" G_GINT64_MODIFIER "X - 0x%016" G_GINT64_MODIFIER
- "X",
- range->base_address, range->base_address + range->size);
+ 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 = GSIZE_TO_POINTER(addr & page_mask);
+ size_t page_offset = addr & page_offset_mask;
+
+ /* If it spans a page, then bail */
+ if (page_size - page_offset < size) { return false; }
/*
- * We can't use /dev/null or /dev/zero for this since it appears that they
- * don't validate the input buffer. Persumably as an optimization because they
- * don't actually write any data. The file will be deleted on close.
+ * Our address map can change (e.g. stack growth), use msync as a fallback to
+ * validate our address.
*/
- fd_tmp = cmplog_create_temp();
+ if (msync(page_addr, page_offset + size, MS_ASYNC) < 0) {
-}
+ if (!g_hash_table_add(hash_no, GSIZE_TO_POINTER(addr))) {
-static gboolean cmplog_contains(GumAddress inner_base, GumAddress inner_limit,
- GumAddress outer_base, GumAddress outer_limit) {
+ FATAL("Failed - g_hash_table_add");
- return (inner_base >= outer_base && inner_limit <= outer_limit);
+ }
+
+ return false;
+
+ } else {
+
+ if (!g_hash_table_add(hash_yes, GSIZE_TO_POINTER(addr))) {
+
+ FATAL("Failed - g_hash_table_add");
+
+ }
+
+ return true;
+
+ }
}
@@ -125,45 +158,16 @@ gboolean cmplog_is_readable(guint64 addr, size_t size) {
for (guint i = 0; i < cmplog_ranges->len; i++) {
GumMemoryRange *range = &g_array_index(cmplog_ranges, GumMemoryRange, i);
- GumAddress outer_base = range->base_address;
- GumAddress outer_limit = outer_base + range->size;
+
+ GumAddress outer_base = range->base_address;
+ GumAddress outer_limit = outer_base + range->size;
if (cmplog_contains(inner_base, inner_limit, outer_base, outer_limit))
return true;
}
- /*
- * Our address map can change (e.g. stack growth), use write as a fallback to
- * validate our address.
- */
- ssize_t written = syscall(__NR_write, fd_tmp, (void *)addr, size);
-
- /*
- * If the write succeeds, then the buffer must be valid otherwise it would
- * return EFAULT
- */
- if (written > 0) {
-
- fd_tmp_size += written;
- if (fd_tmp_size > FD_TMP_MAX_SIZE) {
-
- /*
- * Truncate the file, we don't want our temp file to continue growing!
- */
- if (ftruncate(fd_tmp, 0) < 0) {
-
- FATAL("Failed to truncate fd_tmp (%d), errno: %d", fd_tmp, errno);
-
- }
-
- fd_tmp_size = 0;
-
- }
-
- if ((size_t)written == size) { return true; }
-
- }
+ if (cmplog_test_addr(addr, size)) { return true; }
return false;
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 9f56c32a..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"
@@ -177,7 +177,7 @@ static void cmplog_handle_cmp_sub(GumCpuContext *context, gsize operand1,
register uintptr_t k = (uintptr_t)address;
k = (k >> 4) ^ (k << 8);
- k &= CMP_MAP_W - 1;
+ k &= CMP_MAP_W - 7;
__afl_cmp_map->headers[k].type = CMP_TYPE_INS;
@@ -198,8 +198,6 @@ static void cmplog_cmp_sub_callout(GumCpuContext *context, gpointer user_data) {
gsize operand1;
gsize operand2;
- if (ctx->operand1.size != ctx->operand2.size) FATAL("Operand size mismatch");
-
if (!cmplog_get_operand_value(context, &ctx->operand1, &operand1)) { return; }
if (!cmplog_get_operand_value(context, &ctx->operand2, &operand2)) { return; }
@@ -233,6 +231,15 @@ static void cmplog_instrument_cmp_sub(const cs_insn * instr,
case X86_INS_CMP:
case X86_INS_SUB:
+ case X86_INS_SCASB:
+ case X86_INS_SCASD:
+ case X86_INS_SCASQ:
+ case X86_INS_SCASW:
+ case X86_INS_CMPSB:
+ case X86_INS_CMPSD:
+ case X86_INS_CMPSQ:
+ case X86_INS_CMPSS:
+ case X86_INS_CMPSW:
break;
default:
return;
@@ -247,13 +254,8 @@ static void cmplog_instrument_cmp_sub(const cs_insn * instr,
if (operand1->type == X86_OP_INVALID) return;
if (operand2->type == X86_OP_INVALID) return;
- if ((operand1->type == X86_OP_MEM) &&
- (operand1->mem.segment != X86_REG_INVALID))
- return;
-
- if ((operand2->type == X86_OP_MEM) &&
- (operand2->mem.segment != X86_REG_INVALID))
- return;
+ /* Both operands are the same size */
+ if (operand1->size == 1) { return; }
cmplog_instrument_cmp_sub_put_callout(iterator, operand1, operand2);
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 c5900533..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"
@@ -49,9 +49,18 @@ gsize ctx_read_reg(GumX64CpuContext *ctx, x86_reg reg) {
X86_REG_8L(X86_REG_BL, ctx->rbx)
X86_REG_8L(X86_REG_CL, ctx->rcx)
X86_REG_8L(X86_REG_DL, ctx->rdx)
+ X86_REG_8L(X86_REG_SPL, ctx->rsp)
X86_REG_8L(X86_REG_BPL, ctx->rbp)
X86_REG_8L(X86_REG_SIL, ctx->rsi)
X86_REG_8L(X86_REG_DIL, ctx->rdi)
+ X86_REG_8L(X86_REG_R8B, ctx->r8)
+ X86_REG_8L(X86_REG_R9B, ctx->r9)
+ X86_REG_8L(X86_REG_R10B, ctx->r10)
+ X86_REG_8L(X86_REG_R11B, ctx->r11)
+ X86_REG_8L(X86_REG_R12B, ctx->r12)
+ X86_REG_8L(X86_REG_R13B, ctx->r13)
+ X86_REG_8L(X86_REG_R14B, ctx->r14)
+ X86_REG_8L(X86_REG_R15B, ctx->r15)
X86_REG_8H(X86_REG_AH, ctx->rax)
X86_REG_8H(X86_REG_BH, ctx->rbx)
@@ -62,14 +71,23 @@ gsize ctx_read_reg(GumX64CpuContext *ctx, x86_reg reg) {
X86_REG_16(X86_REG_BX, ctx->rbx)
X86_REG_16(X86_REG_CX, ctx->rcx)
X86_REG_16(X86_REG_DX, ctx->rdx)
+ X86_REG_16(X86_REG_SP, ctx->rsp)
+ X86_REG_16(X86_REG_BP, ctx->rbp)
X86_REG_16(X86_REG_DI, ctx->rdi)
X86_REG_16(X86_REG_SI, ctx->rsi)
- X86_REG_16(X86_REG_BP, ctx->rbp)
+ X86_REG_16(X86_REG_R8W, ctx->r8)
+ X86_REG_16(X86_REG_R9W, ctx->r9)
+ X86_REG_16(X86_REG_R10W, ctx->r10)
+ X86_REG_16(X86_REG_R11W, ctx->r11)
+ X86_REG_16(X86_REG_R12W, ctx->r12)
+ X86_REG_16(X86_REG_R13W, ctx->r13)
+ X86_REG_16(X86_REG_R14W, ctx->r14)
+ X86_REG_16(X86_REG_R15W, ctx->r15)
X86_REG_32(X86_REG_EAX, ctx->rax)
+ X86_REG_32(X86_REG_EBX, ctx->rbx)
X86_REG_32(X86_REG_ECX, ctx->rcx)
X86_REG_32(X86_REG_EDX, ctx->rdx)
- X86_REG_32(X86_REG_EBX, ctx->rbx)
X86_REG_32(X86_REG_ESP, ctx->rsp)
X86_REG_32(X86_REG_EBP, ctx->rbp)
X86_REG_32(X86_REG_ESI, ctx->rsi)
diff --git a/frida_mode/src/ctx/ctx_x86.c b/frida_mode/src/ctx/ctx_x86.c
index 45308272..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"
@@ -42,6 +42,7 @@ gsize ctx_read_reg(GumIA32CpuContext *ctx, x86_reg reg) {
X86_REG_8L(X86_REG_BL, ctx->ebx)
X86_REG_8L(X86_REG_CL, ctx->ecx)
X86_REG_8L(X86_REG_DL, ctx->edx)
+ X86_REG_8L(X86_REG_SPL, ctx->esp)
X86_REG_8L(X86_REG_BPL, ctx->ebp)
X86_REG_8L(X86_REG_SIL, ctx->esi)
X86_REG_8L(X86_REG_DIL, ctx->edi)
@@ -55,14 +56,15 @@ gsize ctx_read_reg(GumIA32CpuContext *ctx, x86_reg reg) {
X86_REG_16(X86_REG_BX, ctx->ebx)
X86_REG_16(X86_REG_CX, ctx->ecx)
X86_REG_16(X86_REG_DX, ctx->edx)
+ X86_REG_16(X86_REG_SP, ctx->esp)
+ X86_REG_16(X86_REG_BP, ctx->ebp)
X86_REG_16(X86_REG_DI, ctx->edi)
X86_REG_16(X86_REG_SI, ctx->esi)
- X86_REG_16(X86_REG_BP, ctx->ebp)
X86_REG_32(X86_REG_EAX, ctx->eax)
+ X86_REG_32(X86_REG_EBX, ctx->ebx)
X86_REG_32(X86_REG_ECX, ctx->ecx)
X86_REG_32(X86_REG_EDX, ctx->edx)
- X86_REG_32(X86_REG_EBX, ctx->ebx)
X86_REG_32(X86_REG_ESP, ctx->esp)
X86_REG_32(X86_REG_EBP, ctx->ebp)
X86_REG_32(X86_REG_ESI, ctx->esi)
diff --git a/frida_mode/src/entry.c b/frida_mode/src/entry.c
index e71386a0..e95b923b 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,33 @@
extern void __afl_manual_init();
-guint64 entry_start = 0;
+guint64 entry_point = 0;
static void entry_launch(void) {
+ OKF("Entry point reached");
__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..2a217d96 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"
@@ -11,6 +11,7 @@
#include "entry.h"
#include "frida_cmplog.h"
#include "instrument.h"
+#include "js.h"
#include "persistent.h"
#include "prefetch.h"
#include "ranges.h"
@@ -18,12 +19,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 +63,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 +79,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 +92,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 +100,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 +114,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 +153,7 @@ static void instr_basic_block(GumStalkerIterator *iterator,
if (likely(!excluded)) {
- if (likely(optimize)) {
+ if (likely(instrument_optimize)) {
instrument_coverage_optimize(instr, output);
@@ -163,8 +166,6 @@ static void instr_basic_block(GumStalkerIterator *iterator,
}
- begin = FALSE;
-
}
instrument_debug_instruction(instr->address, instr->size);
@@ -176,7 +177,13 @@ static void instr_basic_block(GumStalkerIterator *iterator,
}
- gum_stalker_iterator_keep(iterator);
+ if (js_stalker_callback(instr, begin, excluded, output)) {
+
+ gum_stalker_iterator_keep(iterator);
+
+ }
+
+ begin = FALSE;
}
@@ -185,31 +192,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 +232,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..4cb04704
--- /dev/null
+++ b/frida_mode/src/js/api.js
@@ -0,0 +1,243 @@
+"use strict";
+class Afl {
+ /**
+ * This is equivalent to setting a value in `AFL_FRIDA_EXCLUDE_RANGES`,
+ * it takes as arguments a `NativePointer` and a `number`. It can be
+ * called multiple times to exclude several ranges.
+ */
+ static addExcludedRange(addressess, size) {
+ Afl.jsApiAddExcludeRange(addressess, size);
+ }
+ /**
+ * This is equivalent to setting a value in `AFL_FRIDA_INST_RANGES`,
+ * it takes as arguments a `NativePointer` and a `number`. It can be
+ * called multiple times to include several ranges.
+ */
+ static addIncludedRange(addressess, size) {
+ Afl.jsApiAddIncludeRange(addressess, size);
+ }
+ /**
+ * This must always be called at the end of your script. This lets
+ * FRIDA mode know that your configuration is finished and that
+ * execution has reached the end of your script. Failure to call
+ * this will result in a fatal error.
+ */
+ static done() {
+ Afl.jsApiDone();
+ }
+ /**
+ * This function can be called within your script to cause FRIDA
+ * mode to trigger a fatal error. This is useful if for example you
+ * discover a problem you weren't expecting and want everything to
+ * stop. The user will need to enable `AFL_DEBUG_CHILD=1` to view
+ * this error message.
+ */
+ static error(msg) {
+ const buf = Memory.allocUtf8String(msg);
+ Afl.jsApiError(buf);
+ }
+ /**
+ * Function used to provide access to `__afl_fuzz_ptr`, which contains the length of
+ * fuzzing data when using in-memory test case fuzzing.
+ */
+ static getAflFuzzLen() {
+ return Afl.jsApiGetSymbol("__afl_fuzz_len");
+ }
+ /**
+ * Function used to provide access to `__afl_fuzz_ptr`, which contains the fuzzing
+ * data when using in-memory test case fuzzing.
+ */
+ static getAflFuzzPtr() {
+ return Afl.jsApiGetSymbol("__afl_fuzz_ptr");
+ }
+ /**
+ * Print a message to the STDOUT. This should be preferred to
+ * FRIDA's `console.log` since FRIDA will queue it's log messages.
+ * If `console.log` is used in a callback in particular, then there
+ * may no longer be a thread running to service this queue.
+ */
+ static print(msg) {
+ const STDOUT_FILENO = 2;
+ const log = `${msg}\n`;
+ const buf = Memory.allocUtf8String(log);
+ Afl.jsApiWrite(STDOUT_FILENO, buf, log.length);
+ }
+ /**
+ * See `AFL_FRIDA_DEBUG_MAPS`.
+ */
+ static setDebugMaps() {
+ Afl.jsApiSetDebugMaps();
+ }
+ /**
+ * This has the same effect as setting `AFL_ENTRYPOINT`, but has the
+ * convenience of allowing you to use FRIDAs APIs to determine the
+ * address you would like to configure, rather than having to grep
+ * the output of `readelf` or something similarly ugly. This
+ * function should be called with a `NativePointer` as its
+ * argument.
+ */
+ static setEntryPoint(address) {
+ Afl.jsApiSetEntryPoint(address);
+ }
+ /**
+ * Function used to enable in-memory test cases for fuzzing.
+ */
+ static setInMemoryFuzzing() {
+ Afl.jsApiAflSharedMemFuzzing.writeInt(1);
+ }
+ /**
+ * See `AFL_FRIDA_INST_DEBUG_FILE`. This function takes a single `string` as
+ * an argument.
+ */
+ static setInstrumentDebugFile(file) {
+ const buf = Memory.allocUtf8String(file);
+ Afl.jsApiSetInstrumentDebugFile(buf);
+ }
+ /**
+ * See `AFL_FRIDA_INST_TRACE`.
+ */
+ static setInstrumentEnableTracing() {
+ Afl.jsApiSetInstrumentTrace();
+ }
+ /**
+ * See `AFL_INST_LIBS`.
+ */
+ static setInstrumentLibraries() {
+ Afl.jsApiSetInstrumentLibraries();
+ }
+ /**
+ * See `AFL_FRIDA_INST_NO_OPTIMIZE`
+ */
+ static setInstrumentNoOptimize() {
+ Afl.jsApiSetInstrumentNoOptimize();
+ }
+ /**
+ * See `AFL_FRIDA_INST_TRACE_UNIQUE`.
+ */
+ static setInstrumentTracingUnique() {
+ Afl.jsApiSetInstrumentTraceUnique();
+ }
+ /**
+ * This is equivalent to setting `AFL_FRIDA_PERSISTENT_ADDR`, again a
+ * `NativePointer` should be provided as it's argument.
+ */
+ static setPersistentAddress(address) {
+ Afl.jsApiSetPersistentAddress(address);
+ }
+ /**
+ * This is equivalent to setting `AFL_FRIDA_PERSISTENT_CNT`, a
+ * `number` should be provided as it's argument.
+ */
+ static setPersistentCount(count) {
+ Afl.jsApiSetPersistentCount(count);
+ }
+ /**
+ * See `AFL_FRIDA_PERSISTENT_DEBUG`.
+ */
+ static setPersistentDebug() {
+ Afl.jsApiSetPersistentDebug();
+ }
+ /**
+ * See `AFL_FRIDA_PERSISTENT_ADDR`. This function takes a NativePointer as an
+ * argument. See above for examples of use.
+ */
+ static setPersistentHook(address) {
+ Afl.jsApiSetPersistentHook(address);
+ }
+ /**
+ * This is equivalent to setting `AFL_FRIDA_PERSISTENT_RET`, again a
+ * `NativePointer` should be provided as it's argument.
+ */
+ static setPersistentReturn(address) {
+ Afl.jsApiSetPersistentReturn(address);
+ }
+ /**
+ * See `AFL_FRIDA_INST_NO_PREFETCH`.
+ */
+ static setPrefetchDisable() {
+ Afl.jsApiSetPrefetchDisable();
+ }
+ /*
+ * Set a function to be called for each instruction which is instrumented
+ * by AFL FRIDA mode.
+ */
+ static setStalkerCallback(callback) {
+ Afl.jsApiSetStalkerCallback(callback);
+ }
+ /**
+ * See `AFL_FRIDA_STATS_FILE`. This function takes a single `string` as
+ * an argument.
+ */
+ static setStatsFile(file) {
+ const buf = Memory.allocUtf8String(file);
+ Afl.jsApiSetStatsFile(buf);
+ }
+ /**
+ * See `AFL_FRIDA_STATS_INTERVAL`. This function takes a `number` as an
+ * argument
+ */
+ static setStatsInterval(interval) {
+ Afl.jsApiSetStatsInterval(interval);
+ }
+ /**
+ * See `AFL_FRIDA_STATS_TRANSITIONS`
+ */
+ static setStatsTransitions() {
+ Afl.jsApiSetStatsTransitions();
+ }
+ /**
+ * See `AFL_FRIDA_OUTPUT_STDERR`. This function takes a single `string` as
+ * an argument.
+ */
+ static setStdErr(file) {
+ const buf = Memory.allocUtf8String(file);
+ Afl.jsApiSetStdErr(buf);
+ }
+ /**
+ * See `AFL_FRIDA_OUTPUT_STDOUT`. This function takes a single `string` as
+ * an argument.
+ */
+ static setStdOut(file) {
+ const buf = Memory.allocUtf8String(file);
+ Afl.jsApiSetStdOut(buf);
+ }
+ static jsApiGetFunction(name, retType, argTypes) {
+ const addr = Afl.module.getExportByName(name);
+ return new NativeFunction(addr, retType, argTypes);
+ }
+ static jsApiGetSymbol(name) {
+ return Afl.module.getExportByName(name);
+ }
+}
+/**
+ * Field containing the `Module` object for `afl-frida-trace.so` (the FRIDA mode
+ * implementation).
+ */
+Afl.module = Process.getModuleByName("afl-frida-trace.so");
+Afl.jsApiAddExcludeRange = Afl.jsApiGetFunction("js_api_add_exclude_range", "void", ["pointer", "size_t"]);
+Afl.jsApiAddIncludeRange = Afl.jsApiGetFunction("js_api_add_include_range", "void", ["pointer", "size_t"]);
+Afl.jsApiAflSharedMemFuzzing = Afl.jsApiGetSymbol("__afl_sharedmem_fuzzing");
+Afl.jsApiDone = Afl.jsApiGetFunction("js_api_done", "void", []);
+Afl.jsApiError = Afl.jsApiGetFunction("js_api_error", "void", ["pointer"]);
+Afl.jsApiSetDebugMaps = Afl.jsApiGetFunction("js_api_set_debug_maps", "void", []);
+Afl.jsApiSetEntryPoint = Afl.jsApiGetFunction("js_api_set_entrypoint", "void", ["pointer"]);
+Afl.jsApiSetInstrumentDebugFile = Afl.jsApiGetFunction("js_api_set_instrument_debug_file", "void", ["pointer"]);
+Afl.jsApiSetInstrumentLibraries = Afl.jsApiGetFunction("js_api_set_instrument_libraries", "void", []);
+Afl.jsApiSetInstrumentNoOptimize = Afl.jsApiGetFunction("js_api_set_instrument_no_optimize", "void", []);
+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"]);
+Afl.jsApiSetPersistentCount = Afl.jsApiGetFunction("js_api_set_persistent_count", "void", ["uint64"]);
+Afl.jsApiSetPersistentDebug = Afl.jsApiGetFunction("js_api_set_persistent_debug", "void", []);
+Afl.jsApiSetPersistentHook = Afl.jsApiGetFunction("js_api_set_persistent_hook", "void", ["pointer"]);
+Afl.jsApiSetPersistentReturn = Afl.jsApiGetFunction("js_api_set_persistent_return", "void", ["pointer"]);
+Afl.jsApiSetPrefetchDisable = Afl.jsApiGetFunction("js_api_set_prefetch_disable", "void", []);
+Afl.jsApiSetStalkerCallback = Afl.jsApiGetFunction("js_api_set_stalker_callback", "void", ["pointer"]);
+Afl.jsApiSetStatsFile = Afl.jsApiGetFunction("js_api_set_stats_file", "void", ["pointer"]);
+Afl.jsApiSetStatsInterval = Afl.jsApiGetFunction("js_api_set_stats_interval", "void", ["uint64"]);
+Afl.jsApiSetStatsTransitions = Afl.jsApiGetFunction("js_api_set_stats_transitions", "void", []);
+Afl.jsApiSetStdErr = Afl.jsApiGetFunction("js_api_set_stderr", "void", ["pointer"]);
+Afl.jsApiSetStdOut = Afl.jsApiGetFunction("js_api_set_stdout", "void", ["pointer"]);
+Afl.jsApiWrite = new NativeFunction(
+/* tslint:disable-next-line:no-null-keyword */
+Module.getExportByName(null, "write"), "int", ["int", "pointer", "int"]);
diff --git a/frida_mode/src/js/js.c b/frida_mode/src/js/js.c
new file mode 100644
index 00000000..ed378d2c
--- /dev/null
+++ b/frida_mode/src/js/js.c
@@ -0,0 +1,122 @@
+#include "frida-gumjs.h"
+
+#include "debug.h"
+
+#include "js.h"
+#include "util.h"
+
+static char * js_script = NULL;
+gboolean js_done = FALSE;
+js_api_stalker_callback_t js_user_callback = NULL;
+
+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()"); }
+
+}
+
+gboolean js_stalker_callback(const cs_insn *insn, gboolean begin,
+ gboolean excluded, GumStalkerOutput *output) {
+
+ if (js_user_callback == NULL) { return TRUE; }
+ return js_user_callback(insn, begin, excluded, output);
+
+}
+
diff --git a/frida_mode/src/js/js_api.c b/frida_mode/src/js/js_api.c
new file mode 100644
index 00000000..91dccab2
--- /dev/null
+++ b/frida_mode/src/js/js_api.c
@@ -0,0 +1,152 @@
+#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;
+
+}
+
+void js_api_set_persistent_hook(void *address) {
+
+ persistent_hook = address;
+
+}
+
+void js_api_set_stalker_callback(const js_api_stalker_callback_t callback) {
+
+ js_user_callback = callback;
+
+}
+
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 7ff23755..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) {
@@ -101,7 +95,8 @@ static void afl_print_cmdline(void) {
if (fd < 0) {
- FATAL("Failed to open /proc/self/cmdline, errno: (%d)", errno);
+ WARNF("Failed to open /proc/self/cmdline, errno: (%d)", errno);
+ return;
}
@@ -138,7 +133,8 @@ static void afl_print_env(void) {
if (fd < 0) {
- FATAL("Failed to open /proc/self/cmdline, errno: (%d)", errno);
+ WARNF("Failed to open /proc/self/cmdline, errno: (%d)", errno);
+ return;
}
@@ -172,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();
}
@@ -196,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();
@@ -210,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);
}
@@ -223,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);
}
@@ -234,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);
@@ -243,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..bcc59ea7 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,28 @@ void persistent_init(void) {
}
- if (persistent_start != 0 && persistent_count == 0) persistent_count = 1000;
+ if (hook_name == NULL) { return; }
- if (persistent_count != 0 && persistent_count < 100)
- WARNF("Persistent count out of recommended range (<100)");
+ void *hook_obj = dlopen(hook_name, RTLD_NOW);
+ if (hook_obj == NULL)
+ FATAL("Failed to load AFL_FRIDA_PERSISTENT_HOOK (%s)", hook_name);
- if (persistent_start != 0 && !persistent_is_supported())
- FATAL("Persistent mode not supported on this architecture");
+ 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");
+
+ 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);
+
+}
+
+void persistent_init(void) {
OKF("Instrumentation - persistent mode [%c] (0x%016" G_GINT64_MODIFIER "X)",
persistent_start == 0 ? ' ' : 'X', persistent_start);
@@ -58,27 +79,7 @@ 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) {
-
- 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;
-
- }
+ if (persistent_hook != NULL) { __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..003f058a 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"
@@ -9,99 +9,15 @@
#include "util.h"
#if defined(__aarch64__)
+typedef struct {
-struct arm64_regs {
+ GumCpuContext ctx;
+ uint64_t rflags;
- uint64_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10;
+} persistent_ctx_t;
- union {
-
- uint64_t x11;
- uint32_t fp_32;
-
- };
-
- union {
-
- uint64_t x12;
- uint32_t ip_32;
-
- };
-
- union {
-
- uint64_t x13;
- uint32_t sp_32;
-
- };
-
- union {
-
- uint64_t x14;
- uint32_t lr_32;
-
- };
-
- union {
-
- uint64_t x15;
- uint32_t pc_32;
-
- };
-
- union {
-
- uint64_t x16;
- uint64_t ip0;
-
- };
-
- union {
-
- uint64_t x17;
- uint64_t ip1;
-
- };
-
- uint64_t x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28;
-
- union {
-
- uint64_t x29;
- uint64_t fp;
-
- };
-
- union {
-
- uint64_t x30;
- uint64_t lr;
-
- };
-
- union {
-
- uint64_t x31;
- uint64_t sp;
-
- };
-
- // the zero register is not saved here ofc
-
- uint64_t pc;
-
- uint32_t cpsr;
-
- uint8_t vfp_zregs[32][16 * 16];
- uint8_t vfp_pregs[17][32];
- uint32_t vfp_xregs[16];
-
-};
-
-typedef struct arm64_regs arch_api_regs;
-
-static arch_api_regs saved_regs = {0};
-static gpointer saved_lr = NULL;
+static persistent_ctx_t saved_regs = {0};
+static gpointer saved_lr = NULL;
gboolean persistent_is_supported(void) {
@@ -109,8 +25,8 @@ gboolean persistent_is_supported(void) {
}
-static void instrument_persitent_save_regs(GumArm64Writer * cw,
- struct arm64_regs *regs) {
+static void instrument_persitent_save_regs(GumArm64Writer * cw,
+ persistent_ctx_t *regs) {
GumAddress regs_address = GUM_ADDRESS(regs);
const guint32 mrs_x1_nzcv = 0xd53b4201;
@@ -129,83 +45,87 @@ static void instrument_persitent_save_regs(GumArm64Writer * cw,
/* Skip x0 & x1 we'll do that later */
- gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X3,
- ARM64_REG_X0, (16 * 1),
- GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X4, ARM64_REG_X5,
- ARM64_REG_X0, (16 * 2),
- GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X6, ARM64_REG_X7,
- ARM64_REG_X0, (16 * 3),
- GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X8, ARM64_REG_X9,
- ARM64_REG_X0, (16 * 4),
- GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X10, ARM64_REG_X11,
- ARM64_REG_X0, (16 * 5),
- GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X12, ARM64_REG_X13,
- ARM64_REG_X0, (16 * 6),
- GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X14, ARM64_REG_X15,
- ARM64_REG_X0, (16 * 7),
- GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X16, ARM64_REG_X17,
- ARM64_REG_X0, (16 * 8),
- GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X18, ARM64_REG_X19,
- ARM64_REG_X0, (16 * 9),
- GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X20, ARM64_REG_X21,
- ARM64_REG_X0, (16 * 10),
- GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X22, ARM64_REG_X23,
- ARM64_REG_X0, (16 * 11),
- GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X24, ARM64_REG_X25,
- ARM64_REG_X0, (16 * 12),
- GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X26, ARM64_REG_X27,
- ARM64_REG_X0, (16 * 13),
- GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X28, ARM64_REG_X29,
- ARM64_REG_X0, (16 * 14),
- GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_stp_reg_reg_reg_offset(
+ cw, ARM64_REG_X2, ARM64_REG_X3, ARM64_REG_X0,
+ offsetof(GumCpuContext, x[2]), GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_stp_reg_reg_reg_offset(
+ cw, ARM64_REG_X4, ARM64_REG_X5, ARM64_REG_X0,
+ offsetof(GumCpuContext, x[4]), GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_stp_reg_reg_reg_offset(
+ cw, ARM64_REG_X6, ARM64_REG_X7, ARM64_REG_X0,
+ offsetof(GumCpuContext, x[6]), GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_stp_reg_reg_reg_offset(
+ cw, ARM64_REG_X8, ARM64_REG_X9, ARM64_REG_X0,
+ offsetof(GumCpuContext, x[8]), GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_stp_reg_reg_reg_offset(
+ cw, ARM64_REG_X10, ARM64_REG_X11, ARM64_REG_X0,
+ offsetof(GumCpuContext, x[10]), GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_stp_reg_reg_reg_offset(
+ cw, ARM64_REG_X12, ARM64_REG_X13, ARM64_REG_X0,
+ offsetof(GumCpuContext, x[12]), GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_stp_reg_reg_reg_offset(
+ cw, ARM64_REG_X14, ARM64_REG_X15, ARM64_REG_X0,
+ offsetof(GumCpuContext, x[14]), GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_stp_reg_reg_reg_offset(
+ cw, ARM64_REG_X16, ARM64_REG_X17, ARM64_REG_X0,
+ offsetof(GumCpuContext, x[16]), GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_stp_reg_reg_reg_offset(
+ cw, ARM64_REG_X18, ARM64_REG_X19, ARM64_REG_X0,
+ offsetof(GumCpuContext, x[18]), GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_stp_reg_reg_reg_offset(
+ cw, ARM64_REG_X20, ARM64_REG_X21, ARM64_REG_X0,
+ offsetof(GumCpuContext, x[20]), GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_stp_reg_reg_reg_offset(
+ cw, ARM64_REG_X22, ARM64_REG_X23, ARM64_REG_X0,
+ offsetof(GumCpuContext, x[22]), GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_stp_reg_reg_reg_offset(
+ cw, ARM64_REG_X24, ARM64_REG_X25, ARM64_REG_X0,
+ offsetof(GumCpuContext, x[24]), GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_stp_reg_reg_reg_offset(
+ cw, ARM64_REG_X26, ARM64_REG_X27, ARM64_REG_X0,
+ offsetof(GumCpuContext, x[26]), GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_stp_reg_reg_reg_offset(
+ cw, ARM64_REG_X28, ARM64_REG_X29, ARM64_REG_X0,
+ offsetof(GumCpuContext, x[28]), GUM_INDEX_SIGNED_OFFSET);
- /* LR & Adjusted SP */
- gum_arm64_writer_put_add_reg_reg_imm(cw, ARM64_REG_X2, ARM64_REG_SP,
- (GUM_RED_ZONE_SIZE + 32));
- gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X30, ARM64_REG_X2,
- ARM64_REG_X0, (16 * 15),
- GUM_INDEX_SIGNED_OFFSET);
+ /* LR (x30) */
+ gum_arm64_writer_put_str_reg_reg_offset(cw, ARM64_REG_X30, ARM64_REG_X0,
+ offsetof(GumCpuContext, x[30]));
- /* PC & CPSR */
+ /* PC & Adjusted SP (31) */
gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X2,
GUM_ADDRESS(persistent_start));
- gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X1,
- ARM64_REG_X0, (16 * 16),
- GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_add_reg_reg_imm(cw, ARM64_REG_X3, ARM64_REG_SP,
+ (GUM_RED_ZONE_SIZE + 32));
+ gum_arm64_writer_put_stp_reg_reg_reg_offset(
+ cw, ARM64_REG_X2, ARM64_REG_X3, ARM64_REG_X0, offsetof(GumCpuContext, pc),
+ GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_Q0, ARM64_REG_Q1,
- ARM64_REG_X0, (16 * 17),
- GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_Q2, ARM64_REG_Q3,
- ARM64_REG_X0, (16 * 18),
- GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_Q4, ARM64_REG_Q5,
- ARM64_REG_X0, (16 * 19),
- GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_Q6, ARM64_REG_Q7,
- ARM64_REG_X0, (16 * 20),
- GUM_INDEX_SIGNED_OFFSET);
+ /* CPSR */
+ gum_arm64_writer_put_str_reg_reg_offset(cw, ARM64_REG_X1, ARM64_REG_X0,
+ offsetof(persistent_ctx_t, rflags));
+
+ /* Q */
+ gum_arm64_writer_put_stp_reg_reg_reg_offset(
+ cw, ARM64_REG_Q0, ARM64_REG_Q1, ARM64_REG_X0,
+ offsetof(GumCpuContext, q[0]), GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_stp_reg_reg_reg_offset(
+ cw, ARM64_REG_Q2, ARM64_REG_Q3, ARM64_REG_X0,
+ offsetof(GumCpuContext, q[16]), GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_stp_reg_reg_reg_offset(
+ cw, ARM64_REG_Q4, ARM64_REG_Q5, ARM64_REG_X0,
+ offsetof(GumCpuContext, q[32]), GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_stp_reg_reg_reg_offset(
+ cw, ARM64_REG_Q6, ARM64_REG_Q7, ARM64_REG_X0,
+ offsetof(GumCpuContext, q[48]), GUM_INDEX_SIGNED_OFFSET);
/* x0 & x1 */
gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X3,
ARM64_REG_SP, 16,
GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X3,
- ARM64_REG_X0, (16 * 0),
- GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_stp_reg_reg_reg_offset(
+ cw, ARM64_REG_X2, ARM64_REG_X3, ARM64_REG_X0,
+ offsetof(GumCpuContext, x[0]), GUM_INDEX_SIGNED_OFFSET);
/* Pop the saved values */
gum_arm64_writer_put_ldp_reg_reg_reg_offset(
@@ -217,8 +137,8 @@ static void instrument_persitent_save_regs(GumArm64Writer * cw,
}
-static void instrument_persitent_restore_regs(GumArm64Writer * cw,
- struct arm64_regs *regs) {
+static void instrument_persitent_restore_regs(GumArm64Writer * cw,
+ persistent_ctx_t *regs) {
GumAddress regs_address = GUM_ADDRESS(regs);
const guint32 msr_nzcv_x1 = 0xd51b4201;
@@ -228,82 +148,81 @@ static void instrument_persitent_restore_regs(GumArm64Writer * cw,
/* Skip x0 - x3 we'll do that last */
- gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X4, ARM64_REG_X5,
- ARM64_REG_X0, (16 * 2),
- GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X6, ARM64_REG_X7,
- ARM64_REG_X0, (16 * 3),
- GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X8, ARM64_REG_X9,
- ARM64_REG_X0, (16 * 4),
- GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X10, ARM64_REG_X11,
- ARM64_REG_X0, (16 * 5),
- GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X12, ARM64_REG_X13,
- ARM64_REG_X0, (16 * 6),
- GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X14, ARM64_REG_X15,
- ARM64_REG_X0, (16 * 7),
- GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X16, ARM64_REG_X17,
- ARM64_REG_X0, (16 * 8),
- GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X18, ARM64_REG_X19,
- ARM64_REG_X0, (16 * 9),
- GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X20, ARM64_REG_X21,
- ARM64_REG_X0, (16 * 10),
- GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X22, ARM64_REG_X23,
- ARM64_REG_X0, (16 * 11),
- GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X24, ARM64_REG_X25,
- ARM64_REG_X0, (16 * 12),
- GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X26, ARM64_REG_X27,
- ARM64_REG_X0, (16 * 13),
- GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X28, ARM64_REG_X29,
- ARM64_REG_X0, (16 * 14),
- GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+ cw, ARM64_REG_X4, ARM64_REG_X5, ARM64_REG_X0,
+ offsetof(GumCpuContext, x[4]), GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+ cw, ARM64_REG_X6, ARM64_REG_X7, ARM64_REG_X0,
+ offsetof(GumCpuContext, x[6]), GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+ cw, ARM64_REG_X8, ARM64_REG_X9, ARM64_REG_X0,
+ offsetof(GumCpuContext, x[8]), GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+ cw, ARM64_REG_X10, ARM64_REG_X11, ARM64_REG_X0,
+ offsetof(GumCpuContext, x[10]), GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+ cw, ARM64_REG_X12, ARM64_REG_X13, ARM64_REG_X0,
+ offsetof(GumCpuContext, x[12]), GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+ cw, ARM64_REG_X14, ARM64_REG_X15, ARM64_REG_X0,
+ offsetof(GumCpuContext, x[14]), GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+ cw, ARM64_REG_X16, ARM64_REG_X17, ARM64_REG_X0,
+ offsetof(GumCpuContext, x[16]), GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+ cw, ARM64_REG_X18, ARM64_REG_X19, ARM64_REG_X0,
+ offsetof(GumCpuContext, x[18]), GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+ cw, ARM64_REG_X20, ARM64_REG_X21, ARM64_REG_X0,
+ offsetof(GumCpuContext, x[20]), GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+ cw, ARM64_REG_X22, ARM64_REG_X23, ARM64_REG_X0,
+ offsetof(GumCpuContext, x[22]), GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+ cw, ARM64_REG_X24, ARM64_REG_X25, ARM64_REG_X0,
+ offsetof(GumCpuContext, x[24]), GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+ cw, ARM64_REG_X26, ARM64_REG_X27, ARM64_REG_X0,
+ offsetof(GumCpuContext, x[26]), GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+ cw, ARM64_REG_X28, ARM64_REG_X29, ARM64_REG_X0,
+ offsetof(GumCpuContext, x[28]), GUM_INDEX_SIGNED_OFFSET);
- /* LR & Adjusted SP (use x1 as clobber) */
- gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X30, ARM64_REG_X1,
- ARM64_REG_X0, (16 * 15),
- GUM_INDEX_SIGNED_OFFSET);
+ /* LR (x30) */
+ gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X30, ARM64_REG_X0,
+ offsetof(GumCpuContext, x[30]));
+ /* Adjusted SP (31) (use x1 as clobber)*/
+ gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X1, ARM64_REG_X0,
+ offsetof(GumCpuContext, sp));
gum_arm64_writer_put_mov_reg_reg(cw, ARM64_REG_SP, ARM64_REG_X1);
- /* Don't restore RIP use x1-x3 as clobber */
-
- /* PC (x2) & CPSR (x1) */
- gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X1,
- ARM64_REG_X0, (16 * 16),
- GUM_INDEX_SIGNED_OFFSET);
+ /* CPSR */
+ gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X1, ARM64_REG_X0,
+ offsetof(persistent_ctx_t, rflags));
gum_arm64_writer_put_instruction(cw, msr_nzcv_x1);
- gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_Q0, ARM64_REG_Q1,
- ARM64_REG_X0, (16 * 17),
- GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_Q2, ARM64_REG_Q3,
- ARM64_REG_X0, (16 * 18),
- GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_Q4, ARM64_REG_Q5,
- ARM64_REG_X0, (16 * 19),
- GUM_INDEX_SIGNED_OFFSET);
- gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_Q6, ARM64_REG_Q7,
- ARM64_REG_X0, (16 * 20),
- GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+ cw, ARM64_REG_Q0, ARM64_REG_Q1, ARM64_REG_X0,
+ offsetof(GumCpuContext, q[0]), GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+ cw, ARM64_REG_Q2, ARM64_REG_Q3, ARM64_REG_X0,
+ offsetof(GumCpuContext, q[16]), GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+ cw, ARM64_REG_Q4, ARM64_REG_Q5, ARM64_REG_X0,
+ offsetof(GumCpuContext, q[32]), GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+ cw, ARM64_REG_Q6, ARM64_REG_Q7, ARM64_REG_X0,
+ offsetof(GumCpuContext, q[48]), GUM_INDEX_SIGNED_OFFSET);
/* x2 & x3 */
- gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X3,
- ARM64_REG_X0, (16 * 1),
- GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+ cw, ARM64_REG_X2, ARM64_REG_X3, ARM64_REG_X0,
+ offsetof(GumCpuContext, x[2]), GUM_INDEX_SIGNED_OFFSET);
/* x0 & x1 */
- gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X0, ARM64_REG_X1,
- ARM64_REG_X0, (16 * 0),
- GUM_INDEX_SIGNED_OFFSET);
+ gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+ cw, ARM64_REG_X0, ARM64_REG_X1, ARM64_REG_X0,
+ offsetof(GumCpuContext, x[0]), GUM_INDEX_SIGNED_OFFSET);
}
@@ -318,7 +237,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;
}
@@ -334,29 +253,29 @@ static void instrument_afl_persistent_loop(GumArm64Writer *cw) {
}
-static void persistent_prologue_hook(GumArm64Writer * cw,
- struct arm64_regs *regs) {
+static void persistent_prologue_hook(GumArm64Writer * cw,
+ persistent_ctx_t *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);
- gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X3,
+ gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X2,
GUM_ADDRESS(&__afl_fuzz_len));
- gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X3, ARM64_REG_X3, 0);
- gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X3, ARM64_REG_X3, 0);
+ gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X2, 0);
+ gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X2, 0);
- gum_arm64_writer_put_and_reg_reg_imm(cw, ARM64_REG_X3, ARM64_REG_X3,
+ gum_arm64_writer_put_and_reg_reg_imm(cw, ARM64_REG_X2, ARM64_REG_X2,
G_MAXULONG);
- gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X2,
+ gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X1,
GUM_ADDRESS(&__afl_fuzz_ptr));
- gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X2, 0);
+ gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X1, ARM64_REG_X1, 0);
gum_arm64_writer_put_call_address_with_arguments(
- cw, GUM_ADDRESS(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);
+ cw, GUM_ADDRESS(persistent_hook), 3, GUM_ARG_ADDRESS,
+ GUM_ADDRESS(&regs->ctx), GUM_ARG_REGISTER, ARM64_REG_X1, GUM_ARG_REGISTER,
+ ARM64_REG_X2);
gum_arm64_writer_put_add_reg_reg_imm(cw, ARM64_REG_SP, ARM64_REG_SP,
GUM_RED_ZONE_SIZE);
@@ -406,6 +325,8 @@ void persistent_prologue(GumStalkerOutput *output) {
gconstpointer loop = cw->code + 1;
+ OKF("Persistent loop reached");
+
instrument_persitent_save_regs(cw, &saved_regs);
/* loop: */
diff --git a/frida_mode/src/persistent/persistent_x64.c b/frida_mode/src/persistent/persistent_x64.c
index 653acefe..b2186db1 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"
@@ -10,40 +10,15 @@
#if defined(__x86_64__)
-struct x86_64_regs {
+typedef struct {
- uint64_t rax, rbx, rcx, rdx, rdi, rsi, rbp, r8, r9, r10, r11, r12, r13, r14,
- r15;
+ GumCpuContext ctx;
+ uint64_t rflags;
- union {
+} persistent_ctx_t;
- uint64_t rip;
- uint64_t pc;
-
- };
-
- union {
-
- uint64_t rsp;
- uint64_t sp;
-
- };
-
- union {
-
- uint64_t rflags;
- uint64_t flags;
-
- };
-
- uint8_t zmm_regs[32][64];
-
-};
-
-typedef struct x86_64_regs arch_api_regs;
-
-static arch_api_regs saved_regs = {0};
-static gpointer saved_ret = NULL;
+static persistent_ctx_t saved_regs = {0};
+static gpointer saved_ret = NULL;
gboolean persistent_is_supported(void) {
@@ -51,8 +26,8 @@ gboolean persistent_is_supported(void) {
}
-static void instrument_persitent_save_regs(GumX86Writer * cw,
- struct x86_64_regs *regs) {
+static void instrument_persitent_save_regs(GumX86Writer * cw,
+ persistent_ctx_t *regs) {
GumAddress regs_address = GUM_ADDRESS(regs);
gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP,
@@ -64,41 +39,41 @@ static void instrument_persitent_save_regs(GumX86Writer * cw,
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RAX, regs_address);
- gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 1),
- GUM_REG_RBX);
- gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 2),
- GUM_REG_RCX);
- gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 3),
- GUM_REG_RDX);
- gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 4),
- GUM_REG_RDI);
- gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 5),
- GUM_REG_RSI);
- gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 6),
- GUM_REG_RBP);
- gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 7),
- GUM_REG_R8);
- gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 8),
- GUM_REG_R9);
- gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 9),
- GUM_REG_R10);
- gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 10),
- GUM_REG_R11);
- gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 11),
- GUM_REG_R12);
- gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 12),
- GUM_REG_R13);
- gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 13),
- GUM_REG_R14);
- gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 14),
- GUM_REG_R15);
+ gum_x86_writer_put_mov_reg_offset_ptr_reg(
+ cw, GUM_REG_RAX, offsetof(GumCpuContext, rbx), GUM_REG_RBX);
+ gum_x86_writer_put_mov_reg_offset_ptr_reg(
+ cw, GUM_REG_RAX, offsetof(GumCpuContext, rcx), GUM_REG_RCX);
+ gum_x86_writer_put_mov_reg_offset_ptr_reg(
+ cw, GUM_REG_RAX, offsetof(GumCpuContext, rdx), GUM_REG_RDX);
+ gum_x86_writer_put_mov_reg_offset_ptr_reg(
+ cw, GUM_REG_RAX, offsetof(GumCpuContext, rdi), GUM_REG_RDI);
+ gum_x86_writer_put_mov_reg_offset_ptr_reg(
+ cw, GUM_REG_RAX, offsetof(GumCpuContext, rsi), GUM_REG_RSI);
+ gum_x86_writer_put_mov_reg_offset_ptr_reg(
+ cw, GUM_REG_RAX, offsetof(GumCpuContext, rbp), GUM_REG_RBP);
+ gum_x86_writer_put_mov_reg_offset_ptr_reg(
+ cw, GUM_REG_RAX, offsetof(GumCpuContext, r8), GUM_REG_R8);
+ gum_x86_writer_put_mov_reg_offset_ptr_reg(
+ cw, GUM_REG_RAX, offsetof(GumCpuContext, r9), GUM_REG_R9);
+ gum_x86_writer_put_mov_reg_offset_ptr_reg(
+ cw, GUM_REG_RAX, offsetof(GumCpuContext, r10), GUM_REG_R10);
+ gum_x86_writer_put_mov_reg_offset_ptr_reg(
+ cw, GUM_REG_RAX, offsetof(GumCpuContext, r11), GUM_REG_R11);
+ gum_x86_writer_put_mov_reg_offset_ptr_reg(
+ cw, GUM_REG_RAX, offsetof(GumCpuContext, r12), GUM_REG_R12);
+ gum_x86_writer_put_mov_reg_offset_ptr_reg(
+ cw, GUM_REG_RAX, offsetof(GumCpuContext, r13), GUM_REG_R13);
+ gum_x86_writer_put_mov_reg_offset_ptr_reg(
+ cw, GUM_REG_RAX, offsetof(GumCpuContext, r14), GUM_REG_R14);
+ gum_x86_writer_put_mov_reg_offset_ptr_reg(
+ cw, GUM_REG_RAX, offsetof(GumCpuContext, r15), GUM_REG_R15);
/* Store RIP */
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RBX,
GUM_ADDRESS(persistent_start));
- gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 15),
- GUM_REG_RBX);
+ gum_x86_writer_put_mov_reg_offset_ptr_reg(
+ cw, GUM_REG_RAX, offsetof(GumCpuContext, rip), GUM_REG_RBX);
/* Store adjusted RSP */
gum_x86_writer_put_mov_reg_reg(cw, GUM_REG_RBX, GUM_REG_RSP);
@@ -106,18 +81,18 @@ static void instrument_persitent_save_regs(GumX86Writer * cw,
/* RED_ZONE + Saved flags, RAX, alignment */
gum_x86_writer_put_add_reg_imm(cw, GUM_REG_RBX,
GUM_RED_ZONE_SIZE + (0x8 * 2));
- gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 16),
- GUM_REG_RBX);
+ gum_x86_writer_put_mov_reg_offset_ptr_reg(
+ cw, GUM_REG_RAX, offsetof(GumCpuContext, rsp), GUM_REG_RBX);
/* Save the flags */
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBX, GUM_REG_RSP, 0x8);
- gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 17),
- GUM_REG_RBX);
+ gum_x86_writer_put_mov_reg_offset_ptr_reg(
+ cw, GUM_REG_RAX, offsetof(persistent_ctx_t, rflags), GUM_REG_RBX);
/* Save the RAX */
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBX, GUM_REG_RSP, 0x0);
- gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 0),
- GUM_REG_RBX);
+ gum_x86_writer_put_mov_reg_offset_ptr_reg(
+ cw, GUM_REG_RAX, offsetof(GumCpuContext, rax), GUM_REG_RBX);
/* Pop the saved values */
gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, 0x10);
@@ -127,56 +102,56 @@ static void instrument_persitent_save_regs(GumX86Writer * cw,
}
-static void instrument_persitent_restore_regs(GumX86Writer * cw,
- struct x86_64_regs *regs) {
+static void instrument_persitent_restore_regs(GumX86Writer * cw,
+ persistent_ctx_t *regs) {
GumAddress regs_address = GUM_ADDRESS(regs);
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RAX, regs_address);
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RCX, GUM_REG_RAX,
- (0x8 * 2));
+ offsetof(GumCpuContext, rcx));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RDX, GUM_REG_RAX,
- (0x8 * 3));
+ offsetof(GumCpuContext, rdx));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RDI, GUM_REG_RAX,
- (0x8 * 4));
+ offsetof(GumCpuContext, rdi));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RSI, GUM_REG_RAX,
- (0x8 * 5));
+ offsetof(GumCpuContext, rsi));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBP, GUM_REG_RAX,
- (0x8 * 6));
+ offsetof(GumCpuContext, rbp));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R8, GUM_REG_RAX,
- (0x8 * 7));
+ offsetof(GumCpuContext, r8));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R9, GUM_REG_RAX,
- (0x8 * 8));
+ offsetof(GumCpuContext, r9));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R10, GUM_REG_RAX,
- (0x8 * 9));
+ offsetof(GumCpuContext, r10));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R11, GUM_REG_RAX,
- (0x8 * 10));
+ offsetof(GumCpuContext, r11));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R12, GUM_REG_RAX,
- (0x8 * 11));
+ offsetof(GumCpuContext, r12));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R13, GUM_REG_RAX,
- (0x8 * 12));
+ offsetof(GumCpuContext, r13));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R14, GUM_REG_RAX,
- (0x8 * 13));
+ offsetof(GumCpuContext, r14));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R15, GUM_REG_RAX,
- (0x8 * 14));
+ offsetof(GumCpuContext, r15));
/* Don't restore RIP */
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RSP, GUM_REG_RAX,
- (0x8 * 16));
+ offsetof(GumCpuContext, rsp));
/* Restore RBX, RAX & Flags */
gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP,
-(GUM_RED_ZONE_SIZE));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBX, GUM_REG_RAX,
- (0x8 * 1));
+ offsetof(GumCpuContext, rbx));
gum_x86_writer_put_push_reg(cw, GUM_REG_RBX);
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBX, GUM_REG_RAX,
- (0x8 * 0));
+ offsetof(GumCpuContext, rax));
gum_x86_writer_put_push_reg(cw, GUM_REG_RBX);
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBX, GUM_REG_RAX,
- (0x8 * 17));
+ offsetof(persistent_ctx_t, rflags));
gum_x86_writer_put_push_reg(cw, GUM_REG_RBX);
gum_x86_writer_put_popfx(cw);
@@ -199,7 +174,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;
}
@@ -217,28 +192,27 @@ static void instrument_afl_persistent_loop(GumX86Writer *cw) {
}
-static void persistent_prologue_hook(GumX86Writer * cw,
- struct x86_64_regs *regs) {
+static void persistent_prologue_hook(GumX86Writer *cw, persistent_ctx_t *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));
- gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RCX,
+ gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RDX,
GUM_ADDRESS(&__afl_fuzz_len));
- gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RCX, GUM_REG_RCX, 0);
- gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RCX, GUM_REG_RCX, 0);
+ gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RDX, GUM_REG_RDX, 0);
+ gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RDX, GUM_REG_RDX, 0);
gum_x86_writer_put_mov_reg_u64(cw, GUM_REG_RDI, 0xffffffff);
- gum_x86_writer_put_and_reg_reg(cw, GUM_REG_RCX, GUM_REG_RDI);
+ gum_x86_writer_put_and_reg_reg(cw, GUM_REG_RDX, GUM_REG_RDI);
- gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RDX,
+ gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RSI,
GUM_ADDRESS(&__afl_fuzz_ptr));
- gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RDX, GUM_REG_RDX, 0);
+ gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RSI, GUM_REG_RSI, 0);
gum_x86_writer_put_call_address_with_arguments(
- cw, GUM_CALL_CAPI, GUM_ADDRESS(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);
+ cw, GUM_CALL_CAPI, GUM_ADDRESS(persistent_hook), 3, GUM_ARG_ADDRESS,
+ GUM_ADDRESS(&regs->ctx), GUM_ARG_REGISTER, GUM_REG_RSI, GUM_ARG_REGISTER,
+ GUM_REG_RDX);
gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP,
(GUM_RED_ZONE_SIZE));
@@ -296,6 +270,8 @@ void persistent_prologue(GumStalkerOutput *output) {
gconstpointer loop = cw->code + 1;
+ OKF("Persistent loop reached");
+
/* Pop the return value */
gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, 8);
diff --git a/frida_mode/src/persistent/persistent_x86.c b/frida_mode/src/persistent/persistent_x86.c
index 7add6e99..f50bccb0 100644
--- a/frida_mode/src/persistent/persistent_x86.c
+++ b/frida_mode/src/persistent/persistent_x86.c
@@ -1,45 +1,23 @@
-#include "frida-gum.h"
+#include "frida-gumjs.h"
#include "config.h"
+#include "debug.h"
#include "instrument.h"
#include "persistent.h"
#if defined(__i386__)
-struct x86_regs {
+typedef struct {
- uint32_t eax, ebx, ecx, edx, edi, esi, ebp;
+ GumCpuContext ctx;
+ uint32_t eflags;
- union {
+} persistent_ctx_t;
- uint32_t eip;
- uint32_t pc;
+static persistent_ctx_t saved_regs = {0};
- };
-
- union {
-
- uint32_t esp;
- uint32_t sp;
-
- };
-
- union {
-
- uint32_t eflags;
- uint32_t flags;
-
- };
-
- uint8_t xmm_regs[8][16];
-
-};
-
-typedef struct x86_regs arch_api_regs;
-
-static arch_api_regs saved_regs = {0};
-static gpointer saved_ret = NULL;
+static gpointer saved_ret = NULL;
gboolean persistent_is_supported(void) {
@@ -47,8 +25,8 @@ gboolean persistent_is_supported(void) {
}
-static void instrument_persitent_save_regs(GumX86Writer * cw,
- struct x86_regs *regs) {
+static void instrument_persitent_save_regs(GumX86Writer * cw,
+ persistent_ctx_t *regs) {
GumAddress regs_address = GUM_ADDRESS(regs);
@@ -58,80 +36,80 @@ static void instrument_persitent_save_regs(GumX86Writer * cw,
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EAX, regs_address);
- gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 1),
- GUM_REG_EBX);
- gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 2),
- GUM_REG_ECX);
- gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 3),
- GUM_REG_EDX);
- gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 4),
- GUM_REG_EDI);
- gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 5),
- GUM_REG_ESI);
- gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 6),
- GUM_REG_EBP);
+ gum_x86_writer_put_mov_reg_offset_ptr_reg(
+ cw, GUM_REG_EAX, offsetof(GumCpuContext, ebx), GUM_REG_EBX);
+ gum_x86_writer_put_mov_reg_offset_ptr_reg(
+ cw, GUM_REG_EAX, offsetof(GumCpuContext, ecx), GUM_REG_ECX);
+ gum_x86_writer_put_mov_reg_offset_ptr_reg(
+ cw, GUM_REG_EAX, offsetof(GumCpuContext, edx), GUM_REG_EDX);
+ gum_x86_writer_put_mov_reg_offset_ptr_reg(
+ cw, GUM_REG_EAX, offsetof(GumCpuContext, edi), GUM_REG_EDI);
+ gum_x86_writer_put_mov_reg_offset_ptr_reg(
+ cw, GUM_REG_EAX, offsetof(GumCpuContext, esi), GUM_REG_ESI);
+ gum_x86_writer_put_mov_reg_offset_ptr_reg(
+ cw, GUM_REG_EAX, offsetof(GumCpuContext, ebp), GUM_REG_EBP);
/* Store RIP */
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EBX,
GUM_ADDRESS(persistent_start));
- gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 7),
- GUM_REG_EBX);
+ gum_x86_writer_put_mov_reg_offset_ptr_reg(
+ cw, GUM_REG_EAX, offsetof(GumCpuContext, eip), GUM_REG_EBX);
/* Store adjusted RSP */
gum_x86_writer_put_mov_reg_reg(cw, GUM_REG_EBX, GUM_REG_ESP);
/* RED_ZONE + Saved flags, RAX */
gum_x86_writer_put_add_reg_imm(cw, GUM_REG_EBX, (0x4 * 2));
- gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 8),
- GUM_REG_EBX);
+ gum_x86_writer_put_mov_reg_offset_ptr_reg(
+ cw, GUM_REG_EAX, offsetof(GumCpuContext, esp), GUM_REG_EBX);
/* Save the flags */
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_ESP, 0x4);
- gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 9),
- GUM_REG_EBX);
+ gum_x86_writer_put_mov_reg_offset_ptr_reg(
+ cw, GUM_REG_EAX, offsetof(persistent_ctx_t, eflags), GUM_REG_EBX);
/* Save the RAX */
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_ESP, 0x0);
- gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 0),
- GUM_REG_EBX);
+ gum_x86_writer_put_mov_reg_offset_ptr_reg(
+ cw, GUM_REG_EAX, offsetof(GumCpuContext, eax), GUM_REG_EBX);
/* Pop the saved values */
gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_ESP, GUM_REG_ESP, 0x8);
}
-static void instrument_persitent_restore_regs(GumX86Writer * cw,
- struct x86_regs *regs) {
+static void instrument_persitent_restore_regs(GumX86Writer * cw,
+ persistent_ctx_t *regs) {
GumAddress regs_address = GUM_ADDRESS(regs);
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EAX, regs_address);
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_ECX, GUM_REG_EAX,
- (0x4 * 2));
+ offsetof(GumCpuContext, ecx));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EDX, GUM_REG_EAX,
- (0x4 * 3));
+ offsetof(GumCpuContext, edx));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EDI, GUM_REG_EAX,
- (0x4 * 4));
+ offsetof(GumCpuContext, edi));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_ESI, GUM_REG_EAX,
- (0x4 * 5));
+ offsetof(GumCpuContext, esi));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBP, GUM_REG_EAX,
- (0x4 * 6));
+ offsetof(GumCpuContext, ebp));
/* Don't restore RIP */
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_ESP, GUM_REG_EAX,
- (0x4 * 8));
+ offsetof(GumCpuContext, esp));
/* Restore RBX, RAX & Flags */
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_EAX,
- (0x4 * 1));
+ offsetof(GumCpuContext, ebx));
gum_x86_writer_put_push_reg(cw, GUM_REG_EBX);
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_EAX,
- (0x4 * 0));
+ offsetof(GumCpuContext, eax));
gum_x86_writer_put_push_reg(cw, GUM_REG_EBX);
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_EAX,
- (0x4 * 9));
+ offsetof(persistent_ctx_t, eflags));
gum_x86_writer_put_push_reg(cw, GUM_REG_EBX);
gum_x86_writer_put_popfx(cw);
@@ -152,7 +130,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;
}
@@ -165,9 +143,9 @@ static void instrument_afl_persistent_loop(GumX86Writer *cw) {
}
-static void persistent_prologue_hook(GumX86Writer *cw, struct x86_regs *regs) {
+static void persistent_prologue_hook(GumX86Writer *cw, persistent_ctx_t *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,9 +158,8 @@ 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,
- GUM_ADDRESS(regs), GUM_ARG_ADDRESS, GUM_ADDRESS(0), GUM_ARG_ADDRESS,
- GUM_ADDRESS(0), GUM_ARG_REGISTER, GUM_REG_EDX, GUM_ARG_REGISTER,
+ cw, GUM_CALL_CAPI, GUM_ADDRESS(persistent_hook), 3, GUM_ARG_ADDRESS,
+ GUM_ADDRESS(&regs->ctx), GUM_ARG_REGISTER, GUM_REG_EDX, GUM_ARG_REGISTER,
GUM_REG_ECX);
}
@@ -233,6 +210,8 @@ void persistent_prologue(GumStalkerOutput *output) {
gconstpointer loop = cw->code + 1;
+ OKF("Persistent loop reached");
+
/* Pop the return value */
gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_ESP, GUM_REG_ESP, 4);
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"