about summary refs log tree commit diff
path: root/frida_mode
diff options
context:
space:
mode:
Diffstat (limited to 'frida_mode')
-rw-r--r--frida_mode/GNUmakefile3
-rw-r--r--frida_mode/README.md6
-rw-r--r--frida_mode/frida.map1
-rw-r--r--frida_mode/include/entry.h3
-rw-r--r--frida_mode/src/entry.c32
-rw-r--r--frida_mode/src/js/api.js7
-rw-r--r--frida_mode/src/js/js_api.c6
-rw-r--r--frida_mode/src/main.c13
-rw-r--r--frida_mode/src/seccomp/seccomp_callback.c20
-rw-r--r--frida_mode/src/seccomp/seccomp_filter.c2
-rw-r--r--frida_mode/ts/lib/afl.ts12
11 files changed, 105 insertions, 0 deletions
diff --git a/frida_mode/GNUmakefile b/frida_mode/GNUmakefile
index ed35c9f6..b5fee7a6 100644
--- a/frida_mode/GNUmakefile
+++ b/frida_mode/GNUmakefile
@@ -78,6 +78,9 @@ endif
 
 ifeq "$(shell uname)" "Linux"
  OS:=linux
+ ifneq "$(findstring musl, $(shell ldd --version 2>&1 | head -n 1))" ""
+  CFLAGS+=       -D__MUSL__
+ endif
 endif
 
 ifneq "$(findstring android, $(shell $(CC) --version 2>/dev/null))" ""
diff --git a/frida_mode/README.md b/frida_mode/README.md
index df40c771..bb194080 100644
--- a/frida_mode/README.md
+++ b/frida_mode/README.md
@@ -288,6 +288,12 @@ ucomisd                                 2 ( 0.86%)
 * `AFL_FRIDA_STATS_INTERVAL` - The maximum frequency to output statistics
 information. Stats will be written whenever they are updated if the given
 interval has elapsed since last time they were written.
+* `AFL_FRIDA_TRACEABLE` - Set the child process to be traceable by any process
+to aid debugging and overcome the restrictions imposed by YAMA. Supported on
+Linux only. Permits a non-root user to use `gcore` or similar to collect a core
+dump of the instrumented target. Note that in order to capture the core dump you
+must set a sufficient timeout (using `-t`) to avoid `afl-fuzz` killing the
+process whilst it is being dumped.
 
 ## FASAN - Frida Address Sanitizer Mode
 Frida mode also supports FASAN. The design of this is actually quite simple and
diff --git a/frida_mode/frida.map b/frida_mode/frida.map
index 0fc48aa6..e2ae87a7 100644
--- a/frida_mode/frida.map
+++ b/frida_mode/frida.map
@@ -33,6 +33,7 @@
     js_api_set_stats_interval;
     js_api_set_stderr;
     js_api_set_stdout;
+    js_api_set_traceable;
 
   local:
     *;
diff --git a/frida_mode/include/entry.h b/frida_mode/include/entry.h
index 3f0a4ecc..edc41467 100644
--- a/frida_mode/include/entry.h
+++ b/frida_mode/include/entry.h
@@ -4,6 +4,7 @@
 #include "frida-gumjs.h"
 
 extern guint64  entry_point;
+extern gboolean traceable;
 extern gboolean entry_compiled;
 extern gboolean entry_run;
 
@@ -15,5 +16,7 @@ void entry_start(void);
 
 void entry_prologue(GumStalkerIterator *iterator, GumStalkerOutput *output);
 
+void entry_on_fork(void);
+
 #endif
 
diff --git a/frida_mode/src/entry.c b/frida_mode/src/entry.c
index 186ddd3a..c51e202f 100644
--- a/frida_mode/src/entry.c
+++ b/frida_mode/src/entry.c
@@ -1,5 +1,9 @@
 #include <dlfcn.h>
 
+#if defined(__linux__) && !defined(__ANDROID__)
+  #include <sys/prctl.h>
+#endif
+
 #include "frida-gumjs.h"
 
 #include "debug.h"
@@ -16,6 +20,7 @@
 extern void __afl_manual_init();
 
 guint64  entry_point = 0;
+gboolean traceable = FALSE;
 gboolean entry_compiled = FALSE;
 gboolean entry_run = FALSE;
 
@@ -26,21 +31,48 @@ static void entry_launch(void) {
 
   /* Child here */
   entry_run = TRUE;
+  entry_on_fork();
   instrument_on_fork();
   seccomp_on_fork();
   stats_on_fork();
 
 }
 
+#if defined(__linux__) && !defined(__ANDROID__)
+void entry_on_fork(void) {
+
+  if (traceable) {
+
+    if (prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY) < 0) {
+
+      FATAL("Failed to PR_SET_PTRACER");
+
+    }
+
+  }
+
+}
+
+#else
+void entry_on_fork(void) {
+
+  if (traceable) { WARNF("AFL_FRIDA_TRACEABLE unsupported"); }
+
+}
+
+#endif
+
 void entry_config(void) {
 
   entry_point = util_read_address("AFL_ENTRYPOINT");
+  if (getenv("AFL_FRIDA_TRACEABLE") != NULL) { traceable = TRUE; }
 
 }
 
 void entry_init(void) {
 
   OKF("entry_point: 0x%016" G_GINT64_MODIFIER "X", entry_point);
+  OKF("dumpable: [%c]", traceable ? 'X' : ' ');
 
   if (dlopen(NULL, RTLD_NOW) == NULL) { FATAL("Failed to dlopen: %d", errno); }
 
diff --git a/frida_mode/src/js/api.js b/frida_mode/src/js/api.js
index 40bb4a16..6f9f05d8 100644
--- a/frida_mode/src/js/api.js
+++ b/frida_mode/src/js/api.js
@@ -243,6 +243,12 @@ class Afl {
         const buf = Memory.allocUtf8String(file);
         Afl.jsApiSetStdOut(buf);
     }
+    /**
+     * See `AFL_FRIDA_TRACEABLE`.
+     */
+    static setTraceable() {
+        Afl.jsApiSetTraceable();
+    }
     static jsApiGetFunction(name, retType, argTypes) {
         const addr = Afl.module.getExportByName(name);
         return new NativeFunction(addr, retType, argTypes);
@@ -286,6 +292,7 @@ Afl.jsApiSetStatsFile = Afl.jsApiGetFunction("js_api_set_stats_file", "void", ["
 Afl.jsApiSetStatsInterval = Afl.jsApiGetFunction("js_api_set_stats_interval", "void", ["uint64"]);
 Afl.jsApiSetStdErr = Afl.jsApiGetFunction("js_api_set_stderr", "void", ["pointer"]);
 Afl.jsApiSetStdOut = Afl.jsApiGetFunction("js_api_set_stdout", "void", ["pointer"]);
+Afl.jsApiSetTraceable = Afl.jsApiGetFunction("js_api_set_traceable", "void", []);
 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_api.c b/frida_mode/src/js/js_api.c
index 9dba79aa..f3d81a32 100644
--- a/frida_mode/src/js/js_api.c
+++ b/frida_mode/src/js/js_api.c
@@ -231,3 +231,9 @@ __attribute__((visibility("default"))) void js_api_set_stalker_ic_entries(
 
 }
 
+__attribute__((visibility("default"))) void js_api_set_traceable(void) {
+
+  traceable = TRUE;
+
+}
+
diff --git a/frida_mode/src/main.c b/frida_mode/src/main.c
index c0de9c6b..c8183d8f 100644
--- a/frida_mode/src/main.c
+++ b/frida_mode/src/main.c
@@ -6,6 +6,7 @@
 #ifdef __APPLE__
   #include <mach/mach.h>
   #include <mach-o/dyld_images.h>
+  #include <crt_externs.h>
 #else
   #include <sys/wait.h>
   #include <sys/personality.h>
@@ -90,6 +91,7 @@ static void embedded_init(void) {
 
 static void afl_print_cmdline(void) {
 
+#if defined(__linux__)
   char * buffer = g_malloc0(PROC_MAX);
   gchar *fname = g_strdup_printf("/proc/%d/cmdline", getppid());
   int    fd = open(fname, O_RDONLY);
@@ -123,6 +125,17 @@ static void afl_print_cmdline(void) {
   close(fd);
   g_free(fname);
   g_free(buffer);
+#elif defined(__APPLE__)
+  int idx;
+  char **argv = *_NSGetArgv();
+  int nargv = *_NSGetArgc();
+
+  for (idx = 0; idx < nargv; idx ++) {
+
+    OKF("AFL - COMMANDLINE: argv[%d] = %s", idx, argv[idx]);
+
+  }
+#endif
 
 }
 
diff --git a/frida_mode/src/seccomp/seccomp_callback.c b/frida_mode/src/seccomp/seccomp_callback.c
index a88196ac..4232d842 100644
--- a/frida_mode/src/seccomp/seccomp_callback.c
+++ b/frida_mode/src/seccomp/seccomp_callback.c
@@ -1,6 +1,8 @@
 #if defined(__linux__) && !defined(__ANDROID__)
 
+#if !defined(__MUSL__)
   #include <execinfo.h>
+#endif
   #include <fcntl.h>
 
   #include "seccomp.h"
@@ -29,6 +31,7 @@ static void seccomp_callback_filter(struct seccomp_notif *     req,
       req->data.args[0], req->data.args[1], req->data.args[2],
       req->data.args[3], req->data.args[4], req->data.args[5]);
 
+#if !defined(__MUSL__)
   seccomp_print("FRAMES: (%u)\n", frames->len);
   char **syms = backtrace_symbols(frames->items, frames->len);
   if (syms == NULL) { FATAL("Failed to get symbols"); }
@@ -49,6 +52,23 @@ static void seccomp_callback_filter(struct seccomp_notif *     req,
   }
 
   free(syms);
+#else
+  void **syms = (void **)__builtin_frame_address(0);
+  void *framep = __builtin_frame_address(1);
+  int i = 0;
+
+  syms = framep;
+  while (syms) {
+   
+    framep = *syms;   
+    syms = framep;
+
+    if (!syms) break;
+
+    seccomp_print("\%3d. %s\n", i ++, (char *)framep);
+
+  }
+#endif
 
   resp->error = 0;
   resp->val = 0;
diff --git a/frida_mode/src/seccomp/seccomp_filter.c b/frida_mode/src/seccomp/seccomp_filter.c
index 8d56c367..7ee5ead1 100644
--- a/frida_mode/src/seccomp/seccomp_filter.c
+++ b/frida_mode/src/seccomp/seccomp_filter.c
@@ -2,7 +2,9 @@
 
   #include <alloca.h>
   #include <errno.h>
+#if !defined(__MUSL__)
   #include <execinfo.h>
+#endif
   #include <linux/filter.h>
   #include <sys/ioctl.h>
   #include <sys/prctl.h>
diff --git a/frida_mode/ts/lib/afl.ts b/frida_mode/ts/lib/afl.ts
index 8a1ebf1b..538d9b70 100644
--- a/frida_mode/ts/lib/afl.ts
+++ b/frida_mode/ts/lib/afl.ts
@@ -284,6 +284,13 @@ class Afl {
     Afl.jsApiSetStdOut(buf);
   }
 
+  /**
+   * See `AFL_FRIDA_TRACEABLE`.
+   */
+  public static setTraceable(): void {
+    Afl.jsApiSetTraceable();
+  }
+
   private static readonly jsApiAddExcludeRange = Afl.jsApiGetFunction(
     "js_api_add_exclude_range",
     "void",
@@ -431,6 +438,11 @@ class Afl {
     "void",
     ["pointer"]);
 
+  private static readonly jsApiSetTraceable = Afl.jsApiGetFunction(
+    "js_api_set_traceable",
+    "void",
+    []);
+
   private static readonly jsApiWrite = new NativeFunction(
     /* tslint:disable-next-line:no-null-keyword */
     Module.getExportByName(null, "write"),