run code formatter

This commit is contained in:
Andrea Fioraldi
2019-09-02 18:49:43 +02:00
parent 2ae4ca91b4
commit b24639d011
57 changed files with 8674 additions and 7125 deletions

View File

@ -22,7 +22,7 @@
#define AFL_MAIN
#ifdef __ANDROID__
#include "android-ashmem.h"
# include "android-ashmem.h"
#endif
#include "config.h"
#include "types.h"
@ -50,61 +50,59 @@
#include <sys/types.h>
#include <sys/resource.h>
static s32 child_pid; /* PID of the tested program */
static s32 child_pid; /* PID of the tested program */
u8* trace_bits; /* SHM with instrumentation bitmap */
u8* trace_bits; /* SHM with instrumentation bitmap */
static u8 *in_file, /* Analyzer input test case */
*prog_in, /* Targeted program input file */
*target_path, /* Path to target binary */
*doc_path; /* Path to docs */
static u8 *in_file, /* Analyzer input test case */
*prog_in, /* Targeted program input file */
*target_path, /* Path to target binary */
*doc_path; /* Path to docs */
static u8 *in_data; /* Input data for analysis */
static u8* in_data; /* Input data for analysis */
static u32 in_len, /* Input data length */
orig_cksum, /* Original checksum */
total_execs, /* Total number of execs */
exec_hangs, /* Total number of hangs */
exec_tmout = EXEC_TIMEOUT; /* Exec timeout (ms) */
static u32 in_len, /* Input data length */
orig_cksum, /* Original checksum */
total_execs, /* Total number of execs */
exec_hangs, /* Total number of hangs */
exec_tmout = EXEC_TIMEOUT; /* Exec timeout (ms) */
static u64 mem_limit = MEM_LIMIT; /* Memory limit (MB) */
static u64 mem_limit = MEM_LIMIT; /* Memory limit (MB) */
static s32 dev_null_fd = -1; /* FD to /dev/null */
static s32 dev_null_fd = -1; /* FD to /dev/null */
static u8 edges_only, /* Ignore hit counts? */
use_hex_offsets, /* Show hex offsets? */
use_stdin = 1; /* Use stdin for program input? */
static volatile u8
stop_soon, /* Ctrl-C pressed? */
child_timed_out; /* Child timed out? */
static u8 edges_only, /* Ignore hit counts? */
use_hex_offsets, /* Show hex offsets? */
use_stdin = 1; /* Use stdin for program input? */
static volatile u8 stop_soon, /* Ctrl-C pressed? */
child_timed_out; /* Child timed out? */
/* Constants used for describing byte behavior. */
#define RESP_NONE 0x00 /* Changing byte is a no-op. */
#define RESP_MINOR 0x01 /* Some changes have no effect. */
#define RESP_VARIABLE 0x02 /* Changes produce variable paths. */
#define RESP_FIXED 0x03 /* Changes produce fixed patterns. */
#define RESP_NONE 0x00 /* Changing byte is a no-op. */
#define RESP_MINOR 0x01 /* Some changes have no effect. */
#define RESP_VARIABLE 0x02 /* Changes produce variable paths. */
#define RESP_FIXED 0x03 /* Changes produce fixed patterns. */
#define RESP_LEN 0x04 /* Potential length field */
#define RESP_CKSUM 0x05 /* Potential checksum */
#define RESP_SUSPECT 0x06 /* Potential "suspect" blob */
#define RESP_LEN 0x04 /* Potential length field */
#define RESP_CKSUM 0x05 /* Potential checksum */
#define RESP_SUSPECT 0x06 /* Potential "suspect" blob */
/* Classify tuple counts. This is a slow & naive version, but good enough here. */
/* Classify tuple counts. This is a slow & naive version, but good enough here.
*/
static u8 count_class_lookup[256] = {
[0] = 0,
[1] = 1,
[2] = 2,
[3] = 4,
[4 ... 7] = 8,
[8 ... 15] = 16,
[16 ... 31] = 32,
[32 ... 127] = 64,
[128 ... 255] = 128
[0] = 0,
[1] = 1,
[2] = 2,
[3] = 4,
[4 ... 7] = 8,
[8 ... 15] = 16,
[16 ... 31] = 32,
[32 ... 127] = 64,
[128 ... 255] = 128
};
@ -115,61 +113,62 @@ static void classify_counts(u8* mem) {
if (edges_only) {
while (i--) {
if (*mem) *mem = 1;
mem++;
}
} else {
while (i--) {
*mem = count_class_lookup[*mem];
mem++;
}
}
}
/* See if any bytes are set in the bitmap. */
static inline u8 anything_set(void) {
u32* ptr = (u32*)trace_bits;
u32 i = (MAP_SIZE >> 2);
u32 i = (MAP_SIZE >> 2);
while (i--) if (*(ptr++)) return 1;
while (i--)
if (*(ptr++)) return 1;
return 0;
}
/* Get rid of temp files (atexit handler). */
static void at_exit_handler(void) {
unlink(prog_in); /* Ignore errors */
unlink(prog_in); /* Ignore errors */
}
/* Read initial file. */
static void read_initial_file(void) {
struct stat st;
s32 fd = open(in_file, O_RDONLY);
s32 fd = open(in_file, O_RDONLY);
if (fd < 0) PFATAL("Unable to open '%s'", in_file);
if (fstat(fd, &st) || !st.st_size)
FATAL("Zero-sized input file.");
if (fstat(fd, &st) || !st.st_size) FATAL("Zero-sized input file.");
if (st.st_size >= TMIN_MAX_FILE)
FATAL("Input file is too large (%u MB max)", TMIN_MAX_FILE / 1024 / 1024);
in_len = st.st_size;
in_len = st.st_size;
in_data = ck_alloc_nozero(in_len);
ck_read(fd, in_data, in_len, in_file);
@ -180,14 +179,13 @@ static void read_initial_file(void) {
}
/* Write output file. */
static s32 write_to_file(u8* path, u8* mem, u32 len) {
s32 ret;
unlink(path); /* Ignore errors */
unlink(path); /* Ignore errors */
ret = open(path, O_RDWR | O_CREAT | O_EXCL, 0600);
@ -201,7 +199,6 @@ static s32 write_to_file(u8* path, u8* mem, u32 len) {
}
/* Handle timeout signal. */
static void handle_timeout(int sig) {
@ -211,14 +208,13 @@ static void handle_timeout(int sig) {
}
/* Execute target application. Returns exec checksum, or 0 if program
times out. */
static u32 run_target(char** argv, u8* mem, u32 len, u8 first_run) {
static struct itimerval it;
int status = 0;
int status = 0;
s32 prog_in_fd;
u32 cksum;
@ -237,8 +233,7 @@ static u32 run_target(char** argv, u8* mem, u32 len, u8 first_run) {
struct rlimit r;
if (dup2(use_stdin ? prog_in_fd : dev_null_fd, 0) < 0 ||
dup2(dev_null_fd, 1) < 0 ||
dup2(dev_null_fd, 2) < 0) {
dup2(dev_null_fd, 1) < 0 || dup2(dev_null_fd, 2) < 0) {
*(u32*)trace_bits = EXEC_FAIL_SIG;
PFATAL("dup2() failed");
@ -254,18 +249,18 @@ static u32 run_target(char** argv, u8* mem, u32 len, u8 first_run) {
#ifdef RLIMIT_AS
setrlimit(RLIMIT_AS, &r); /* Ignore errors */
setrlimit(RLIMIT_AS, &r); /* Ignore errors */
#else
setrlimit(RLIMIT_DATA, &r); /* Ignore errors */
setrlimit(RLIMIT_DATA, &r); /* Ignore errors */
#endif /* ^RLIMIT_AS */
}
r.rlim_max = r.rlim_cur = 0;
setrlimit(RLIMIT_CORE, &r); /* Ignore errors */
setrlimit(RLIMIT_CORE, &r); /* Ignore errors */
execv(target_path, argv);
@ -303,8 +298,10 @@ static u32 run_target(char** argv, u8* mem, u32 len, u8 first_run) {
total_execs++;
if (stop_soon) {
SAYF(cRST cLRD "\n+++ Analysis aborted by user +++\n" cRST);
exit(1);
}
/* Always discard inputs that time out. */
@ -335,7 +332,6 @@ static u32 run_target(char** argv, u8* mem, u32 len, u8 first_run) {
}
#ifdef USE_COLOR
/* Helper function to display a human-readable character. */
@ -353,24 +349,25 @@ static void show_char(u8 val) {
}
/* Show the legend */
static void show_legend(void) {
SAYF(" " cLGR bgGRA " 01 " cRST " - no-op block "
cBLK bgLGN " 01 " cRST " - suspected length field\n"
" " cBRI bgGRA " 01 " cRST " - superficial content "
cBLK bgYEL " 01 " cRST " - suspected cksum or magic int\n"
" " cBLK bgCYA " 01 " cRST " - critical stream "
cBLK bgLRD " 01 " cRST " - suspected checksummed block\n"
SAYF(" " cLGR bgGRA " 01 " cRST " - no-op block " cBLK bgLGN
" 01 " cRST
" - suspected length field\n"
" " cBRI bgGRA " 01 " cRST " - superficial content " cBLK bgYEL
" 01 " cRST
" - suspected cksum or magic int\n"
" " cBLK bgCYA " 01 " cRST " - critical stream " cBLK bgLRD
" 01 " cRST
" - suspected checksummed block\n"
" " cBLK bgMGN " 01 " cRST " - \"magic value\" section\n\n");
}
#endif /* USE_COLOR */
/* Interpret and report a pattern in the input file. */
static void dump_hex(u8* buf, u32 len, u8* b_data) {
@ -385,7 +382,7 @@ static void dump_hex(u8* buf, u32 len, u8* b_data) {
u32 rlen = 1;
#endif /* ^USE_COLOR */
u8 rtype = b_data[i] & 0x0f;
u8 rtype = b_data[i] & 0x0f;
/* Look ahead to determine the length of run. */
@ -404,51 +401,61 @@ static void dump_hex(u8* buf, u32 len, u8* b_data) {
case 2: {
u16 val = *(u16*)(in_data + i);
u16 val = *(u16*)(in_data + i);
/* Small integers may be length fields. */
/* Small integers may be length fields. */
if (val && (val <= in_len || SWAP16(val) <= in_len)) {
rtype = RESP_LEN;
break;
}
/* Uniform integers may be checksums. */
if (val && abs(in_data[i] - in_data[i + 1]) > 32) {
rtype = RESP_CKSUM;
break;
}
if (val && (val <= in_len || SWAP16(val) <= in_len)) {
rtype = RESP_LEN;
break;
}
/* Uniform integers may be checksums. */
if (val && abs(in_data[i] - in_data[i + 1]) > 32) {
rtype = RESP_CKSUM;
break;
}
break;
}
case 4: {
u32 val = *(u32*)(in_data + i);
u32 val = *(u32*)(in_data + i);
/* Small integers may be length fields. */
/* Small integers may be length fields. */
if (val && (val <= in_len || SWAP32(val) <= in_len)) {
rtype = RESP_LEN;
break;
}
/* Uniform integers may be checksums. */
if (val && (in_data[i] >> 7 != in_data[i + 1] >> 7 ||
in_data[i] >> 7 != in_data[i + 2] >> 7 ||
in_data[i] >> 7 != in_data[i + 3] >> 7)) {
rtype = RESP_CKSUM;
break;
}
if (val && (val <= in_len || SWAP32(val) <= in_len)) {
rtype = RESP_LEN;
break;
}
case 1: case 3: case 5 ... MAX_AUTO_EXTRA - 1: break;
/* Uniform integers may be checksums. */
if (val && (in_data[i] >> 7 != in_data[i + 1] >> 7 ||
in_data[i] >> 7 != in_data[i + 2] >> 7 ||
in_data[i] >> 7 != in_data[i + 3] >> 7)) {
rtype = RESP_CKSUM;
break;
}
break;
}
case 1:
case 3:
case 5 ... MAX_AUTO_EXTRA - 1: break;
default: rtype = RESP_SUSPECT;
@ -477,19 +484,22 @@ static void dump_hex(u8* buf, u32 len, u8* b_data) {
switch (rtype) {
case RESP_NONE: SAYF(cLGR bgGRA); break;
case RESP_MINOR: SAYF(cBRI bgGRA); break;
case RESP_NONE: SAYF(cLGR bgGRA); break;
case RESP_MINOR: SAYF(cBRI bgGRA); break;
case RESP_VARIABLE: SAYF(cBLK bgCYA); break;
case RESP_FIXED: SAYF(cBLK bgMGN); break;
case RESP_LEN: SAYF(cBLK bgLGN); break;
case RESP_CKSUM: SAYF(cBLK bgYEL); break;
case RESP_SUSPECT: SAYF(cBLK bgLRD); break;
case RESP_FIXED: SAYF(cBLK bgMGN); break;
case RESP_LEN: SAYF(cBLK bgLGN); break;
case RESP_CKSUM: SAYF(cBLK bgYEL); break;
case RESP_SUSPECT: SAYF(cBLK bgLRD); break;
}
show_char(in_data[i + off]);
if (off != rlen - 1 && (i + off + 1) % 16) SAYF(" "); else SAYF(cRST " ");
if (off != rlen - 1 && (i + off + 1) % 16)
SAYF(" ");
else
SAYF(cRST " ");
}
@ -502,13 +512,13 @@ static void dump_hex(u8* buf, u32 len, u8* b_data) {
switch (rtype) {
case RESP_NONE: SAYF("no-op block\n"); break;
case RESP_MINOR: SAYF("superficial content\n"); break;
case RESP_NONE: SAYF("no-op block\n"); break;
case RESP_MINOR: SAYF("superficial content\n"); break;
case RESP_VARIABLE: SAYF("critical stream\n"); break;
case RESP_FIXED: SAYF("\"magic value\" section\n"); break;
case RESP_LEN: SAYF("suspected length field\n"); break;
case RESP_CKSUM: SAYF("suspected cksum or magic int\n"); break;
case RESP_SUSPECT: SAYF("suspected checksummed block\n"); break;
case RESP_FIXED: SAYF("\"magic value\" section\n"); break;
case RESP_LEN: SAYF("suspected length field\n"); break;
case RESP_CKSUM: SAYF("suspected cksum or magic int\n"); break;
case RESP_SUSPECT: SAYF("suspected checksummed block\n"); break;
}
@ -524,8 +534,6 @@ static void dump_hex(u8* buf, u32 len, u8* b_data) {
}
/* Actually analyze! */
static void analyze(char** argv) {
@ -536,7 +544,7 @@ static void analyze(char** argv) {
u8* b_data = ck_alloc(in_len + 1);
u8 seq_byte = 0;
b_data[in_len] = 0xff; /* Intentional terminator. */
b_data[in_len] = 0xff; /* Intentional terminator. */
ACTF("Analyzing input file (this may take a while)...\n");
@ -587,12 +595,15 @@ static void analyze(char** argv) {
b_data[i] = RESP_FIXED;
} else b_data[i] = RESP_VARIABLE;
} else
b_data[i] = RESP_VARIABLE;
/* When all checksums change, flip most significant bit of b_data. */
if (prev_xff != xor_ff && prev_x01 != xor_01 &&
prev_s10 != sub_10 && prev_a10 != add_10) seq_byte ^= 0x80;
if (prev_xff != xor_ff && prev_x01 != xor_01 && prev_s10 != sub_10 &&
prev_a10 != add_10)
seq_byte ^= 0x80;
b_data[i] |= seq_byte;
@ -601,7 +612,7 @@ static void analyze(char** argv) {
prev_s10 = sub_10;
prev_a10 = add_10;
}
}
dump_hex(in_data, in_len, b_data);
@ -618,8 +629,6 @@ static void analyze(char** argv) {
}
/* Handle Ctrl-C and the like. */
static void handle_stop_sig(int sig) {
@ -630,7 +639,6 @@ static void handle_stop_sig(int sig) {
}
/* Do basic preparations - persistent fds, filenames, etc. */
static void set_up_environment(void) {
@ -674,18 +682,20 @@ static void set_up_environment(void) {
if (x) {
if (!strstr(x, "exit_code=" STRINGIFY(MSAN_ERROR)))
FATAL("Custom MSAN_OPTIONS set without exit_code="
STRINGIFY(MSAN_ERROR) " - please fix!");
FATAL("Custom MSAN_OPTIONS set without exit_code=" STRINGIFY(
MSAN_ERROR) " - please fix!");
if (!strstr(x, "symbolize=0"))
FATAL("Custom MSAN_OPTIONS set without symbolize=0 - please fix!");
}
setenv("ASAN_OPTIONS", "abort_on_error=1:"
"detect_leaks=0:"
"symbolize=0:"
"allocator_may_return_null=1", 0);
setenv("ASAN_OPTIONS",
"abort_on_error=1:"
"detect_leaks=0:"
"symbolize=0:"
"allocator_may_return_null=1",
0);
setenv("MSAN_OPTIONS", "exit_code=" STRINGIFY(MSAN_ERROR) ":"
"symbolize=0:"
@ -694,21 +704,22 @@ static void set_up_environment(void) {
"msan_track_origins=0", 0);
if (getenv("AFL_PRELOAD")) {
setenv("LD_PRELOAD", getenv("AFL_PRELOAD"), 1);
setenv("DYLD_INSERT_LIBRARIES", getenv("AFL_PRELOAD"), 1);
}
}
/* Setup signal handlers, duh. */
static void setup_signal_handlers(void) {
struct sigaction sa;
sa.sa_handler = NULL;
sa.sa_flags = SA_RESTART;
sa.sa_handler = NULL;
sa.sa_flags = SA_RESTART;
sa.sa_sigaction = NULL;
sigemptyset(&sa.sa_mask);
@ -727,43 +738,42 @@ static void setup_signal_handlers(void) {
}
/* Display usage hints. */
static void usage(u8* argv0) {
SAYF("\n%s [ options ] -- /path/to/target_app [ ... ]\n\n"
SAYF(
"\n%s [ options ] -- /path/to/target_app [ ... ]\n\n"
"Required parameters:\n\n"
"Required parameters:\n\n"
" -i file - input test case to be analyzed by the tool\n"
" -i file - input test case to be analyzed by the tool\n"
"Execution control settings:\n\n"
"Execution control settings:\n\n"
" -f file - input file read by the tested program (stdin)\n"
" -t msec - timeout for each run (%d ms)\n"
" -m megs - memory limit for child process (%d MB)\n"
" -Q - use binary-only instrumentation (QEMU mode)\n"
" -U - use unicorn-based instrumentation (Unicorn mode)\n\n"
" -f file - input file read by the tested program (stdin)\n"
" -t msec - timeout for each run (%d ms)\n"
" -m megs - memory limit for child process (%d MB)\n"
" -Q - use binary-only instrumentation (QEMU mode)\n"
" -U - use unicorn-based instrumentation (Unicorn mode)\n\n"
"Analysis settings:\n\n"
"Analysis settings:\n\n"
" -e - look for edge coverage only, ignore hit counts\n\n"
" -e - look for edge coverage only, ignore hit counts\n\n"
"For additional tips, please consult %s/README.\n\n",
"For additional tips, please consult %s/README.\n\n",
argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path);
argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path);
exit(1);
}
/* Find binary. */
static void find_binary(u8* fname) {
u8* env_path = 0;
u8* env_path = 0;
struct stat st;
if (strchr(fname, '/') || !(env_path = getenv("PATH"))) {
@ -786,7 +796,9 @@ static void find_binary(u8* fname) {
memcpy(cur_elem, env_path, delim - env_path);
delim++;
} else cur_elem = ck_strdup(env_path);
} else
cur_elem = ck_strdup(env_path);
env_path = delim;
@ -798,7 +810,8 @@ static void find_binary(u8* fname) {
ck_free(cur_elem);
if (!stat(target_path, &st) && S_ISREG(st.st_mode) &&
(st.st_mode & 0111) && st.st_size >= 4) break;
(st.st_mode & 0111) && st.st_size >= 4)
break;
ck_free(target_path);
target_path = 0;
@ -811,13 +824,12 @@ static void find_binary(u8* fname) {
}
/* Fix up argv for QEMU. */
static char** get_qemu_argv(u8* own_loc, char** argv, int argc) {
char** new_argv = ck_alloc(sizeof(char*) * (argc + 4));
u8 *tmp, *cp, *rsl, *own_copy;
u8 * tmp, *cp, *rsl, *own_copy;
memcpy(new_argv + 3, argv + 1, sizeof(char*) * argc);
@ -832,8 +844,7 @@ static char** get_qemu_argv(u8* own_loc, char** argv, int argc) {
cp = alloc_printf("%s/afl-qemu-trace", tmp);
if (access(cp, X_OK))
FATAL("Unable to find '%s'", tmp);
if (access(cp, X_OK)) FATAL("Unable to find '%s'", tmp);
target_path = new_argv[0] = cp;
return new_argv;
@ -857,7 +868,9 @@ static char** get_qemu_argv(u8* own_loc, char** argv, int argc) {
}
} else ck_free(own_copy);
} else
ck_free(own_copy);
if (!access(BIN_PATH "/afl-qemu-trace", X_OK)) {
@ -882,7 +895,7 @@ int main(int argc, char** argv) {
SAYF(cCYA "afl-analyze" VERSION cRST " by <lcamtuf@google.com>\n");
while ((opt = getopt(argc,argv,"+i:f:m:t:eQU")) > 0)
while ((opt = getopt(argc, argv, "+i:f:m:t:eQU")) > 0)
switch (opt) {
@ -896,7 +909,7 @@ int main(int argc, char** argv) {
if (prog_in) FATAL("Multiple -f options not supported");
use_stdin = 0;
prog_in = optarg;
prog_in = optarg;
break;
case 'e':
@ -907,40 +920,41 @@ int main(int argc, char** argv) {
case 'm': {
u8 suffix = 'M';
u8 suffix = 'M';
if (mem_limit_given) FATAL("Multiple -m options not supported");
mem_limit_given = 1;
if (mem_limit_given) FATAL("Multiple -m options not supported");
mem_limit_given = 1;
if (!strcmp(optarg, "none")) {
if (!strcmp(optarg, "none")) {
mem_limit = 0;
break;
}
if (sscanf(optarg, "%llu%c", &mem_limit, &suffix) < 1 ||
optarg[0] == '-') FATAL("Bad syntax used for -m");
switch (suffix) {
case 'T': mem_limit *= 1024 * 1024; break;
case 'G': mem_limit *= 1024; break;
case 'k': mem_limit /= 1024; break;
case 'M': break;
default: FATAL("Unsupported suffix or bad syntax for -m");
}
if (mem_limit < 5) FATAL("Dangerously low value of -m");
if (sizeof(rlim_t) == 4 && mem_limit > 2000)
FATAL("Value of -m out of range on 32-bit systems");
mem_limit = 0;
break;
}
break;
if (sscanf(optarg, "%llu%c", &mem_limit, &suffix) < 1 ||
optarg[0] == '-')
FATAL("Bad syntax used for -m");
switch (suffix) {
case 'T': mem_limit *= 1024 * 1024; break;
case 'G': mem_limit *= 1024; break;
case 'k': mem_limit /= 1024; break;
case 'M': break;
default: FATAL("Unsupported suffix or bad syntax for -m");
}
if (mem_limit < 5) FATAL("Dangerously low value of -m");
if (sizeof(rlim_t) == 4 && mem_limit > 2000)
FATAL("Value of -m out of range on 32-bit systems");
}
break;
case 't':
@ -970,9 +984,7 @@ int main(int argc, char** argv) {
unicorn_mode = 1;
break;
default:
usage(argv[0]);
default: usage(argv[0]);
}