about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--frida_mode/src/cmplog/cmplog.c84
-rw-r--r--frida_mode/src/main.c84
2 files changed, 166 insertions, 2 deletions
diff --git a/frida_mode/src/cmplog/cmplog.c b/frida_mode/src/cmplog/cmplog.c
index 7b11c350..3df7d13d 100644
--- a/frida_mode/src/cmplog/cmplog.c
+++ b/frida_mode/src/cmplog/cmplog.c
@@ -1,3 +1,8 @@
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <syscall.h>
+
 #include "frida-gum.h"
 
 #include "debug.h"
@@ -5,10 +10,13 @@
 #include "util.h"
 
 #define DEFAULT_MMAP_MIN_ADDR (32UL << 10)
+#define FD_TMP_MAX_SIZE 65536
 
 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 gboolean cmplog_range(const GumRangeDetails *details,
                              gpointer               user_data) {
@@ -27,6 +35,40 @@ static gint cmplog_sort(gconstpointer a, gconstpointer b) {
 
 }
 
+static int cmplog_create_temp(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);
+
+  if (fd < 0) {
+
+    FATAL("Failed to create temp file: %s, errno: %d", fname, errno);
+
+  }
+
+  if (unlink(fname) < 0) {
+
+    FATAL("Failed to unlink temp file: %s (%d), errno: %d", fname, fd, errno);
+
+  }
+
+  if (ftruncate(fd, 0) < 0) {
+
+    FATAL("Failed to ftruncate temp file: %s (%d), errno: %d", fname, fd,
+          errno);
+
+  }
+
+  g_free(fname);
+
+  return fd;
+
+}
+
 void cmplog_init(void) {
 
   if (__afl_cmp_map != NULL) { OKF("CMPLOG mode enabled"); }
@@ -44,6 +86,13 @@ void cmplog_init(void) {
 
   }
 
+  /*
+   * 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.
+   */
+  fd_tmp = cmplog_create_temp();
+
 }
 
 static gboolean cmplog_contains(GumAddress inner_base, GumAddress inner_limit,
@@ -67,6 +116,9 @@ gboolean cmplog_is_readable(guint64 addr, size_t size) {
    */
   if (addr < DEFAULT_MMAP_MIN_ADDR) { return false; }
 
+  /* Check our addres/length don't wrap around */
+  if (SIZE_MAX - addr < size) { return false; }
+
   GumAddress inner_base = addr;
   GumAddress inner_limit = inner_base + size;
 
@@ -81,6 +133,38 @@ 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; }
+
+  }
+
   return false;
 
 }
diff --git a/frida_mode/src/main.c b/frida_mode/src/main.c
index 1ab9993f..7ff23755 100644
--- a/frida_mode/src/main.c
+++ b/frida_mode/src/main.c
@@ -1,4 +1,5 @@
 #include <errno.h>
+#include <fcntl.h>
 #include <unistd.h>
 #include <sys/types.h>
 
@@ -27,6 +28,8 @@
 #include "stats.h"
 #include "util.h"
 
+#define PROC_MAX 65536
+
 #ifdef __APPLE__
 extern mach_port_t mach_task_self();
 extern GumAddress  gum_darwin_find_entrypoint(mach_port_t task);
@@ -78,7 +81,7 @@ static void on_main_os(int argc, char **argv, char **envp) {
 
 #endif
 
-static void embedded_init() {
+static void embedded_init(void) {
 
   static gboolean initialized = false;
   if (!initialized) {
@@ -90,7 +93,84 @@ static void embedded_init() {
 
 }
 
-void afl_frida_start() {
+static void afl_print_cmdline(void) {
+
+  char * buffer = g_malloc0(PROC_MAX);
+  gchar *fname = g_strdup_printf("/proc/%d/cmdline", getppid());
+  int    fd = open(fname, O_RDONLY);
+
+  if (fd < 0) {
+
+    FATAL("Failed to open /proc/self/cmdline, errno: (%d)", errno);
+
+  }
+
+  ssize_t bytes_read = read(fd, buffer, PROC_MAX - 1);
+  if (bytes_read < 0) {
+
+    FATAL("Failed to read /proc/self/cmdline, errno: (%d)", errno);
+
+  }
+
+  int idx = 0;
+
+  for (ssize_t i = 0; i < bytes_read; i++) {
+
+    if (i == 0 || buffer[i - 1] == '\0') {
+
+      OKF("AFL - COMMANDLINE: argv[%d] = %s", idx++, &buffer[i]);
+
+    }
+
+  }
+
+  close(fd);
+  g_free(fname);
+  g_free(buffer);
+
+}
+
+static void afl_print_env(void) {
+
+  char * buffer = g_malloc0(PROC_MAX);
+  gchar *fname = g_strdup_printf("/proc/%d/environ", getppid());
+  int    fd = open(fname, O_RDONLY);
+
+  if (fd < 0) {
+
+    FATAL("Failed to open /proc/self/cmdline, errno: (%d)", errno);
+
+  }
+
+  ssize_t bytes_read = read(fd, buffer, PROC_MAX - 1);
+  if (bytes_read < 0) {
+
+    FATAL("Failed to read /proc/self/cmdline, errno: (%d)", errno);
+
+  }
+
+  int idx = 0;
+
+  for (ssize_t i = 0; i < bytes_read; i++) {
+
+    if (i == 0 || buffer[i - 1] == '\0') {
+
+      OKF("AFL - ENVIRONMENT %3d: %s", idx++, &buffer[i]);
+
+    }
+
+  }
+
+  close(fd);
+  g_free(fname);
+  g_free(buffer);
+
+}
+
+void afl_frida_start(void) {
+
+  afl_print_cmdline();
+  afl_print_env();
 
   embedded_init();
   stalker_init();