fauxserver

This commit is contained in:
Dominik Maier
2020-03-15 17:02:48 +01:00
parent f3799f94bf
commit 15ba6249fc
8 changed files with 175 additions and 245 deletions

View File

@ -146,7 +146,7 @@ ifdef STATIC
PYFLAGS= PYFLAGS=
CFLAGS += -static CFLAGS += -static
LDFLAGS += -lm -lrt -lpthread -lz -lutil LDFLAGS += -lm -lpthread -lz -lutil
endif endif
ifeq "$(shell echo '$(HASH)include <sys/ipc.h>@$(HASH)include <sys/shm.h>@int main() { int _id = shmget(IPC_PRIVATE, 65536, IPC_CREAT | IPC_EXCL | 0600); shmctl(_id, IPC_RMID, 0); return 0;}' | tr @ '\n' | $(CC) -x c - -o .test2 2>/dev/null && echo 1 || echo 0 ; rm -f .test2 )" "1" ifeq "$(shell echo '$(HASH)include <sys/ipc.h>@$(HASH)include <sys/shm.h>@int main() { int _id = shmget(IPC_PRIVATE, 65536, IPC_CREAT | IPC_EXCL | 0600); shmctl(_id, IPC_RMID, 0); return 0;}' | tr @ '\n' | $(CC) -x c - -o .test2 2>/dev/null && echo 1 || echo 0 ; rm -f .test2 )" "1"
@ -154,13 +154,13 @@ ifeq "$(shell echo '$(HASH)include <sys/ipc.h>@$(HASH)include <sys/shm.h>@int ma
else else
SHMAT_OK=0 SHMAT_OK=0
CFLAGS+=-DUSEMMAP=1 CFLAGS+=-DUSEMMAP=1
LDFLAGS+=-Wno-deprecated-declarations -lrt LDFLAGS+=-Wno-deprecated-declarations
endif endif
ifeq "$(TEST_MMAP)" "1" ifeq "$(TEST_MMAP)" "1"
SHMAT_OK=0 SHMAT_OK=0
CFLAGS+=-DUSEMMAP=1 CFLAGS+=-DUSEMMAP=1
LDFLAGS+=-Wno-deprecated-declarations -lrt LDFLAGS+=-Wno-deprecated-declarations
endif endif
ifdef ASAN_BUILD ifdef ASAN_BUILD
@ -282,7 +282,7 @@ src/third_party/libradamsa/libradamsa.so: src/third_party/libradamsa/libradamsa.
$(MAKE) -C src/third_party/libradamsa/ CFLAGS="$(CFLAGS)" $(MAKE) -C src/third_party/libradamsa/ CFLAGS="$(CFLAGS)"
afl-fuzz: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o | test_x86 afl-fuzz: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o | test_x86
$(CC) $(CFLAGS) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) -lrt src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o $@ $(PYFLAGS) $(LDFLAGS) $(CC) $(CFLAGS) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o $@ $(PYFLAGS) $(LDFLAGS)
afl-showmap: src/afl-showmap.c src/afl-common.o src/afl-sharedmem.o $(COMM_HDR) | test_x86 afl-showmap: src/afl-showmap.c src/afl-common.o src/afl-sharedmem.o $(COMM_HDR) | test_x86
$(CC) $(CFLAGS) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o $@ $(LDFLAGS) $(CC) $(CFLAGS) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o $@ $(LDFLAGS)

View File

@ -101,7 +101,7 @@
#include <TargetConditionals.h> #include <TargetConditionals.h>
#endif #endif
#undef LIST_FOREACH /* clashes with FreeBSD */ #undef LIST_FOREACH /* clashes with FreeBSD */
#include "list.h" #include "list.h"
#ifndef SIMPLE_FILES #ifndef SIMPLE_FILES
#define CASE_PREFIX "id:" #define CASE_PREFIX "id:"

View File

@ -42,7 +42,7 @@ typedef struct afl_forkserver {
child_pid, /* PID of the fuzzed program */ child_pid, /* PID of the fuzzed program */
out_dir_fd; /* FD of the lock file */ out_dir_fd; /* FD of the lock file */
s32 out_fd, /* Persistent fd for afl->fsrv.out_file */ s32 out_fd, /* Persistent fd for fsrv->out_file */
#ifndef HAVE_ARC4RANDOM #ifndef HAVE_ARC4RANDOM
dev_urandom_fd, /* Persistent fd for /dev/urandom */ dev_urandom_fd, /* Persistent fd for /dev/urandom */
#endif #endif
@ -60,6 +60,8 @@ typedef struct afl_forkserver {
u8 child_timed_out; /* Traced process timed out? */ u8 child_timed_out; /* Traced process timed out? */
u8 use_fauxsrv; /* Fauxsrv for non-forking targets? */
} afl_forkserver_t; } afl_forkserver_t;
void handle_timeout(int sig); void handle_timeout(int sig);

View File

@ -42,15 +42,12 @@ extern u8 be_quiet;
void detect_file_args(char **argv, u8 *prog_in, u8 *use_stdin) { void detect_file_args(char **argv, u8 *prog_in, u8 *use_stdin) {
u32 i = 0; u32 i = 0;
u8 cwd[PATH_MAX]; u8 cwd[PATH_MAX];
if (getcwd(cwd, (size_t)sizeof(cwd)) == NULL) { if (getcwd(cwd, (size_t)sizeof(cwd)) == NULL) { PFATAL("getcwd() failed"); }
PFATAL("getcwd() failed");
}
/* we are working with libc-heap-allocated argvs. So do not mix them with /* we are working with libc-heap-allocated argvs. So do not mix them with
* other allocation APIs like ck_alloc. That would disturb the free() calls. */ * other allocation APIs like ck_alloc. That would disturb the free() calls.
*/
while (argv[i]) { while (argv[i]) {
u8 *aa_loc = strstr(argv[i], "@@"); u8 *aa_loc = strstr(argv[i], "@@");
@ -72,10 +69,15 @@ void detect_file_args(char **argv, u8 *prog_in, u8 *use_stdin) {
/* Construct a replacement argv value. */ /* Construct a replacement argv value. */
if (prog_in[0] == '/') { if (prog_in[0] == '/') {
n_arg = alloc_printf("%s%s%s", argv[i], prog_in, aa_loc + 2); n_arg = alloc_printf("%s%s%s", argv[i], prog_in, aa_loc + 2);
} else { } else {
n_arg = alloc_printf("%s%s/%s%s", argv[i], cwd, prog_in, aa_loc + 2); n_arg = alloc_printf("%s%s/%s%s", argv[i], cwd, prog_in, aa_loc + 2);
} }
ck_free(argv[i]); ck_free(argv[i]);
argv[i] = n_arg; argv[i] = n_arg;
@ -86,7 +88,9 @@ void detect_file_args(char **argv, u8 *prog_in, u8 *use_stdin) {
i++; i++;
} }
/* argvs are automatically freed at exit. */ /* argvs are automatically freed at exit. */
} }
/* duplicate the system argv so that /* duplicate the system argv so that

View File

@ -43,6 +43,10 @@
#include <sys/resource.h> #include <sys/resource.h>
#include <sys/select.h> #include <sys/select.h>
/**
* The correct fds for reading and writing pipes
*/
/* Describe integer as memory size. */ /* Describe integer as memory size. */
extern u8 *doc_path; extern u8 *doc_path;
@ -151,10 +155,87 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) {
fsrv->child_pid = -1; fsrv->child_pid = -1;
fsrv->out_dir_fd = -1; fsrv->out_dir_fd = -1;
fsrv->use_fauxsrv = 0;
list_append(&fsrv_list, fsrv); list_append(&fsrv_list, fsrv);
} }
/* Internal forkserver for dumb_mode=1 and non-forkserver mode runs.
It execvs for each fork, forwarding exit codes and child pids to afl. */
static void afl_fauxsrv_execv(afl_forkserver_t *fsrv, char **argv) {
static unsigned char tmp[4] = {0};
pid_t child_pid = -1;
/* Phone home and tell the parent that we're OK. If parent isn't there,
assume we're not running in forkserver mode and just execute program. */
if (write(FORKSRV_FD + 1, tmp, 4) != 4) abort(); // TODO: Abort?
void (*old_sigchld_handler)(int) = signal(SIGCHLD, SIG_DFL);
while (1) {
uint32_t was_killed;
int status;
/* Wait for parent by reading from the pipe. Exit if read fails. */
if (read(FORKSRV_FD, &was_killed, 4) != 4) exit(0);
/* Create a clone of our process. */
child_pid = fork();
if (child_pid < 0) PFATAL("Fork failed");
/* In child process: close fds, resume execution. */
if (!child_pid) { // New child
signal(SIGCHLD, old_sigchld_handler);
// FORKSRV_FD is for communication with AFL, we don't need it in the
// child.
close(FORKSRV_FD);
close(FORKSRV_FD + 1);
// TODO: exec...
execv(fsrv->target_path, argv);
/* Use a distinctive bitmap signature to tell the parent about execv()
falling through. */
*(u32 *)fsrv->trace_bits = EXEC_FAIL_SIG;
PFATAL("Execv failed in fauxserver.");
}
/* In parent process: write PID to AFL. */
if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) exit(0);
/* after child exited, get and relay exit status to parent through waitpid.
*/
if (waitpid(child_pid, &status, 0) < 0) {
// Zombie Child could not be collected. Scary!
PFATAL("Fauxserver could not determin child's exit code. ");
}
/* Relay wait status to AFL pipe, then loop back. */
if (write(FORKSRV_FD + 1, &status, 4) != 4) exit(0);
}
}
/* Spins up fork server (instrumented mode only). The idea is explained here: /* Spins up fork server (instrumented mode only). The idea is explained here:
http://lcamtuf.blogspot.com/2014/10/fuzzing-binaries-without-execve.html http://lcamtuf.blogspot.com/2014/10/fuzzing-binaries-without-execve.html
@ -170,6 +251,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv) {
int status; int status;
s32 rlen; s32 rlen;
if (fsrv->use_fauxsrv) ACTF("Using Fauxserver:");
if (!getenv("AFL_QUIET")) ACTF("Spinning up the fork server..."); if (!getenv("AFL_QUIET")) ACTF("Spinning up the fork server...");
if (pipe(st_pipe) || pipe(ctl_pipe)) PFATAL("pipe() failed"); if (pipe(st_pipe) || pipe(ctl_pipe)) PFATAL("pipe() failed");
@ -284,7 +367,15 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv) {
"msan_track_origins=0", "msan_track_origins=0",
0); 0);
execv(fsrv->target_path, argv); if (fsrv->use_fauxsrv) {
afl_fauxsrv_execv(fsrv, argv);
} else {
execv(fsrv->target_path, argv);
}
/* Use a distinctive bitmap signature to tell the parent about execv() /* Use a distinctive bitmap signature to tell the parent about execv()
falling through. */ falling through. */

View File

@ -39,16 +39,16 @@ void timeout_handle(union sigval timer_data) {
u8 run_target(afl_state_t *afl, u32 timeout) { u8 run_target(afl_state_t *afl, u32 timeout) {
struct sigevent timer_signal_event; s32 res;
static timer_t timer; int sret;
static struct itimerspec timer_period;
static struct timeval it; fd_set readfds;
static u32 prev_timed_out = 0;
static u64 exec_ms = 0; static struct timeval it;
static u32 prev_timed_out = 0;
int status = 0; int status = 0;
u32 tb4; u32 tb4;
int timer_status;
afl->fsrv.child_timed_out = 0; afl->fsrv.child_timed_out = 0;
@ -57,245 +57,77 @@ u8 run_target(afl_state_t *afl, u32 timeout) {
territory. */ territory. */
memset(afl->fsrv.trace_bits, 0, MAP_SIZE); memset(afl->fsrv.trace_bits, 0, MAP_SIZE);
memset(&timer_signal_event, 0, sizeof(struct sigevent));
timer_signal_event.sigev_notify = SIGEV_THREAD;
timer_signal_event.sigev_notify_function = timeout_handle;
MEM_BARRIER(); MEM_BARRIER();
/* If we're running in "dumb" mode, we can't rely on the fork server /* we have the fork server (or faux server) up and running, so simply
logic compiled into the target program, so we will just keep calling tell it to have at it, and then read back PID. */
execve(). There is a bit of code duplication between here and
init_forkserver(), but c'est la vie. */
if (afl->dumb_mode == 1 || afl->no_forkserver) { if ((res = write(afl->fsrv.fsrv_ctl_fd, &prev_timed_out, 4)) != 4) {
afl->fsrv.child_pid = fork(); if (afl->stop_soon) return 0;
RPFATAL(res, "Unable to request new process from fork server (OOM?)");
if (afl->fsrv.child_pid < 0) PFATAL("fork() failed");
if (!afl->fsrv.child_pid) {
struct rlimit r;
if (afl->fsrv.mem_limit) {
r.rlim_max = r.rlim_cur = ((rlim_t)afl->fsrv.mem_limit) << 20;
#ifdef RLIMIT_AS
setrlimit(RLIMIT_AS, &r); /* Ignore errors */
#else
setrlimit(RLIMIT_DATA, &r); /* Ignore errors */
#endif /* ^RLIMIT_AS */
}
r.rlim_max = r.rlim_cur = 0;
setrlimit(RLIMIT_CORE, &r); /* Ignore errors */
/* Isolate the process and configure standard descriptors. If
afl->fsrv.out_file is specified, stdin is /dev/null; otherwise,
afl->fsrv.out_fd is cloned instead. */
setsid();
dup2(afl->fsrv.dev_null_fd, 1);
dup2(afl->fsrv.dev_null_fd, 2);
if (afl->fsrv.out_file) {
dup2(afl->fsrv.dev_null_fd, 0);
} else {
dup2(afl->fsrv.out_fd, 0);
close(afl->fsrv.out_fd);
}
/* On Linux, would be faster to use O_CLOEXEC. Maybe TODO. */
close(afl->fsrv.dev_null_fd);
close(afl->fsrv.out_dir_fd);
#ifndef HAVE_ARC4RANDOM
close(afl->fsrv.dev_urandom_fd);
#endif
close(fileno(afl->fsrv.plot_file));
/* Set sane defaults for ASAN if nothing else specified. */
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:"
"msan_track_origins=0", 0);
execv(afl->fsrv.target_path, afl->argv);
/* Use a distinctive bitmap value to tell the parent about execv()
falling through. */
*(u32 *)afl->fsrv.trace_bits = EXEC_FAIL_SIG;
exit(0);
}
/* Configure timeout using POSIX timers in dumb-mode,
as requested by user, then wait for child to terminate.
*/
timer_signal_event.sigev_value.sival_int = afl->fsrv.child_pid;
timer_status = timer_create(CLOCK_MONOTONIC, &timer_signal_event, &timer);
if (timer_status == -1) { FATAL("Failed to create Timer"); }
timer_period.it_value.tv_sec = (timeout / 1000);
timer_period.it_value.tv_nsec = (timeout % 1000) * 1000000;
timer_period.it_interval.tv_sec = 0;
timer_period.it_interval.tv_nsec = 0;
timer_status = timer_settime(timer, 0, &timer_period, NULL);
if (timer_status == -1) {
timer_delete(timer);
if (errno == EINVAL) {
FATAL("Failed to set the timer. The timeout given is invalid.");
} else {
FATAL("Failed to set the timer to the given timeout");
}
}
} else {
/* In non-dumb mode, we have the fork server up and running, so simply
tell it to have at it, and then read back PID. */
int res;
if ((res = write(afl->fsrv.fsrv_ctl_fd, &prev_timed_out, 4)) != 4) {
if (afl->stop_soon) return 0;
RPFATAL(res, "Unable to request new process from fork server (OOM?)");
}
if ((res = read(afl->fsrv.fsrv_st_fd, &afl->fsrv.child_pid, 4)) != 4) {
if (afl->stop_soon) return 0;
RPFATAL(res, "Unable to request new process from fork server (OOM?)");
}
if (afl->fsrv.child_pid <= 0) FATAL("Fork server is misbehaving (OOM?)");
} }
if (afl->dumb_mode == 1 || afl->no_forkserver) { if ((res = read(afl->fsrv.fsrv_st_fd, &afl->fsrv.child_pid, 4)) != 4) {
if (waitpid(afl->fsrv.child_pid, &status, 0) <= 0) { if (afl->stop_soon) return 0;
RPFATAL(res, "Unable to request new process from fork server (OOM?)");
timer_delete(timer); }
PFATAL("waitpid() failed");
} if (afl->fsrv.child_pid <= 0) FATAL("Fork server is misbehaving (OOM?)");
timer_gettime(timer, &timer_period); /* use select to monitor the forkserver for timeouts. */
exec_ms = (u64)timeout - (timer_period.it_value.tv_sec * 1000 +
timer_period.it_value.tv_nsec / 1000000);
timer_period.it_value.tv_sec = 0;
timer_period.it_value.tv_nsec = 0;
timer_status = timer_settime(timer, 0, &timer_period, NULL); FD_ZERO(&readfds);
FD_SET(afl->fsrv.fsrv_st_fd, &readfds);
it.tv_sec = ((timeout) / 1000);
it.tv_usec = ((timeout) % 1000) * 1000;
if (timer_status == -1) { sret = select(afl->fsrv.fsrv_st_fd + 1, &readfds, NULL, NULL, &it);
timer_delete(timer); if (sret == 0) {
FATAL("Failed to reset the timer.");
} /* If there was no response from forkserver after timeout seconds,
we kill the child. The forkserver should inform us afterwards */
timer_delete(timer); kill(afl->fsrv.child_pid, SIGKILL);
afl->fsrv.child_timed_out = 1;
} else { }
/* In non-dumb mode, use select to monitor the forkserver for timeouts. if ((res = read(afl->fsrv.fsrv_st_fd, &status, 4)) != 4) {
*/
s32 res; if (afl->stop_soon) return 0;
int sret; SAYF("\n" cLRD "[-] " cRST
"Unable to communicate with fork server. Some possible reasons:\n\n"
fd_set readfds; " - You've run out of memory. Use -m to increase the the memory "
FD_ZERO(&readfds); "limit\n"
FD_SET(afl->fsrv.fsrv_st_fd, &readfds); " to something higher than %lld.\n"
it.tv_sec = ((timeout) / 1000); " - The binary or one of the libraries it uses manages to "
it.tv_usec = ((timeout) % 1000) * 1000; "create\n"
" threads before the forkserver initializes.\n"
sret = select(afl->fsrv.fsrv_st_fd + 1, &readfds, NULL, NULL, &it); " - The binary, at least in some circumstances, exits in a way "
"that\n"
if (sret == 0) { " also kills the parent process - raise() could be the "
"culprit.\n"
kill(afl->fsrv.child_pid, SIGKILL); " - If using persistent mode with QEMU, "
"AFL_QEMU_PERSISTENT_ADDR "
} else { "is\n"
" probably not valid (hint: add the base address in case of "
if ((res = read(afl->fsrv.fsrv_st_fd, &status, 4)) != 4) { "PIE)"
"\n\n"
if (afl->stop_soon) return 0; "If all else fails you can disable the fork server via "
SAYF( "AFL_NO_FORKSRV=1.\n",
"\n" cLRD "[-] " cRST afl->fsrv.mem_limit);
"Unable to communicate with fork server. Some possible reasons:\n\n" RPFATAL(res, "Unable to communicate with fork server");
" - You've run out of memory. Use -m to increase the the memory "
"limit\n"
" to something higher than %lld.\n"
" - The binary or one of the libraries it uses manages to "
"create\n"
" threads before the forkserver initializes.\n"
" - The binary, at least in some circumstances, exits in a way "
"that\n"
" also kills the parent process - raise() could be the "
"culprit.\n"
" - If using persistent mode with QEMU, "
"AFL_QEMU_PERSISTENT_ADDR "
"is\n"
" probably not valid (hint: add the base address in case of "
"PIE)"
"\n\n"
"If all else fails you can disable the fork server via "
"AFL_NO_FORKSRV=1.\n",
afl->fsrv.mem_limit);
RPFATAL(res, "Unable to communicate with fork server");
}
}
exec_ms = (u64)timeout - (it.tv_sec * 1000 + it.tv_usec / 1000);
it.tv_sec = 0;
it.tv_usec = 0;
} }
if (!WIFSTOPPED(status)) afl->fsrv.child_pid = 0; if (!WIFSTOPPED(status)) afl->fsrv.child_pid = 0;
if (exec_ms >= timeout) { afl->fsrv.child_timed_out = 1; }
++afl->total_execs; ++afl->total_execs;
/* Any subsequent operations on afl->fsrv.trace_bits must not be moved by the /* Any subsequent operations on afl->fsrv.trace_bits must not be moved by the
@ -494,8 +326,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
/* Make sure the forkserver is up before we do anything, and let's not /* Make sure the forkserver is up before we do anything, and let's not
count its spin-up time toward binary calibration. */ count its spin-up time toward binary calibration. */
if (afl->dumb_mode != 1 && !afl->no_forkserver && !afl->fsrv.fsrv_pid) if (!afl->fsrv.fsrv_pid) afl_fsrv_start(&afl->fsrv, afl->argv);
afl_fsrv_start(&afl->fsrv, afl->argv);
if (afl->dumb_mode != 1 && !afl->no_forkserver && !afl->cmplog_fsrv_pid && if (afl->dumb_mode != 1 && !afl->no_forkserver && !afl->cmplog_fsrv_pid &&
afl->shm.cmplog_mode) afl->shm.cmplog_mode)
init_cmplog_forkserver(afl); init_cmplog_forkserver(afl);

View File

@ -347,9 +347,9 @@ void show_stats(afl_state_t *afl) {
/* Lord, forgive me this. */ /* Lord, forgive me this. */
SAYF(SET_G1 bSTG bLT bH bSTOP cCYA SAYF(SET_G1 bSTG bLT bH bSTOP cCYA
" process timing " bSTG bH30 bH5 bH bHB bH bSTOP cCYA " process timing " bSTG bH30 bH5 bH bHB bH bSTOP cCYA
" overall results " bSTG bH2 bH2 bRT "\n"); " overall results " bSTG bH2 bH2 bRT "\n");
if (afl->dumb_mode) { if (afl->dumb_mode) {
@ -429,9 +429,9 @@ void show_stats(afl_state_t *afl) {
" uniq hangs : " cRST "%-6s" bSTG bV "\n", " uniq hangs : " cRST "%-6s" bSTG bV "\n",
DTD(cur_ms, afl->last_hang_time), tmp); DTD(cur_ms, afl->last_hang_time), tmp);
SAYF(bVR bH bSTOP cCYA SAYF(bVR bH bSTOP cCYA
" cycle progress " bSTG bH10 bH5 bH2 bH2 bHB bH bSTOP cCYA " cycle progress " bSTG bH10 bH5 bH2 bH2 bHB bH bSTOP cCYA
" map coverage " bSTG bH bHT bH20 bH2 bVL "\n"); " map coverage " bSTG bH bHT bH20 bH2 bVL "\n");
/* This gets funny because we want to print several variable-length variables /* This gets funny because we want to print several variable-length variables
together, but then cram them into a fixed-width field - so we need to together, but then cram them into a fixed-width field - so we need to
@ -460,9 +460,9 @@ void show_stats(afl_state_t *afl) {
SAYF(bSTOP " count coverage : " cRST "%-21s" bSTG bV "\n", tmp); SAYF(bSTOP " count coverage : " cRST "%-21s" bSTG bV "\n", tmp);
SAYF(bVR bH bSTOP cCYA SAYF(bVR bH bSTOP cCYA
" stage progress " bSTG bH10 bH5 bH2 bH2 bX bH bSTOP cCYA " stage progress " bSTG bH10 bH5 bH2 bH2 bX bH bSTOP cCYA
" findings in depth " bSTG bH10 bH5 bH2 bH2 bVL "\n"); " findings in depth " bSTG bH10 bH5 bH2 bH2 bVL "\n");
sprintf(tmp, "%s (%0.02f%%)", DI(afl->queued_favored), sprintf(tmp, "%s (%0.02f%%)", DI(afl->queued_favored),
((double)afl->queued_favored) * 100 / afl->queued_paths); ((double)afl->queued_favored) * 100 / afl->queued_paths);
@ -533,7 +533,7 @@ void show_stats(afl_state_t *afl) {
/* Aaaalmost there... hold on! */ /* Aaaalmost there... hold on! */
SAYF(bVR bH cCYA bSTOP SAYF(bVR bH cCYA bSTOP
" fuzzing strategy yields " bSTG bH10 bHT bH10 bH5 bHB bH bSTOP cCYA " fuzzing strategy yields " bSTG bH10 bHT bH10 bH5 bHB bH bSTOP cCYA
" path geometry " bSTG bH5 bH2 bVL "\n"); " path geometry " bSTG bH5 bH2 bVL "\n");

View File

@ -785,6 +785,8 @@ int main(int argc, char **argv_orig, char **envp) {
if (afl->dumb_mode == 2 && afl->no_forkserver) if (afl->dumb_mode == 2 && afl->no_forkserver)
FATAL("AFL_DUMB_FORKSRV and AFL_NO_FORKSRV are mutually exclusive"); FATAL("AFL_DUMB_FORKSRV and AFL_NO_FORKSRV are mutually exclusive");
afl->fsrv.use_fauxsrv = afl->dumb_mode == 1 || afl->no_forkserver;
if (getenv("LD_PRELOAD")) if (getenv("LD_PRELOAD"))
WARNF( WARNF(
"LD_PRELOAD is set, are you sure that is what to you want to do " "LD_PRELOAD is set, are you sure that is what to you want to do "