aboutsummaryrefslogtreecommitdiff
path: root/utils/afl_frida
diff options
context:
space:
mode:
Diffstat (limited to 'utils/afl_frida')
-rw-r--r--utils/afl_frida/afl-frida.c201
-rw-r--r--utils/afl_frida/android/README.md1
-rw-r--r--utils/afl_frida/android/frida-gum-example.c130
3 files changed, 249 insertions, 83 deletions
diff --git a/utils/afl_frida/afl-frida.c b/utils/afl_frida/afl-frida.c
index b5b8196d..087f18e8 100644
--- a/utils/afl_frida/afl-frida.c
+++ b/utils/afl_frida/afl-frida.c
@@ -153,7 +153,7 @@ static int enumerate_ranges(const GumRangeDetails *details,
}
-int main() {
+int main(int argc, char** argv) {
#ifndef __APPLE__
(void)personality(ADDR_NO_RANDOMIZE); // disable ASLR
@@ -164,105 +164,140 @@ int main() {
// If there is just one function, then there is nothing to change
// or add here.
- void *dl = dlopen(TARGET_LIBRARY, RTLD_LAZY);
+ void *dl = NULL;
+ if (argc > 2) {
+ dl = dlopen(argv[1], RTLD_LAZY);
+ } else {
+ dl = dlopen(TARGET_LIBRARY, RTLD_LAZY);
+ }
if (!dl) {
- fprintf(stderr, "Could not load %s\n", TARGET_LIBRARY);
+ if (argc > 2)
+ fprintf(stderr, "Could not load %s\n", argv[1]);
+ else
+ fprintf(stderr, "Could not load %s\n", TARGET_LIBRARY);
exit(-1);
}
- if (!(o_function = dlsym(dl, TARGET_FUNCTION))) {
+ if (argc > 2)
+ o_function = dlsym(dl, argv[2]);
+ else
+ o_function = dlsym(dl, TARGET_FUNCTION);
+ if (!o_function) {
- fprintf(stderr, "Could not find function %s\n", TARGET_FUNCTION);
+ if (argc > 2)
+ fprintf(stderr, "Could not find function %s\n", argv[2]);
+ else
+ fprintf(stderr, "Could not find function %s\n", TARGET_FUNCTION);
exit(-1);
}
// END STEP 2
- gum_init_embedded();
- if (!gum_stalker_is_supported()) {
-
- gum_deinit_embedded();
- return 1;
-
- }
-
- GumStalker *stalker = gum_stalker_new();
-
- GumAddress base_address = gum_module_find_base_address(TARGET_LIBRARY);
- GumMemoryRange code_range;
- gum_module_enumerate_ranges(TARGET_LIBRARY, GUM_PAGE_RX, enumerate_ranges,
- &code_range);
-
- guint64 code_start = code_range.base_address;
- guint64 code_end = code_range.base_address + code_range.size;
- range_t instr_range = {0, code_start, code_end};
-
- printf("Frida instrumentation: base=0x%lx instrumenting=0x%lx-%lx\n",
- base_address, code_start, code_end);
- if (!code_start || !code_end) {
-
- fprintf(stderr, "Error: no valid memory address found for %s\n",
- TARGET_LIBRARY);
- exit(-1);
-
- }
-
- GumStalkerTransformer *transformer =
- gum_stalker_transformer_make_from_callback(instr_basic_block,
- &instr_range, NULL);
-
- // to ensure that the signatures are not optimized out
- memcpy(__afl_area_ptr, (void *)AFL_PERSISTENT, sizeof(AFL_PERSISTENT) + 1);
- memcpy(__afl_area_ptr + 32, (void *)AFL_DEFER_FORKSVR,
- sizeof(AFL_DEFER_FORKSVR) + 1);
- __afl_manual_init();
-
- //
- // any expensive target library initialization that has to be done just once
- // - put that here
- //
-
- gum_stalker_follow_me(stalker, transformer, NULL);
-
- while (__afl_persistent_loop(UINT32_MAX) != 0) {
-
- previous_pc = 0; // Required!
-
-#ifdef _DEBUG
- fprintf(stderr, "CLIENT crc: %016llx len: %u\n",
- hash64(__afl_fuzz_ptr, *__afl_fuzz_len), *__afl_fuzz_len);
- fprintf(stderr, "RECV:");
- for (int i = 0; i < *__afl_fuzz_len; i++)
- fprintf(stderr, "%02x", __afl_fuzz_ptr[i]);
- fprintf(stderr, "\n");
-#endif
-
- // STEP 3: ensure the minimum length is present and setup the target
- // function to fuzz.
-
- if (*__afl_fuzz_len > 0) {
-
- __afl_fuzz_ptr[*__afl_fuzz_len] = 0; // if you need to null terminate
- (*o_function)(__afl_fuzz_ptr, *__afl_fuzz_len);
-
+ if (!getenv("AFL_FRIDA_TEST_INPUT")) {
+ gum_init_embedded();
+ if (!gum_stalker_is_supported()) {
+
+ gum_deinit_embedded();
+ return 1;
+
}
+
+ GumStalker *stalker = gum_stalker_new();
+
+ GumAddress base_address;
+ if (argc > 2)
+ base_address = gum_module_find_base_address(argv[1]);
+ else
+ base_address = gum_module_find_base_address(TARGET_LIBRARY);
+ GumMemoryRange code_range;
+ if (argc > 2)
+ gum_module_enumerate_ranges(argv[1], GUM_PAGE_RX, enumerate_ranges,
+ &code_range);
+ else
+ gum_module_enumerate_ranges(TARGET_LIBRARY, GUM_PAGE_RX, enumerate_ranges,
+ &code_range);
+
+ guint64 code_start = code_range.base_address;
+ guint64 code_end = code_range.base_address + code_range.size;
+ range_t instr_range = {0, code_start, code_end};
+
+ printf("Frida instrumentation: base=0x%lx instrumenting=0x%lx-%lx\n",
+ base_address, code_start, code_end);
+ if (!code_start || !code_end) {
+
+ if (argc > 2)
+ fprintf(stderr, "Error: no valid memory address found for %s\n",
+ argv[1]);
+ else
+ fprintf(stderr, "Error: no valid memory address found for %s\n",
+ TARGET_LIBRARY);
+ exit(-1);
+
+ }
+
+ GumStalkerTransformer *transformer =
+ gum_stalker_transformer_make_from_callback(instr_basic_block,
+ &instr_range, NULL);
+
+ // to ensure that the signatures are not optimized out
+ memcpy(__afl_area_ptr, (void *)AFL_PERSISTENT, sizeof(AFL_PERSISTENT) + 1);
+ memcpy(__afl_area_ptr + 32, (void *)AFL_DEFER_FORKSVR,
+ sizeof(AFL_DEFER_FORKSVR) + 1);
+ __afl_manual_init();
+
+ //
+ // any expensive target library initialization that has to be done just once
+ // - put that here
+ //
+
+ gum_stalker_follow_me(stalker, transformer, NULL);
+
+ while (__afl_persistent_loop(UINT32_MAX) != 0) {
+
+ previous_pc = 0; // Required!
+
+ #ifdef _DEBUG
+ fprintf(stderr, "CLIENT crc: %016llx len: %u\n",
+ hash64(__afl_fuzz_ptr, *__afl_fuzz_len), *__afl_fuzz_len);
+ fprintf(stderr, "RECV:");
+ for (int i = 0; i < *__afl_fuzz_len; i++)
+ fprintf(stderr, "%02x", __afl_fuzz_ptr[i]);
+ fprintf(stderr, "\n");
+ #endif
+
+ // STEP 3: ensure the minimum length is present and setup the target
+ // function to fuzz.
+
+ if (*__afl_fuzz_len > 0) {
+
+ __afl_fuzz_ptr[*__afl_fuzz_len] = 0; // if you need to null terminate
+ (*o_function)(__afl_fuzz_ptr, *__afl_fuzz_len);
+
+ }
+
+ // END STEP 3
+
+ }
+
+ gum_stalker_unfollow_me(stalker);
+
+ while (gum_stalker_garbage_collect(stalker))
+ g_usleep(10000);
+
+ g_object_unref(stalker);
+ g_object_unref(transformer);
+ gum_deinit_embedded();
- // END STEP 3
-
+ } else {
+ char buf[8*1024] = {0};
+ int count = read(0, buf, sizeof(buf));
+ buf[8*1024-1] = '\0';
+ (*o_function)(buf, count);
}
- gum_stalker_unfollow_me(stalker);
-
- while (gum_stalker_garbage_collect(stalker))
- g_usleep(10000);
-
- g_object_unref(stalker);
- g_object_unref(transformer);
- gum_deinit_embedded();
-
return 0;
}
diff --git a/utils/afl_frida/android/README.md b/utils/afl_frida/android/README.md
new file mode 100644
index 00000000..044b48a1
--- /dev/null
+++ b/utils/afl_frida/android/README.md
@@ -0,0 +1 @@
+For android, frida-gum package (ex. https://github.com/frida/frida/releases/download/14.2.6/frida-gum-devkit-14.2.6-android-arm64.tar.xz) is needed to be extracted in the directory.
diff --git a/utils/afl_frida/android/frida-gum-example.c b/utils/afl_frida/android/frida-gum-example.c
new file mode 100644
index 00000000..14d98248
--- /dev/null
+++ b/utils/afl_frida/android/frida-gum-example.c
@@ -0,0 +1,130 @@
+/*
+ * Compile with:
+ *
+ * clang -fPIC -DANDROID -ffunction-sections -fdata-sections -Os -pipe -g3 frida-gum-example.c -o frida-gum-example -L. -lfrida-gum -llog -ldl -lm -pthread -Wl,--gc-sections,-z,noexecstack,-z,relro,-z,now -fuse-ld=gold -fuse-ld=gold -Wl,--icf=all
+ *
+ * Visit https://frida.re to learn more about Frida.
+ */
+
+#include "frida-gum.h"
+
+#include <fcntl.h>
+#include <unistd.h>
+
+typedef struct _ExampleListener ExampleListener;
+typedef enum _ExampleHookId ExampleHookId;
+
+struct _ExampleListener
+{
+ GObject parent;
+
+ guint num_calls;
+};
+
+enum _ExampleHookId
+{
+ EXAMPLE_HOOK_OPEN,
+ EXAMPLE_HOOK_CLOSE
+};
+
+static void example_listener_iface_init (gpointer g_iface, gpointer iface_data);
+
+#define EXAMPLE_TYPE_LISTENER (example_listener_get_type ())
+G_DECLARE_FINAL_TYPE (ExampleListener, example_listener, EXAMPLE, LISTENER, GObject)
+G_DEFINE_TYPE_EXTENDED (ExampleListener,
+ example_listener,
+ G_TYPE_OBJECT,
+ 0,
+ G_IMPLEMENT_INTERFACE (GUM_TYPE_INVOCATION_LISTENER,
+ example_listener_iface_init))
+
+int
+main (int argc,
+ char * argv[])
+{
+ GumInterceptor * interceptor;
+ GumInvocationListener * listener;
+
+ gum_init_embedded ();
+
+ interceptor = gum_interceptor_obtain ();
+ listener = g_object_new (EXAMPLE_TYPE_LISTENER, NULL);
+
+ gum_interceptor_begin_transaction (interceptor);
+ gum_interceptor_attach (interceptor,
+ GSIZE_TO_POINTER (gum_module_find_export_by_name (NULL, "open")),
+ listener,
+ GSIZE_TO_POINTER (EXAMPLE_HOOK_OPEN));
+ gum_interceptor_attach (interceptor,
+ GSIZE_TO_POINTER (gum_module_find_export_by_name (NULL, "close")),
+ listener,
+ GSIZE_TO_POINTER (EXAMPLE_HOOK_CLOSE));
+ gum_interceptor_end_transaction (interceptor);
+
+ close (open ("/etc/hosts", O_RDONLY));
+ close (open ("/etc/fstab", O_RDONLY));
+
+ g_print ("[*] listener got %u calls\n", EXAMPLE_LISTENER (listener)->num_calls);
+
+ gum_interceptor_detach (interceptor, listener);
+
+ close (open ("/etc/hosts", O_RDONLY));
+ close (open ("/etc/fstab", O_RDONLY));
+
+ g_print ("[*] listener still has %u calls\n", EXAMPLE_LISTENER (listener)->num_calls);
+
+ g_object_unref (listener);
+ g_object_unref (interceptor);
+
+ gum_deinit_embedded ();
+
+ return 0;
+}
+
+static void
+example_listener_on_enter (GumInvocationListener * listener,
+ GumInvocationContext * ic)
+{
+ ExampleListener * self = EXAMPLE_LISTENER (listener);
+ ExampleHookId hook_id = GUM_IC_GET_FUNC_DATA (ic, ExampleHookId);
+
+ switch (hook_id)
+ {
+ case EXAMPLE_HOOK_OPEN:
+ g_print ("[*] open(\"%s\")\n", (const gchar *) gum_invocation_context_get_nth_argument (ic, 0));
+ break;
+ case EXAMPLE_HOOK_CLOSE:
+ g_print ("[*] close(%d)\n", GPOINTER_TO_INT (gum_invocation_context_get_nth_argument (ic, 0)));
+ break;
+ }
+
+ self->num_calls++;
+}
+
+static void
+example_listener_on_leave (GumInvocationListener * listener,
+ GumInvocationContext * ic)
+{
+}
+
+static void
+example_listener_class_init (ExampleListenerClass * klass)
+{
+ (void) EXAMPLE_IS_LISTENER;
+ (void) glib_autoptr_cleanup_ExampleListener;
+}
+
+static void
+example_listener_iface_init (gpointer g_iface,
+ gpointer iface_data)
+{
+ GumInvocationListenerInterface * iface = g_iface;
+
+ iface->on_enter = example_listener_on_enter;
+ iface->on_leave = example_listener_on_leave;
+}
+
+static void
+example_listener_init (ExampleListener * self)
+{
+}