1*08b48e0bSAndroid Build Coastguard Worker /*
2*08b48e0bSAndroid Build Coastguard Worker american fuzzy lop++ - file format analyzer
3*08b48e0bSAndroid Build Coastguard Worker -------------------------------------------
4*08b48e0bSAndroid Build Coastguard Worker
5*08b48e0bSAndroid Build Coastguard Worker Originally written by Michal Zalewski
6*08b48e0bSAndroid Build Coastguard Worker
7*08b48e0bSAndroid Build Coastguard Worker Now maintained by Marc Heuse <[email protected]>,
8*08b48e0bSAndroid Build Coastguard Worker Heiko Eißfeldt <[email protected]> and
9*08b48e0bSAndroid Build Coastguard Worker Andrea Fioraldi <[email protected]>
10*08b48e0bSAndroid Build Coastguard Worker
11*08b48e0bSAndroid Build Coastguard Worker Copyright 2016, 2017 Google Inc. All rights reserved.
12*08b48e0bSAndroid Build Coastguard Worker Copyright 2019-2024 AFLplusplus Project. All rights reserved.
13*08b48e0bSAndroid Build Coastguard Worker
14*08b48e0bSAndroid Build Coastguard Worker Licensed under the Apache License, Version 2.0 (the "License");
15*08b48e0bSAndroid Build Coastguard Worker you may not use this file except in compliance with the License.
16*08b48e0bSAndroid Build Coastguard Worker You may obtain a copy of the License at:
17*08b48e0bSAndroid Build Coastguard Worker
18*08b48e0bSAndroid Build Coastguard Worker https://www.apache.org/licenses/LICENSE-2.0
19*08b48e0bSAndroid Build Coastguard Worker
20*08b48e0bSAndroid Build Coastguard Worker A nifty utility that grabs an input file and takes a stab at explaining
21*08b48e0bSAndroid Build Coastguard Worker its structure by observing how changes to it affect the execution path.
22*08b48e0bSAndroid Build Coastguard Worker
23*08b48e0bSAndroid Build Coastguard Worker If the output scrolls past the edge of the screen, pipe it to 'less -r'.
24*08b48e0bSAndroid Build Coastguard Worker
25*08b48e0bSAndroid Build Coastguard Worker */
26*08b48e0bSAndroid Build Coastguard Worker
27*08b48e0bSAndroid Build Coastguard Worker #define AFL_MAIN
28*08b48e0bSAndroid Build Coastguard Worker
29*08b48e0bSAndroid Build Coastguard Worker #include "config.h"
30*08b48e0bSAndroid Build Coastguard Worker #include "types.h"
31*08b48e0bSAndroid Build Coastguard Worker #include "debug.h"
32*08b48e0bSAndroid Build Coastguard Worker #include "alloc-inl.h"
33*08b48e0bSAndroid Build Coastguard Worker #include "hash.h"
34*08b48e0bSAndroid Build Coastguard Worker #include "sharedmem.h"
35*08b48e0bSAndroid Build Coastguard Worker #include "common.h"
36*08b48e0bSAndroid Build Coastguard Worker #include "forkserver.h"
37*08b48e0bSAndroid Build Coastguard Worker
38*08b48e0bSAndroid Build Coastguard Worker #include <stdio.h>
39*08b48e0bSAndroid Build Coastguard Worker #include <unistd.h>
40*08b48e0bSAndroid Build Coastguard Worker #include <stdlib.h>
41*08b48e0bSAndroid Build Coastguard Worker #include <string.h>
42*08b48e0bSAndroid Build Coastguard Worker #include <time.h>
43*08b48e0bSAndroid Build Coastguard Worker #include <errno.h>
44*08b48e0bSAndroid Build Coastguard Worker #include <signal.h>
45*08b48e0bSAndroid Build Coastguard Worker #include <dirent.h>
46*08b48e0bSAndroid Build Coastguard Worker #include <fcntl.h>
47*08b48e0bSAndroid Build Coastguard Worker #include <ctype.h>
48*08b48e0bSAndroid Build Coastguard Worker
49*08b48e0bSAndroid Build Coastguard Worker #include <sys/wait.h>
50*08b48e0bSAndroid Build Coastguard Worker #include <sys/time.h>
51*08b48e0bSAndroid Build Coastguard Worker #ifndef USEMMAP
52*08b48e0bSAndroid Build Coastguard Worker #include <sys/shm.h>
53*08b48e0bSAndroid Build Coastguard Worker #endif
54*08b48e0bSAndroid Build Coastguard Worker #include <sys/stat.h>
55*08b48e0bSAndroid Build Coastguard Worker #include <sys/types.h>
56*08b48e0bSAndroid Build Coastguard Worker #include <sys/resource.h>
57*08b48e0bSAndroid Build Coastguard Worker
58*08b48e0bSAndroid Build Coastguard Worker static u8 *in_file; /* Analyzer input test case */
59*08b48e0bSAndroid Build Coastguard Worker
60*08b48e0bSAndroid Build Coastguard Worker static u8 *in_data; /* Input data for analysis */
61*08b48e0bSAndroid Build Coastguard Worker
62*08b48e0bSAndroid Build Coastguard Worker static u32 in_len, /* Input data length */
63*08b48e0bSAndroid Build Coastguard Worker total_execs, /* Total number of execs */
64*08b48e0bSAndroid Build Coastguard Worker exec_hangs, /* Total number of hangs */
65*08b48e0bSAndroid Build Coastguard Worker exec_tmout = EXEC_TIMEOUT; /* Exec timeout (ms) */
66*08b48e0bSAndroid Build Coastguard Worker
67*08b48e0bSAndroid Build Coastguard Worker static u64 orig_cksum; /* Original checksum */
68*08b48e0bSAndroid Build Coastguard Worker
69*08b48e0bSAndroid Build Coastguard Worker static u64 mem_limit = MEM_LIMIT; /* Memory limit (MB) */
70*08b48e0bSAndroid Build Coastguard Worker
71*08b48e0bSAndroid Build Coastguard Worker static bool edges_only, /* Ignore hit counts? */
72*08b48e0bSAndroid Build Coastguard Worker use_hex_offsets, /* Show hex offsets? */
73*08b48e0bSAndroid Build Coastguard Worker use_stdin = true; /* Use stdin for program input? */
74*08b48e0bSAndroid Build Coastguard Worker
75*08b48e0bSAndroid Build Coastguard Worker static volatile u8 stop_soon; /* Ctrl-C pressed? */
76*08b48e0bSAndroid Build Coastguard Worker
77*08b48e0bSAndroid Build Coastguard Worker static u8 *target_path;
78*08b48e0bSAndroid Build Coastguard Worker static u8 frida_mode;
79*08b48e0bSAndroid Build Coastguard Worker static u8 qemu_mode;
80*08b48e0bSAndroid Build Coastguard Worker static u8 cs_mode;
81*08b48e0bSAndroid Build Coastguard Worker static u32 map_size = MAP_SIZE;
82*08b48e0bSAndroid Build Coastguard Worker
83*08b48e0bSAndroid Build Coastguard Worker static afl_forkserver_t fsrv = {0}; /* The forkserver */
84*08b48e0bSAndroid Build Coastguard Worker
85*08b48e0bSAndroid Build Coastguard Worker /* Constants used for describing byte behavior. */
86*08b48e0bSAndroid Build Coastguard Worker
87*08b48e0bSAndroid Build Coastguard Worker #define RESP_NONE 0x00 /* Changing byte is a no-op. */
88*08b48e0bSAndroid Build Coastguard Worker #define RESP_MINOR 0x01 /* Some changes have no effect. */
89*08b48e0bSAndroid Build Coastguard Worker #define RESP_VARIABLE 0x02 /* Changes produce variable paths. */
90*08b48e0bSAndroid Build Coastguard Worker #define RESP_FIXED 0x03 /* Changes produce fixed patterns. */
91*08b48e0bSAndroid Build Coastguard Worker
92*08b48e0bSAndroid Build Coastguard Worker #define RESP_LEN 0x04 /* Potential length field */
93*08b48e0bSAndroid Build Coastguard Worker #define RESP_CKSUM 0x05 /* Potential checksum */
94*08b48e0bSAndroid Build Coastguard Worker #define RESP_SUSPECT 0x06 /* Potential "suspect" blob */
95*08b48e0bSAndroid Build Coastguard Worker
96*08b48e0bSAndroid Build Coastguard Worker /* Classify tuple counts. This is a slow & naive version, but good enough here.
97*08b48e0bSAndroid Build Coastguard Worker */
98*08b48e0bSAndroid Build Coastguard Worker
99*08b48e0bSAndroid Build Coastguard Worker static u8 count_class_lookup[256] = {
100*08b48e0bSAndroid Build Coastguard Worker
101*08b48e0bSAndroid Build Coastguard Worker [0] = 0,
102*08b48e0bSAndroid Build Coastguard Worker [1] = 1,
103*08b48e0bSAndroid Build Coastguard Worker [2] = 2,
104*08b48e0bSAndroid Build Coastguard Worker [3] = 4,
105*08b48e0bSAndroid Build Coastguard Worker [4 ... 7] = 8,
106*08b48e0bSAndroid Build Coastguard Worker [8 ... 15] = 16,
107*08b48e0bSAndroid Build Coastguard Worker [16 ... 31] = 32,
108*08b48e0bSAndroid Build Coastguard Worker [32 ... 127] = 64,
109*08b48e0bSAndroid Build Coastguard Worker [128 ... 255] = 128
110*08b48e0bSAndroid Build Coastguard Worker
111*08b48e0bSAndroid Build Coastguard Worker };
112*08b48e0bSAndroid Build Coastguard Worker
kill_child()113*08b48e0bSAndroid Build Coastguard Worker static void kill_child() {
114*08b48e0bSAndroid Build Coastguard Worker
115*08b48e0bSAndroid Build Coastguard Worker if (fsrv.child_pid > 0) {
116*08b48e0bSAndroid Build Coastguard Worker
117*08b48e0bSAndroid Build Coastguard Worker kill(fsrv.child_pid, fsrv.child_kill_signal);
118*08b48e0bSAndroid Build Coastguard Worker fsrv.child_pid = -1;
119*08b48e0bSAndroid Build Coastguard Worker
120*08b48e0bSAndroid Build Coastguard Worker }
121*08b48e0bSAndroid Build Coastguard Worker
122*08b48e0bSAndroid Build Coastguard Worker }
123*08b48e0bSAndroid Build Coastguard Worker
classify_counts(u8 * mem,u32 mem_size)124*08b48e0bSAndroid Build Coastguard Worker static void classify_counts(u8 *mem, u32 mem_size) {
125*08b48e0bSAndroid Build Coastguard Worker
126*08b48e0bSAndroid Build Coastguard Worker u32 i = mem_size;
127*08b48e0bSAndroid Build Coastguard Worker
128*08b48e0bSAndroid Build Coastguard Worker if (edges_only) {
129*08b48e0bSAndroid Build Coastguard Worker
130*08b48e0bSAndroid Build Coastguard Worker while (i--) {
131*08b48e0bSAndroid Build Coastguard Worker
132*08b48e0bSAndroid Build Coastguard Worker if (*mem) { *mem = 1; }
133*08b48e0bSAndroid Build Coastguard Worker mem++;
134*08b48e0bSAndroid Build Coastguard Worker
135*08b48e0bSAndroid Build Coastguard Worker }
136*08b48e0bSAndroid Build Coastguard Worker
137*08b48e0bSAndroid Build Coastguard Worker } else {
138*08b48e0bSAndroid Build Coastguard Worker
139*08b48e0bSAndroid Build Coastguard Worker while (i--) {
140*08b48e0bSAndroid Build Coastguard Worker
141*08b48e0bSAndroid Build Coastguard Worker *mem = count_class_lookup[*mem];
142*08b48e0bSAndroid Build Coastguard Worker mem++;
143*08b48e0bSAndroid Build Coastguard Worker
144*08b48e0bSAndroid Build Coastguard Worker }
145*08b48e0bSAndroid Build Coastguard Worker
146*08b48e0bSAndroid Build Coastguard Worker }
147*08b48e0bSAndroid Build Coastguard Worker
148*08b48e0bSAndroid Build Coastguard Worker }
149*08b48e0bSAndroid Build Coastguard Worker
150*08b48e0bSAndroid Build Coastguard Worker /* See if any bytes are set in the bitmap. */
151*08b48e0bSAndroid Build Coastguard Worker
anything_set(void)152*08b48e0bSAndroid Build Coastguard Worker static inline u8 anything_set(void) {
153*08b48e0bSAndroid Build Coastguard Worker
154*08b48e0bSAndroid Build Coastguard Worker u32 *ptr = (u32 *)fsrv.trace_bits;
155*08b48e0bSAndroid Build Coastguard Worker u32 i = (map_size >> 2);
156*08b48e0bSAndroid Build Coastguard Worker
157*08b48e0bSAndroid Build Coastguard Worker while (i--) {
158*08b48e0bSAndroid Build Coastguard Worker
159*08b48e0bSAndroid Build Coastguard Worker if (*(ptr++)) { return 1; }
160*08b48e0bSAndroid Build Coastguard Worker
161*08b48e0bSAndroid Build Coastguard Worker }
162*08b48e0bSAndroid Build Coastguard Worker
163*08b48e0bSAndroid Build Coastguard Worker return 0;
164*08b48e0bSAndroid Build Coastguard Worker
165*08b48e0bSAndroid Build Coastguard Worker }
166*08b48e0bSAndroid Build Coastguard Worker
167*08b48e0bSAndroid Build Coastguard Worker /* Get rid of temp files (atexit handler). */
168*08b48e0bSAndroid Build Coastguard Worker
at_exit_handler(void)169*08b48e0bSAndroid Build Coastguard Worker static void at_exit_handler(void) {
170*08b48e0bSAndroid Build Coastguard Worker
171*08b48e0bSAndroid Build Coastguard Worker unlink(fsrv.out_file); /* Ignore errors */
172*08b48e0bSAndroid Build Coastguard Worker
173*08b48e0bSAndroid Build Coastguard Worker }
174*08b48e0bSAndroid Build Coastguard Worker
175*08b48e0bSAndroid Build Coastguard Worker /* Read initial file. */
176*08b48e0bSAndroid Build Coastguard Worker
read_initial_file(void)177*08b48e0bSAndroid Build Coastguard Worker static void read_initial_file(void) {
178*08b48e0bSAndroid Build Coastguard Worker
179*08b48e0bSAndroid Build Coastguard Worker struct stat st;
180*08b48e0bSAndroid Build Coastguard Worker s32 fd = open(in_file, O_RDONLY);
181*08b48e0bSAndroid Build Coastguard Worker
182*08b48e0bSAndroid Build Coastguard Worker if (fd < 0) { PFATAL("Unable to open '%s'", in_file); }
183*08b48e0bSAndroid Build Coastguard Worker
184*08b48e0bSAndroid Build Coastguard Worker if (fstat(fd, &st) || !st.st_size) { FATAL("Zero-sized input file."); }
185*08b48e0bSAndroid Build Coastguard Worker
186*08b48e0bSAndroid Build Coastguard Worker if (st.st_size >= TMIN_MAX_FILE) {
187*08b48e0bSAndroid Build Coastguard Worker
188*08b48e0bSAndroid Build Coastguard Worker FATAL("Input file is too large (%ld MB max)", TMIN_MAX_FILE / 1024 / 1024);
189*08b48e0bSAndroid Build Coastguard Worker
190*08b48e0bSAndroid Build Coastguard Worker }
191*08b48e0bSAndroid Build Coastguard Worker
192*08b48e0bSAndroid Build Coastguard Worker in_len = st.st_size;
193*08b48e0bSAndroid Build Coastguard Worker in_data = ck_alloc_nozero(in_len);
194*08b48e0bSAndroid Build Coastguard Worker
195*08b48e0bSAndroid Build Coastguard Worker ck_read(fd, in_data, in_len, in_file);
196*08b48e0bSAndroid Build Coastguard Worker
197*08b48e0bSAndroid Build Coastguard Worker close(fd);
198*08b48e0bSAndroid Build Coastguard Worker
199*08b48e0bSAndroid Build Coastguard Worker OKF("Read %u byte%s from '%s'.", in_len, in_len == 1 ? "" : "s", in_file);
200*08b48e0bSAndroid Build Coastguard Worker
201*08b48e0bSAndroid Build Coastguard Worker }
202*08b48e0bSAndroid Build Coastguard Worker
203*08b48e0bSAndroid Build Coastguard Worker /* Execute target application. Returns exec checksum, or 0 if program
204*08b48e0bSAndroid Build Coastguard Worker times out. */
205*08b48e0bSAndroid Build Coastguard Worker
analyze_run_target(u8 * mem,u32 len,u8 first_run)206*08b48e0bSAndroid Build Coastguard Worker static u64 analyze_run_target(u8 *mem, u32 len, u8 first_run) {
207*08b48e0bSAndroid Build Coastguard Worker
208*08b48e0bSAndroid Build Coastguard Worker afl_fsrv_write_to_testcase(&fsrv, mem, len);
209*08b48e0bSAndroid Build Coastguard Worker fsrv_run_result_t ret = afl_fsrv_run_target(&fsrv, exec_tmout, &stop_soon);
210*08b48e0bSAndroid Build Coastguard Worker
211*08b48e0bSAndroid Build Coastguard Worker if (ret == FSRV_RUN_ERROR) {
212*08b48e0bSAndroid Build Coastguard Worker
213*08b48e0bSAndroid Build Coastguard Worker FATAL("Error in forkserver");
214*08b48e0bSAndroid Build Coastguard Worker
215*08b48e0bSAndroid Build Coastguard Worker } else if (ret == FSRV_RUN_NOINST) {
216*08b48e0bSAndroid Build Coastguard Worker
217*08b48e0bSAndroid Build Coastguard Worker FATAL("Target not instrumented");
218*08b48e0bSAndroid Build Coastguard Worker
219*08b48e0bSAndroid Build Coastguard Worker } else if (ret == FSRV_RUN_NOBITS) {
220*08b48e0bSAndroid Build Coastguard Worker
221*08b48e0bSAndroid Build Coastguard Worker FATAL("Failed to run target");
222*08b48e0bSAndroid Build Coastguard Worker
223*08b48e0bSAndroid Build Coastguard Worker }
224*08b48e0bSAndroid Build Coastguard Worker
225*08b48e0bSAndroid Build Coastguard Worker classify_counts(fsrv.trace_bits, fsrv.map_size);
226*08b48e0bSAndroid Build Coastguard Worker total_execs++;
227*08b48e0bSAndroid Build Coastguard Worker
228*08b48e0bSAndroid Build Coastguard Worker if (stop_soon) {
229*08b48e0bSAndroid Build Coastguard Worker
230*08b48e0bSAndroid Build Coastguard Worker SAYF(cRST cLRD "\n+++ Analysis aborted by user +++\n" cRST);
231*08b48e0bSAndroid Build Coastguard Worker exit(1);
232*08b48e0bSAndroid Build Coastguard Worker
233*08b48e0bSAndroid Build Coastguard Worker }
234*08b48e0bSAndroid Build Coastguard Worker
235*08b48e0bSAndroid Build Coastguard Worker /* Always discard inputs that time out. */
236*08b48e0bSAndroid Build Coastguard Worker
237*08b48e0bSAndroid Build Coastguard Worker if (fsrv.last_run_timed_out) {
238*08b48e0bSAndroid Build Coastguard Worker
239*08b48e0bSAndroid Build Coastguard Worker exec_hangs++;
240*08b48e0bSAndroid Build Coastguard Worker return 0;
241*08b48e0bSAndroid Build Coastguard Worker
242*08b48e0bSAndroid Build Coastguard Worker }
243*08b48e0bSAndroid Build Coastguard Worker
244*08b48e0bSAndroid Build Coastguard Worker u64 cksum = hash64(fsrv.trace_bits, fsrv.map_size, HASH_CONST);
245*08b48e0bSAndroid Build Coastguard Worker
246*08b48e0bSAndroid Build Coastguard Worker if (ret == FSRV_RUN_CRASH) {
247*08b48e0bSAndroid Build Coastguard Worker
248*08b48e0bSAndroid Build Coastguard Worker /* We don't actually care if the target is crashing or not,
249*08b48e0bSAndroid Build Coastguard Worker except that when it does, the checksum should be different. */
250*08b48e0bSAndroid Build Coastguard Worker
251*08b48e0bSAndroid Build Coastguard Worker cksum ^= 0xffffffff;
252*08b48e0bSAndroid Build Coastguard Worker
253*08b48e0bSAndroid Build Coastguard Worker }
254*08b48e0bSAndroid Build Coastguard Worker
255*08b48e0bSAndroid Build Coastguard Worker if (first_run) { orig_cksum = cksum; }
256*08b48e0bSAndroid Build Coastguard Worker
257*08b48e0bSAndroid Build Coastguard Worker return cksum;
258*08b48e0bSAndroid Build Coastguard Worker
259*08b48e0bSAndroid Build Coastguard Worker }
260*08b48e0bSAndroid Build Coastguard Worker
261*08b48e0bSAndroid Build Coastguard Worker #ifdef USE_COLOR
262*08b48e0bSAndroid Build Coastguard Worker
263*08b48e0bSAndroid Build Coastguard Worker /* Helper function to display a human-readable character. */
264*08b48e0bSAndroid Build Coastguard Worker
show_char(u8 val)265*08b48e0bSAndroid Build Coastguard Worker static void show_char(u8 val) {
266*08b48e0bSAndroid Build Coastguard Worker
267*08b48e0bSAndroid Build Coastguard Worker switch (val) {
268*08b48e0bSAndroid Build Coastguard Worker
269*08b48e0bSAndroid Build Coastguard Worker case 0 ... 32:
270*08b48e0bSAndroid Build Coastguard Worker case 127 ... 255:
271*08b48e0bSAndroid Build Coastguard Worker SAYF("#%02x", val);
272*08b48e0bSAndroid Build Coastguard Worker break;
273*08b48e0bSAndroid Build Coastguard Worker
274*08b48e0bSAndroid Build Coastguard Worker default:
275*08b48e0bSAndroid Build Coastguard Worker SAYF(" %c ", val);
276*08b48e0bSAndroid Build Coastguard Worker
277*08b48e0bSAndroid Build Coastguard Worker }
278*08b48e0bSAndroid Build Coastguard Worker
279*08b48e0bSAndroid Build Coastguard Worker }
280*08b48e0bSAndroid Build Coastguard Worker
281*08b48e0bSAndroid Build Coastguard Worker /* Show the legend */
282*08b48e0bSAndroid Build Coastguard Worker
show_legend(void)283*08b48e0bSAndroid Build Coastguard Worker static void show_legend(void) {
284*08b48e0bSAndroid Build Coastguard Worker
285*08b48e0bSAndroid Build Coastguard Worker SAYF(" " cLGR bgGRA " 01 " cRST " - no-op block " cBLK bgLGN
286*08b48e0bSAndroid Build Coastguard Worker " 01 " cRST
287*08b48e0bSAndroid Build Coastguard Worker " - suspected length field\n"
288*08b48e0bSAndroid Build Coastguard Worker " " cBRI bgGRA " 01 " cRST " - superficial content " cBLK bgYEL
289*08b48e0bSAndroid Build Coastguard Worker " 01 " cRST
290*08b48e0bSAndroid Build Coastguard Worker " - suspected cksum or magic int\n"
291*08b48e0bSAndroid Build Coastguard Worker " " cBLK bgCYA " 01 " cRST " - critical stream " cBLK bgLRD
292*08b48e0bSAndroid Build Coastguard Worker " 01 " cRST
293*08b48e0bSAndroid Build Coastguard Worker " - suspected checksummed block\n"
294*08b48e0bSAndroid Build Coastguard Worker " " cBLK bgMGN " 01 " cRST " - \"magic value\" section\n\n");
295*08b48e0bSAndroid Build Coastguard Worker
296*08b48e0bSAndroid Build Coastguard Worker }
297*08b48e0bSAndroid Build Coastguard Worker
298*08b48e0bSAndroid Build Coastguard Worker #endif /* USE_COLOR */
299*08b48e0bSAndroid Build Coastguard Worker
300*08b48e0bSAndroid Build Coastguard Worker /* Interpret and report a pattern in the input file. */
301*08b48e0bSAndroid Build Coastguard Worker
dump_hex(u32 len,u8 * b_data)302*08b48e0bSAndroid Build Coastguard Worker static void dump_hex(u32 len, u8 *b_data) {
303*08b48e0bSAndroid Build Coastguard Worker
304*08b48e0bSAndroid Build Coastguard Worker u32 i;
305*08b48e0bSAndroid Build Coastguard Worker
306*08b48e0bSAndroid Build Coastguard Worker for (i = 0; i < len; i++) {
307*08b48e0bSAndroid Build Coastguard Worker
308*08b48e0bSAndroid Build Coastguard Worker #ifdef USE_COLOR
309*08b48e0bSAndroid Build Coastguard Worker u32 rlen = 1, off;
310*08b48e0bSAndroid Build Coastguard Worker #else
311*08b48e0bSAndroid Build Coastguard Worker u32 rlen = 1;
312*08b48e0bSAndroid Build Coastguard Worker #endif /* ^USE_COLOR */
313*08b48e0bSAndroid Build Coastguard Worker
314*08b48e0bSAndroid Build Coastguard Worker u8 rtype = b_data[i] & 0x0f;
315*08b48e0bSAndroid Build Coastguard Worker
316*08b48e0bSAndroid Build Coastguard Worker /* Look ahead to determine the length of run. */
317*08b48e0bSAndroid Build Coastguard Worker
318*08b48e0bSAndroid Build Coastguard Worker while (i + rlen < len && (b_data[i] >> 7) == (b_data[i + rlen] >> 7)) {
319*08b48e0bSAndroid Build Coastguard Worker
320*08b48e0bSAndroid Build Coastguard Worker if (rtype < (b_data[i + rlen] & 0x0f)) {
321*08b48e0bSAndroid Build Coastguard Worker
322*08b48e0bSAndroid Build Coastguard Worker rtype = b_data[i + rlen] & 0x0f;
323*08b48e0bSAndroid Build Coastguard Worker
324*08b48e0bSAndroid Build Coastguard Worker }
325*08b48e0bSAndroid Build Coastguard Worker
326*08b48e0bSAndroid Build Coastguard Worker rlen++;
327*08b48e0bSAndroid Build Coastguard Worker
328*08b48e0bSAndroid Build Coastguard Worker }
329*08b48e0bSAndroid Build Coastguard Worker
330*08b48e0bSAndroid Build Coastguard Worker /* Try to do some further classification based on length & value. */
331*08b48e0bSAndroid Build Coastguard Worker
332*08b48e0bSAndroid Build Coastguard Worker if (rtype == RESP_FIXED) {
333*08b48e0bSAndroid Build Coastguard Worker
334*08b48e0bSAndroid Build Coastguard Worker switch (rlen) {
335*08b48e0bSAndroid Build Coastguard Worker
336*08b48e0bSAndroid Build Coastguard Worker case 2: {
337*08b48e0bSAndroid Build Coastguard Worker
338*08b48e0bSAndroid Build Coastguard Worker u16 val = *(u16 *)(in_data + i);
339*08b48e0bSAndroid Build Coastguard Worker
340*08b48e0bSAndroid Build Coastguard Worker /* Small integers may be length fields. */
341*08b48e0bSAndroid Build Coastguard Worker
342*08b48e0bSAndroid Build Coastguard Worker if (val && (val <= in_len || SWAP16(val) <= in_len)) {
343*08b48e0bSAndroid Build Coastguard Worker
344*08b48e0bSAndroid Build Coastguard Worker rtype = RESP_LEN;
345*08b48e0bSAndroid Build Coastguard Worker break;
346*08b48e0bSAndroid Build Coastguard Worker
347*08b48e0bSAndroid Build Coastguard Worker }
348*08b48e0bSAndroid Build Coastguard Worker
349*08b48e0bSAndroid Build Coastguard Worker /* Uniform integers may be checksums. */
350*08b48e0bSAndroid Build Coastguard Worker
351*08b48e0bSAndroid Build Coastguard Worker if (val && abs(in_data[i] - in_data[i + 1]) > 32) {
352*08b48e0bSAndroid Build Coastguard Worker
353*08b48e0bSAndroid Build Coastguard Worker rtype = RESP_CKSUM;
354*08b48e0bSAndroid Build Coastguard Worker break;
355*08b48e0bSAndroid Build Coastguard Worker
356*08b48e0bSAndroid Build Coastguard Worker }
357*08b48e0bSAndroid Build Coastguard Worker
358*08b48e0bSAndroid Build Coastguard Worker break;
359*08b48e0bSAndroid Build Coastguard Worker
360*08b48e0bSAndroid Build Coastguard Worker }
361*08b48e0bSAndroid Build Coastguard Worker
362*08b48e0bSAndroid Build Coastguard Worker case 4: {
363*08b48e0bSAndroid Build Coastguard Worker
364*08b48e0bSAndroid Build Coastguard Worker u32 val = *(u32 *)(in_data + i);
365*08b48e0bSAndroid Build Coastguard Worker
366*08b48e0bSAndroid Build Coastguard Worker /* Small integers may be length fields. */
367*08b48e0bSAndroid Build Coastguard Worker
368*08b48e0bSAndroid Build Coastguard Worker if (val && (val <= in_len || SWAP32(val) <= in_len)) {
369*08b48e0bSAndroid Build Coastguard Worker
370*08b48e0bSAndroid Build Coastguard Worker rtype = RESP_LEN;
371*08b48e0bSAndroid Build Coastguard Worker break;
372*08b48e0bSAndroid Build Coastguard Worker
373*08b48e0bSAndroid Build Coastguard Worker }
374*08b48e0bSAndroid Build Coastguard Worker
375*08b48e0bSAndroid Build Coastguard Worker /* Uniform integers may be checksums. */
376*08b48e0bSAndroid Build Coastguard Worker
377*08b48e0bSAndroid Build Coastguard Worker if (val && (in_data[i] >> 7 != in_data[i + 1] >> 7 ||
378*08b48e0bSAndroid Build Coastguard Worker in_data[i] >> 7 != in_data[i + 2] >> 7 ||
379*08b48e0bSAndroid Build Coastguard Worker in_data[i] >> 7 != in_data[i + 3] >> 7)) {
380*08b48e0bSAndroid Build Coastguard Worker
381*08b48e0bSAndroid Build Coastguard Worker rtype = RESP_CKSUM;
382*08b48e0bSAndroid Build Coastguard Worker break;
383*08b48e0bSAndroid Build Coastguard Worker
384*08b48e0bSAndroid Build Coastguard Worker }
385*08b48e0bSAndroid Build Coastguard Worker
386*08b48e0bSAndroid Build Coastguard Worker break;
387*08b48e0bSAndroid Build Coastguard Worker
388*08b48e0bSAndroid Build Coastguard Worker }
389*08b48e0bSAndroid Build Coastguard Worker
390*08b48e0bSAndroid Build Coastguard Worker case 1:
391*08b48e0bSAndroid Build Coastguard Worker case 3:
392*08b48e0bSAndroid Build Coastguard Worker case 5 ... MAX_AUTO_EXTRA - 1:
393*08b48e0bSAndroid Build Coastguard Worker break;
394*08b48e0bSAndroid Build Coastguard Worker
395*08b48e0bSAndroid Build Coastguard Worker default:
396*08b48e0bSAndroid Build Coastguard Worker rtype = RESP_SUSPECT;
397*08b48e0bSAndroid Build Coastguard Worker
398*08b48e0bSAndroid Build Coastguard Worker }
399*08b48e0bSAndroid Build Coastguard Worker
400*08b48e0bSAndroid Build Coastguard Worker }
401*08b48e0bSAndroid Build Coastguard Worker
402*08b48e0bSAndroid Build Coastguard Worker /* Print out the entire run. */
403*08b48e0bSAndroid Build Coastguard Worker
404*08b48e0bSAndroid Build Coastguard Worker #ifdef USE_COLOR
405*08b48e0bSAndroid Build Coastguard Worker
406*08b48e0bSAndroid Build Coastguard Worker for (off = 0; off < rlen; off++) {
407*08b48e0bSAndroid Build Coastguard Worker
408*08b48e0bSAndroid Build Coastguard Worker /* Every 16 digits, display offset. */
409*08b48e0bSAndroid Build Coastguard Worker
410*08b48e0bSAndroid Build Coastguard Worker if (!((i + off) % 16)) {
411*08b48e0bSAndroid Build Coastguard Worker
412*08b48e0bSAndroid Build Coastguard Worker if (off) { SAYF(cRST cLCY ">"); }
413*08b48e0bSAndroid Build Coastguard Worker
414*08b48e0bSAndroid Build Coastguard Worker if (use_hex_offsets) {
415*08b48e0bSAndroid Build Coastguard Worker
416*08b48e0bSAndroid Build Coastguard Worker SAYF(cRST cGRA "%s[%06x] " cRST, (i + off) ? "\n" : "", i + off);
417*08b48e0bSAndroid Build Coastguard Worker
418*08b48e0bSAndroid Build Coastguard Worker } else {
419*08b48e0bSAndroid Build Coastguard Worker
420*08b48e0bSAndroid Build Coastguard Worker SAYF(cRST cGRA "%s[%06u] " cRST, (i + off) ? "\n" : "", i + off);
421*08b48e0bSAndroid Build Coastguard Worker
422*08b48e0bSAndroid Build Coastguard Worker }
423*08b48e0bSAndroid Build Coastguard Worker
424*08b48e0bSAndroid Build Coastguard Worker }
425*08b48e0bSAndroid Build Coastguard Worker
426*08b48e0bSAndroid Build Coastguard Worker switch (rtype) {
427*08b48e0bSAndroid Build Coastguard Worker
428*08b48e0bSAndroid Build Coastguard Worker case RESP_NONE:
429*08b48e0bSAndroid Build Coastguard Worker SAYF(cLGR bgGRA);
430*08b48e0bSAndroid Build Coastguard Worker break;
431*08b48e0bSAndroid Build Coastguard Worker case RESP_MINOR:
432*08b48e0bSAndroid Build Coastguard Worker SAYF(cBRI bgGRA);
433*08b48e0bSAndroid Build Coastguard Worker break;
434*08b48e0bSAndroid Build Coastguard Worker case RESP_VARIABLE:
435*08b48e0bSAndroid Build Coastguard Worker SAYF(cBLK bgCYA);
436*08b48e0bSAndroid Build Coastguard Worker break;
437*08b48e0bSAndroid Build Coastguard Worker case RESP_FIXED:
438*08b48e0bSAndroid Build Coastguard Worker SAYF(cBLK bgMGN);
439*08b48e0bSAndroid Build Coastguard Worker break;
440*08b48e0bSAndroid Build Coastguard Worker case RESP_LEN:
441*08b48e0bSAndroid Build Coastguard Worker SAYF(cBLK bgLGN);
442*08b48e0bSAndroid Build Coastguard Worker break;
443*08b48e0bSAndroid Build Coastguard Worker case RESP_CKSUM:
444*08b48e0bSAndroid Build Coastguard Worker SAYF(cBLK bgYEL);
445*08b48e0bSAndroid Build Coastguard Worker break;
446*08b48e0bSAndroid Build Coastguard Worker case RESP_SUSPECT:
447*08b48e0bSAndroid Build Coastguard Worker SAYF(cBLK bgLRD);
448*08b48e0bSAndroid Build Coastguard Worker break;
449*08b48e0bSAndroid Build Coastguard Worker
450*08b48e0bSAndroid Build Coastguard Worker }
451*08b48e0bSAndroid Build Coastguard Worker
452*08b48e0bSAndroid Build Coastguard Worker show_char(in_data[i + off]);
453*08b48e0bSAndroid Build Coastguard Worker
454*08b48e0bSAndroid Build Coastguard Worker if (off != rlen - 1 && (i + off + 1) % 16) {
455*08b48e0bSAndroid Build Coastguard Worker
456*08b48e0bSAndroid Build Coastguard Worker SAYF(" ");
457*08b48e0bSAndroid Build Coastguard Worker
458*08b48e0bSAndroid Build Coastguard Worker } else {
459*08b48e0bSAndroid Build Coastguard Worker
460*08b48e0bSAndroid Build Coastguard Worker SAYF(cRST " ");
461*08b48e0bSAndroid Build Coastguard Worker
462*08b48e0bSAndroid Build Coastguard Worker }
463*08b48e0bSAndroid Build Coastguard Worker
464*08b48e0bSAndroid Build Coastguard Worker }
465*08b48e0bSAndroid Build Coastguard Worker
466*08b48e0bSAndroid Build Coastguard Worker #else
467*08b48e0bSAndroid Build Coastguard Worker
468*08b48e0bSAndroid Build Coastguard Worker if (use_hex_offsets)
469*08b48e0bSAndroid Build Coastguard Worker SAYF(" Offset %x, length %u: ", i, rlen);
470*08b48e0bSAndroid Build Coastguard Worker else
471*08b48e0bSAndroid Build Coastguard Worker SAYF(" Offset %u, length %u: ", i, rlen);
472*08b48e0bSAndroid Build Coastguard Worker
473*08b48e0bSAndroid Build Coastguard Worker switch (rtype) {
474*08b48e0bSAndroid Build Coastguard Worker
475*08b48e0bSAndroid Build Coastguard Worker case RESP_NONE:
476*08b48e0bSAndroid Build Coastguard Worker SAYF("no-op block\n");
477*08b48e0bSAndroid Build Coastguard Worker break;
478*08b48e0bSAndroid Build Coastguard Worker case RESP_MINOR:
479*08b48e0bSAndroid Build Coastguard Worker SAYF("superficial content\n");
480*08b48e0bSAndroid Build Coastguard Worker break;
481*08b48e0bSAndroid Build Coastguard Worker case RESP_VARIABLE:
482*08b48e0bSAndroid Build Coastguard Worker SAYF("critical stream\n");
483*08b48e0bSAndroid Build Coastguard Worker break;
484*08b48e0bSAndroid Build Coastguard Worker case RESP_FIXED:
485*08b48e0bSAndroid Build Coastguard Worker SAYF("\"magic value\" section\n");
486*08b48e0bSAndroid Build Coastguard Worker break;
487*08b48e0bSAndroid Build Coastguard Worker case RESP_LEN:
488*08b48e0bSAndroid Build Coastguard Worker SAYF("suspected length field\n");
489*08b48e0bSAndroid Build Coastguard Worker break;
490*08b48e0bSAndroid Build Coastguard Worker case RESP_CKSUM:
491*08b48e0bSAndroid Build Coastguard Worker SAYF("suspected cksum or magic int\n");
492*08b48e0bSAndroid Build Coastguard Worker break;
493*08b48e0bSAndroid Build Coastguard Worker case RESP_SUSPECT:
494*08b48e0bSAndroid Build Coastguard Worker SAYF("suspected checksummed block\n");
495*08b48e0bSAndroid Build Coastguard Worker break;
496*08b48e0bSAndroid Build Coastguard Worker
497*08b48e0bSAndroid Build Coastguard Worker }
498*08b48e0bSAndroid Build Coastguard Worker
499*08b48e0bSAndroid Build Coastguard Worker #endif /* ^USE_COLOR */
500*08b48e0bSAndroid Build Coastguard Worker
501*08b48e0bSAndroid Build Coastguard Worker i += rlen - 1;
502*08b48e0bSAndroid Build Coastguard Worker
503*08b48e0bSAndroid Build Coastguard Worker }
504*08b48e0bSAndroid Build Coastguard Worker
505*08b48e0bSAndroid Build Coastguard Worker #ifdef USE_COLOR
506*08b48e0bSAndroid Build Coastguard Worker SAYF(cRST "\n");
507*08b48e0bSAndroid Build Coastguard Worker #endif /* USE_COLOR */
508*08b48e0bSAndroid Build Coastguard Worker
509*08b48e0bSAndroid Build Coastguard Worker }
510*08b48e0bSAndroid Build Coastguard Worker
511*08b48e0bSAndroid Build Coastguard Worker /* Actually analyze! */
512*08b48e0bSAndroid Build Coastguard Worker
analyze()513*08b48e0bSAndroid Build Coastguard Worker static void analyze() {
514*08b48e0bSAndroid Build Coastguard Worker
515*08b48e0bSAndroid Build Coastguard Worker u32 i;
516*08b48e0bSAndroid Build Coastguard Worker u32 boring_len = 0, prev_xff = 0, prev_x01 = 0, prev_s10 = 0, prev_a10 = 0;
517*08b48e0bSAndroid Build Coastguard Worker
518*08b48e0bSAndroid Build Coastguard Worker u8 *b_data = ck_alloc(in_len + 1);
519*08b48e0bSAndroid Build Coastguard Worker u8 seq_byte = 0;
520*08b48e0bSAndroid Build Coastguard Worker
521*08b48e0bSAndroid Build Coastguard Worker b_data[in_len] = 0xff; /* Intentional terminator. */
522*08b48e0bSAndroid Build Coastguard Worker
523*08b48e0bSAndroid Build Coastguard Worker ACTF("Analyzing input file (this may take a while)...\n");
524*08b48e0bSAndroid Build Coastguard Worker
525*08b48e0bSAndroid Build Coastguard Worker #ifdef USE_COLOR
526*08b48e0bSAndroid Build Coastguard Worker show_legend();
527*08b48e0bSAndroid Build Coastguard Worker #endif /* USE_COLOR */
528*08b48e0bSAndroid Build Coastguard Worker
529*08b48e0bSAndroid Build Coastguard Worker for (i = 0; i < in_len; i++) {
530*08b48e0bSAndroid Build Coastguard Worker
531*08b48e0bSAndroid Build Coastguard Worker u64 xor_ff, xor_01, sub_10, add_10;
532*08b48e0bSAndroid Build Coastguard Worker u8 xff_orig, x01_orig, s10_orig, a10_orig;
533*08b48e0bSAndroid Build Coastguard Worker
534*08b48e0bSAndroid Build Coastguard Worker /* Perform walking byte adjustments across the file. We perform four
535*08b48e0bSAndroid Build Coastguard Worker operations designed to elicit some response from the underlying
536*08b48e0bSAndroid Build Coastguard Worker code. */
537*08b48e0bSAndroid Build Coastguard Worker
538*08b48e0bSAndroid Build Coastguard Worker in_data[i] ^= 0xff;
539*08b48e0bSAndroid Build Coastguard Worker xor_ff = analyze_run_target(in_data, in_len, 0);
540*08b48e0bSAndroid Build Coastguard Worker
541*08b48e0bSAndroid Build Coastguard Worker in_data[i] ^= 0xfe;
542*08b48e0bSAndroid Build Coastguard Worker xor_01 = analyze_run_target(in_data, in_len, 0);
543*08b48e0bSAndroid Build Coastguard Worker
544*08b48e0bSAndroid Build Coastguard Worker in_data[i] = (in_data[i] ^ 0x01) - 0x10;
545*08b48e0bSAndroid Build Coastguard Worker sub_10 = analyze_run_target(in_data, in_len, 0);
546*08b48e0bSAndroid Build Coastguard Worker
547*08b48e0bSAndroid Build Coastguard Worker in_data[i] += 0x20;
548*08b48e0bSAndroid Build Coastguard Worker add_10 = analyze_run_target(in_data, in_len, 0);
549*08b48e0bSAndroid Build Coastguard Worker in_data[i] -= 0x10;
550*08b48e0bSAndroid Build Coastguard Worker
551*08b48e0bSAndroid Build Coastguard Worker /* Classify current behavior. */
552*08b48e0bSAndroid Build Coastguard Worker
553*08b48e0bSAndroid Build Coastguard Worker xff_orig = (xor_ff == orig_cksum);
554*08b48e0bSAndroid Build Coastguard Worker x01_orig = (xor_01 == orig_cksum);
555*08b48e0bSAndroid Build Coastguard Worker s10_orig = (sub_10 == orig_cksum);
556*08b48e0bSAndroid Build Coastguard Worker a10_orig = (add_10 == orig_cksum);
557*08b48e0bSAndroid Build Coastguard Worker
558*08b48e0bSAndroid Build Coastguard Worker if (xff_orig && x01_orig && s10_orig && a10_orig) {
559*08b48e0bSAndroid Build Coastguard Worker
560*08b48e0bSAndroid Build Coastguard Worker b_data[i] = RESP_NONE;
561*08b48e0bSAndroid Build Coastguard Worker boring_len++;
562*08b48e0bSAndroid Build Coastguard Worker
563*08b48e0bSAndroid Build Coastguard Worker } else if (xff_orig || x01_orig || s10_orig || a10_orig) {
564*08b48e0bSAndroid Build Coastguard Worker
565*08b48e0bSAndroid Build Coastguard Worker b_data[i] = RESP_MINOR;
566*08b48e0bSAndroid Build Coastguard Worker boring_len++;
567*08b48e0bSAndroid Build Coastguard Worker
568*08b48e0bSAndroid Build Coastguard Worker } else if (xor_ff == xor_01 && xor_ff == sub_10 && xor_ff == add_10) {
569*08b48e0bSAndroid Build Coastguard Worker
570*08b48e0bSAndroid Build Coastguard Worker b_data[i] = RESP_FIXED;
571*08b48e0bSAndroid Build Coastguard Worker
572*08b48e0bSAndroid Build Coastguard Worker } else {
573*08b48e0bSAndroid Build Coastguard Worker
574*08b48e0bSAndroid Build Coastguard Worker b_data[i] = RESP_VARIABLE;
575*08b48e0bSAndroid Build Coastguard Worker
576*08b48e0bSAndroid Build Coastguard Worker }
577*08b48e0bSAndroid Build Coastguard Worker
578*08b48e0bSAndroid Build Coastguard Worker /* When all checksums change, flip most significant bit of b_data. */
579*08b48e0bSAndroid Build Coastguard Worker
580*08b48e0bSAndroid Build Coastguard Worker if (prev_xff != xor_ff && prev_x01 != xor_01 && prev_s10 != sub_10 &&
581*08b48e0bSAndroid Build Coastguard Worker prev_a10 != add_10) {
582*08b48e0bSAndroid Build Coastguard Worker
583*08b48e0bSAndroid Build Coastguard Worker seq_byte ^= 0x80;
584*08b48e0bSAndroid Build Coastguard Worker
585*08b48e0bSAndroid Build Coastguard Worker }
586*08b48e0bSAndroid Build Coastguard Worker
587*08b48e0bSAndroid Build Coastguard Worker b_data[i] |= seq_byte;
588*08b48e0bSAndroid Build Coastguard Worker
589*08b48e0bSAndroid Build Coastguard Worker prev_xff = xor_ff;
590*08b48e0bSAndroid Build Coastguard Worker prev_x01 = xor_01;
591*08b48e0bSAndroid Build Coastguard Worker prev_s10 = sub_10;
592*08b48e0bSAndroid Build Coastguard Worker prev_a10 = add_10;
593*08b48e0bSAndroid Build Coastguard Worker
594*08b48e0bSAndroid Build Coastguard Worker }
595*08b48e0bSAndroid Build Coastguard Worker
596*08b48e0bSAndroid Build Coastguard Worker dump_hex(in_len, b_data);
597*08b48e0bSAndroid Build Coastguard Worker
598*08b48e0bSAndroid Build Coastguard Worker SAYF("\n");
599*08b48e0bSAndroid Build Coastguard Worker
600*08b48e0bSAndroid Build Coastguard Worker OKF("Analysis complete. Interesting bits: %0.02f%% of the input file.",
601*08b48e0bSAndroid Build Coastguard Worker 100.0 - ((double)boring_len * 100) / in_len);
602*08b48e0bSAndroid Build Coastguard Worker
603*08b48e0bSAndroid Build Coastguard Worker if (exec_hangs) {
604*08b48e0bSAndroid Build Coastguard Worker
605*08b48e0bSAndroid Build Coastguard Worker WARNF(cLRD "Encountered %u timeouts - results may be skewed." cRST,
606*08b48e0bSAndroid Build Coastguard Worker exec_hangs);
607*08b48e0bSAndroid Build Coastguard Worker
608*08b48e0bSAndroid Build Coastguard Worker }
609*08b48e0bSAndroid Build Coastguard Worker
610*08b48e0bSAndroid Build Coastguard Worker ck_free(b_data);
611*08b48e0bSAndroid Build Coastguard Worker
612*08b48e0bSAndroid Build Coastguard Worker }
613*08b48e0bSAndroid Build Coastguard Worker
614*08b48e0bSAndroid Build Coastguard Worker /* Handle Ctrl-C and the like. */
615*08b48e0bSAndroid Build Coastguard Worker
handle_stop_sig(int sig)616*08b48e0bSAndroid Build Coastguard Worker static void handle_stop_sig(int sig) {
617*08b48e0bSAndroid Build Coastguard Worker
618*08b48e0bSAndroid Build Coastguard Worker (void)sig;
619*08b48e0bSAndroid Build Coastguard Worker stop_soon = 1;
620*08b48e0bSAndroid Build Coastguard Worker
621*08b48e0bSAndroid Build Coastguard Worker afl_fsrv_killall();
622*08b48e0bSAndroid Build Coastguard Worker
623*08b48e0bSAndroid Build Coastguard Worker }
624*08b48e0bSAndroid Build Coastguard Worker
625*08b48e0bSAndroid Build Coastguard Worker /* Do basic preparations - persistent fds, filenames, etc. */
626*08b48e0bSAndroid Build Coastguard Worker
set_up_environment(char ** argv)627*08b48e0bSAndroid Build Coastguard Worker static void set_up_environment(char **argv) {
628*08b48e0bSAndroid Build Coastguard Worker
629*08b48e0bSAndroid Build Coastguard Worker u8 *x;
630*08b48e0bSAndroid Build Coastguard Worker char *afl_preload;
631*08b48e0bSAndroid Build Coastguard Worker char *frida_afl_preload = NULL;
632*08b48e0bSAndroid Build Coastguard Worker
633*08b48e0bSAndroid Build Coastguard Worker fsrv.dev_null_fd = open("/dev/null", O_RDWR);
634*08b48e0bSAndroid Build Coastguard Worker if (fsrv.dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); }
635*08b48e0bSAndroid Build Coastguard Worker
636*08b48e0bSAndroid Build Coastguard Worker if (!fsrv.out_file) {
637*08b48e0bSAndroid Build Coastguard Worker
638*08b48e0bSAndroid Build Coastguard Worker u8 *use_dir = ".";
639*08b48e0bSAndroid Build Coastguard Worker
640*08b48e0bSAndroid Build Coastguard Worker if (access(use_dir, R_OK | W_OK | X_OK)) {
641*08b48e0bSAndroid Build Coastguard Worker
642*08b48e0bSAndroid Build Coastguard Worker use_dir = get_afl_env("TMPDIR");
643*08b48e0bSAndroid Build Coastguard Worker if (!use_dir) { use_dir = "/tmp"; }
644*08b48e0bSAndroid Build Coastguard Worker
645*08b48e0bSAndroid Build Coastguard Worker }
646*08b48e0bSAndroid Build Coastguard Worker
647*08b48e0bSAndroid Build Coastguard Worker fsrv.out_file =
648*08b48e0bSAndroid Build Coastguard Worker alloc_printf("%s/.afl-analyze-temp-%u", use_dir, (u32)getpid());
649*08b48e0bSAndroid Build Coastguard Worker
650*08b48e0bSAndroid Build Coastguard Worker }
651*08b48e0bSAndroid Build Coastguard Worker
652*08b48e0bSAndroid Build Coastguard Worker unlink(fsrv.out_file);
653*08b48e0bSAndroid Build Coastguard Worker fsrv.out_fd =
654*08b48e0bSAndroid Build Coastguard Worker open(fsrv.out_file, O_RDWR | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
655*08b48e0bSAndroid Build Coastguard Worker
656*08b48e0bSAndroid Build Coastguard Worker if (fsrv.out_fd < 0) { PFATAL("Unable to create '%s'", fsrv.out_file); }
657*08b48e0bSAndroid Build Coastguard Worker
658*08b48e0bSAndroid Build Coastguard Worker /* Set sane defaults... */
659*08b48e0bSAndroid Build Coastguard Worker x = get_afl_env("MSAN_OPTIONS");
660*08b48e0bSAndroid Build Coastguard Worker
661*08b48e0bSAndroid Build Coastguard Worker if (x) {
662*08b48e0bSAndroid Build Coastguard Worker
663*08b48e0bSAndroid Build Coastguard Worker if (!strstr(x, "exit_code=" STRINGIFY(MSAN_ERROR))) {
664*08b48e0bSAndroid Build Coastguard Worker
665*08b48e0bSAndroid Build Coastguard Worker FATAL("Custom MSAN_OPTIONS set without exit_code=" STRINGIFY(
666*08b48e0bSAndroid Build Coastguard Worker MSAN_ERROR) " - please fix!");
667*08b48e0bSAndroid Build Coastguard Worker
668*08b48e0bSAndroid Build Coastguard Worker }
669*08b48e0bSAndroid Build Coastguard Worker
670*08b48e0bSAndroid Build Coastguard Worker }
671*08b48e0bSAndroid Build Coastguard Worker
672*08b48e0bSAndroid Build Coastguard Worker set_sanitizer_defaults();
673*08b48e0bSAndroid Build Coastguard Worker
674*08b48e0bSAndroid Build Coastguard Worker if (get_afl_env("AFL_PRELOAD")) {
675*08b48e0bSAndroid Build Coastguard Worker
676*08b48e0bSAndroid Build Coastguard Worker if (qemu_mode) {
677*08b48e0bSAndroid Build Coastguard Worker
678*08b48e0bSAndroid Build Coastguard Worker /* afl-qemu-trace takes care of converting AFL_PRELOAD. */
679*08b48e0bSAndroid Build Coastguard Worker
680*08b48e0bSAndroid Build Coastguard Worker } else if (frida_mode) {
681*08b48e0bSAndroid Build Coastguard Worker
682*08b48e0bSAndroid Build Coastguard Worker afl_preload = getenv("AFL_PRELOAD");
683*08b48e0bSAndroid Build Coastguard Worker u8 *frida_binary = find_afl_binary(argv[0], "afl-frida-trace.so");
684*08b48e0bSAndroid Build Coastguard Worker if (afl_preload) {
685*08b48e0bSAndroid Build Coastguard Worker
686*08b48e0bSAndroid Build Coastguard Worker frida_afl_preload = alloc_printf("%s:%s", afl_preload, frida_binary);
687*08b48e0bSAndroid Build Coastguard Worker
688*08b48e0bSAndroid Build Coastguard Worker } else {
689*08b48e0bSAndroid Build Coastguard Worker
690*08b48e0bSAndroid Build Coastguard Worker frida_afl_preload = alloc_printf("%s", frida_binary);
691*08b48e0bSAndroid Build Coastguard Worker
692*08b48e0bSAndroid Build Coastguard Worker }
693*08b48e0bSAndroid Build Coastguard Worker
694*08b48e0bSAndroid Build Coastguard Worker ck_free(frida_binary);
695*08b48e0bSAndroid Build Coastguard Worker
696*08b48e0bSAndroid Build Coastguard Worker setenv("LD_PRELOAD", frida_afl_preload, 1);
697*08b48e0bSAndroid Build Coastguard Worker setenv("DYLD_INSERT_LIBRARIES", frida_afl_preload, 1);
698*08b48e0bSAndroid Build Coastguard Worker
699*08b48e0bSAndroid Build Coastguard Worker } else {
700*08b48e0bSAndroid Build Coastguard Worker
701*08b48e0bSAndroid Build Coastguard Worker /* CoreSight mode uses the default behavior. */
702*08b48e0bSAndroid Build Coastguard Worker
703*08b48e0bSAndroid Build Coastguard Worker setenv("LD_PRELOAD", getenv("AFL_PRELOAD"), 1);
704*08b48e0bSAndroid Build Coastguard Worker setenv("DYLD_INSERT_LIBRARIES", getenv("AFL_PRELOAD"), 1);
705*08b48e0bSAndroid Build Coastguard Worker
706*08b48e0bSAndroid Build Coastguard Worker }
707*08b48e0bSAndroid Build Coastguard Worker
708*08b48e0bSAndroid Build Coastguard Worker } else if (frida_mode) {
709*08b48e0bSAndroid Build Coastguard Worker
710*08b48e0bSAndroid Build Coastguard Worker u8 *frida_binary = find_afl_binary(argv[0], "afl-frida-trace.so");
711*08b48e0bSAndroid Build Coastguard Worker setenv("LD_PRELOAD", frida_binary, 1);
712*08b48e0bSAndroid Build Coastguard Worker setenv("DYLD_INSERT_LIBRARIES", frida_binary, 1);
713*08b48e0bSAndroid Build Coastguard Worker ck_free(frida_binary);
714*08b48e0bSAndroid Build Coastguard Worker
715*08b48e0bSAndroid Build Coastguard Worker }
716*08b48e0bSAndroid Build Coastguard Worker
717*08b48e0bSAndroid Build Coastguard Worker if (frida_afl_preload) { ck_free(frida_afl_preload); }
718*08b48e0bSAndroid Build Coastguard Worker
719*08b48e0bSAndroid Build Coastguard Worker }
720*08b48e0bSAndroid Build Coastguard Worker
721*08b48e0bSAndroid Build Coastguard Worker /* Setup signal handlers, duh. */
722*08b48e0bSAndroid Build Coastguard Worker
setup_signal_handlers(void)723*08b48e0bSAndroid Build Coastguard Worker static void setup_signal_handlers(void) {
724*08b48e0bSAndroid Build Coastguard Worker
725*08b48e0bSAndroid Build Coastguard Worker struct sigaction sa;
726*08b48e0bSAndroid Build Coastguard Worker
727*08b48e0bSAndroid Build Coastguard Worker sa.sa_handler = NULL;
728*08b48e0bSAndroid Build Coastguard Worker #ifdef SA_RESTART
729*08b48e0bSAndroid Build Coastguard Worker sa.sa_flags = SA_RESTART;
730*08b48e0bSAndroid Build Coastguard Worker #else
731*08b48e0bSAndroid Build Coastguard Worker sa.sa_flags = 0;
732*08b48e0bSAndroid Build Coastguard Worker #endif
733*08b48e0bSAndroid Build Coastguard Worker sa.sa_sigaction = NULL;
734*08b48e0bSAndroid Build Coastguard Worker
735*08b48e0bSAndroid Build Coastguard Worker sigemptyset(&sa.sa_mask);
736*08b48e0bSAndroid Build Coastguard Worker
737*08b48e0bSAndroid Build Coastguard Worker /* Various ways of saying "stop". */
738*08b48e0bSAndroid Build Coastguard Worker
739*08b48e0bSAndroid Build Coastguard Worker sa.sa_handler = handle_stop_sig;
740*08b48e0bSAndroid Build Coastguard Worker sigaction(SIGHUP, &sa, NULL);
741*08b48e0bSAndroid Build Coastguard Worker sigaction(SIGINT, &sa, NULL);
742*08b48e0bSAndroid Build Coastguard Worker sigaction(SIGTERM, &sa, NULL);
743*08b48e0bSAndroid Build Coastguard Worker
744*08b48e0bSAndroid Build Coastguard Worker }
745*08b48e0bSAndroid Build Coastguard Worker
746*08b48e0bSAndroid Build Coastguard Worker /* Display usage hints. */
747*08b48e0bSAndroid Build Coastguard Worker
usage(u8 * argv0)748*08b48e0bSAndroid Build Coastguard Worker static void usage(u8 *argv0) {
749*08b48e0bSAndroid Build Coastguard Worker
750*08b48e0bSAndroid Build Coastguard Worker SAYF(
751*08b48e0bSAndroid Build Coastguard Worker "\n%s [ options ] -- /path/to/target_app [ ... ]\n\n"
752*08b48e0bSAndroid Build Coastguard Worker
753*08b48e0bSAndroid Build Coastguard Worker "Required parameters:\n"
754*08b48e0bSAndroid Build Coastguard Worker
755*08b48e0bSAndroid Build Coastguard Worker " -i file - input test case to be analyzed by the tool\n\n"
756*08b48e0bSAndroid Build Coastguard Worker
757*08b48e0bSAndroid Build Coastguard Worker "Execution control settings:\n"
758*08b48e0bSAndroid Build Coastguard Worker
759*08b48e0bSAndroid Build Coastguard Worker " -f file - input file read by the tested program (stdin)\n"
760*08b48e0bSAndroid Build Coastguard Worker " -t msec - timeout for each run (%u ms)\n"
761*08b48e0bSAndroid Build Coastguard Worker " -m megs - memory limit for child process (%u MB)\n"
762*08b48e0bSAndroid Build Coastguard Worker #if defined(__linux__) && defined(__aarch64__)
763*08b48e0bSAndroid Build Coastguard Worker " -A - use binary-only instrumentation (ARM CoreSight mode)\n"
764*08b48e0bSAndroid Build Coastguard Worker #endif
765*08b48e0bSAndroid Build Coastguard Worker " -O - use binary-only instrumentation (FRIDA mode)\n"
766*08b48e0bSAndroid Build Coastguard Worker #if defined(__linux__)
767*08b48e0bSAndroid Build Coastguard Worker " -Q - use binary-only instrumentation (QEMU mode)\n"
768*08b48e0bSAndroid Build Coastguard Worker " -U - use unicorn-based instrumentation (Unicorn mode)\n"
769*08b48e0bSAndroid Build Coastguard Worker " -W - use qemu-based instrumentation with Wine (Wine "
770*08b48e0bSAndroid Build Coastguard Worker "mode)\n"
771*08b48e0bSAndroid Build Coastguard Worker " -X - use Nyx mode\n"
772*08b48e0bSAndroid Build Coastguard Worker #endif
773*08b48e0bSAndroid Build Coastguard Worker "\n"
774*08b48e0bSAndroid Build Coastguard Worker
775*08b48e0bSAndroid Build Coastguard Worker "Analysis settings:\n"
776*08b48e0bSAndroid Build Coastguard Worker
777*08b48e0bSAndroid Build Coastguard Worker " -e - look for edge coverage only, ignore hit counts\n\n"
778*08b48e0bSAndroid Build Coastguard Worker
779*08b48e0bSAndroid Build Coastguard Worker "For additional tips, please consult %s/README.md.\n\n"
780*08b48e0bSAndroid Build Coastguard Worker
781*08b48e0bSAndroid Build Coastguard Worker "Environment variables used:\n"
782*08b48e0bSAndroid Build Coastguard Worker "TMPDIR: directory to use for temporary input files\n"
783*08b48e0bSAndroid Build Coastguard Worker "ASAN_OPTIONS: custom settings for ASAN\n"
784*08b48e0bSAndroid Build Coastguard Worker " (must contain abort_on_error=1 and symbolize=0)\n"
785*08b48e0bSAndroid Build Coastguard Worker "MSAN_OPTIONS: custom settings for MSAN\n"
786*08b48e0bSAndroid Build Coastguard Worker " (must contain exitcode="STRINGIFY(MSAN_ERROR)" and symbolize=0)\n"
787*08b48e0bSAndroid Build Coastguard Worker "AFL_ANALYZE_HEX: print file offsets in hexadecimal instead of decimal\n"
788*08b48e0bSAndroid Build Coastguard Worker "AFL_KILL_SIGNAL: Signal ID delivered to child processes on timeout, etc.\n"
789*08b48e0bSAndroid Build Coastguard Worker " (default: SIGKILL)\n"
790*08b48e0bSAndroid Build Coastguard Worker "AFL_FORK_SERVER_KILL_SIGNAL: Kill signal for the fork server on termination\n"
791*08b48e0bSAndroid Build Coastguard Worker " (default: SIGTERM). If unset and AFL_KILL_SIGNAL is\n"
792*08b48e0bSAndroid Build Coastguard Worker " set, that value will be used.\n"
793*08b48e0bSAndroid Build Coastguard Worker "AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n"
794*08b48e0bSAndroid Build Coastguard Worker " the target was compiled for\n"
795*08b48e0bSAndroid Build Coastguard Worker "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
796*08b48e0bSAndroid Build Coastguard Worker "AFL_SKIP_BIN_CHECK: skip checking the location of and the target\n"
797*08b48e0bSAndroid Build Coastguard Worker , argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path);
798*08b48e0bSAndroid Build Coastguard Worker
799*08b48e0bSAndroid Build Coastguard Worker exit(1);
800*08b48e0bSAndroid Build Coastguard Worker
801*08b48e0bSAndroid Build Coastguard Worker }
802*08b48e0bSAndroid Build Coastguard Worker
803*08b48e0bSAndroid Build Coastguard Worker /* Main entry point */
804*08b48e0bSAndroid Build Coastguard Worker
main(int argc,char ** argv_orig,char ** envp)805*08b48e0bSAndroid Build Coastguard Worker int main(int argc, char **argv_orig, char **envp) {
806*08b48e0bSAndroid Build Coastguard Worker
807*08b48e0bSAndroid Build Coastguard Worker s32 opt;
808*08b48e0bSAndroid Build Coastguard Worker u8 mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0;
809*08b48e0bSAndroid Build Coastguard Worker char **use_argv;
810*08b48e0bSAndroid Build Coastguard Worker char **argv = argv_cpy_dup(argc, argv_orig);
811*08b48e0bSAndroid Build Coastguard Worker
812*08b48e0bSAndroid Build Coastguard Worker doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH;
813*08b48e0bSAndroid Build Coastguard Worker
814*08b48e0bSAndroid Build Coastguard Worker SAYF(cCYA "afl-analyze" VERSION cRST " by Michal Zalewski\n");
815*08b48e0bSAndroid Build Coastguard Worker
816*08b48e0bSAndroid Build Coastguard Worker afl_fsrv_init(&fsrv);
817*08b48e0bSAndroid Build Coastguard Worker
818*08b48e0bSAndroid Build Coastguard Worker while ((opt = getopt(argc, argv, "+i:f:m:t:eAOQUWXYh")) > 0) {
819*08b48e0bSAndroid Build Coastguard Worker
820*08b48e0bSAndroid Build Coastguard Worker switch (opt) {
821*08b48e0bSAndroid Build Coastguard Worker
822*08b48e0bSAndroid Build Coastguard Worker case 'i':
823*08b48e0bSAndroid Build Coastguard Worker
824*08b48e0bSAndroid Build Coastguard Worker if (in_file) { FATAL("Multiple -i options not supported"); }
825*08b48e0bSAndroid Build Coastguard Worker in_file = optarg;
826*08b48e0bSAndroid Build Coastguard Worker break;
827*08b48e0bSAndroid Build Coastguard Worker
828*08b48e0bSAndroid Build Coastguard Worker case 'f':
829*08b48e0bSAndroid Build Coastguard Worker
830*08b48e0bSAndroid Build Coastguard Worker if (fsrv.out_file) { FATAL("Multiple -f options not supported"); }
831*08b48e0bSAndroid Build Coastguard Worker fsrv.use_stdin = 0;
832*08b48e0bSAndroid Build Coastguard Worker fsrv.out_file = ck_strdup(optarg);
833*08b48e0bSAndroid Build Coastguard Worker break;
834*08b48e0bSAndroid Build Coastguard Worker
835*08b48e0bSAndroid Build Coastguard Worker case 'e':
836*08b48e0bSAndroid Build Coastguard Worker
837*08b48e0bSAndroid Build Coastguard Worker if (edges_only) { FATAL("Multiple -e options not supported"); }
838*08b48e0bSAndroid Build Coastguard Worker edges_only = 1;
839*08b48e0bSAndroid Build Coastguard Worker break;
840*08b48e0bSAndroid Build Coastguard Worker
841*08b48e0bSAndroid Build Coastguard Worker case 'm': {
842*08b48e0bSAndroid Build Coastguard Worker
843*08b48e0bSAndroid Build Coastguard Worker u8 suffix = 'M';
844*08b48e0bSAndroid Build Coastguard Worker
845*08b48e0bSAndroid Build Coastguard Worker if (mem_limit_given) { FATAL("Multiple -m options not supported"); }
846*08b48e0bSAndroid Build Coastguard Worker mem_limit_given = 1;
847*08b48e0bSAndroid Build Coastguard Worker
848*08b48e0bSAndroid Build Coastguard Worker if (!optarg) { FATAL("Wrong usage of -m"); }
849*08b48e0bSAndroid Build Coastguard Worker
850*08b48e0bSAndroid Build Coastguard Worker if (!strcmp(optarg, "none")) {
851*08b48e0bSAndroid Build Coastguard Worker
852*08b48e0bSAndroid Build Coastguard Worker mem_limit = 0;
853*08b48e0bSAndroid Build Coastguard Worker fsrv.mem_limit = 0;
854*08b48e0bSAndroid Build Coastguard Worker break;
855*08b48e0bSAndroid Build Coastguard Worker
856*08b48e0bSAndroid Build Coastguard Worker }
857*08b48e0bSAndroid Build Coastguard Worker
858*08b48e0bSAndroid Build Coastguard Worker if (sscanf(optarg, "%llu%c", &mem_limit, &suffix) < 1 ||
859*08b48e0bSAndroid Build Coastguard Worker optarg[0] == '-') {
860*08b48e0bSAndroid Build Coastguard Worker
861*08b48e0bSAndroid Build Coastguard Worker FATAL("Bad syntax used for -m");
862*08b48e0bSAndroid Build Coastguard Worker
863*08b48e0bSAndroid Build Coastguard Worker }
864*08b48e0bSAndroid Build Coastguard Worker
865*08b48e0bSAndroid Build Coastguard Worker switch (suffix) {
866*08b48e0bSAndroid Build Coastguard Worker
867*08b48e0bSAndroid Build Coastguard Worker case 'T':
868*08b48e0bSAndroid Build Coastguard Worker mem_limit *= 1024 * 1024;
869*08b48e0bSAndroid Build Coastguard Worker break;
870*08b48e0bSAndroid Build Coastguard Worker case 'G':
871*08b48e0bSAndroid Build Coastguard Worker mem_limit *= 1024;
872*08b48e0bSAndroid Build Coastguard Worker break;
873*08b48e0bSAndroid Build Coastguard Worker case 'k':
874*08b48e0bSAndroid Build Coastguard Worker mem_limit /= 1024;
875*08b48e0bSAndroid Build Coastguard Worker break;
876*08b48e0bSAndroid Build Coastguard Worker case 'M':
877*08b48e0bSAndroid Build Coastguard Worker break;
878*08b48e0bSAndroid Build Coastguard Worker
879*08b48e0bSAndroid Build Coastguard Worker default:
880*08b48e0bSAndroid Build Coastguard Worker FATAL("Unsupported suffix or bad syntax for -m");
881*08b48e0bSAndroid Build Coastguard Worker
882*08b48e0bSAndroid Build Coastguard Worker }
883*08b48e0bSAndroid Build Coastguard Worker
884*08b48e0bSAndroid Build Coastguard Worker if (mem_limit < 5) { FATAL("Dangerously low value of -m"); }
885*08b48e0bSAndroid Build Coastguard Worker
886*08b48e0bSAndroid Build Coastguard Worker if (sizeof(rlim_t) == 4 && mem_limit > 2000) {
887*08b48e0bSAndroid Build Coastguard Worker
888*08b48e0bSAndroid Build Coastguard Worker FATAL("Value of -m out of range on 32-bit systems");
889*08b48e0bSAndroid Build Coastguard Worker
890*08b48e0bSAndroid Build Coastguard Worker }
891*08b48e0bSAndroid Build Coastguard Worker
892*08b48e0bSAndroid Build Coastguard Worker fsrv.mem_limit = mem_limit;
893*08b48e0bSAndroid Build Coastguard Worker
894*08b48e0bSAndroid Build Coastguard Worker }
895*08b48e0bSAndroid Build Coastguard Worker
896*08b48e0bSAndroid Build Coastguard Worker break;
897*08b48e0bSAndroid Build Coastguard Worker
898*08b48e0bSAndroid Build Coastguard Worker case 't':
899*08b48e0bSAndroid Build Coastguard Worker
900*08b48e0bSAndroid Build Coastguard Worker if (timeout_given) { FATAL("Multiple -t options not supported"); }
901*08b48e0bSAndroid Build Coastguard Worker timeout_given = 1;
902*08b48e0bSAndroid Build Coastguard Worker
903*08b48e0bSAndroid Build Coastguard Worker if (!optarg) { FATAL("Wrong usage of -t"); }
904*08b48e0bSAndroid Build Coastguard Worker
905*08b48e0bSAndroid Build Coastguard Worker exec_tmout = atoi(optarg);
906*08b48e0bSAndroid Build Coastguard Worker
907*08b48e0bSAndroid Build Coastguard Worker if (exec_tmout < 10 || optarg[0] == '-') {
908*08b48e0bSAndroid Build Coastguard Worker
909*08b48e0bSAndroid Build Coastguard Worker FATAL("Dangerously low value of -t");
910*08b48e0bSAndroid Build Coastguard Worker
911*08b48e0bSAndroid Build Coastguard Worker }
912*08b48e0bSAndroid Build Coastguard Worker
913*08b48e0bSAndroid Build Coastguard Worker fsrv.exec_tmout = exec_tmout;
914*08b48e0bSAndroid Build Coastguard Worker
915*08b48e0bSAndroid Build Coastguard Worker break;
916*08b48e0bSAndroid Build Coastguard Worker
917*08b48e0bSAndroid Build Coastguard Worker case 'A': /* CoreSight mode */
918*08b48e0bSAndroid Build Coastguard Worker
919*08b48e0bSAndroid Build Coastguard Worker #if !defined(__aarch64__) || !defined(__linux__)
920*08b48e0bSAndroid Build Coastguard Worker FATAL("-A option is not supported on this platform");
921*08b48e0bSAndroid Build Coastguard Worker #endif
922*08b48e0bSAndroid Build Coastguard Worker
923*08b48e0bSAndroid Build Coastguard Worker if (cs_mode) { FATAL("Multiple -A options not supported"); }
924*08b48e0bSAndroid Build Coastguard Worker
925*08b48e0bSAndroid Build Coastguard Worker cs_mode = 1;
926*08b48e0bSAndroid Build Coastguard Worker fsrv.cs_mode = cs_mode;
927*08b48e0bSAndroid Build Coastguard Worker break;
928*08b48e0bSAndroid Build Coastguard Worker
929*08b48e0bSAndroid Build Coastguard Worker case 'O': /* FRIDA mode */
930*08b48e0bSAndroid Build Coastguard Worker
931*08b48e0bSAndroid Build Coastguard Worker if (frida_mode) { FATAL("Multiple -O options not supported"); }
932*08b48e0bSAndroid Build Coastguard Worker
933*08b48e0bSAndroid Build Coastguard Worker frida_mode = 1;
934*08b48e0bSAndroid Build Coastguard Worker fsrv.frida_mode = frida_mode;
935*08b48e0bSAndroid Build Coastguard Worker setenv("AFL_FRIDA_INST_SEED", "1", 1);
936*08b48e0bSAndroid Build Coastguard Worker
937*08b48e0bSAndroid Build Coastguard Worker break;
938*08b48e0bSAndroid Build Coastguard Worker
939*08b48e0bSAndroid Build Coastguard Worker case 'Q':
940*08b48e0bSAndroid Build Coastguard Worker
941*08b48e0bSAndroid Build Coastguard Worker if (qemu_mode) { FATAL("Multiple -Q options not supported"); }
942*08b48e0bSAndroid Build Coastguard Worker if (!mem_limit_given) { mem_limit = MEM_LIMIT_QEMU; }
943*08b48e0bSAndroid Build Coastguard Worker
944*08b48e0bSAndroid Build Coastguard Worker qemu_mode = 1;
945*08b48e0bSAndroid Build Coastguard Worker fsrv.mem_limit = mem_limit;
946*08b48e0bSAndroid Build Coastguard Worker fsrv.qemu_mode = qemu_mode;
947*08b48e0bSAndroid Build Coastguard Worker break;
948*08b48e0bSAndroid Build Coastguard Worker
949*08b48e0bSAndroid Build Coastguard Worker case 'U':
950*08b48e0bSAndroid Build Coastguard Worker
951*08b48e0bSAndroid Build Coastguard Worker if (unicorn_mode) { FATAL("Multiple -U options not supported"); }
952*08b48e0bSAndroid Build Coastguard Worker if (!mem_limit_given) { mem_limit = MEM_LIMIT_UNICORN; }
953*08b48e0bSAndroid Build Coastguard Worker
954*08b48e0bSAndroid Build Coastguard Worker unicorn_mode = 1;
955*08b48e0bSAndroid Build Coastguard Worker fsrv.mem_limit = mem_limit;
956*08b48e0bSAndroid Build Coastguard Worker break;
957*08b48e0bSAndroid Build Coastguard Worker
958*08b48e0bSAndroid Build Coastguard Worker case 'W': /* Wine+QEMU mode */
959*08b48e0bSAndroid Build Coastguard Worker
960*08b48e0bSAndroid Build Coastguard Worker if (use_wine) { FATAL("Multiple -W options not supported"); }
961*08b48e0bSAndroid Build Coastguard Worker qemu_mode = 1;
962*08b48e0bSAndroid Build Coastguard Worker use_wine = 1;
963*08b48e0bSAndroid Build Coastguard Worker
964*08b48e0bSAndroid Build Coastguard Worker if (!mem_limit_given) { mem_limit = 0; }
965*08b48e0bSAndroid Build Coastguard Worker fsrv.qemu_mode = qemu_mode;
966*08b48e0bSAndroid Build Coastguard Worker fsrv.mem_limit = mem_limit;
967*08b48e0bSAndroid Build Coastguard Worker
968*08b48e0bSAndroid Build Coastguard Worker break;
969*08b48e0bSAndroid Build Coastguard Worker
970*08b48e0bSAndroid Build Coastguard Worker case 'Y': // fallthough
971*08b48e0bSAndroid Build Coastguard Worker #ifdef __linux__
972*08b48e0bSAndroid Build Coastguard Worker case 'X': /* NYX mode */
973*08b48e0bSAndroid Build Coastguard Worker
974*08b48e0bSAndroid Build Coastguard Worker if (fsrv.nyx_mode) { FATAL("Multiple -X options not supported"); }
975*08b48e0bSAndroid Build Coastguard Worker
976*08b48e0bSAndroid Build Coastguard Worker fsrv.nyx_mode = 1;
977*08b48e0bSAndroid Build Coastguard Worker fsrv.nyx_parent = true;
978*08b48e0bSAndroid Build Coastguard Worker fsrv.nyx_standalone = true;
979*08b48e0bSAndroid Build Coastguard Worker
980*08b48e0bSAndroid Build Coastguard Worker break;
981*08b48e0bSAndroid Build Coastguard Worker #else
982*08b48e0bSAndroid Build Coastguard Worker case 'X':
983*08b48e0bSAndroid Build Coastguard Worker FATAL("Nyx mode is only availabe on linux...");
984*08b48e0bSAndroid Build Coastguard Worker break;
985*08b48e0bSAndroid Build Coastguard Worker #endif
986*08b48e0bSAndroid Build Coastguard Worker
987*08b48e0bSAndroid Build Coastguard Worker case 'h':
988*08b48e0bSAndroid Build Coastguard Worker usage(argv[0]);
989*08b48e0bSAndroid Build Coastguard Worker return -1;
990*08b48e0bSAndroid Build Coastguard Worker break;
991*08b48e0bSAndroid Build Coastguard Worker
992*08b48e0bSAndroid Build Coastguard Worker default:
993*08b48e0bSAndroid Build Coastguard Worker usage(argv[0]);
994*08b48e0bSAndroid Build Coastguard Worker
995*08b48e0bSAndroid Build Coastguard Worker }
996*08b48e0bSAndroid Build Coastguard Worker
997*08b48e0bSAndroid Build Coastguard Worker }
998*08b48e0bSAndroid Build Coastguard Worker
999*08b48e0bSAndroid Build Coastguard Worker if (optind == argc || !in_file) { usage(argv[0]); }
1000*08b48e0bSAndroid Build Coastguard Worker
1001*08b48e0bSAndroid Build Coastguard Worker map_size = get_map_size();
1002*08b48e0bSAndroid Build Coastguard Worker fsrv.map_size = map_size;
1003*08b48e0bSAndroid Build Coastguard Worker
1004*08b48e0bSAndroid Build Coastguard Worker use_hex_offsets = !!get_afl_env("AFL_ANALYZE_HEX");
1005*08b48e0bSAndroid Build Coastguard Worker
1006*08b48e0bSAndroid Build Coastguard Worker check_environment_vars(envp);
1007*08b48e0bSAndroid Build Coastguard Worker
1008*08b48e0bSAndroid Build Coastguard Worker sharedmem_t shm = {0};
1009*08b48e0bSAndroid Build Coastguard Worker
1010*08b48e0bSAndroid Build Coastguard Worker /* initialize cmplog_mode */
1011*08b48e0bSAndroid Build Coastguard Worker shm.cmplog_mode = 0;
1012*08b48e0bSAndroid Build Coastguard Worker
1013*08b48e0bSAndroid Build Coastguard Worker atexit(at_exit_handler);
1014*08b48e0bSAndroid Build Coastguard Worker setup_signal_handlers();
1015*08b48e0bSAndroid Build Coastguard Worker
1016*08b48e0bSAndroid Build Coastguard Worker set_up_environment(argv);
1017*08b48e0bSAndroid Build Coastguard Worker
1018*08b48e0bSAndroid Build Coastguard Worker #ifdef __linux__
1019*08b48e0bSAndroid Build Coastguard Worker if (!fsrv.nyx_mode) {
1020*08b48e0bSAndroid Build Coastguard Worker
1021*08b48e0bSAndroid Build Coastguard Worker fsrv.target_path = find_binary(argv[optind]);
1022*08b48e0bSAndroid Build Coastguard Worker
1023*08b48e0bSAndroid Build Coastguard Worker } else {
1024*08b48e0bSAndroid Build Coastguard Worker
1025*08b48e0bSAndroid Build Coastguard Worker fsrv.target_path = ck_strdup(argv[optind]);
1026*08b48e0bSAndroid Build Coastguard Worker
1027*08b48e0bSAndroid Build Coastguard Worker }
1028*08b48e0bSAndroid Build Coastguard Worker
1029*08b48e0bSAndroid Build Coastguard Worker #else
1030*08b48e0bSAndroid Build Coastguard Worker fsrv.target_path = find_binary(argv[optind]);
1031*08b48e0bSAndroid Build Coastguard Worker #endif
1032*08b48e0bSAndroid Build Coastguard Worker
1033*08b48e0bSAndroid Build Coastguard Worker fsrv.trace_bits = afl_shm_init(&shm, map_size, 0);
1034*08b48e0bSAndroid Build Coastguard Worker detect_file_args(argv + optind, fsrv.out_file, &use_stdin);
1035*08b48e0bSAndroid Build Coastguard Worker signal(SIGALRM, kill_child);
1036*08b48e0bSAndroid Build Coastguard Worker
1037*08b48e0bSAndroid Build Coastguard Worker if (qemu_mode) {
1038*08b48e0bSAndroid Build Coastguard Worker
1039*08b48e0bSAndroid Build Coastguard Worker if (use_wine) {
1040*08b48e0bSAndroid Build Coastguard Worker
1041*08b48e0bSAndroid Build Coastguard Worker use_argv =
1042*08b48e0bSAndroid Build Coastguard Worker get_wine_argv(argv[0], &target_path, argc - optind, argv + optind);
1043*08b48e0bSAndroid Build Coastguard Worker
1044*08b48e0bSAndroid Build Coastguard Worker } else {
1045*08b48e0bSAndroid Build Coastguard Worker
1046*08b48e0bSAndroid Build Coastguard Worker use_argv =
1047*08b48e0bSAndroid Build Coastguard Worker get_qemu_argv(argv[0], &target_path, argc - optind, argv + optind);
1048*08b48e0bSAndroid Build Coastguard Worker
1049*08b48e0bSAndroid Build Coastguard Worker }
1050*08b48e0bSAndroid Build Coastguard Worker
1051*08b48e0bSAndroid Build Coastguard Worker } else if (cs_mode) {
1052*08b48e0bSAndroid Build Coastguard Worker
1053*08b48e0bSAndroid Build Coastguard Worker use_argv = get_cs_argv(argv[0], &target_path, argc - optind, argv + optind);
1054*08b48e0bSAndroid Build Coastguard Worker
1055*08b48e0bSAndroid Build Coastguard Worker #ifdef __linux__
1056*08b48e0bSAndroid Build Coastguard Worker
1057*08b48e0bSAndroid Build Coastguard Worker } else if (fsrv.nyx_mode) {
1058*08b48e0bSAndroid Build Coastguard Worker
1059*08b48e0bSAndroid Build Coastguard Worker fsrv.nyx_id = 0;
1060*08b48e0bSAndroid Build Coastguard Worker
1061*08b48e0bSAndroid Build Coastguard Worker u8 *libnyx_binary = find_afl_binary(argv[0], "libnyx.so");
1062*08b48e0bSAndroid Build Coastguard Worker fsrv.nyx_handlers = afl_load_libnyx_plugin(libnyx_binary);
1063*08b48e0bSAndroid Build Coastguard Worker if (fsrv.nyx_handlers == NULL) {
1064*08b48e0bSAndroid Build Coastguard Worker
1065*08b48e0bSAndroid Build Coastguard Worker FATAL("failed to initialize libnyx.so...");
1066*08b48e0bSAndroid Build Coastguard Worker
1067*08b48e0bSAndroid Build Coastguard Worker }
1068*08b48e0bSAndroid Build Coastguard Worker
1069*08b48e0bSAndroid Build Coastguard Worker fsrv.nyx_use_tmp_workdir = true;
1070*08b48e0bSAndroid Build Coastguard Worker fsrv.nyx_bind_cpu_id = 0;
1071*08b48e0bSAndroid Build Coastguard Worker
1072*08b48e0bSAndroid Build Coastguard Worker use_argv = argv + optind;
1073*08b48e0bSAndroid Build Coastguard Worker #endif
1074*08b48e0bSAndroid Build Coastguard Worker
1075*08b48e0bSAndroid Build Coastguard Worker } else {
1076*08b48e0bSAndroid Build Coastguard Worker
1077*08b48e0bSAndroid Build Coastguard Worker use_argv = argv + optind;
1078*08b48e0bSAndroid Build Coastguard Worker
1079*08b48e0bSAndroid Build Coastguard Worker }
1080*08b48e0bSAndroid Build Coastguard Worker
1081*08b48e0bSAndroid Build Coastguard Worker SAYF("\n");
1082*08b48e0bSAndroid Build Coastguard Worker
1083*08b48e0bSAndroid Build Coastguard Worker if (getenv("AFL_FORKSRV_INIT_TMOUT")) {
1084*08b48e0bSAndroid Build Coastguard Worker
1085*08b48e0bSAndroid Build Coastguard Worker s32 forksrv_init_tmout = atoi(getenv("AFL_FORKSRV_INIT_TMOUT"));
1086*08b48e0bSAndroid Build Coastguard Worker if (forksrv_init_tmout < 1) {
1087*08b48e0bSAndroid Build Coastguard Worker
1088*08b48e0bSAndroid Build Coastguard Worker FATAL("Bad value specified for AFL_FORKSRV_INIT_TMOUT");
1089*08b48e0bSAndroid Build Coastguard Worker
1090*08b48e0bSAndroid Build Coastguard Worker }
1091*08b48e0bSAndroid Build Coastguard Worker
1092*08b48e0bSAndroid Build Coastguard Worker fsrv.init_tmout = (u32)forksrv_init_tmout;
1093*08b48e0bSAndroid Build Coastguard Worker
1094*08b48e0bSAndroid Build Coastguard Worker }
1095*08b48e0bSAndroid Build Coastguard Worker
1096*08b48e0bSAndroid Build Coastguard Worker configure_afl_kill_signals(
1097*08b48e0bSAndroid Build Coastguard Worker &fsrv, NULL, NULL, (fsrv.qemu_mode || unicorn_mode) ? SIGKILL : SIGTERM);
1098*08b48e0bSAndroid Build Coastguard Worker
1099*08b48e0bSAndroid Build Coastguard Worker read_initial_file();
1100*08b48e0bSAndroid Build Coastguard Worker #ifdef __linux__
1101*08b48e0bSAndroid Build Coastguard Worker if (!fsrv.nyx_mode) { (void)check_binary_signatures(fsrv.target_path); }
1102*08b48e0bSAndroid Build Coastguard Worker #else
1103*08b48e0bSAndroid Build Coastguard Worker (void)check_binary_signatures(fsrv.target_path);
1104*08b48e0bSAndroid Build Coastguard Worker #endif
1105*08b48e0bSAndroid Build Coastguard Worker
1106*08b48e0bSAndroid Build Coastguard Worker ACTF("Performing dry run (mem limit = %llu MB, timeout = %u ms%s)...",
1107*08b48e0bSAndroid Build Coastguard Worker mem_limit, exec_tmout, edges_only ? ", edges only" : "");
1108*08b48e0bSAndroid Build Coastguard Worker
1109*08b48e0bSAndroid Build Coastguard Worker afl_fsrv_start(&fsrv, use_argv, &stop_soon, false);
1110*08b48e0bSAndroid Build Coastguard Worker analyze_run_target(in_data, in_len, 1);
1111*08b48e0bSAndroid Build Coastguard Worker
1112*08b48e0bSAndroid Build Coastguard Worker if (fsrv.last_run_timed_out) {
1113*08b48e0bSAndroid Build Coastguard Worker
1114*08b48e0bSAndroid Build Coastguard Worker FATAL("Target binary times out (adjusting -t may help).");
1115*08b48e0bSAndroid Build Coastguard Worker
1116*08b48e0bSAndroid Build Coastguard Worker }
1117*08b48e0bSAndroid Build Coastguard Worker
1118*08b48e0bSAndroid Build Coastguard Worker if (get_afl_env("AFL_SKIP_BIN_CHECK") == NULL && !anything_set()) {
1119*08b48e0bSAndroid Build Coastguard Worker
1120*08b48e0bSAndroid Build Coastguard Worker FATAL("No instrumentation detected.");
1121*08b48e0bSAndroid Build Coastguard Worker
1122*08b48e0bSAndroid Build Coastguard Worker }
1123*08b48e0bSAndroid Build Coastguard Worker
1124*08b48e0bSAndroid Build Coastguard Worker analyze();
1125*08b48e0bSAndroid Build Coastguard Worker
1126*08b48e0bSAndroid Build Coastguard Worker OKF("We're done here. Have a nice day!\n");
1127*08b48e0bSAndroid Build Coastguard Worker
1128*08b48e0bSAndroid Build Coastguard Worker afl_shm_deinit(&shm);
1129*08b48e0bSAndroid Build Coastguard Worker afl_fsrv_deinit(&fsrv);
1130*08b48e0bSAndroid Build Coastguard Worker if (fsrv.target_path) { ck_free(fsrv.target_path); }
1131*08b48e0bSAndroid Build Coastguard Worker if (in_data) { ck_free(in_data); }
1132*08b48e0bSAndroid Build Coastguard Worker
1133*08b48e0bSAndroid Build Coastguard Worker exit(0);
1134*08b48e0bSAndroid Build Coastguard Worker
1135*08b48e0bSAndroid Build Coastguard Worker }
1136*08b48e0bSAndroid Build Coastguard Worker
1137