Changes to make JS run in foreground thread
MODIFY
frida_mode/src/js/js.c
frida_mode/src/js/js.c
@@ -15,6 +15,9 @@ static GumScriptBackend *backend;
static GCancellable * cancellable = NULL;
static GError * error = NULL;
static GumScript * script;
+static GumScriptScheduler *scheduler;
+static GMainContext * context;
+static GMainLoop * main_loop;
static void js_msg(GumScript *script, const gchar *message, GBytes *data,
gpointer user_data) {
@@ -80,18 +83,44 @@ static void js_print_script(gchar *source) {
}
-void js_start(void) {
+static void create_cb(GObject *source_object, GAsyncResult *result,
+ gpointer user_data) {
+
+ UNUSED_PARAMETER(source_object);
+ UNUSED_PARAMETER(user_data);
+ script = gum_script_backend_create_finish(backend, result, &error);
+
+}
+
+static void load_cb(GObject *source_object, GAsyncResult *result,
+ gpointer user_data) {
+
+ UNUSED_PARAMETER(source_object);
+ UNUSED_PARAMETER(user_data);
+ gum_script_load_finish(script, result);
+
+}
- GMainContext *context;
+void js_start(void) {
gchar *source = js_get_script();
if (source == NULL) { return; }
js_print_script(source);
+ scheduler = gum_script_backend_get_scheduler();
+ gum_script_scheduler_disable_background_thread(scheduler);
+
backend = gum_script_backend_obtain_qjs();
- script = gum_script_backend_create_sync(backend, "example", source,
- cancellable, &error);
+ context = gum_script_scheduler_get_js_context(scheduler);
+ main_loop = g_main_loop_new(context, true);
+ g_main_context_push_thread_default(context);
+
+ gum_script_backend_create(backend, "example", source, cancellable, create_cb,
+ &error);
+
+ while (g_main_context_pending(context))
+ g_main_context_iteration(context, FALSE);
if (error != NULL) {
@@ -100,14 +129,13 @@ void js_start(void) {
}
- gum_script_set_message_handler(script, js_msg, NULL, NULL);
-
- gum_script_load_sync(script, cancellable);
+ gum_script_load(script, cancellable, load_cb, NULL);
- context = g_main_context_get_thread_default();
while (g_main_context_pending(context))
g_main_context_iteration(context, FALSE);
+ gum_script_set_message_handler(script, js_msg, NULL, NULL);
+
if (!js_done) { FATAL("Script didn't call Afl.done()"); }
}

MODIFY
frida_mode/test/js/GNUmakefile
frida_mode/test/js/GNUmakefile
@@ -17,7 +17,7 @@ ifeq "$(shell uname)" "Darwin"
AFL_PRELOAD=/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation
endif
-.PHONY: all 32 clean qemu frida
+.PHONY: all 32 clean qemu frida debug
all: $(TESTINSTBIN) $(TESTINSTBIN2)
make -C $(ROOT)frida_mode/
@@ -84,3 +84,15 @@ frida_js_stalker: $(TESTINSTBIN2) $(TEST_DATA_FILE)
-o $(FRIDA_OUT) \
-- \
$(TESTINSTBIN2) @@
+
+debug: $(TEST_DATA_FILE)
+ gdb \
+ --ex 'set environment LD_PRELOAD=$(ROOT)afl-frida-trace.so' \
+ --ex 'set environment AFL_FRIDA_JS_SCRIPT=entry.js' \
+ --ex 'set disassembly-flavor intel' \
+ --args $(TESTINSTBIN) $(TEST_DATA_FILE)
+
+strace: $(TEST_DATA_FILE)
+ LD_PRELOAD=$(ROOT)afl-frida-trace.so \
+ AFL_FRIDA_JS_SCRIPT=entry.js \
+ strace $(TESTINSTBIN) $(TEST_DATA_FILE)

MODIFY
frida_mode/test/js/entry.js
frida_mode/test/js/entry.js
@@ -9,13 +9,18 @@ new ModuleMap().values().forEach(m => {
Afl.print(`${m.base}-${m.base.add(m.size)} ${m.name}`);
});
+const name = Process.enumerateModules()[0].name;
+Afl.print(`Name: ${name}`);
+
+if (name === 'test') {
+
Afl.print('Searching...\n');
const entry_point = DebugSymbol.fromName('run');
Afl.print(`entry_point: ${entry_point}`);
Afl.setEntryPoint(entry_point.address);
-// Afl.error('HARD NOPE');
+}
Afl.done();
Afl.print("done");

Changes to make JS run in foreground thread (#1009)

Co-authored-by: Your Name <you@example.com>