aboutsummaryrefslogtreecommitdiff
path: root/frida_mode/src/module.c
diff options
context:
space:
mode:
authorvan Hauser <vh@thc.org>2022-04-03 09:30:23 +0200
committerGitHub <noreply@github.com>2022-04-03 09:30:23 +0200
commit881aef21fd6ca3f3bcf0847587d4d6d86f3a69db (patch)
treed076384dedf423a4bb7c3d1507cb07281ebc2865 /frida_mode/src/module.c
parent1d4f1e48797c064ee71441ba555b29fc3f467983 (diff)
parentc4363dd8b3d19a3e4bab8bc1fca1708ae2ff7899 (diff)
downloadafl++-881aef21fd6ca3f3bcf0847587d4d6d86f3a69db.tar.gz
Merge pull request #1362 from AFLplusplus/dev
push to stable
Diffstat (limited to 'frida_mode/src/module.c')
-rw-r--r--frida_mode/src/module.c106
1 files changed, 106 insertions, 0 deletions
diff --git a/frida_mode/src/module.c b/frida_mode/src/module.c
new file mode 100644
index 00000000..65b394cd
--- /dev/null
+++ b/frida_mode/src/module.c
@@ -0,0 +1,106 @@
+#include "intercept.h"
+#include "module.h"
+#include "util.h"
+
+#if defined(__linux__)
+ #include <dlfcn.h>
+ #include <link.h>
+#endif
+
+static guint page_size = 0;
+static gboolean handle_dlclose = FALSE;
+
+void module_config(void) {
+
+#if defined(__linux__)
+ handle_dlclose = (getenv("AFL_FRIDA_NO_MODULE") == NULL);
+#else
+ FWARNF("AFL_FRIDA_MODULE not supported");
+#endif
+
+}
+
+typedef struct {
+
+ GumMemoryRange range;
+ GumPageProtection protection;
+ GumFileMapping file;
+
+} gum_range_t;
+
+gboolean found_range(const GumRangeDetails *details, gpointer user_data) {
+
+ gum_range_t range = {0};
+ GArray * ranges = (GArray *)user_data;
+
+ range.range = *details->range;
+ range.protection = details->protection;
+ if (details->file != NULL) { range.file = *details->file; }
+
+ g_array_append_val(ranges, range);
+ return FALSE;
+
+}
+
+#if defined(__linux__)
+static int on_dlclose(void *handle) {
+
+ GArray * ranges = NULL;
+ struct link_map *lm = NULL;
+ gum_range_t * range = NULL;
+ GumAddress base;
+ GumAddress limit;
+ gpointer mem;
+
+ if (dlinfo(handle, RTLD_DI_LINKMAP, &lm) < 0) {
+
+ FFATAL("Failed to dlinfo: %s", dlerror());
+
+ }
+
+ FVERBOSE("on_dlclose: %s", lm->l_name);
+
+ ranges = g_array_new(FALSE, TRUE, sizeof(gum_range_t));
+ gum_module_enumerate_ranges(lm->l_name, GUM_PAGE_EXECUTE, found_range,
+ ranges);
+
+ int ret = dlclose(handle);
+ if (ret != 0) {
+
+ FWARNF("dlclose returned: %d (%s)", ret, dlerror());
+ return ret;
+
+ }
+
+ for (guint i = 0; i < ranges->len; i++) {
+
+ range = &g_array_index(ranges, gum_range_t, i);
+ base = range->range.base_address;
+ limit = base + range->range.size;
+ FVERBOSE("Reserving range: 0x%016lx, 0x%016lX", base, limit);
+ mem = gum_memory_allocate(GSIZE_TO_POINTER(base), range->range.size,
+ page_size, GUM_PAGE_NO_ACCESS);
+ if (mem == NULL) { FATAL("Failed to allocate %p (%d)", mem, errno); }
+
+ }
+
+ g_array_free(ranges, TRUE);
+ return 0;
+
+}
+
+#endif
+
+void module_init(void) {
+
+ FOKF(cBLU "Module" cRST " - " cYEL " [%c]", handle_dlclose ? 'X' : ' ');
+
+#if defined(__linux__)
+ if (!handle_dlclose) { return; }
+
+ page_size = gum_query_page_size();
+ intercept_hook(dlclose, on_dlclose, NULL);
+#endif
+
+}
+