mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-13 02:28:09 +00:00
run code formatter
This commit is contained in:
374
src/afl-tmin.c
374
src/afl-tmin.c
@ -22,7 +22,7 @@
|
||||
#define AFL_MAIN
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include "android-ashmem.h"
|
||||
# include "android-ashmem.h"
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
@ -51,72 +51,71 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
s32 forksrv_pid, /* PID of the fork server */
|
||||
child_pid; /* PID of the tested program */
|
||||
s32 forksrv_pid, /* PID of the fork server */
|
||||
child_pid; /* PID of the tested program */
|
||||
|
||||
s32 fsrv_ctl_fd, /* Fork server control pipe (write) */
|
||||
fsrv_st_fd; /* Fork server status pipe (read) */
|
||||
s32 fsrv_ctl_fd, /* Fork server control pipe (write) */
|
||||
fsrv_st_fd; /* Fork server status pipe (read) */
|
||||
|
||||
u8 *trace_bits; /* SHM with instrumentation bitmap */
|
||||
static u8 *mask_bitmap; /* Mask for trace bits (-B) */
|
||||
u8* trace_bits; /* SHM with instrumentation bitmap */
|
||||
static u8* mask_bitmap; /* Mask for trace bits (-B) */
|
||||
|
||||
u8 *in_file, /* Minimizer input test case */
|
||||
*output_file, /* Minimizer output file */
|
||||
*out_file, /* Targeted program input file */
|
||||
*target_path, /* Path to target binary */
|
||||
*doc_path; /* Path to docs */
|
||||
u8 *in_file, /* Minimizer input test case */
|
||||
*output_file, /* Minimizer output file */
|
||||
*out_file, /* Targeted program input file */
|
||||
*target_path, /* Path to target binary */
|
||||
*doc_path; /* Path to docs */
|
||||
|
||||
s32 out_fd; /* Persistent fd for out_file */
|
||||
s32 out_fd; /* Persistent fd for out_file */
|
||||
|
||||
static u8* in_data; /* Input data for trimming */
|
||||
static u8* in_data; /* Input data for trimming */
|
||||
|
||||
static u32 in_len, /* Input data length */
|
||||
orig_cksum, /* Original checksum */
|
||||
total_execs, /* Total number of execs */
|
||||
missed_hangs, /* Misses due to hangs */
|
||||
missed_crashes, /* Misses due to crashes */
|
||||
missed_paths; /* Misses due to exec path diffs */
|
||||
u32 exec_tmout = EXEC_TIMEOUT; /* Exec timeout (ms) */
|
||||
static u32 in_len, /* Input data length */
|
||||
orig_cksum, /* Original checksum */
|
||||
total_execs, /* Total number of execs */
|
||||
missed_hangs, /* Misses due to hangs */
|
||||
missed_crashes, /* Misses due to crashes */
|
||||
missed_paths; /* Misses due to exec path diffs */
|
||||
u32 exec_tmout = EXEC_TIMEOUT; /* Exec timeout (ms) */
|
||||
|
||||
u64 mem_limit = MEM_LIMIT; /* Memory limit (MB) */
|
||||
u64 mem_limit = MEM_LIMIT; /* Memory limit (MB) */
|
||||
|
||||
s32 dev_null_fd = -1; /* FD to /dev/null */
|
||||
s32 dev_null_fd = -1; /* FD to /dev/null */
|
||||
|
||||
static u8 crash_mode, /* Crash-centric mode? */
|
||||
exit_crash, /* Treat non-zero exit as crash? */
|
||||
edges_only, /* Ignore hit counts? */
|
||||
exact_mode, /* Require path match for crashes? */
|
||||
use_stdin = 1; /* Use stdin for program input? */
|
||||
static u8 crash_mode, /* Crash-centric mode? */
|
||||
exit_crash, /* Treat non-zero exit as crash? */
|
||||
edges_only, /* Ignore hit counts? */
|
||||
exact_mode, /* Require path match for crashes? */
|
||||
use_stdin = 1; /* Use stdin for program input? */
|
||||
|
||||
static volatile u8
|
||||
stop_soon; /* Ctrl-C pressed? */
|
||||
static volatile u8 stop_soon; /* Ctrl-C pressed? */
|
||||
|
||||
/*
|
||||
* forkserver section
|
||||
*/
|
||||
|
||||
/* we only need this to use afl-forkserver */
|
||||
FILE *plot_file;
|
||||
u8 uses_asan;
|
||||
s32 out_fd = -1, out_dir_fd = -1, dev_urandom_fd = -1;
|
||||
FILE* plot_file;
|
||||
u8 uses_asan;
|
||||
s32 out_fd = -1, out_dir_fd = -1, dev_urandom_fd = -1;
|
||||
|
||||
/* we import this as we need this information */
|
||||
extern u8 child_timed_out;
|
||||
|
||||
|
||||
/* 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 const 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
|
||||
|
||||
};
|
||||
|
||||
@ -127,22 +126,25 @@ 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++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Apply mask to classified bitmap (if set). */
|
||||
|
||||
static void apply_mask(u32* mem, u32* mask) {
|
||||
@ -161,25 +163,26 @@ static void apply_mask(u32* mem, u32* mask) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* 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) {
|
||||
if (out_file) unlink(out_file); /* Ignore errors */
|
||||
|
||||
if (out_file) unlink(out_file); /* Ignore errors */
|
||||
|
||||
}
|
||||
|
||||
/* Read initial file. */
|
||||
@ -187,17 +190,16 @@ static void at_exit_handler(void) {
|
||||
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);
|
||||
@ -208,14 +210,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);
|
||||
|
||||
@ -239,13 +240,15 @@ static void write_to_testcase(void* mem, u32 len) {
|
||||
|
||||
if (!use_stdin) {
|
||||
|
||||
unlink(out_file); /* Ignore errors. */
|
||||
unlink(out_file); /* Ignore errors. */
|
||||
|
||||
fd = open(out_file, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
||||
|
||||
if (fd < 0) PFATAL("Unable to create '%s'", out_file);
|
||||
|
||||
} else lseek(fd, 0, SEEK_SET);
|
||||
} else
|
||||
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
|
||||
ck_write(fd, mem, len, out_file);
|
||||
|
||||
@ -254,12 +257,12 @@ static void write_to_testcase(void* mem, u32 len) {
|
||||
if (ftruncate(fd, len)) PFATAL("ftruncate() failed");
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
|
||||
} else close(fd);
|
||||
} else
|
||||
|
||||
close(fd);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Handle timeout signal. */
|
||||
/*
|
||||
static void handle_timeout(int sig) {
|
||||
@ -277,11 +280,13 @@ static void handle_timeout(int sig) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/* start the app and it's forkserver */
|
||||
/*
|
||||
static void init_forkserver(char **argv) {
|
||||
|
||||
static struct itimerval it;
|
||||
int st_pipe[2], ctl_pipe[2];
|
||||
int status = 0;
|
||||
@ -348,7 +353,7 @@ static void init_forkserver(char **argv) {
|
||||
|
||||
}
|
||||
|
||||
// Close the unneeded endpoints.
|
||||
// Close the unneeded endpoints.
|
||||
|
||||
close(ctl_pipe[0]);
|
||||
close(st_pipe[1]);
|
||||
@ -378,8 +383,10 @@ static void init_forkserver(char **argv) {
|
||||
// Otherwise, try to figure out what went wrong.
|
||||
|
||||
if (rlen == 4) {
|
||||
|
||||
ACTF("All right - fork server is up.");
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (waitpid(forksrv_pid, &status, 0) <= 0)
|
||||
@ -398,6 +405,7 @@ static void init_forkserver(char **argv) {
|
||||
SAYF(cLRD "\n+++ Program killed by signal %u +++\n" cRST, WTERMSIG(status));
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/* Execute target application. Returns 0 if the changes are a dud, or
|
||||
@ -406,8 +414,8 @@ static void init_forkserver(char **argv) {
|
||||
static u8 run_target(char** argv, u8* mem, u32 len, u8 first_run) {
|
||||
|
||||
static struct itimerval it;
|
||||
static u32 prev_timed_out = 0;
|
||||
int status = 0;
|
||||
static u32 prev_timed_out = 0;
|
||||
int status = 0;
|
||||
|
||||
u32 cksum;
|
||||
|
||||
@ -440,8 +448,10 @@ static u8 run_target(char** argv, u8* mem, u32 len, u8 first_run) {
|
||||
/* Configure timeout, wait for child, cancel timeout. */
|
||||
|
||||
if (exec_tmout) {
|
||||
|
||||
it.it_value.tv_sec = (exec_tmout / 1000);
|
||||
it.it_value.tv_usec = (exec_tmout % 1000) * 1000;
|
||||
|
||||
}
|
||||
|
||||
setitimer(ITIMER_REAL, &it, NULL);
|
||||
@ -508,9 +518,9 @@ static u8 run_target(char** argv, u8* mem, u32 len, u8 first_run) {
|
||||
|
||||
} else
|
||||
|
||||
/* Handle non-crashing inputs appropriately. */
|
||||
/* Handle non-crashing inputs appropriately. */
|
||||
|
||||
if (crash_mode) {
|
||||
if (crash_mode) {
|
||||
|
||||
missed_paths++;
|
||||
return 0;
|
||||
@ -522,24 +532,23 @@ static u8 run_target(char** argv, u8* mem, u32 len, u8 first_run) {
|
||||
if (first_run) orig_cksum = cksum;
|
||||
|
||||
if (orig_cksum == cksum) return 1;
|
||||
|
||||
|
||||
missed_paths++;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Find first power of two greater or equal to val. */
|
||||
|
||||
static u32 next_p2(u32 val) {
|
||||
|
||||
u32 ret = 1;
|
||||
while (val > ret) ret <<= 1;
|
||||
while (val > ret)
|
||||
ret <<= 1;
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Actually minimize! */
|
||||
|
||||
static void minimize(char** argv) {
|
||||
@ -557,8 +566,8 @@ static void minimize(char** argv) {
|
||||
* BLOCK NORMALIZATION *
|
||||
***********************/
|
||||
|
||||
set_len = next_p2(in_len / TMIN_SET_STEPS);
|
||||
set_pos = 0;
|
||||
set_len = next_p2(in_len / TMIN_SET_STEPS);
|
||||
set_pos = 0;
|
||||
|
||||
if (set_len < TMIN_SET_MIN_SIZE) set_len = TMIN_SET_MIN_SIZE;
|
||||
|
||||
@ -575,14 +584,14 @@ static void minimize(char** argv) {
|
||||
|
||||
memcpy(tmp_buf, in_data, in_len);
|
||||
memset(tmp_buf + set_pos, '0', use_len);
|
||||
|
||||
u8 res;
|
||||
|
||||
u8 res;
|
||||
res = run_target(argv, tmp_buf, in_len, 0);
|
||||
|
||||
if (res) {
|
||||
|
||||
memset(in_data + set_pos, '0', use_len);
|
||||
/* changed_any = 1; value is not used */
|
||||
/* changed_any = 1; value is not used */
|
||||
alpha_del0 += use_len;
|
||||
|
||||
}
|
||||
@ -615,11 +624,11 @@ next_pass:
|
||||
next_del_blksize:
|
||||
|
||||
if (!del_len) del_len = 1;
|
||||
del_pos = 0;
|
||||
del_pos = 0;
|
||||
prev_del = 1;
|
||||
|
||||
SAYF(cGRA " Block length = %u, remaining size = %u\n" cRST,
|
||||
del_len, in_len);
|
||||
SAYF(cGRA " Block length = %u, remaining size = %u\n" cRST, del_len,
|
||||
in_len);
|
||||
|
||||
while (del_pos < in_len) {
|
||||
|
||||
@ -634,8 +643,8 @@ next_del_blksize:
|
||||
very end of the buffer (tail_len > 0), and the current block is the same
|
||||
as the previous one... skip this step as a no-op. */
|
||||
|
||||
if (!prev_del && tail_len && !memcmp(in_data + del_pos - del_len,
|
||||
in_data + del_pos, del_len)) {
|
||||
if (!prev_del && tail_len &&
|
||||
!memcmp(in_data + del_pos - del_len, in_data + del_pos, del_len)) {
|
||||
|
||||
del_pos += del_len;
|
||||
continue;
|
||||
@ -656,11 +665,13 @@ next_del_blksize:
|
||||
|
||||
memcpy(in_data, tmp_buf, del_pos + tail_len);
|
||||
prev_del = 1;
|
||||
in_len = del_pos + tail_len;
|
||||
in_len = del_pos + tail_len;
|
||||
|
||||
changed_any = 1;
|
||||
|
||||
} else del_pos += del_len;
|
||||
} else
|
||||
|
||||
del_pos += del_len;
|
||||
|
||||
}
|
||||
|
||||
@ -674,7 +685,8 @@ next_del_blksize:
|
||||
OKF("Block removal complete, %u bytes deleted.", stage_o_len - in_len);
|
||||
|
||||
if (!in_len && changed_any)
|
||||
WARNF(cLRD "Down to zero bytes - check the command line and mem limit!" cRST);
|
||||
WARNF(cLRD
|
||||
"Down to zero bytes - check the command line and mem limit!" cRST);
|
||||
|
||||
if (cur_pass > 1 && !changed_any) goto finalize_all;
|
||||
|
||||
@ -682,15 +694,17 @@ next_del_blksize:
|
||||
* ALPHABET MINIMIZATION *
|
||||
*************************/
|
||||
|
||||
alpha_size = 0;
|
||||
alpha_del1 = 0;
|
||||
alpha_size = 0;
|
||||
alpha_del1 = 0;
|
||||
syms_removed = 0;
|
||||
|
||||
memset(alpha_map, 0, sizeof(alpha_map));
|
||||
|
||||
for (i = 0; i < in_len; i++) {
|
||||
|
||||
if (!alpha_map[in_data[i]]) alpha_size++;
|
||||
alpha_map[in_data[i]]++;
|
||||
|
||||
}
|
||||
|
||||
ACTF(cBRI "Stage #2: " cRST "Minimizing symbols (%u code point%s)...",
|
||||
@ -699,14 +713,14 @@ next_del_blksize:
|
||||
for (i = 0; i < 256; i++) {
|
||||
|
||||
u32 r;
|
||||
u8 res;
|
||||
u8 res;
|
||||
|
||||
if (i == '0' || !alpha_map[i]) continue;
|
||||
|
||||
memcpy(tmp_buf, in_data, in_len);
|
||||
|
||||
for (r = 0; r < in_len; r++)
|
||||
if (tmp_buf[r] == i) tmp_buf[r] = '0';
|
||||
if (tmp_buf[r] == i) tmp_buf[r] = '0';
|
||||
|
||||
res = run_target(argv, tmp_buf, in_len, 0);
|
||||
|
||||
@ -724,8 +738,8 @@ next_del_blksize:
|
||||
alpha_d_total += alpha_del1;
|
||||
|
||||
OKF("Symbol minimization finished, %u symbol%s (%u byte%s) replaced.",
|
||||
syms_removed, syms_removed == 1 ? "" : "s",
|
||||
alpha_del1, alpha_del1 == 1 ? "" : "s");
|
||||
syms_removed, syms_removed == 1 ? "" : "s", alpha_del1,
|
||||
alpha_del1 == 1 ? "" : "s");
|
||||
|
||||
/**************************
|
||||
* CHARACTER MINIMIZATION *
|
||||
@ -752,36 +766,34 @@ next_del_blksize:
|
||||
alpha_del2++;
|
||||
changed_any = 1;
|
||||
|
||||
} else tmp_buf[i] = orig;
|
||||
} else
|
||||
|
||||
tmp_buf[i] = orig;
|
||||
|
||||
}
|
||||
|
||||
alpha_d_total += alpha_del2;
|
||||
|
||||
OKF("Character minimization done, %u byte%s replaced.",
|
||||
alpha_del2, alpha_del2 == 1 ? "" : "s");
|
||||
OKF("Character minimization done, %u byte%s replaced.", alpha_del2,
|
||||
alpha_del2 == 1 ? "" : "s");
|
||||
|
||||
if (changed_any) goto next_pass;
|
||||
|
||||
finalize_all:
|
||||
|
||||
SAYF("\n"
|
||||
cGRA " File size reduced by : " cRST "%0.02f%% (to %u byte%s)\n"
|
||||
cGRA " Characters simplified : " cRST "%0.02f%%\n"
|
||||
cGRA " Number of execs done : " cRST "%u\n"
|
||||
cGRA " Fruitless execs : " cRST "path=%u crash=%u hang=%s%u\n\n",
|
||||
SAYF("\n" cGRA " File size reduced by : " cRST
|
||||
"%0.02f%% (to %u byte%s)\n" cGRA " Characters simplified : " cRST
|
||||
"%0.02f%%\n" cGRA " Number of execs done : " cRST "%u\n" cGRA
|
||||
" Fruitless execs : " cRST "path=%u crash=%u hang=%s%u\n\n",
|
||||
100 - ((double)in_len) * 100 / orig_len, in_len, in_len == 1 ? "" : "s",
|
||||
((double)(alpha_d_total)) * 100 / (in_len ? in_len : 1),
|
||||
total_execs, missed_paths, missed_crashes, missed_hangs ? cLRD : "",
|
||||
missed_hangs);
|
||||
((double)(alpha_d_total)) * 100 / (in_len ? in_len : 1), total_execs,
|
||||
missed_paths, missed_crashes, missed_hangs ? cLRD : "", missed_hangs);
|
||||
|
||||
if (total_execs > 50 && missed_hangs * 10 > total_execs)
|
||||
WARNF(cLRD "Frequent timeouts - results may be skewed." cRST);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Handle Ctrl-C and the like. */
|
||||
|
||||
static void handle_stop_sig(int sig) {
|
||||
@ -792,7 +804,6 @@ static void handle_stop_sig(int sig) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Do basic preparations - persistent fds, filenames, etc. */
|
||||
|
||||
static void set_up_environment(void) {
|
||||
@ -823,7 +834,6 @@ static void set_up_environment(void) {
|
||||
|
||||
if (out_fd < 0) PFATAL("Unable to create '%s'", out_file);
|
||||
|
||||
|
||||
/* Set sane defaults... */
|
||||
|
||||
x = getenv("ASAN_OPTIONS");
|
||||
@ -843,18 +853,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:"
|
||||
@ -863,21 +875,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);
|
||||
@ -896,46 +909,46 @@ 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 shrunk by the tool\n"
|
||||
" -o file - final output location for the minimized data\n\n"
|
||||
" -i file - input test case to be shrunk by the tool\n"
|
||||
" -o file - final output location for the minimized data\n\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"
|
||||
" (Not necessary, here for consistency with other afl-* tools)\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"
|
||||
" (Not necessary, here for consistency with other afl-* "
|
||||
"tools)\n\n"
|
||||
|
||||
"Minimization settings:\n\n"
|
||||
"Minimization settings:\n\n"
|
||||
|
||||
" -e - solve for edge coverage only, ignore hit counts\n"
|
||||
" -x - treat non-zero exit codes as crashes\n\n"
|
||||
" -e - solve for edge coverage only, ignore hit counts\n"
|
||||
" -x - treat non-zero exit codes as crashes\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"))) {
|
||||
@ -958,7 +971,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;
|
||||
|
||||
@ -970,7 +985,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;
|
||||
@ -983,13 +999,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);
|
||||
|
||||
@ -1004,8 +1019,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;
|
||||
@ -1029,7 +1043,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)) {
|
||||
|
||||
@ -1056,8 +1072,6 @@ static void read_bitmap(u8* fname) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Main entry point */
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
@ -1070,7 +1084,7 @@ int main(int argc, char** argv) {
|
||||
|
||||
SAYF(cCYA "afl-tmin" VERSION cRST " by <lcamtuf@google.com>\n");
|
||||
|
||||
while ((opt = getopt(argc,argv,"+i:o:f:m:t:B:xeQU")) > 0)
|
||||
while ((opt = getopt(argc, argv, "+i:o:f:m:t:B:xeQU")) > 0)
|
||||
|
||||
switch (opt) {
|
||||
|
||||
@ -1090,7 +1104,7 @@ int main(int argc, char** argv) {
|
||||
|
||||
if (out_file) FATAL("Multiple -f options not supported");
|
||||
use_stdin = 0;
|
||||
out_file = optarg;
|
||||
out_file = optarg;
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
@ -1107,40 +1121,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':
|
||||
|
||||
@ -1170,7 +1185,7 @@ int main(int argc, char** argv) {
|
||||
unicorn_mode = 1;
|
||||
break;
|
||||
|
||||
case 'B': /* load bitmap */
|
||||
case 'B': /* load bitmap */
|
||||
|
||||
/* This is a secret undocumented option! It is speculated to be useful
|
||||
if you have a baseline "boring" input file and another "interesting"
|
||||
@ -1190,9 +1205,7 @@ int main(int argc, char** argv) {
|
||||
read_bitmap(optarg);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
usage(argv[0]);
|
||||
default: usage(argv[0]);
|
||||
|
||||
}
|
||||
|
||||
@ -1230,15 +1243,16 @@ int main(int argc, char** argv) {
|
||||
|
||||
if (!crash_mode) {
|
||||
|
||||
OKF("Program terminates normally, minimizing in "
|
||||
cCYA "instrumented" cRST " mode.");
|
||||
OKF("Program terminates normally, minimizing in " cCYA "instrumented" cRST
|
||||
" mode.");
|
||||
|
||||
if (!anything_set()) FATAL("No instrumentation detected.");
|
||||
if (!anything_set()) FATAL("No instrumentation detected.");
|
||||
|
||||
} else {
|
||||
|
||||
OKF("Program exits with a signal, minimizing in " cMGN "%scrash" cRST
|
||||
" mode.", exact_mode ? "EXACT " : "");
|
||||
OKF("Program exits with a signal, minimizing in " cMGN "%scrash" cRST
|
||||
" mode.",
|
||||
exact_mode ? "EXACT " : "");
|
||||
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user