aboutsummaryrefslogtreecommitdiff
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();