1 #include <errno.h>
2 #include <fcntl.h>
3 #include <unistd.h>
4 #include <sys/types.h>
5
6 #ifdef __APPLE__
7 #include <mach/mach.h>
8 #include <mach-o/dyld_images.h>
9 #else
10 #include <sys/wait.h>
11 #include <sys/personality.h>
12 #endif
13
14 #include "frida-gumjs.h"
15
16 #include "config.h"
17 #include "debug.h"
18
19 #include "entry.h"
20 #include "instrument.h"
21 #include "intercept.h"
22 #include "js.h"
23 #include "lib.h"
24 #include "output.h"
25 #include "persistent.h"
26 #include "prefetch.h"
27 #include "ranges.h"
28 #include "stalker.h"
29 #include "stats.h"
30 #include "util.h"
31
32 #define PROC_MAX 65536
33
34 #ifdef __APPLE__
35 extern mach_port_t mach_task_self();
36 extern GumAddress gum_darwin_find_entrypoint(mach_port_t task);
37 #else
38 extern int __libc_start_main(int *(main)(int, char **, char **), int argc,
39 char **ubp_av, void (*init)(void),
40 void (*fini)(void), void (*rtld_fini)(void),
41 void(*stack_end));
42 #endif
43
44 typedef int *(*main_fn_t)(int argc, char **argv, char **envp);
45
46 static main_fn_t main_fn = NULL;
47
48 #ifdef __APPLE__
on_main_os(int argc,char ** argv,char ** envp)49 static void on_main_os(int argc, char **argv, char **envp) {
50
51 UNUSED_PARAMETER(argc);
52 UNUSED_PARAMETER(argv);
53 UNUSED_PARAMETER(envp);
54
55 }
56
57 #else
on_main_os(int argc,char ** argv,char ** envp)58 static void on_main_os(int argc, char **argv, char **envp) {
59
60 UNUSED_PARAMETER(argc);
61 /* Personality doesn't affect the current process, it only takes effect on
62 * evec */
63 int persona = personality(ADDR_NO_RANDOMIZE);
64 if (persona == -1) { WARNF("Failed to set ADDR_NO_RANDOMIZE: %d", errno); }
65 if ((persona & ADDR_NO_RANDOMIZE) == 0) { execvpe(argv[0], argv, envp); }
66
67 GumInterceptor *interceptor = gum_interceptor_obtain();
68
69 gum_interceptor_begin_transaction(interceptor);
70 gum_interceptor_revert(interceptor, __libc_start_main);
71 gum_interceptor_end_transaction(interceptor);
72 gum_interceptor_flush(interceptor);
73
74 }
75
76 #endif
77
embedded_init(void)78 static void embedded_init(void) {
79
80 static gboolean initialized = false;
81 if (!initialized) {
82
83 gum_init_embedded();
84 initialized = true;
85
86 }
87
88 }
89
afl_print_cmdline(void)90 static void afl_print_cmdline(void) {
91
92 char * buffer = g_malloc0(PROC_MAX);
93 gchar *fname = g_strdup_printf("/proc/%d/cmdline", getppid());
94 int fd = open(fname, O_RDONLY);
95
96 if (fd < 0) {
97
98 WARNF("Failed to open /proc/self/cmdline, errno: (%d)", errno);
99 return;
100
101 }
102
103 ssize_t bytes_read = read(fd, buffer, PROC_MAX - 1);
104 if (bytes_read < 0) {
105
106 FATAL("Failed to read /proc/self/cmdline, errno: (%d)", errno);
107
108 }
109
110 int idx = 0;
111
112 for (ssize_t i = 0; i < bytes_read; i++) {
113
114 if (i == 0 || buffer[i - 1] == '\0') {
115
116 OKF("AFL - COMMANDLINE: argv[%d] = %s", idx++, &buffer[i]);
117
118 }
119
120 }
121
122 close(fd);
123 g_free(fname);
124 g_free(buffer);
125
126 }
127
afl_print_env(void)128 static void afl_print_env(void) {
129
130 char * buffer = g_malloc0(PROC_MAX);
131 gchar *fname = g_strdup_printf("/proc/%d/environ", getppid());
132 int fd = open(fname, O_RDONLY);
133
134 if (fd < 0) {
135
136 WARNF("Failed to open /proc/self/cmdline, errno: (%d)", errno);
137 return;
138
139 }
140
141 ssize_t bytes_read = read(fd, buffer, PROC_MAX - 1);
142 if (bytes_read < 0) {
143
144 FATAL("Failed to read /proc/self/cmdline, errno: (%d)", errno);
145
146 }
147
148 int idx = 0;
149
150 for (ssize_t i = 0; i < bytes_read; i++) {
151
152 if (i == 0 || buffer[i - 1] == '\0') {
153
154 OKF("AFL - ENVIRONMENT %3d: %s", idx++, &buffer[i]);
155
156 }
157
158 }
159
160 close(fd);
161 g_free(fname);
162 g_free(buffer);
163
164 }
165
afl_frida_start(void)166 __attribute__((visibility("default"))) void afl_frida_start(void) {
167
168 afl_print_cmdline();
169 afl_print_env();
170
171 /* Configure */
172 entry_config();
173 instrument_config();
174 js_config();
175 lib_config();
176 output_config();
177 persistent_config();
178 prefetch_config();
179 ranges_config();
180 stalker_config();
181 stats_config();
182
183 js_start();
184
185 /* Initialize */
186 output_init();
187
188 embedded_init();
189 entry_init();
190 instrument_init();
191 lib_init();
192 persistent_init();
193 prefetch_init();
194 stalker_init();
195 ranges_init();
196 stats_init();
197
198 /* Start */
199 stalker_start();
200 entry_start();
201
202 }
203
on_main(int argc,char ** argv,char ** envp)204 static int *on_main(int argc, char **argv, char **envp) {
205
206 on_main_os(argc, argv, envp);
207
208 intercept_unhook_self();
209
210 afl_frida_start();
211
212 return main_fn(argc, argv, envp);
213
214 }
215
216 #if defined(EMBEDDED)
217 extern int *main(int argc, char **argv, char **envp);
218
intercept_main(void)219 static void intercept_main(void) {
220
221 main_fn = main;
222 intercept_hook(main, on_main, NULL);
223
224 }
225
226 #elif defined(__APPLE__)
intercept_main(void)227 static void intercept_main(void) {
228
229 mach_port_t task = mach_task_self();
230 OKF("Task Id: %u", task);
231 GumAddress entry = gum_darwin_find_entrypoint(task);
232 OKF("Entry Point: 0x%016" G_GINT64_MODIFIER "x", entry);
233 void *main = GSIZE_TO_POINTER(entry);
234 main_fn = main;
235 intercept_hook(main, on_main, NULL);
236
237 }
238
239 #else
on_libc_start_main(int * (main)(int,char **,char **),int argc,char ** ubp_av,void (* init)(void),void (* fini)(void),void (* rtld_fini)(void),void (* stack_end))240 static int on_libc_start_main(int *(main)(int, char **, char **), int argc,
241 char **ubp_av, void (*init)(void),
242 void (*fini)(void), void (*rtld_fini)(void),
243 void(*stack_end)) {
244
245 main_fn = main;
246 intercept_unhook_self();
247 intercept_hook(main, on_main, NULL);
248 return __libc_start_main(main, argc, ubp_av, init, fini, rtld_fini,
249 stack_end);
250
251 }
252
intercept_main(void)253 static void intercept_main(void) {
254
255 intercept_hook(__libc_start_main, on_libc_start_main, NULL);
256
257 }
258
259 #endif
260
init(void)261 __attribute__((constructor)) static void init(void) {
262
263 embedded_init();
264
265 intercept_main();
266
267 }
268
269