1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
#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__) && !defined(__ANDROID__)
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%016" G_GINT64_MODIFIER
"x, 0x%016" G_GINT64_MODIFIER "X",
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__) && !defined(__ANDROID__)
if (!handle_dlclose) { return; }
page_size = gum_query_page_size();
intercept_hook(dlclose, on_dlclose, NULL);
#endif
}
|