aboutsummaryrefslogtreecommitdiff
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"),