diff options
author | Your Name <you@example.com> | 2021-08-20 17:28:40 +0100 |
---|---|---|
committer | Your Name <you@example.com> | 2021-08-20 17:28:40 +0100 |
commit | 028f8ced8f772d82a7efc522ec629bf4a5fff32d (patch) | |
tree | f5440087d2779984812b5e8c50f1fda6bdbb489b /frida_mode/src/prefetch.c | |
parent | 3513ba2e51222151945e8ae87236bb9d2f07f37a (diff) | |
download | afl++-028f8ced8f772d82a7efc522ec629bf4a5fff32d.tar.gz |
Fixed coverage on OSX (dependency on pipe2)
Removed use of 'realpath' in makefiles to fix OSX incompatibility Fixed handling of when prefetching should be enabled Snap the main binary during initialization to avoid stability issues with lazy loading Add support for configurable inline cache entries for FRIDA on x86/x64 Support for prefetching FRIDA backpatches on x86/x64 Improved stats support on x86/x64/aarch64
Diffstat (limited to 'frida_mode/src/prefetch.c')
-rw-r--r-- | frida_mode/src/prefetch.c | 98 |
1 files changed, 93 insertions, 5 deletions
diff --git a/frida_mode/src/prefetch.c b/frida_mode/src/prefetch.c index 50d10c9e..0efbc9bf 100644 --- a/frida_mode/src/prefetch.c +++ b/frida_mode/src/prefetch.c @@ -6,32 +6,66 @@ #include "debug.h" +#include "entry.h" #include "intercept.h" #include "prefetch.h" #include "stalker.h" +#include "util.h" #define TRUST 0 #define PREFETCH_SIZE 65536 #define PREFETCH_ENTRIES ((PREFETCH_SIZE - sizeof(size_t)) / sizeof(void *)) +#define BP_SIZE 524288 + typedef struct { size_t count; void * entry[PREFETCH_ENTRIES]; + guint8 backpatch_data[BP_SIZE]; + gsize backpatch_size; + } prefetch_data_t; gboolean prefetch_enable = TRUE; +gboolean prefetch_backpatch = TRUE; static prefetch_data_t *prefetch_data = NULL; static int prefetch_shm_id = -1; +static void gum_afl_stalker_backpatcher_notify(GumStalkerObserver *self, + const GumBackpatch *backpatch, + gsize size) { + + UNUSED_PARAMETER(self); + if (!entry_run) { return; } + gsize remaining = + sizeof(prefetch_data->backpatch_data) - prefetch_data->backpatch_size; + if (sizeof(gsize) + size > remaining) { return; } + + *(gsize *)(&prefetch_data->backpatch_data[prefetch_data->backpatch_size]) = + size; + prefetch_data->backpatch_size += sizeof(gsize); + + memcpy(&prefetch_data->backpatch_data[prefetch_data->backpatch_size], + backpatch, size); + prefetch_data->backpatch_size += size; + +} + /* * We do this from the transformer since we need one anyway for coverage, this * saves the need to use an event sink. */ void prefetch_write(void *addr) { +#if defined(__aarch64__) + if (!entry_compiled) { return; } +#else + if (!entry_run) { return; } +#endif + /* Bail if we aren't initialized */ if (prefetch_data == NULL) return; @@ -51,10 +85,7 @@ void prefetch_write(void *addr) { } -/* - * Read the IPC region one block at the time and prefetch it - */ -void prefetch_read(void) { +static void prefetch_read_blocks(void) { GumStalker *stalker = stalker_get(); if (prefetch_data == NULL) return; @@ -74,10 +105,60 @@ void prefetch_read(void) { } +static void prefetch_read_patches(void) { + + gsize offset = 0; + GumStalker * stalker = stalker_get(); + GumBackpatch *backpatch = NULL; + + for (gsize remaining = prefetch_data->backpatch_size - offset; + remaining > sizeof(gsize); + remaining = prefetch_data->backpatch_size - offset) { + + gsize size = *(gsize *)(&prefetch_data->backpatch_data[offset]); + offset += sizeof(gsize); + + if (prefetch_data->backpatch_size - offset < size) { + + FATAL("Incomplete backpatch entry"); + + } + + backpatch = (GumBackpatch *)&prefetch_data->backpatch_data[offset]; + gum_stalker_prefetch_backpatch(stalker, backpatch); + offset += size; + + } + + prefetch_data->backpatch_size = 0; + +} + +/* + * Read the IPC region one block at the time and prefetch it + */ +void prefetch_read(void) { + + prefetch_read_blocks(); + prefetch_read_patches(); + +} + void prefetch_config(void) { prefetch_enable = (getenv("AFL_FRIDA_INST_NO_PREFETCH") == NULL); + if (prefetch_enable) { + + prefetch_backpatch = + (getenv("AFL_FRIDA_INST_NO_PREFETCH_BACKPATCH") == NULL); + + } else { + + prefetch_backpatch = FALSE; + + } + } static int prefetch_on_fork(void) { @@ -97,8 +178,9 @@ static void prefetch_hook_fork(void) { void prefetch_init(void) { - g_assert_cmpint(sizeof(prefetch_data_t), ==, PREFETCH_SIZE); OKF("Instrumentation - prefetch [%c]", prefetch_enable ? 'X' : ' '); + OKF("Instrumentation - prefetch_backpatch [%c]", + prefetch_backpatch ? 'X' : ' '); if (!prefetch_enable) { return; } /* @@ -131,5 +213,11 @@ void prefetch_init(void) { prefetch_hook_fork(); + if (!prefetch_backpatch) { return; } + + GumStalkerObserver * observer = stalker_get_observer(); + GumStalkerObserverInterface *iface = GUM_STALKER_OBSERVER_GET_IFACE(observer); + iface->notify_backpatch = gum_afl_stalker_backpatcher_notify; + } |