mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-15 03:18:07 +00:00
step 1
This commit is contained in:
@ -98,7 +98,7 @@ ifneq "$(shell uname -m)" "x86_64"
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
CFLAGS ?= -O3 -funroll-loops $(CFLAGS_OPT)
|
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)\" \
|
-I include/ -DAFL_PATH=\"$(HELPER_PATH)\" \
|
||||||
-DBIN_PATH=\"$(BIN_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\"
|
-DBIN_PATH=\"$(BIN_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\"
|
||||||
|
|
||||||
|
@ -371,6 +371,8 @@ typedef struct afl_state {
|
|||||||
afl_env_vars_t afl_env;
|
afl_env_vars_t afl_env;
|
||||||
|
|
||||||
char **argv; /* argv if needed */
|
char **argv; /* argv if needed */
|
||||||
|
|
||||||
|
char **argv_taint; /* argv for taint mode */
|
||||||
|
|
||||||
/* MOpt:
|
/* MOpt:
|
||||||
Lots of globals, but mostly for the status UI and other things where it
|
Lots of globals, but mostly for the status UI and other things where it
|
||||||
@ -581,6 +583,9 @@ typedef struct afl_state {
|
|||||||
char * cmplog_binary;
|
char * cmplog_binary;
|
||||||
afl_forkserver_t cmplog_fsrv; /* cmplog has its own little forkserver */
|
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 */
|
/* Custom mutators */
|
||||||
struct custom_mutator *mutator;
|
struct custom_mutator *mutator;
|
||||||
|
|
||||||
@ -889,6 +894,7 @@ u32 calculate_score(afl_state_t *, struct queue_entry *);
|
|||||||
|
|
||||||
void write_bitmap(afl_state_t *);
|
void write_bitmap(afl_state_t *);
|
||||||
u32 count_bits(afl_state_t *, u8 *);
|
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_bytes(afl_state_t *, u8 *);
|
||||||
u32 count_non_255_bytes(afl_state_t *, u8 *);
|
u32 count_non_255_bytes(afl_state_t *, u8 *);
|
||||||
#ifdef WORD_SIZE_64
|
#ifdef WORD_SIZE_64
|
||||||
|
@ -79,6 +79,8 @@ typedef struct afl_forkserver {
|
|||||||
u8 use_fauxsrv; /* Fauxsrv for non-forking targets? */
|
u8 use_fauxsrv; /* Fauxsrv for non-forking targets? */
|
||||||
|
|
||||||
u8 qemu_mode; /* if running in qemu mode or not */
|
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 */
|
u32 *shmem_fuzz_len; /* length of the fuzzing test case */
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ Only touched bytes are then fuzzed by afl-fuzz
|
|||||||
|
|
||||||
## How to use
|
## How to use
|
||||||
|
|
||||||
Add the -T flag to afl-fuzz
|
Add the -A flag to afl-fuzz
|
||||||
|
|
||||||
## Caveats
|
## Caveats
|
||||||
|
|
||||||
|
@ -138,6 +138,7 @@ void argv_cpy_free(char **argv) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Rewrite argv for QEMU. */
|
/* Rewrite argv for QEMU. */
|
||||||
|
|
||||||
char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) {
|
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",
|
"handle_sigill=0",
|
||||||
0);
|
0);
|
||||||
|
|
||||||
|
fprintf(stderr, "init %p\n", fsrv->init_child_func);
|
||||||
fsrv->init_child_func(fsrv, argv);
|
fsrv->init_child_func(fsrv, argv);
|
||||||
|
|
||||||
/* Use a distinctive bitmap signature to tell the parent about execv()
|
/* Use a distinctive bitmap signature to tell the parent about execv()
|
||||||
@ -496,10 +497,20 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
|||||||
|
|
||||||
char pid_buf[16];
|
char pid_buf[16];
|
||||||
sprintf(pid_buf, "%d", fsrv->fsrv_pid);
|
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);
|
setenv("__AFL_TARGET_PID2", pid_buf, 1);
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
setenv("__AFL_TARGET_PID1", pid_buf, 1);
|
setenv("__AFL_TARGET_PID1", pid_buf, 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Close the unneeded endpoints. */
|
/* Close the unneeded endpoints. */
|
||||||
|
|
||||||
|
@ -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,
|
/* Count the number of bytes set in the bitmap. Called fairly sporadically,
|
||||||
mostly to update the status screen or calibrate and examine confirmed
|
mostly to update the status screen or calibrate and examine confirmed
|
||||||
new paths. */
|
new paths. */
|
||||||
|
@ -471,6 +471,19 @@ abort_calibration:
|
|||||||
afl->stage_cur = old_sc;
|
afl->stage_cur = old_sc;
|
||||||
afl->stage_max = old_sm;
|
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); }
|
if (!first_run) { show_stats(afl); }
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
|
@ -53,6 +53,9 @@ static void at_exit() {
|
|||||||
ptr = getenv("__AFL_TARGET_PID2");
|
ptr = getenv("__AFL_TARGET_PID2");
|
||||||
if (ptr && *ptr && (i = atoi(ptr)) > 0) kill(i, SIGKILL);
|
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;
|
i = 0;
|
||||||
while (list[i] != NULL) {
|
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"
|
" -o dir - output directory for fuzzer findings\n\n"
|
||||||
|
|
||||||
"Execution control settings:\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. "
|
" -p schedule - power schedules compute a seed's performance score. "
|
||||||
"<explore\n"
|
"<explore\n"
|
||||||
" (default), fast, coe, lin, quad, exploit, mmopt, "
|
" (default), fast, coe, lin, quad, exploit, mmopt, "
|
||||||
@ -277,10 +281,15 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
while ((opt = getopt(
|
while ((opt = getopt(
|
||||||
argc, argv,
|
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) {
|
switch (opt) {
|
||||||
|
|
||||||
|
case 'A':
|
||||||
|
afl->fsrv.taint_mode = 1;
|
||||||
|
if (!mem_limit_given) { afl->fsrv.mem_limit = MEM_LIMIT_QEMU; }
|
||||||
|
break;
|
||||||
|
|
||||||
case 'I':
|
case 'I':
|
||||||
afl->infoexec = optarg;
|
afl->infoexec = optarg;
|
||||||
break;
|
break;
|
||||||
@ -485,7 +494,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
if (!optarg) { FATAL("Wrong usage of -m"); }
|
if (!optarg) { FATAL("Wrong usage of -m"); }
|
||||||
|
|
||||||
if (!strcmp(optarg, "none")) {
|
if (!strcmp(optarg, "none") || !strcmp(optarg, "0")) {
|
||||||
|
|
||||||
afl->fsrv.mem_limit = 0;
|
afl->fsrv.mem_limit = 0;
|
||||||
break;
|
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;
|
if (!mem_limit_given && afl->shm.cmplog_mode) afl->fsrv.mem_limit += 260;
|
||||||
|
|
||||||
OKF("afl++ is maintained by Marc \"van Hauser\" Heuse, Heiko \"hexcoder\" "
|
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->crash_mode) { FATAL("-C and -n are mutually exclusive"); }
|
||||||
if (afl->fsrv.qemu_mode) { FATAL("-Q 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->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->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 *qemu_preload = getenv("QEMU_SET_ENV");
|
||||||
u8 *afl_preload = getenv("AFL_PRELOAD");
|
u8 *afl_preload = getenv("AFL_PRELOAD");
|
||||||
@ -1220,7 +1238,6 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
ACTF("Spawning cmplog forkserver");
|
ACTF("Spawning cmplog forkserver");
|
||||||
afl_fsrv_init_dup(&afl->cmplog_fsrv, &afl->fsrv);
|
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.trace_bits = afl->fsrv.trace_bits;
|
||||||
afl->cmplog_fsrv.qemu_mode = afl->fsrv.qemu_mode;
|
afl->cmplog_fsrv.qemu_mode = afl->fsrv.qemu_mode;
|
||||||
afl->cmplog_fsrv.cmplog_binary = afl->cmplog_binary;
|
afl->cmplog_fsrv.cmplog_binary = afl->cmplog_binary;
|
||||||
@ -1230,6 +1247,29 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
OKF("Cmplog forkserver successfully started");
|
OKF("Cmplog forkserver successfully started");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
perform_dry_run(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);
|
afl_fsrv_deinit(&afl->fsrv);
|
||||||
if (afl->orig_cmdline) { ck_free(afl->orig_cmdline); }
|
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.target_path);
|
||||||
ck_free(afl->fsrv.out_file);
|
ck_free(afl->fsrv.out_file);
|
||||||
ck_free(afl->sync_id);
|
ck_free(afl->sync_id);
|
||||||
|
Reference in New Issue
Block a user