mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-15 11:28:08 +00:00
step 1
This commit is contained in:
@ -98,7 +98,7 @@ ifneq "$(shell uname -m)" "x86_64"
|
||||
endif
|
||||
|
||||
CFLAGS ?= -O3 -funroll-loops $(CFLAGS_OPT)
|
||||
override CFLAGS += -Wall -Wextra -Werror -g -Wno-pointer-sign \
|
||||
override CFLAGS += -g -Wno-pointer-sign \
|
||||
-I include/ -DAFL_PATH=\"$(HELPER_PATH)\" \
|
||||
-DBIN_PATH=\"$(BIN_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\"
|
||||
|
||||
|
@ -372,6 +372,8 @@ typedef struct afl_state {
|
||||
|
||||
char **argv; /* argv if needed */
|
||||
|
||||
char **argv_taint; /* argv for taint mode */
|
||||
|
||||
/* MOpt:
|
||||
Lots of globals, but mostly for the status UI and other things where it
|
||||
really makes no sense to haul them around as function parameters. */
|
||||
@ -581,6 +583,9 @@ typedef struct afl_state {
|
||||
char * cmplog_binary;
|
||||
afl_forkserver_t cmplog_fsrv; /* cmplog has its own little forkserver */
|
||||
|
||||
/* Taint mode */
|
||||
afl_forkserver_t taint_fsrv; /* taint mode has its own little forkserver */
|
||||
|
||||
/* Custom mutators */
|
||||
struct custom_mutator *mutator;
|
||||
|
||||
@ -889,6 +894,7 @@ u32 calculate_score(afl_state_t *, struct queue_entry *);
|
||||
|
||||
void write_bitmap(afl_state_t *);
|
||||
u32 count_bits(afl_state_t *, u8 *);
|
||||
u32 count_bits_len(afl_state_t *, u8 *, u32);
|
||||
u32 count_bytes(afl_state_t *, u8 *);
|
||||
u32 count_non_255_bytes(afl_state_t *, u8 *);
|
||||
#ifdef WORD_SIZE_64
|
||||
|
@ -80,6 +80,8 @@ typedef struct afl_forkserver {
|
||||
|
||||
u8 qemu_mode; /* if running in qemu mode or not */
|
||||
|
||||
u8 taint_mode; /* if running taint analysis or not */
|
||||
|
||||
u32 *shmem_fuzz_len; /* length of the fuzzing test case */
|
||||
|
||||
u8 *shmem_fuzz; /* allocated memory for fuzzing */
|
||||
|
@ -18,7 +18,7 @@ Only touched bytes are then fuzzed by afl-fuzz
|
||||
|
||||
## How to use
|
||||
|
||||
Add the -T flag to afl-fuzz
|
||||
Add the -A flag to afl-fuzz
|
||||
|
||||
## Caveats
|
||||
|
||||
|
@ -138,6 +138,7 @@ void argv_cpy_free(char **argv) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Rewrite argv for QEMU. */
|
||||
|
||||
char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) {
|
||||
|
@ -481,6 +481,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
||||
"handle_sigill=0",
|
||||
0);
|
||||
|
||||
fprintf(stderr, "init %p\n", fsrv->init_child_func);
|
||||
fsrv->init_child_func(fsrv, argv);
|
||||
|
||||
/* Use a distinctive bitmap signature to tell the parent about execv()
|
||||
@ -496,11 +497,21 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
||||
|
||||
char pid_buf[16];
|
||||
sprintf(pid_buf, "%d", fsrv->fsrv_pid);
|
||||
if (fsrv->cmplog_binary)
|
||||
|
||||
if (fsrv->qemu_mode == 2) {
|
||||
|
||||
setenv("__AFL_TARGET_PID3", pid_buf, 1);
|
||||
|
||||
} else if (fsrv->cmplog_binary) {
|
||||
|
||||
setenv("__AFL_TARGET_PID2", pid_buf, 1);
|
||||
else
|
||||
|
||||
} else {
|
||||
|
||||
setenv("__AFL_TARGET_PID1", pid_buf, 1);
|
||||
|
||||
}
|
||||
|
||||
/* Close the unneeded endpoints. */
|
||||
|
||||
close(ctl_pipe[0]);
|
||||
|
@ -177,6 +177,38 @@ u32 count_bits(afl_state_t *afl, u8 *mem) {
|
||||
|
||||
}
|
||||
|
||||
u32 count_bits_len(afl_state_t *afl, u8 *mem, u32 len) {
|
||||
|
||||
u32 *ptr = (u32 *)mem;
|
||||
u32 i = (len >> 2);
|
||||
u32 ret = 0;
|
||||
|
||||
if (len % 4) i++;
|
||||
|
||||
while (i--) {
|
||||
|
||||
u32 v = *(ptr++);
|
||||
|
||||
/* This gets called on the inverse, virgin bitmap; optimize for sparse
|
||||
data. */
|
||||
|
||||
if (v == 0xffffffff) {
|
||||
|
||||
ret += 32;
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
v -= ((v >> 1) & 0x55555555);
|
||||
v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
|
||||
ret += (((v + (v >> 4)) & 0xF0F0F0F) * 0x01010101) >> 24;
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
/* Count the number of bytes set in the bitmap. Called fairly sporadically,
|
||||
mostly to update the status screen or calibrate and examine confirmed
|
||||
new paths. */
|
||||
|
@ -471,6 +471,19 @@ abort_calibration:
|
||||
afl->stage_cur = old_sc;
|
||||
afl->stage_max = old_sm;
|
||||
|
||||
/* if taint mode was selected, run the taint */
|
||||
|
||||
if (afl->fsrv.taint_mode) {
|
||||
write_to_testcase(afl, use_mem, q->len);
|
||||
if (afl_fsrv_run_target(&afl->taint_fsrv, use_tmout, &afl->stop_soon) == 0) {
|
||||
u32 len = q->len / 8;
|
||||
if (q->len % 8) len++;
|
||||
u32 bits = count_bits_len(afl, afl->taint_fsrv.trace_bits, len);
|
||||
if (afl->debug) fprintf(stderr, "Debug: tainted bytes: %u\n", bits);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (!first_run) { show_stats(afl); }
|
||||
|
||||
return fault;
|
||||
|
@ -53,6 +53,9 @@ static void at_exit() {
|
||||
ptr = getenv("__AFL_TARGET_PID2");
|
||||
if (ptr && *ptr && (i = atoi(ptr)) > 0) kill(i, SIGKILL);
|
||||
|
||||
ptr = getenv("__AFL_TARGET_PID3");
|
||||
if (ptr && *ptr && (i = atoi(ptr)) > 0) kill(i, SIGKILL);
|
||||
|
||||
i = 0;
|
||||
while (list[i] != NULL) {
|
||||
|
||||
@ -89,6 +92,7 @@ static void usage(u8 *argv0, int more_help) {
|
||||
" -o dir - output directory for fuzzer findings\n\n"
|
||||
|
||||
"Execution control settings:\n"
|
||||
" -A - use first level taint analysis (see qemu_taint/README.md)\n"
|
||||
" -p schedule - power schedules compute a seed's performance score. "
|
||||
"<explore\n"
|
||||
" (default), fast, coe, lin, quad, exploit, mmopt, "
|
||||
@ -277,10 +281,15 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
while ((opt = getopt(
|
||||
argc, argv,
|
||||
"+b:c:i:I:o:f:F:m:t:T:dDnCB:S:M:x:QNUWe:p:s:V:E:L:hRP:")) > 0) {
|
||||
"+b:c:i:I:o:f:F:m:t:T:dDnCB:S:M:x:QANUWe:p:s:V:E:L:hRP:")) > 0) {
|
||||
|
||||
switch (opt) {
|
||||
|
||||
case 'A':
|
||||
afl->fsrv.taint_mode = 1;
|
||||
if (!mem_limit_given) { afl->fsrv.mem_limit = MEM_LIMIT_QEMU; }
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
afl->infoexec = optarg;
|
||||
break;
|
||||
@ -485,7 +494,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
if (!optarg) { FATAL("Wrong usage of -m"); }
|
||||
|
||||
if (!strcmp(optarg, "none")) {
|
||||
if (!strcmp(optarg, "none") || !strcmp(optarg, "0")) {
|
||||
|
||||
afl->fsrv.mem_limit = 0;
|
||||
break;
|
||||
@ -815,6 +824,14 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
}
|
||||
|
||||
if (afl->fsrv.taint_mode && afl->fsrv.map_size < (MAX_FILE / 8) + 1) {
|
||||
|
||||
afl->shm.map_size = (MAX_FILE / 8);
|
||||
if (MAX_FILE % 8) afl->shm.map_size++;
|
||||
afl->fsrv.map_size = afl->shm.map_size;
|
||||
|
||||
}
|
||||
|
||||
if (!mem_limit_given && afl->shm.cmplog_mode) afl->fsrv.mem_limit += 260;
|
||||
|
||||
OKF("afl++ is maintained by Marc \"van Hauser\" Heuse, Heiko \"hexcoder\" "
|
||||
@ -869,6 +886,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
if (afl->crash_mode) { FATAL("-C and -n are mutually exclusive"); }
|
||||
if (afl->fsrv.qemu_mode) { FATAL("-Q and -n are mutually exclusive"); }
|
||||
if (afl->unicorn_mode) { FATAL("-U and -n are mutually exclusive"); }
|
||||
if (afl->fsrv.taint_mode) { FATAL("-A and -n are mutually exclusive"); }
|
||||
|
||||
}
|
||||
|
||||
@ -969,7 +987,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
if (afl->afl_env.afl_preload) {
|
||||
|
||||
if (afl->fsrv.qemu_mode) {
|
||||
if (afl->fsrv.qemu_mode || afl->fsrv.taint_mode) {
|
||||
|
||||
u8 *qemu_preload = getenv("QEMU_SET_ENV");
|
||||
u8 *afl_preload = getenv("AFL_PRELOAD");
|
||||
@ -1220,7 +1238,6 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
ACTF("Spawning cmplog forkserver");
|
||||
afl_fsrv_init_dup(&afl->cmplog_fsrv, &afl->fsrv);
|
||||
// TODO: this is semi-nice
|
||||
afl->cmplog_fsrv.trace_bits = afl->fsrv.trace_bits;
|
||||
afl->cmplog_fsrv.qemu_mode = afl->fsrv.qemu_mode;
|
||||
afl->cmplog_fsrv.cmplog_binary = afl->cmplog_binary;
|
||||
@ -1231,6 +1248,29 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
}
|
||||
|
||||
if (afl->fsrv.taint_mode) {
|
||||
|
||||
ACTF("Spawning qemu_taint forkserver");
|
||||
afl_fsrv_init_dup(&afl->taint_fsrv, &afl->fsrv);
|
||||
afl->taint_fsrv.qemu_mode = 2;
|
||||
afl->taint_fsrv.trace_bits = afl->fsrv.trace_bits;
|
||||
ck_free(afl->taint_fsrv.target_path);
|
||||
afl->taint_fsrv.target_path = ck_strdup(afl->fsrv.target_path);
|
||||
afl->argv_taint = get_qemu_argv(argv[0], &afl->taint_fsrv.target_path,
|
||||
argc - optind, argv + optind);
|
||||
u32 len = strlen(afl->taint_fsrv.target_path);
|
||||
strcpy(afl->taint_fsrv.target_path + len - 5, "taint");
|
||||
strcpy((afl->argv_taint[0]) + len - 5, "taint");
|
||||
if (afl->fsrv.use_stdin)
|
||||
unsetenv("AFL_TAINT_INPUT");
|
||||
else
|
||||
setenv("AFL_TAINT_INPUT", afl->fsrv.out_file, 1);
|
||||
afl_fsrv_start(&afl->taint_fsrv, afl->argv_taint, &afl->stop_soon,
|
||||
afl->afl_env.afl_debug_child_output);
|
||||
OKF("Taint forkserver successfully started");
|
||||
|
||||
}
|
||||
|
||||
perform_dry_run(afl);
|
||||
|
||||
cull_queue(afl);
|
||||
@ -1493,8 +1533,11 @@ stop_fuzzing:
|
||||
|
||||
}
|
||||
|
||||
if (afl->cmplog_binary) afl_fsrv_deinit(&afl->cmplog_fsrv);
|
||||
if (afl->fsrv.taint_mode) afl_fsrv_deinit(&afl->taint_fsrv);
|
||||
afl_fsrv_deinit(&afl->fsrv);
|
||||
if (afl->orig_cmdline) { ck_free(afl->orig_cmdline); }
|
||||
if (afl->argv_taint) { ck_free(afl->argv_taint); }
|
||||
ck_free(afl->fsrv.target_path);
|
||||
ck_free(afl->fsrv.out_file);
|
||||
ck_free(afl->sync_id);
|
||||
|
Reference in New Issue
Block a user