aboutsummaryrefslogtreecommitdiff
path: root/frida_mode/src
diff options
context:
space:
mode:
authorWorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com>2021-06-16 20:53:57 +0100
committerGitHub <noreply@github.com>2021-06-16 21:53:57 +0200
commit58747f9f4fe960cf97d40dd6d6db0f2f7f13b505 (patch)
treed2823cdaefb1f4af9f8c0a64c600dee7cbb12643 /frida_mode/src
parent35153e9b495e3f61c032a3d911e4906fed0b50d6 (diff)
downloadafl++-58747f9f4fe960cf97d40dd6d6db0f2f7f13b505.tar.gz
Perf regression4 (#979)
* Added test for libjpeg * Added proj4 test * Added missing members to x86/64 context * Changes to use memfd and hashtable cache * Removed redundant check Co-authored-by: Your Name <you@example.com>
Diffstat (limited to 'frida_mode/src')
-rw-r--r--frida_mode/src/cmplog/cmplog.c139
-rw-r--r--frida_mode/src/ctx/ctx_x64.c22
-rw-r--r--frida_mode/src/ctx/ctx_x86.c6
3 files changed, 92 insertions, 75 deletions
diff --git a/frida_mode/src/cmplog/cmplog.c b/frida_mode/src/cmplog/cmplog.c
index 3df7d13d..a6c95ab0 100644
--- a/frida_mode/src/cmplog/cmplog.c
+++ b/frida_mode/src/cmplog/cmplog.c
@@ -10,18 +10,20 @@
#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 int fd_tmp = -1;
-static ssize_t fd_tmp_size = 0;
+static GHashTable * hash = NULL;
+
+static int memfd = -1;
+static size_t memfd_size = 0;
+static u8 scratch[MAX_MEMFD_SIZE] = {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,71 +37,95 @@ 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");
+
+ 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);
- if (fd < 0) {
+ for (guint i = 0; i < cmplog_ranges->len; i++) {
- FATAL("Failed to create temp file: %s, errno: %d", fname, errno);
+ GumMemoryRange *range = &g_array_index(cmplog_ranges, GumMemoryRange, i);
}
- if (unlink(fname) < 0) {
+ g_array_free(cmplog_ranges, TRUE);
- FATAL("Failed to unlink temp file: %s (%d), errno: %d", fname, fd, errno);
+}
- }
+void cmplog_init(void) {
+
+ if (__afl_cmp_map != NULL) { OKF("CMPLOG mode enabled"); }
+
+ cmplog_get_ranges();
- if (ftruncate(fd, 0) < 0) {
+ for (guint i = 0; i < cmplog_ranges->len; i++) {
- FATAL("Failed to ftruncate temp file: %s (%d), errno: %d", fname, fd,
- errno);
+ 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);
}
- g_free(fname);
+ memfd = syscall(__NR_memfd_create, "cmplog_memfd", 0);
+ if (memfd < 0) {
- return fd;
+ FATAL("Failed to create_memfd, errno: %d", errno);
+
+ }
+
+ hash = g_hash_table_new (g_direct_hash, g_direct_equal);
+ if (hash == NULL) {
+ FATAL("Failed to g_hash_table_new, errno: %d", errno);
+ }
}
-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, (gpointer)addr)) { return true; }
+ if (memfd_size > MAX_MEMFD_SIZE) {
+ if (lseek(memfd, 0, SEEK_SET) < 0) {
+ FATAL("CMPLOG - Failed lseek, errno: %d", errno);
+ }
}
/*
- * 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 write as a fallback to
+ * validate our address.
+ */
+ ssize_t written = syscall(__NR_write, memfd, (void *)addr, size);
+ if (written < 0 && errno != EFAULT && errno != 0) {
+ FATAL("CMPLOG - Failed __NR_write, errno: %d", errno);
+ }
+ /*
+ * If the write succeeds, then the buffer must be valid otherwise it would
+ * return EFAULT
*/
- fd_tmp = cmplog_create_temp();
+ if (written > 0) { memfd_size += written; }
-}
+ if ((size_t)written == size) {
+ if (!g_hash_table_add (hash, (gpointer)addr)) {
+ FATAL("Failed - g_hash_table_add");
+ }
+ return true;
+ }
-static gboolean cmplog_contains(GumAddress inner_base, GumAddress inner_limit,
- GumAddress outer_base, GumAddress outer_limit) {
- return (inner_base >= outer_base && inner_limit <= outer_limit);
+ return false;
}
gboolean cmplog_is_readable(guint64 addr, size_t size) {
@@ -125,6 +151,7 @@ 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;
@@ -133,37 +160,7 @@ gboolean cmplog_is_readable(guint64 addr, size_t size) {
}
- /*
- * 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/ctx/ctx_x64.c b/frida_mode/src/ctx/ctx_x64.c
index c5900533..1772a252 100644
--- a/frida_mode/src/ctx/ctx_x64.c
+++ b/frida_mode/src/ctx/ctx_x64.c
@@ -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..9b50cb52 100644
--- a/frida_mode/src/ctx/ctx_x86.c
+++ b/frida_mode/src/ctx/ctx_x86.c
@@ -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)