mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-14 11:08:06 +00:00
add Nyx mode
This commit is contained in:
9
.gitmodules
vendored
9
.gitmodules
vendored
@ -19,3 +19,12 @@
|
||||
[submodule "coresight_mode/coresight-trace"]
|
||||
path = coresight_mode/coresight-trace
|
||||
url = https://github.com/RICSecLab/coresight-trace.git
|
||||
[submodule "nyx_mode/libnyx"]
|
||||
path = nyx_mode/libnyx
|
||||
url = https://github.com/nyx-fuzz/libnyx.git
|
||||
[submodule "nyx_mode/QEMU-Nyx"]
|
||||
path = nyx_mode/QEMU-Nyx
|
||||
url = https://github.com/nyx-fuzz/qemu-nyx.git
|
||||
[submodule "nyx_mode/packer"]
|
||||
path = nyx_mode/packer
|
||||
url = https://github.com/nyx-fuzz/packer.git
|
||||
|
@ -346,7 +346,7 @@ help:
|
||||
@echo "HELP --- the following make targets exist:"
|
||||
@echo "=========================================="
|
||||
@echo "all: the main afl++ binaries and llvm/gcc instrumentation"
|
||||
@echo "binary-only: everything for binary-only fuzzing: frida_mode, qemu_mode, frida_mode, unicorn_mode, coresight_mode, libdislocator, libtokencap"
|
||||
@echo "binary-only: everything for binary-only fuzzing: frida_mode, nyx_mode, qemu_mode, frida_mode, unicorn_mode, coresight_mode, libdislocator, libtokencap"
|
||||
@echo "source-only: everything for source code fuzzing: libdislocator, libtokencap"
|
||||
@echo "distrib: everything (for both binary-only and source code fuzzing)"
|
||||
@echo "man: creates simple man pages from the help option of the programs"
|
||||
@ -636,6 +636,7 @@ ifeq "$(ARCH)" "aarch64"
|
||||
endif
|
||||
-cd qemu_mode && sh ./build_qemu_support.sh
|
||||
-cd unicorn_mode && unset CFLAGS && sh ./build_unicorn_support.sh
|
||||
-cd nyx_mode && sh ./build_nyx_support.sh
|
||||
endif
|
||||
|
||||
.PHONY: source-only
|
||||
|
@ -33,6 +33,40 @@
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#ifdef __linux__
|
||||
/**
|
||||
* Nyx related typedefs taken from libnyx.h
|
||||
*/
|
||||
|
||||
typedef enum NyxReturnValue {
|
||||
Normal,
|
||||
Crash,
|
||||
Asan,
|
||||
Timout,
|
||||
InvalidWriteToPayload,
|
||||
Error,
|
||||
IoError,
|
||||
Abort,
|
||||
} NyxReturnValue;
|
||||
|
||||
typedef struct{
|
||||
void* (*nyx_new)(const char *sharedir,
|
||||
const char *workdir,
|
||||
uint32_t worker_id,
|
||||
uint32_t cpu_id,
|
||||
bool create_snapshot);
|
||||
void (*nyx_shutdown)(void *qemu_process);
|
||||
void (*nyx_option_set_reload_mode)(void *qemu_process, bool enable);
|
||||
void (*nyx_option_set_timeout)(void *qemu_process, uint8_t timeout_sec, uint32_t timeout_usec);
|
||||
void (*nyx_option_apply)(void *qemu_process);
|
||||
void (*nyx_set_afl_input)(void *qemu_process, uint8_t *buffer, uint32_t size);
|
||||
enum NyxReturnValue (*nyx_exec)(void *qemu_process);
|
||||
uint8_t* (*nyx_get_bitmap_buffer)(void *qemu_process);
|
||||
size_t (*nyx_get_bitmap_buffer_size)(void *qemu_process);
|
||||
} nyx_plugin_handler_t;
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct afl_forkserver {
|
||||
|
||||
/* a program that includes afl-forkserver needs to define these */
|
||||
@ -121,6 +155,17 @@ typedef struct afl_forkserver {
|
||||
|
||||
u8 kill_signal;
|
||||
|
||||
#ifdef __linux__
|
||||
nyx_plugin_handler_t* nyx_handlers;
|
||||
char *out_dir_path; /* path to the output directory */
|
||||
u8 nyx_mode; /* if running in nyx mode or not */
|
||||
bool nyx_parent; /* create initial snapshot */
|
||||
bool nyx_standalone; /* don't serialize the snapshot */
|
||||
void* nyx_runner; /* nyx runner object */
|
||||
u32 nyx_id; /* nyx runner id (0 -> master) */
|
||||
u32 nyx_bind_cpu_id; /* nyx runner cpu id */
|
||||
#endif
|
||||
|
||||
} afl_forkserver_t;
|
||||
|
||||
typedef enum fsrv_run_result {
|
||||
|
1
nyx_mode/QEMU-Nyx
Submodule
1
nyx_mode/QEMU-Nyx
Submodule
Submodule nyx_mode/QEMU-Nyx added at acc90e462b
69
nyx_mode/build_nyx_support.sh
Normal file
69
nyx_mode/build_nyx_support.sh
Normal file
@ -0,0 +1,69 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "================================================="
|
||||
echo " Nyx build script"
|
||||
echo "================================================="
|
||||
echo
|
||||
|
||||
echo "[*] Performing basic sanity checks..."
|
||||
|
||||
if [ ! "`uname -s`" = "Linux" ]; then
|
||||
|
||||
echo "[-] Error: Nyx mode is only available on Linux."
|
||||
exit 0
|
||||
|
||||
fi
|
||||
|
||||
echo "[*] Making sure all Nyx is checked out"
|
||||
|
||||
git status 1>/dev/null 2>/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
git submodule init || exit 1
|
||||
echo "[*] initializing QEMU-Nyx submodule"
|
||||
git submodule update ./QEMU-Nyx 2>/dev/null # ignore errors
|
||||
echo "[*] initializing packer submodule"
|
||||
git submodule update ./packer 2>/dev/null # ignore errors
|
||||
echo "[*] initializing libnyx submodule"
|
||||
git submodule update ./libnyx 2>/dev/null # ignore errors
|
||||
|
||||
else
|
||||
echo "[ ] not a git repo..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
test -d QEMU-Nyx || { echo "[-] Not checked out, please install git or check your internet connection." ; exit 1 ; }
|
||||
test -d packer || { echo "[-] Not checked out, please install git or check your internet connection." ; exit 1 ; }
|
||||
test -d libnyx || { echo "[-] Not checked out, please install git or check your internet connection." ; exit 1 ; }
|
||||
|
||||
echo "[*] checking packer init.cpio.gz ..."
|
||||
if [ ! -f "packer/linux_initramfs/init.cpio.gz" ]; then
|
||||
cd packer/linux_initramfs/
|
||||
sh pack.sh
|
||||
cd ../../
|
||||
fi
|
||||
|
||||
echo "[*] Checking libnyx ..."
|
||||
if [ ! -f "libnyx/libnyx/target/release/liblibnyx.a" ]; then
|
||||
cd libnyx/libnyx
|
||||
cargo build --release
|
||||
cd ../../
|
||||
fi
|
||||
|
||||
echo "[*] Checking QEMU-Nyx ..."
|
||||
if [ ! -f "QEMU-Nyx/x86_64-softmmu/qemu-system-x86_64" ]; then
|
||||
cd QEMU-Nyx/
|
||||
./compile_qemu_nyx.sh
|
||||
cd ..
|
||||
fi
|
||||
|
||||
echo "[*] Checking libnyx.so ..."
|
||||
if [ -f "libnyx/libnyx/target/release/liblibnyx.so" ]; then
|
||||
cp libnyx/libnyx/target/release/liblibnyx.so libnyx.so
|
||||
else
|
||||
echo "[ ] libnyx.so not found..."
|
||||
exit 1
|
||||
fi
|
||||
echo "[+] All done for nyx_mode, enjoy!"
|
||||
|
||||
exit 0
|
1
nyx_mode/libnyx
Submodule
1
nyx_mode/libnyx
Submodule
Submodule nyx_mode/libnyx added at ecbcb2d723
1
nyx_mode/packer
Submodule
1
nyx_mode/packer
Submodule
Submodule nyx_mode/packer added at 87837335d6
@ -71,6 +71,17 @@ static void fsrv_exec_child(afl_forkserver_t *fsrv, char **argv) {
|
||||
|
||||
void afl_fsrv_init(afl_forkserver_t *fsrv) {
|
||||
|
||||
#ifdef __linux__
|
||||
fsrv->nyx_handlers = NULL;
|
||||
fsrv->out_dir_path = NULL;
|
||||
fsrv->nyx_mode = 0;
|
||||
fsrv->nyx_parent = false;
|
||||
fsrv->nyx_standalone = false;
|
||||
fsrv->nyx_runner = NULL;
|
||||
fsrv->nyx_id = 0xFFFFFFFF;
|
||||
fsrv->nyx_bind_cpu_id = 0xFFFFFFFF;
|
||||
#endif
|
||||
|
||||
// this structure needs default so we initialize it if this was not done
|
||||
// already
|
||||
fsrv->out_fd = -1;
|
||||
@ -375,6 +386,72 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
||||
s32 rlen;
|
||||
char *ignore_autodict = getenv("AFL_NO_AUTODICT");
|
||||
|
||||
#ifdef __linux__
|
||||
if (fsrv->nyx_mode) {
|
||||
|
||||
if(fsrv->nyx_runner != NULL){
|
||||
return;
|
||||
}
|
||||
|
||||
if (!be_quiet) { ACTF("Spinning up the NYX backend..."); }
|
||||
|
||||
if(fsrv->out_dir_path == NULL){
|
||||
FATAL("Nyx workdir path not found...");
|
||||
}
|
||||
|
||||
char *x = alloc_printf("%s/workdir", fsrv->out_dir_path);
|
||||
|
||||
if(fsrv->nyx_id == 0xFFFFFFFF){
|
||||
FATAL("Nyx ID is not set...");
|
||||
}
|
||||
|
||||
if(fsrv->nyx_bind_cpu_id == 0xFFFFFFFF){
|
||||
FATAL("Nyx CPU ID is not set...");
|
||||
}
|
||||
|
||||
if (fsrv->nyx_parent){
|
||||
fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new(fsrv->target_path, x, fsrv->nyx_id, fsrv->nyx_bind_cpu_id, !fsrv->nyx_standalone);
|
||||
}
|
||||
else{
|
||||
fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new(fsrv->target_path, x, fsrv->nyx_id, fsrv->nyx_bind_cpu_id, true);
|
||||
}
|
||||
|
||||
if(fsrv->nyx_runner == NULL){
|
||||
FATAL("Something went wrong ...");
|
||||
}
|
||||
|
||||
fsrv->map_size = fsrv->nyx_handlers->nyx_get_bitmap_buffer_size(fsrv->nyx_runner);;
|
||||
fsrv->real_map_size = fsrv->map_size;
|
||||
|
||||
fsrv->trace_bits = fsrv->nyx_handlers->nyx_get_bitmap_buffer(fsrv->nyx_runner);
|
||||
|
||||
fsrv->nyx_handlers->nyx_option_set_reload_mode(fsrv->nyx_runner, getenv("NYX_DISABLE_SNAPSHOT_MODE") == NULL);
|
||||
fsrv->nyx_handlers->nyx_option_apply(fsrv->nyx_runner);
|
||||
|
||||
fsrv->nyx_handlers->nyx_option_set_timeout(fsrv->nyx_runner, 2, 0);
|
||||
fsrv->nyx_handlers->nyx_option_apply(fsrv->nyx_runner);
|
||||
|
||||
/* dry run */
|
||||
fsrv->nyx_handlers->nyx_set_afl_input(fsrv->nyx_runner, "INIT", 4);
|
||||
switch(fsrv->nyx_handlers->nyx_exec(fsrv->nyx_runner)){
|
||||
case Abort:
|
||||
fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner);
|
||||
FATAL("Error: Nyx abort occured...");
|
||||
break;
|
||||
case IoError:
|
||||
FATAL("Error: QEMU-Nyx has died...");
|
||||
break;
|
||||
case Error:
|
||||
fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner);
|
||||
FATAL("Error: Nyx runtime error has occured...");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!be_quiet) { ACTF("Spinning up the fork server..."); }
|
||||
|
||||
#ifdef AFL_PERSISTENT_RECORD
|
||||
@ -1085,6 +1162,11 @@ void afl_fsrv_kill(afl_forkserver_t *fsrv) {
|
||||
fsrv->fsrv_pid = -1;
|
||||
fsrv->child_pid = -1;
|
||||
|
||||
#ifdef __linux__
|
||||
if(fsrv->nyx_mode){
|
||||
fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Get the map size from the target forkserver */
|
||||
@ -1101,6 +1183,12 @@ u32 afl_fsrv_get_mapsize(afl_forkserver_t *fsrv, char **argv,
|
||||
|
||||
void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) {
|
||||
|
||||
#ifdef __linux__
|
||||
if(fsrv->nyx_mode){
|
||||
fsrv->nyx_handlers->nyx_set_afl_input(fsrv->nyx_runner, buf, len);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#ifdef AFL_PERSISTENT_RECORD
|
||||
if (unlikely(fsrv->persistent_record)) {
|
||||
|
||||
@ -1214,12 +1302,62 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
|
||||
u32 exec_ms;
|
||||
u32 write_value = fsrv->last_run_timed_out;
|
||||
|
||||
#ifdef __linux__
|
||||
if(fsrv->nyx_mode){
|
||||
|
||||
static uint32_t last_timeout_value = 0;
|
||||
|
||||
if (last_timeout_value != timeout){
|
||||
fsrv->nyx_handlers->nyx_option_set_timeout(fsrv->nyx_runner, timeout/1000, (timeout%1000) * 1000);
|
||||
fsrv->nyx_handlers->nyx_option_apply(fsrv->nyx_runner);
|
||||
last_timeout_value = timeout;
|
||||
}
|
||||
|
||||
enum NyxReturnValue ret_val = fsrv->nyx_handlers->nyx_exec(fsrv->nyx_runner);
|
||||
|
||||
fsrv->total_execs++;
|
||||
|
||||
switch(ret_val){
|
||||
case Normal:
|
||||
return FSRV_RUN_OK;
|
||||
case Crash:
|
||||
case Asan:
|
||||
return FSRV_RUN_CRASH;
|
||||
case Timout:
|
||||
return FSRV_RUN_TMOUT;
|
||||
case InvalidWriteToPayload:
|
||||
/* ??? */
|
||||
FATAL("FixMe: Nyx InvalidWriteToPayload handler is missing");
|
||||
break;
|
||||
case Abort:
|
||||
fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner);
|
||||
FATAL("Error: Nyx abort occured...");
|
||||
case IoError:
|
||||
if (*stop_soon_p){
|
||||
return 0;
|
||||
}
|
||||
else{
|
||||
FATAL("Error: QEMU-Nyx has died...");
|
||||
}
|
||||
break;
|
||||
case Error:
|
||||
FATAL("Error: Nyx runtime error has occured...");
|
||||
break;
|
||||
}
|
||||
return FSRV_RUN_OK;
|
||||
}
|
||||
#endif
|
||||
/* After this memset, fsrv->trace_bits[] are effectively volatile, so we
|
||||
must prevent any earlier operations from venturing into that
|
||||
territory. */
|
||||
|
||||
#ifdef __linux__
|
||||
if(!fsrv->nyx_mode){
|
||||
memset(fsrv->trace_bits, 0, fsrv->map_size);
|
||||
}
|
||||
#else
|
||||
memset(fsrv->trace_bits, 0, fsrv->map_size);
|
||||
|
||||
#endif
|
||||
MEM_BARRIER();
|
||||
|
||||
/* we have the fork server (or faux server) up and running
|
||||
|
@ -411,7 +411,11 @@ void bind_to_free_cpu(afl_state_t *afl) {
|
||||
OKF("Found a free CPU core, try binding to #%u.", i);
|
||||
|
||||
if (bind_cpu(afl, i)) {
|
||||
|
||||
#ifdef __linux__
|
||||
if(afl->fsrv.nyx_mode){
|
||||
afl->fsrv.nyx_bind_cpu_id = i;
|
||||
}
|
||||
#endif
|
||||
/* Success :) */
|
||||
break;
|
||||
|
||||
@ -1090,6 +1094,11 @@ void perform_dry_run(afl_state_t *afl) {
|
||||
FATAL("Unable to execute target application ('%s')", afl->argv[0]);
|
||||
|
||||
case FSRV_RUN_NOINST:
|
||||
#ifdef __linux__
|
||||
if(afl->fsrv.nyx_mode && afl->fsrv.nyx_runner != NULL){
|
||||
afl->fsrv.nyx_handlers->nyx_shutdown(afl->fsrv.nyx_runner);
|
||||
}
|
||||
#endif
|
||||
FATAL("No instrumentation detected");
|
||||
|
||||
case FSRV_RUN_NOBITS:
|
||||
@ -2443,6 +2452,11 @@ void fix_up_sync(afl_state_t *afl) {
|
||||
|
||||
x = alloc_printf("%s/%s", afl->out_dir, afl->sync_id);
|
||||
|
||||
#ifdef __linux__
|
||||
if(afl->fsrv.nyx_mode){
|
||||
afl->fsrv.out_dir_path = afl->out_dir;
|
||||
}
|
||||
#endif
|
||||
afl->sync_dir = afl->out_dir;
|
||||
afl->out_dir = x;
|
||||
|
||||
@ -2580,6 +2594,19 @@ void check_binary(afl_state_t *afl, u8 *fname) {
|
||||
if (strchr(fname, '/') || !(env_path = getenv("PATH"))) {
|
||||
|
||||
afl->fsrv.target_path = ck_strdup(fname);
|
||||
#ifdef __linux__
|
||||
if(afl->fsrv.nyx_mode){
|
||||
/* check if target_path is a nyx sharedir */
|
||||
if (stat(afl->fsrv.target_path, &st) || S_ISDIR(st.st_mode)){
|
||||
char* tmp = alloc_printf("%s/config.ron", afl->fsrv.target_path);
|
||||
if (stat(tmp, &st) || S_ISREG(st.st_mode)){
|
||||
free(tmp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
FATAL("Directory '%s' not found or is not a nyx share directory", afl->fsrv.target_path);
|
||||
}
|
||||
#endif
|
||||
if (stat(afl->fsrv.target_path, &st) || !S_ISREG(st.st_mode) ||
|
||||
!(st.st_mode & 0111) || (f_len = st.st_size) < 4) {
|
||||
|
||||
@ -2719,6 +2746,9 @@ void check_binary(afl_state_t *afl, u8 *fname) {
|
||||
#endif /* ^!__APPLE__ */
|
||||
|
||||
if (!afl->fsrv.qemu_mode && !afl->fsrv.frida_mode && !afl->unicorn_mode &&
|
||||
#ifdef __linux__
|
||||
!afl->fsrv.nyx_mode &&
|
||||
#endif
|
||||
!afl->fsrv.cs_mode && !afl->non_instrumented_mode &&
|
||||
!memmem(f_data, f_len, SHM_ENV_VAR, strlen(SHM_ENV_VAR) + 1)) {
|
||||
|
||||
|
@ -679,12 +679,25 @@ void show_stats(afl_state_t *afl) {
|
||||
banner_pad = (79 - banner_len) / 2;
|
||||
memset(banner, ' ', banner_pad);
|
||||
|
||||
sprintf(banner + banner_pad,
|
||||
"%s " cLCY VERSION cLBL " {%s} " cLGN "(%s) " cPIN "[%s]",
|
||||
afl->crash_mode ? cPIN "peruvian were-rabbit"
|
||||
: cYEL "american fuzzy lop",
|
||||
si, afl->use_banner, afl->power_name);
|
||||
#ifdef __linux__
|
||||
if(afl->fsrv.nyx_mode){
|
||||
sprintf(banner + banner_pad,
|
||||
"%s " cLCY VERSION cLBL " {%s} " cLGN "(%s) " cPIN "[%s] - Nyx",
|
||||
afl->crash_mode ? cPIN "peruvian were-rabbit"
|
||||
: cYEL "american fuzzy lop",
|
||||
si, afl->use_banner, afl->power_name);
|
||||
}
|
||||
else{
|
||||
#endif
|
||||
sprintf(banner + banner_pad,
|
||||
"%s " cLCY VERSION cLBL " {%s} " cLGN "(%s) " cPIN "[%s]",
|
||||
afl->crash_mode ? cPIN "peruvian were-rabbit"
|
||||
: cYEL "american fuzzy lop",
|
||||
si, afl->use_banner, afl->power_name);
|
||||
|
||||
#ifdef __linux__
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
SAYF("\n%s\n", banner);
|
||||
|
157
src/afl-fuzz.c
157
src/afl-fuzz.c
@ -124,6 +124,8 @@ static void usage(u8 *argv0, int more_help) {
|
||||
" -W - use qemu-based instrumentation with Wine (Wine "
|
||||
"mode)\n"
|
||||
#endif
|
||||
" -X - use VM fuzzing (NYX mode)\n"
|
||||
" -Y - use VM fuzzing (NYX mode - Multiprocessing)\n"
|
||||
"\n"
|
||||
|
||||
"Mutator settings:\n"
|
||||
@ -385,6 +387,75 @@ static void fasan_check_afl_preload(char *afl_preload) {
|
||||
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
#include <dlfcn.h>
|
||||
|
||||
nyx_plugin_handler_t* afl_load_libnyx_plugin(u8* libnyx_binary){
|
||||
void *handle;
|
||||
nyx_plugin_handler_t* plugin = calloc(1, sizeof(nyx_plugin_handler_t));
|
||||
|
||||
ACTF("Trying to load libnyx.so plugin...");
|
||||
handle = dlopen((char*) libnyx_binary, RTLD_NOW);
|
||||
if (!handle) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
plugin->nyx_new = dlsym(handle, "nyx_new");
|
||||
if (plugin->nyx_new == NULL){
|
||||
goto fail;
|
||||
}
|
||||
|
||||
plugin->nyx_shutdown = dlsym(handle, "nyx_shutdown");
|
||||
if (plugin->nyx_shutdown == NULL){
|
||||
goto fail;
|
||||
}
|
||||
|
||||
plugin->nyx_option_set_reload_mode = dlsym(handle, "nyx_option_set_reload_mode");
|
||||
if (plugin->nyx_option_set_reload_mode == NULL){
|
||||
goto fail;
|
||||
}
|
||||
|
||||
plugin->nyx_option_set_timeout = dlsym(handle, "nyx_option_set_timeout");
|
||||
if (plugin->nyx_option_set_timeout == NULL){
|
||||
goto fail;
|
||||
}
|
||||
|
||||
plugin->nyx_option_apply = dlsym(handle, "nyx_option_apply");
|
||||
if (plugin->nyx_option_apply == NULL){
|
||||
goto fail;
|
||||
}
|
||||
|
||||
plugin->nyx_set_afl_input = dlsym(handle, "nyx_set_afl_input");
|
||||
if (plugin->nyx_set_afl_input == NULL){
|
||||
goto fail;
|
||||
}
|
||||
|
||||
plugin->nyx_exec = dlsym(handle, "nyx_exec");
|
||||
if (plugin->nyx_exec == NULL){
|
||||
goto fail;
|
||||
}
|
||||
|
||||
plugin->nyx_get_bitmap_buffer = dlsym(handle, "nyx_get_bitmap_buffer");
|
||||
if (plugin->nyx_get_bitmap_buffer == NULL){
|
||||
goto fail;
|
||||
}
|
||||
|
||||
plugin->nyx_get_bitmap_buffer_size = dlsym(handle, "nyx_get_bitmap_buffer_size");
|
||||
if (plugin->nyx_get_bitmap_buffer_size == NULL){
|
||||
goto fail;
|
||||
}
|
||||
|
||||
OKF("libnyx plugin is ready!");
|
||||
return plugin;
|
||||
|
||||
fail:
|
||||
|
||||
FATAL("failed to load libnyx: %s\n", dlerror());
|
||||
free(plugin);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Main entry point */
|
||||
|
||||
int main(int argc, char **argv_orig, char **envp) {
|
||||
@ -441,7 +512,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
while ((opt = getopt(
|
||||
argc, argv,
|
||||
"+Ab:B:c:CdDe:E:hi:I:f:F:l:L:m:M:nNOo:p:RQs:S:t:T:UV:Wx:Z")) >
|
||||
"+Ab:B:c:CdDe:E:hi:I:f:F:l:L:m:M:nNOXYo:p:RQs:S:t:T:UV:Wx:Z")) >
|
||||
0) {
|
||||
|
||||
switch (opt) {
|
||||
@ -845,6 +916,36 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
afl->use_banner = optarg;
|
||||
break;
|
||||
|
||||
#ifdef __linux__
|
||||
case 'X': /* NYX mode */
|
||||
|
||||
if (afl->fsrv.nyx_mode) {
|
||||
FATAL("Multiple -X options not supported");
|
||||
|
||||
}
|
||||
|
||||
afl->fsrv.nyx_parent = true;
|
||||
afl->fsrv.nyx_standalone = true;
|
||||
afl->fsrv.nyx_mode = 1;
|
||||
afl->fsrv.nyx_id = 0;
|
||||
|
||||
break;
|
||||
|
||||
case 'Y': /* NYX distributed mode */
|
||||
if (afl->fsrv.nyx_mode) {
|
||||
|
||||
FATAL("Multiple -X options not supported");
|
||||
|
||||
}
|
||||
afl->fsrv.nyx_mode = 1;
|
||||
|
||||
break;
|
||||
#else
|
||||
case 'X':
|
||||
case 'Y':
|
||||
FATAL("Nyx mode is only availabe on linux...");
|
||||
break;
|
||||
#endif
|
||||
case 'A': /* CoreSight mode */
|
||||
|
||||
#if !defined(__aarch64__) || !defined(__linux__)
|
||||
@ -1185,6 +1286,13 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
OKF("NOTE: This is v3.x which changes defaults and behaviours - see "
|
||||
"README.md");
|
||||
|
||||
#ifdef __linux__
|
||||
if (afl->fsrv.nyx_mode){
|
||||
OKF("afl++ Nyx mode is enabled (developed and mainted by Sergej Schumilo)");
|
||||
OKF("Nyx is open source, get it at "
|
||||
"https://github.com/Nyx-Fuzz");
|
||||
}
|
||||
#endif
|
||||
if (afl->sync_id && afl->is_main_node &&
|
||||
afl->afl_env.afl_custom_mutator_only) {
|
||||
|
||||
@ -1227,6 +1335,33 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
if (afl->fsrv.nyx_mode) {
|
||||
|
||||
if (afl->fsrv.nyx_standalone && strncmp(afl->sync_id, "default", strlen("default")) != 0){
|
||||
FATAL("distributed fuzzing is not supported in this Nyx mode (use -Y instead)");
|
||||
}
|
||||
|
||||
if (!afl->fsrv.nyx_standalone){
|
||||
if (afl->is_main_node){
|
||||
if(strncmp("0", afl->sync_id, strlen("0") != 0)){
|
||||
FATAL("afl->sync_id has to be 0 in Nyx mode (-M 0)");
|
||||
}
|
||||
afl->fsrv.nyx_id = 0;
|
||||
}
|
||||
|
||||
if (afl->is_secondary_node){
|
||||
long nyx_id = strtol(afl->sync_id, NULL, 10);
|
||||
|
||||
if (nyx_id == 0 || nyx_id == LONG_MAX){
|
||||
FATAL("afl->sync_id has to be numberic and >= 1 (-S id)");
|
||||
}
|
||||
afl->fsrv.nyx_id = nyx_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (afl->sync_id) {
|
||||
|
||||
if (strlen(afl->sync_id) > 24) {
|
||||
@ -1450,8 +1585,22 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
afl->fsrv.use_fauxsrv = afl->non_instrumented_mode == 1 || afl->no_forkserver;
|
||||
|
||||
#ifdef __linux__
|
||||
if (!afl->fsrv.nyx_mode){
|
||||
check_crash_handling();
|
||||
check_cpu_governor(afl);
|
||||
}
|
||||
else{
|
||||
u8* libnyx_binary = find_afl_binary(argv[0], "nyx_mode/libnyx.so");
|
||||
afl->fsrv.nyx_handlers = afl_load_libnyx_plugin(libnyx_binary);
|
||||
if(afl->fsrv.nyx_handlers == NULL){
|
||||
FATAL("failed to initialize libnyx.so...");
|
||||
}
|
||||
}
|
||||
#else
|
||||
check_crash_handling();
|
||||
check_cpu_governor(afl);
|
||||
#endif
|
||||
|
||||
if (getenv("LD_PRELOAD")) {
|
||||
|
||||
@ -1934,7 +2083,11 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
if (!afl->queue_buf[entry]->disabled) { ++valid_seeds; }
|
||||
|
||||
if (!afl->pending_not_fuzzed || !valid_seeds) {
|
||||
|
||||
#ifdef __linux__
|
||||
if(afl->fsrv.nyx_mode){
|
||||
afl->fsrv.nyx_handlers->nyx_shutdown(afl->fsrv.nyx_runner);
|
||||
}
|
||||
#endif
|
||||
FATAL("We need at least one valid input seed that does not crash!");
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user