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