mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-12 18:18:07 +00:00
add AFL_OLD_FORKSERVER feature
This commit is contained in:
@ -20,6 +20,10 @@
|
|||||||
- AFL_FRIDA_DEBUG_MAPS now works as expected
|
- AFL_FRIDA_DEBUG_MAPS now works as expected
|
||||||
- custom mutators:
|
- custom mutators:
|
||||||
- custom_send_tcp custom mutator added, thanks to @dergoegge
|
- custom_send_tcp custom mutator added, thanks to @dergoegge
|
||||||
|
- afl-cc
|
||||||
|
- new runtime (!) variable: `AFL_OLD_FORKSERVER` to use the old vanilla
|
||||||
|
AFL type forkserver. Useful for symcc/symqemu/nautilus/etc. with
|
||||||
|
AFL_LLVM_INSTRUMENT=CLASSIC
|
||||||
|
|
||||||
|
|
||||||
### Version ++4.21c (release)
|
### Version ++4.21c (release)
|
||||||
|
@ -331,7 +331,26 @@ mode.
|
|||||||
the target performs only a few loops, then this will give a small
|
the target performs only a few loops, then this will give a small
|
||||||
performance boost.
|
performance boost.
|
||||||
|
|
||||||
## 4) Settings for afl-fuzz
|
## 4) Runtime settings
|
||||||
|
|
||||||
|
The following environment variables are for a compiled AFL++ target.
|
||||||
|
|
||||||
|
- Setting `AFL_DUMP_MAP_SIZE` when executing the target directly will
|
||||||
|
dump the map size of the target and exit.
|
||||||
|
|
||||||
|
- Setting `AFL_OLD_FORKSERVER` will use the old AFL vanilla forkserver.
|
||||||
|
This makes only sense when you
|
||||||
|
a) compile in a classic colliding coverage mode (e.g.
|
||||||
|
AFL_LLVM_INSTRUMENT=CLASSIC) or if the map size of the target is
|
||||||
|
below MAP_SIZE (65536 by default), AND
|
||||||
|
b) you want to use this compiled AFL++ target with a different tool
|
||||||
|
that expects vanilla AFL behaviour, e.g. symcc, symqemu, nautilus, etc.
|
||||||
|
You would use this option together with the target fuzzing application.
|
||||||
|
|
||||||
|
- Setting `AFL_DISABLE_LLVM_INSTRUMENTATION` will disable collecting
|
||||||
|
instrumentation. (More of an internal option.)
|
||||||
|
|
||||||
|
## 5) Settings for afl-fuzz
|
||||||
|
|
||||||
The main fuzzer binary accepts several options that disable a couple of sanity
|
The main fuzzer binary accepts several options that disable a couple of sanity
|
||||||
checks or alter some of the more exotic semantics of the tool:
|
checks or alter some of the more exotic semantics of the tool:
|
||||||
@ -642,7 +661,7 @@ checks or alter some of the more exotic semantics of the tool:
|
|||||||
Note that will not be exact and with slow targets it can take seconds
|
Note that will not be exact and with slow targets it can take seconds
|
||||||
until there is a slice for the time test.
|
until there is a slice for the time test.
|
||||||
|
|
||||||
## 5) Settings for afl-qemu-trace
|
## 6) Settings for afl-qemu-trace
|
||||||
|
|
||||||
The QEMU wrapper used to instrument binary-only code supports several settings:
|
The QEMU wrapper used to instrument binary-only code supports several settings:
|
||||||
|
|
||||||
@ -714,7 +733,7 @@ The QEMU wrapper used to instrument binary-only code supports several settings:
|
|||||||
crash is found. Setting `AFL_NO_CRASH_README` will prevent this. Useful when
|
crash is found. Setting `AFL_NO_CRASH_README` will prevent this. Useful when
|
||||||
counting crashes based on a file count in that directory.
|
counting crashes based on a file count in that directory.
|
||||||
|
|
||||||
## 7) Settings for afl-frida-trace
|
## 8) Settings for afl-frida-trace
|
||||||
|
|
||||||
The FRIDA wrapper used to instrument binary-only code supports many of the same
|
The FRIDA wrapper used to instrument binary-only code supports many of the same
|
||||||
options as `afl-qemu-trace`, but also has a number of additional advanced
|
options as `afl-qemu-trace`, but also has a number of additional advanced
|
||||||
@ -804,7 +823,7 @@ support.
|
|||||||
dump you must set a sufficient timeout (using `-t`) to avoid `afl-fuzz`
|
dump you must set a sufficient timeout (using `-t`) to avoid `afl-fuzz`
|
||||||
killing the process whilst it is being dumped.
|
killing the process whilst it is being dumped.
|
||||||
|
|
||||||
## 8) Settings for afl-cmin
|
## 9) Settings for afl-cmin
|
||||||
|
|
||||||
The corpus minimization script offers very little customization:
|
The corpus minimization script offers very little customization:
|
||||||
|
|
||||||
@ -822,7 +841,7 @@ The corpus minimization script offers very little customization:
|
|||||||
- `AFL_PRINT_FILENAMES` prints each filename to stdout, as it gets processed.
|
- `AFL_PRINT_FILENAMES` prints each filename to stdout, as it gets processed.
|
||||||
This can help when embedding `afl-cmin` or `afl-showmap` in other scripts.
|
This can help when embedding `afl-cmin` or `afl-showmap` in other scripts.
|
||||||
|
|
||||||
## 9) Settings for afl-tmin
|
## 10) Settings for afl-tmin
|
||||||
|
|
||||||
Virtually nothing to play with. Well, in QEMU mode (`-Q`), `AFL_PATH` will be
|
Virtually nothing to play with. Well, in QEMU mode (`-Q`), `AFL_PATH` will be
|
||||||
searched for afl-qemu-trace. In addition to this, `TMPDIR` may be used if a
|
searched for afl-qemu-trace. In addition to this, `TMPDIR` may be used if a
|
||||||
@ -833,12 +852,12 @@ to match when minimizing crashes. This will make minimization less useful, but
|
|||||||
may prevent the tool from "jumping" from one crashing condition to another in
|
may prevent the tool from "jumping" from one crashing condition to another in
|
||||||
very buggy software. You probably want to combine it with the `-e` flag.
|
very buggy software. You probably want to combine it with the `-e` flag.
|
||||||
|
|
||||||
## 10) Settings for afl-analyze
|
## 11) Settings for afl-analyze
|
||||||
|
|
||||||
You can set `AFL_ANALYZE_HEX` to get file offsets printed as hexadecimal instead
|
You can set `AFL_ANALYZE_HEX` to get file offsets printed as hexadecimal instead
|
||||||
of decimal.
|
of decimal.
|
||||||
|
|
||||||
## 11) Settings for libdislocator
|
## 12) Settings for libdislocator
|
||||||
|
|
||||||
The library honors these environment variables:
|
The library honors these environment variables:
|
||||||
|
|
||||||
@ -860,12 +879,12 @@ The library honors these environment variables:
|
|||||||
- `AFL_LD_VERBOSE` causes the library to output some diagnostic messages that
|
- `AFL_LD_VERBOSE` causes the library to output some diagnostic messages that
|
||||||
may be useful for pinpointing the cause of any observed issues.
|
may be useful for pinpointing the cause of any observed issues.
|
||||||
|
|
||||||
## 11) Settings for libtokencap
|
## 13) Settings for libtokencap
|
||||||
|
|
||||||
This library accepts `AFL_TOKEN_FILE` to indicate the location to which the
|
This library accepts `AFL_TOKEN_FILE` to indicate the location to which the
|
||||||
discovered tokens should be written.
|
discovered tokens should be written.
|
||||||
|
|
||||||
## 12) Third-party variables set by afl-fuzz & other tools
|
## 14) Third-party variables set by afl-fuzz & other tools
|
||||||
|
|
||||||
Several variables are not directly interpreted by afl-fuzz, but are set to
|
Several variables are not directly interpreted by afl-fuzz, but are set to
|
||||||
optimal values if not already present in the environment:
|
optimal values if not already present in the environment:
|
||||||
|
@ -40,8 +40,7 @@ static char *afl_environment_variables[] = {
|
|||||||
"AFL_FRIDA_INST_INSN", "AFL_FRIDA_INST_JIT", "AFL_FRIDA_INST_NO_CACHE",
|
"AFL_FRIDA_INST_INSN", "AFL_FRIDA_INST_JIT", "AFL_FRIDA_INST_NO_CACHE",
|
||||||
"AFL_FRIDA_INST_NO_DYNAMIC_LOAD", "AFL_FRIDA_INST_NO_OPTIMIZE",
|
"AFL_FRIDA_INST_NO_DYNAMIC_LOAD", "AFL_FRIDA_INST_NO_OPTIMIZE",
|
||||||
"AFL_FRIDA_INST_NO_PREFETCH", "AFL_FRIDA_INST_NO_PREFETCH_BACKPATCH",
|
"AFL_FRIDA_INST_NO_PREFETCH", "AFL_FRIDA_INST_NO_PREFETCH_BACKPATCH",
|
||||||
"AFL_FRIDA_INST_NO_SUPPRESS"
|
"AFL_FRIDA_INST_NO_SUPPRESS", "AFL_FRIDA_INST_RANGES",
|
||||||
"AFL_FRIDA_INST_RANGES",
|
|
||||||
"AFL_FRIDA_INST_REGS_FILE", "AFL_FRIDA_INST_SEED", "AFL_FRIDA_INST_TRACE",
|
"AFL_FRIDA_INST_REGS_FILE", "AFL_FRIDA_INST_SEED", "AFL_FRIDA_INST_TRACE",
|
||||||
"AFL_FRIDA_INST_TRACE_UNIQUE", "AFL_FRIDA_INST_UNSTABLE_COVERAGE_FILE",
|
"AFL_FRIDA_INST_TRACE_UNIQUE", "AFL_FRIDA_INST_UNSTABLE_COVERAGE_FILE",
|
||||||
"AFL_FRIDA_JS_SCRIPT", "AFL_FRIDA_OUTPUT_STDOUT", "AFL_FRIDA_OUTPUT_STDERR",
|
"AFL_FRIDA_JS_SCRIPT", "AFL_FRIDA_OUTPUT_STDOUT", "AFL_FRIDA_OUTPUT_STDERR",
|
||||||
@ -50,7 +49,7 @@ static char *afl_environment_variables[] = {
|
|||||||
"AFL_FRIDA_PERSISTENT_RET", "AFL_FRIDA_STALKER_ADJACENT_BLOCKS",
|
"AFL_FRIDA_PERSISTENT_RET", "AFL_FRIDA_STALKER_ADJACENT_BLOCKS",
|
||||||
"AFL_FRIDA_STALKER_IC_ENTRIES", "AFL_FRIDA_STALKER_NO_BACKPATCH",
|
"AFL_FRIDA_STALKER_IC_ENTRIES", "AFL_FRIDA_STALKER_NO_BACKPATCH",
|
||||||
"AFL_FRIDA_STATS_FILE", "AFL_FRIDA_STATS_INTERVAL", "AFL_FRIDA_TRACEABLE",
|
"AFL_FRIDA_STATS_FILE", "AFL_FRIDA_STATS_INTERVAL", "AFL_FRIDA_TRACEABLE",
|
||||||
"AFL_FRIDA_VERBOSE",
|
"AFL_FRIDA_VERBOSE", "AFL_OLD_FORKSERVER",
|
||||||
"AFL_FUZZER_ARGS", // oss-fuzz
|
"AFL_FUZZER_ARGS", // oss-fuzz
|
||||||
"AFL_FUZZER_STATS_UPDATE_INTERVAL", "AFL_GDB", "AFL_GCC_ALLOWLIST",
|
"AFL_FUZZER_STATS_UPDATE_INTERVAL", "AFL_GDB", "AFL_GCC_ALLOWLIST",
|
||||||
"AFL_GCC_DENYLIST", "AFL_GCC_BLOCKLIST", "AFL_GCC_INSTRUMENT_FILE",
|
"AFL_GCC_DENYLIST", "AFL_GCC_BLOCKLIST", "AFL_GCC_INSTRUMENT_FILE",
|
||||||
|
@ -118,6 +118,7 @@ u32 __afl_map_size = MAP_SIZE;
|
|||||||
u32 __afl_dictionary_len;
|
u32 __afl_dictionary_len;
|
||||||
u64 __afl_map_addr;
|
u64 __afl_map_addr;
|
||||||
u32 __afl_first_final_loc;
|
u32 __afl_first_final_loc;
|
||||||
|
u32 __afl_old_forkserver;
|
||||||
|
|
||||||
#ifdef __AFL_CODE_COVERAGE
|
#ifdef __AFL_CODE_COVERAGE
|
||||||
typedef struct afl_module_info_t afl_module_info_t;
|
typedef struct afl_module_info_t afl_module_info_t;
|
||||||
@ -616,7 +617,7 @@ static void __afl_map_shm(void) {
|
|||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"DEBUG: (2) id_str %s, __afl_area_ptr %p, __afl_area_initial %p, "
|
"DEBUG: (2) id_str %s, __afl_area_ptr %p, __afl_area_initial %p, "
|
||||||
"__afl_area_ptr_dummy %p, __afl_map_addr 0x%llx, MAP_SIZE "
|
"__afl_area_ptr_dummy %p, __afl_map_addr 0x%llx, MAP_SIZE "
|
||||||
"%u, __afl_final_loc %u, __afl_map_size %u",
|
"%u, __afl_final_loc %u, __afl_map_size %u\n",
|
||||||
id_str == NULL ? "<null>" : id_str, __afl_area_ptr,
|
id_str == NULL ? "<null>" : id_str, __afl_area_ptr,
|
||||||
__afl_area_initial, __afl_area_ptr_dummy, __afl_map_addr, MAP_SIZE,
|
__afl_area_initial, __afl_area_ptr_dummy, __afl_map_addr, MAP_SIZE,
|
||||||
__afl_final_loc, __afl_map_size);
|
__afl_final_loc, __afl_map_size);
|
||||||
@ -856,7 +857,7 @@ static void __afl_start_forkserver(void) {
|
|||||||
signal(SIGTERM, at_exit);
|
signal(SIGTERM, at_exit);
|
||||||
|
|
||||||
u32 already_read_first = 0;
|
u32 already_read_first = 0;
|
||||||
u32 was_killed;
|
u32 was_killed = 0;
|
||||||
u32 version = 0x41464c00 + FS_NEW_VERSION_MAX;
|
u32 version = 0x41464c00 + FS_NEW_VERSION_MAX;
|
||||||
u32 tmp = version ^ 0xffffffff, status2, status = version;
|
u32 tmp = version ^ 0xffffffff, status2, status = version;
|
||||||
u8 *msg = (u8 *)&status;
|
u8 *msg = (u8 *)&status;
|
||||||
@ -866,75 +867,95 @@ static void __afl_start_forkserver(void) {
|
|||||||
|
|
||||||
void (*old_sigchld_handler)(int) = signal(SIGCHLD, SIG_DFL);
|
void (*old_sigchld_handler)(int) = signal(SIGCHLD, SIG_DFL);
|
||||||
|
|
||||||
|
if (getenv("AFL_OLD_FORKSERVER")) {
|
||||||
|
|
||||||
|
__afl_old_forkserver = 1;
|
||||||
|
status = 0;
|
||||||
|
|
||||||
|
if (__afl_final_loc && __afl_final_loc > MAP_SIZE) {
|
||||||
|
|
||||||
|
fprintf(stderr,
|
||||||
|
"Warning: AFL_OLD_FORKSERVER is used with a target compiled with "
|
||||||
|
"non-colliding coverage instead of AFL_LLVM_INSTRUMENT=CLASSIC - "
|
||||||
|
"this target may crash!\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Phone home and tell the parent that we're OK. If parent isn't there,
|
/* 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. */
|
assume we're not running in forkserver mode and just execute program. */
|
||||||
|
|
||||||
// return because possible non-forkserver usage
|
// return because possible non-forkserver usage
|
||||||
if (write(FORKSRV_FD + 1, msg, 4) != 4) { return; }
|
if (write(FORKSRV_FD + 1, msg, 4) != 4) { return; }
|
||||||
|
|
||||||
if (read(FORKSRV_FD, reply, 4) != 4) { _exit(1); }
|
if (!__afl_old_forkserver) {
|
||||||
if (tmp != status2) {
|
|
||||||
|
|
||||||
write_error("wrong forkserver message from AFL++ tool");
|
if (read(FORKSRV_FD, reply, 4) != 4) { _exit(1); }
|
||||||
_exit(1);
|
if (tmp != status2) {
|
||||||
|
|
||||||
}
|
write_error("wrong forkserver message from AFL++ tool");
|
||||||
|
|
||||||
// send the set/requested options to forkserver
|
|
||||||
status = FS_NEW_OPT_MAPSIZE; // we always send the map size
|
|
||||||
if (__afl_sharedmem_fuzzing) { status |= FS_NEW_OPT_SHDMEM_FUZZ; }
|
|
||||||
if (__afl_dictionary_len && __afl_dictionary) {
|
|
||||||
|
|
||||||
status |= FS_NEW_OPT_AUTODICT;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (write(FORKSRV_FD + 1, msg, 4) != 4) { _exit(1); }
|
|
||||||
|
|
||||||
// Now send the parameters for the set options, increasing by option number
|
|
||||||
|
|
||||||
// FS_NEW_OPT_MAPSIZE - we always send the map size
|
|
||||||
status = __afl_map_size;
|
|
||||||
if (write(FORKSRV_FD + 1, msg, 4) != 4) { _exit(1); }
|
|
||||||
|
|
||||||
// FS_NEW_OPT_SHDMEM_FUZZ - no data
|
|
||||||
|
|
||||||
// FS_NEW_OPT_AUTODICT - send autodictionary
|
|
||||||
if (__afl_dictionary_len && __afl_dictionary) {
|
|
||||||
|
|
||||||
// pass the dictionary through the forkserver FD
|
|
||||||
u32 len = __afl_dictionary_len, offset = 0;
|
|
||||||
|
|
||||||
if (write(FORKSRV_FD + 1, &len, 4) != 4) {
|
|
||||||
|
|
||||||
write(2, "Error: could not send dictionary len\n",
|
|
||||||
strlen("Error: could not send dictionary len\n"));
|
|
||||||
_exit(1);
|
_exit(1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (len != 0) {
|
// send the set/requested options to forkserver
|
||||||
|
status = FS_NEW_OPT_MAPSIZE; // we always send the map size
|
||||||
|
if (__afl_sharedmem_fuzzing) { status |= FS_NEW_OPT_SHDMEM_FUZZ; }
|
||||||
|
if (__afl_dictionary_len && __afl_dictionary) {
|
||||||
|
|
||||||
s32 ret;
|
status |= FS_NEW_OPT_AUTODICT;
|
||||||
ret = write(FORKSRV_FD + 1, __afl_dictionary + offset, len);
|
|
||||||
|
|
||||||
if (ret < 1) {
|
}
|
||||||
|
|
||||||
write_error("could not send dictionary");
|
if (write(FORKSRV_FD + 1, msg, 4) != 4) { _exit(1); }
|
||||||
|
|
||||||
|
// Now send the parameters for the set options, increasing by option number
|
||||||
|
|
||||||
|
// FS_NEW_OPT_MAPSIZE - we always send the map size
|
||||||
|
status = __afl_map_size;
|
||||||
|
if (write(FORKSRV_FD + 1, msg, 4) != 4) { _exit(1); }
|
||||||
|
|
||||||
|
// FS_NEW_OPT_SHDMEM_FUZZ - no data
|
||||||
|
|
||||||
|
// FS_NEW_OPT_AUTODICT - send autodictionary
|
||||||
|
if (__afl_dictionary_len && __afl_dictionary) {
|
||||||
|
|
||||||
|
// pass the dictionary through the forkserver FD
|
||||||
|
u32 len = __afl_dictionary_len, offset = 0;
|
||||||
|
|
||||||
|
if (write(FORKSRV_FD + 1, &len, 4) != 4) {
|
||||||
|
|
||||||
|
write(2, "Error: could not send dictionary len\n",
|
||||||
|
strlen("Error: could not send dictionary len\n"));
|
||||||
_exit(1);
|
_exit(1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
len -= ret;
|
while (len != 0) {
|
||||||
offset += ret;
|
|
||||||
|
s32 ret;
|
||||||
|
ret = write(FORKSRV_FD + 1, __afl_dictionary + offset, len);
|
||||||
|
|
||||||
|
if (ret < 1) {
|
||||||
|
|
||||||
|
write_error("could not send dictionary");
|
||||||
|
_exit(1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
len -= ret;
|
||||||
|
offset += ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
// send welcome message as final message
|
||||||
|
status = version;
|
||||||
|
if (write(FORKSRV_FD + 1, msg, 4) != 4) { _exit(1); }
|
||||||
|
|
||||||
// send welcome message as final message
|
}
|
||||||
status = version;
|
|
||||||
if (write(FORKSRV_FD + 1, msg, 4) != 4) { _exit(1); }
|
|
||||||
|
|
||||||
// END forkserver handshake
|
// END forkserver handshake
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user