Merge pull request #1651 from AFLplusplus/dev

Dev
This commit is contained in:
van Hauser 2023-02-21 01:11:00 +01:00 committed by GitHub
commit c33f8751e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 875 additions and 128 deletions

View File

@ -228,6 +228,7 @@ Thank you! (For people sending pull requests - please add yourself to this list
Thomas Rooijakkers David Carlier
Ruben ten Hove Joey Jiao
fuzzah @intrigus-lgtm
Yaakov Saxon
```
</details>

View File

@ -480,7 +480,8 @@ checks or alter some of the more exotic semantics of the tool:
output from afl-fuzz is redirected to a file or to a pipe.
- Setting `AFL_NO_STARTUP_CALIBRATION` will skip the initial calibration
of all starting seeds, and start fuzzing at once.
of all starting seeds, and start fuzzing at once. Use with care, this
degrades the fuzzing performance!
- Setting `AFL_NO_WARN_INSTABILITY` will suppress instability warnings.

View File

@ -630,7 +630,8 @@ If you have a large corpus, a corpus from a previous run or are fuzzing in a CI,
then also set `export AFL_CMPLOG_ONLY_NEW=1` and `export AFL_FAST_CAL=1`.
If the queue in the CI is huge and/or the execution time is slow then you can
also add `AFL_NO_STARTUP_CALIBRATION=1` to skip the initial queue calibration
phase and start fuzzing at once.
phase and start fuzzing at once - but only do this if the calibration phase
would be too long for your fuzz run time.
You can also use different fuzzers. If you are using AFL spinoffs or AFL
conforming fuzzers, then just use the same -o directory and give it a unique
@ -916,7 +917,8 @@ normal fuzzing campaigns as these are much shorter runnings.
If the queue in the CI is huge and/or the execution time is slow then you can
also add `AFL_NO_STARTUP_CALIBRATION=1` to skip the initial queue calibration
phase and start fuzzing at once.
phase and start fuzzing at once. But only do that if the calibration time is
too long for your overall available fuzz run time.
1. Always:
* LTO has a much longer compile time which is diametrical to short fuzzing -

View File

@ -193,6 +193,13 @@ instrumented address block translations.
backpatching information. By default, the child will report applied
backpatches to the parent so that they can be applied and then be inherited by
the next child on fork.
* `AFL_FRIDA_INST_NO_SUPPRESS` - Disable deterministic branch suppression.
Deterministic branch suppression skips the preamble which generates coverage
information at the start of each block, if the block is reached by a
deterministic branch. This reduces map polution, and may improve performance
when all the executing blocks have been prefetched and backpatching applied.
However, in the event that backpatching is incomplete, this may incur a
performance penatly as branch instructions are disassembled on each branch.
* `AFL_FRIDA_INST_SEED` - Sets the initial seed for the hash function used to
generate block (and hence edge) IDs. Setting this to a constant value may be
useful for debugging purposes, e.g., investigating unstable edges.

View File

@ -22,6 +22,7 @@
js_api_set_instrument_no_optimize;
js_api_set_instrument_regs_file;
js_api_set_instrument_seed;
js_api_set_instrument_suppress_disable;
js_api_set_instrument_trace;
js_api_set_instrument_trace_unique;
js_api_set_instrument_unstable_coverage_file;

View File

@ -15,6 +15,7 @@ extern guint64 instrument_hash_zero;
extern char *instrument_coverage_unstable_filename;
extern gboolean instrument_coverage_insn;
extern char *instrument_regs_filename;
extern gboolean instrument_suppress;
extern gboolean instrument_use_fixed_seed;
extern guint64 instrument_fixed_seed;

View File

@ -27,6 +27,7 @@ gboolean instrument_optimize = false;
gboolean instrument_unique = false;
guint64 instrument_hash_zero = 0;
guint64 instrument_hash_seed = 0;
gboolean instrument_suppress = false;
gboolean instrument_use_fixed_seed = FALSE;
guint64 instrument_fixed_seed = 0;
@ -290,6 +291,7 @@ void instrument_config(void) {
(getenv("AFL_FRIDA_INST_UNSTABLE_COVERAGE_FILE"));
instrument_coverage_insn = (getenv("AFL_FRIDA_INST_INSN") != NULL);
instrument_regs_filename = getenv("AFL_FRIDA_INST_REGS_FILE");
instrument_suppress = (getenv("AFL_FRIDA_INST_NO_SUPPRESS") == NULL);
instrument_debug_config();
instrument_coverage_config();
@ -321,6 +323,9 @@ void instrument_init(void) {
FOKF(cBLU "Instrumentation" cRST " - " cGRN "instructions:" cYEL " [%c]",
instrument_coverage_insn ? 'X' : ' ');
FOKF(cBLU "Instrumentation" cRST " - " cGRN "suppression:" cYEL " [%c]",
instrument_suppress ? 'X' : ' ');
if (instrument_tracing && instrument_optimize) {
WARNF("AFL_FRIDA_INST_TRACE implies AFL_FRIDA_INST_NO_OPTIMIZE");

View File

@ -196,7 +196,15 @@ static void instrument_coverage_switch(GumStalkerObserver *self,
insn = instrument_disassemble(from_insn);
deterministic = instrument_is_deterministic(insn);
cs_free(insn, 1);
if (!deterministic) { return; }
/*
* If the branch is deterministic, then we should start execution at the
* begining of the block. From here, we will branch and skip the coverage
* code and jump right to the target code of the instrumented block.
* Otherwise, if the branch is non-deterministic, then we need to branch
* part way into the block to where the coverage instrumentation starts.
*/
if (deterministic) { return; }
/*
* Since each block is prefixed with a restoration prologue, we need to be
@ -305,7 +313,7 @@ void instrument_coverage_optimize(const cs_insn *instr,
// gum_arm64_writer_put_brk_imm(cw, 0x0);
instrument_coverage_suppress_init();
if (instrument_suppress) { instrument_coverage_suppress_init(); }
code_addr = cw->pc;
@ -325,9 +333,13 @@ void instrument_coverage_optimize(const cs_insn *instr,
block_start =
GSIZE_TO_POINTER(GUM_ADDRESS(cw->code) - GUM_RESTORATION_PROLOG_SIZE);
if (!g_hash_table_add(coverage_blocks, block_start)) {
if (instrument_suppress) {
FATAL("Failed - g_hash_table_add");
if (!g_hash_table_add(coverage_blocks, block_start)) {
FATAL("Failed - g_hash_table_add");
}
}
@ -363,7 +375,17 @@ void instrument_coverage_optimize(const cs_insn *instr,
code.code.mov_x1_curr_loc_shr_1 |= (area_offset_ror << 5);
gum_arm64_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code));
if (instrument_suppress) {
gum_arm64_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code));
} else {
size_t offset = offsetof(afl_log_code, code.stp_x0_x1);
gum_arm64_writer_put_bytes(cw, &code.bytes[offset],
sizeof(afl_log_code) - offset);
}
}

View File

@ -380,11 +380,15 @@ void instrument_coverage_optimize(const cs_insn *instr,
}
instrument_coverage_suppress_init();
if (instrument_suppress) {
if (!g_hash_table_add(coverage_blocks, GSIZE_TO_POINTER(cw->code))) {
instrument_coverage_suppress_init();
FATAL("Failed - g_hash_table_add");
if (!g_hash_table_add(coverage_blocks, GSIZE_TO_POINTER(cw->code))) {
FATAL("Failed - g_hash_table_add");
}
}

View File

@ -203,13 +203,17 @@ void instrument_coverage_optimize(const cs_insn *instr,
code.code = template;
instrument_coverage_suppress_init();
if (instrument_suppress) {
// gum_x86_writer_put_breakpoint(cw);
instrument_coverage_suppress_init();
if (!g_hash_table_add(coverage_blocks, GSIZE_TO_POINTER(cw->code))) {
// gum_x86_writer_put_breakpoint(cw);
FATAL("Failed - g_hash_table_add");
if (!g_hash_table_add(coverage_blocks, GSIZE_TO_POINTER(cw->code))) {
FATAL("Failed - g_hash_table_add");
}
}

View File

@ -170,6 +170,12 @@ class Afl {
static setInstrumentSeed(seed) {
Afl.jsApiSetInstrumentSeed(seed);
}
/*
* See `AFL_FRIDA_INST_NO_SUPPRESS`
*/
static setInstrumentSuppressDisable() {
Afl.jsApiSetInstrumentSuppressDisable();
}
/**
* See `AFL_FRIDA_INST_TRACE_UNIQUE`.
*/
@ -339,6 +345,7 @@ Afl.jsApiSetInstrumentLibraries = Afl.jsApiGetFunction("js_api_set_instrument_li
Afl.jsApiSetInstrumentNoOptimize = Afl.jsApiGetFunction("js_api_set_instrument_no_optimize", "void", []);
Afl.jsApiSetInstrumentRegsFile = Afl.jsApiGetFunction("js_api_set_instrument_regs_file", "void", ["pointer"]);
Afl.jsApiSetInstrumentSeed = Afl.jsApiGetFunction("js_api_set_instrument_seed", "void", ["uint64"]);
Afl.jsApiSetInstrumentSuppressDisable = Afl.jsApiGetFunction("js_api_set_instrument_suppress_disable", "void", []);
Afl.jsApiSetInstrumentTrace = Afl.jsApiGetFunction("js_api_set_instrument_trace", "void", []);
Afl.jsApiSetInstrumentTraceUnique = Afl.jsApiGetFunction("js_api_set_instrument_trace_unique", "void", []);
Afl.jsApiSetInstrumentUnstableCoverageFile = Afl.jsApiGetFunction("js_api_set_instrument_unstable_coverage_file", "void", ["pointer"]);

View File

@ -289,6 +289,13 @@ __attribute__((visibility("default"))) void js_api_set_instrument_cache_size(
}
__attribute__((visibility("default"))) void
js_api_set_instrument_suppress_disable(void) {
instrument_suppress = false;
}
__attribute__((visibility("default"))) void js_api_set_js_main_hook(
const js_main_hook_t hook) {

View File

@ -2,8 +2,9 @@ PWD:=$(shell pwd)/
ROOT:=$(PWD)../../../
BUILD_DIR:=$(PWD)build/
TEST_CMPLOG_BASENAME=compcovtest
TEST_CMPLOG_SRC=$(PWD)cmplog.c
TEST_CMPLOG_OBJ=$(BUILD_DIR)compcovtest
TEST_CMPLOG_OBJ=$(BUILD_DIR)$(TEST_CMPLOG_BASENAME)
TEST_BIN:=$(PWD)../../build/test
@ -13,7 +14,7 @@ CMP_LOG_INPUT:=$(TEST_DATA_DIR)in
QEMU_OUT:=$(BUILD_DIR)qemu-out
FRIDA_OUT:=$(BUILD_DIR)frida-out
.PHONY: all 32 clean qemu frida frida-nocmplog format
.PHONY: all 32 clean qemu frida frida-nocmplog frida-unprefixedpath format
all: $(TEST_CMPLOG_OBJ)
make -C $(ROOT)frida_mode/
@ -64,6 +65,18 @@ frida-nocmplog: $(TEST_CMPLOG_OBJ) $(CMP_LOG_INPUT)
-- \
$(TEST_CMPLOG_OBJ) @@
frida-unprefixedpath: $(TEST_CMPLOG_OBJ) $(CMP_LOG_INPUT)
PATH=$(BUILD_DIR) $(ROOT)afl-fuzz \
-O \
-i $(TEST_DATA_DIR) \
-o $(FRIDA_OUT) \
-c 0 \
-l 3AT \
-Z \
-- \
$(TEST_CMPLOG_BASENAME) @@
debug: $(TEST_CMPLOG_OBJ) $(CMP_LOG_INPUT)
gdb \
--ex 'set environment LD_PRELOAD=$(ROOT)afl-frida-trace.so' \

View File

@ -19,6 +19,9 @@ frida:
frida-nocmplog:
@gmake frida-nocmplog
frida-unprefixedpath:
@gmake frida-unprefixedpath
format:
@gmake format

View File

@ -25,7 +25,7 @@ HARNESS_URL:="https://raw.githubusercontent.com/llvm/llvm-project/main/compiler-
PNGTEST_FILE:=$(PNGTEST_BUILD_DIR)target.cc
PNGTEST_OBJ:=$(PNGTEST_BUILD_DIR)target.o
PNGTEST_URL:="https://raw.githubusercontent.com/google/fuzzbench/master/benchmarks/libpng-1.2.56/target.cc"
PNGTEST_URL:="https://raw.githubusercontent.com/google/fuzzbench/e0c4a994b6999bae46e8dec5bcea9a73251b8dba/benchmarks/libpng-1.2.56/target.cc"
TEST_BIN:=$(BUILD_DIR)test
ifeq "$(shell uname)" "Darwin"

View File

@ -201,6 +201,13 @@ class Afl {
Afl.jsApiSetInstrumentSeed(seed);
}
/*
* See `AFL_FRIDA_INST_NO_SUPPRESS`
*/
public static setInstrumentSuppressDisable(): void{
Afl.jsApiSetInstrumentSuppressDisable();
}
/**
* See `AFL_FRIDA_INST_TRACE_UNIQUE`.
*/
@ -451,6 +458,11 @@ class Afl {
"void",
["uint64"]);
private static readonly jsApiSetInstrumentSuppressDisable = Afl.jsApiGetFunction(
"js_api_set_instrument_suppress_disable",
"void",
[]);
private static readonly jsApiSetInstrumentTrace = Afl.jsApiGetFunction(
"js_api_set_instrument_trace",
"void",

View File

@ -1,11 +1,433 @@
{
"requires": true,
"name": "@worksbutnottested/aflplusplus-frida",
"version": "1.0.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"tsc": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/tsc/-/tsc-2.0.3.tgz",
"integrity": "sha512-SN+9zBUtrpUcOpaUO7GjkEHgWtf22c7FKbKCA4e858eEM7Qz86rRDpgOU2lBIDf0fLCsEg65ms899UMUIB2+Ow==",
"@babel/code-frame": {
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
"integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
"dev": true,
"requires": {
"@babel/highlight": "^7.18.6"
}
},
"@babel/helper-validator-identifier": {
"version": "7.19.1",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
"integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
"dev": true
},
"@babel/highlight": {
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
"integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
"dev": true,
"requires": {
"@babel/helper-validator-identifier": "^7.18.6",
"chalk": "^2.0.0",
"js-tokens": "^4.0.0"
}
},
"@types/frida-gum": {
"version": "16.5.1",
"resolved": "https://registry.npmjs.org/@types/frida-gum/-/frida-gum-16.5.1.tgz",
"integrity": "sha512-t+2HZG6iBO2cEKtb2KvtP33m/7TGmzSd42YqznToA34+TkS97NttsFZ9OY2s0hPyDQOg+hZTjR1QggRkEL/Ovg=="
},
"@types/node": {
"version": "14.18.36",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.36.tgz",
"integrity": "sha512-FXKWbsJ6a1hIrRxv+FoukuHnGTgEzKYGi7kilfMae96AL9UNkPFNWJEEYWzdRI9ooIkbr4AKldyuSTLql06vLQ==",
"dev": true
},
"ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"requires": {
"color-convert": "^1.9.0"
}
},
"argparse": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
"dev": true,
"requires": {
"sprintf-js": "~1.0.2"
}
},
"balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"builtin-modules": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
"integrity": "sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==",
"dev": true
},
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"dev": true,
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
}
},
"color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
"requires": {
"color-name": "1.1.3"
}
},
"color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
"dev": true
},
"commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"dev": true
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
"dev": true
},
"diff": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
"dev": true
},
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
"dev": true
},
"esprima": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
"dev": true
},
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
"dev": true
},
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true
},
"get-caller-file": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
"integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==",
"dev": true
},
"glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.1.1",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
},
"has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"dev": true,
"requires": {
"function-bind": "^1.1.1"
}
},
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
"dev": true
},
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
"dev": true,
"requires": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true
},
"is-core-module": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
"integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
"dev": true,
"requires": {
"has": "^1.0.3"
}
},
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"dev": true
},
"js-yaml": {
"version": "3.14.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
"dev": true,
"requires": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
}
},
"minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
"requires": {
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz",
"integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==",
"dev": true
},
"mkdirp": {
"version": "0.5.6",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
"integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
"dev": true,
"requires": {
"minimist": "^1.2.6"
}
},
"mock-require": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/mock-require/-/mock-require-3.0.3.tgz",
"integrity": "sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg==",
"dev": true,
"requires": {
"get-caller-file": "^1.0.2",
"normalize-path": "^2.1.1"
}
},
"normalize-path": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
"integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==",
"dev": true,
"requires": {
"remove-trailing-separator": "^1.0.1"
}
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"dev": true,
"requires": {
"wrappy": "1"
}
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
"dev": true
},
"path-parse": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"dev": true
},
"remove-trailing-separator": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
"integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==",
"dev": true
},
"resolve": {
"version": "1.22.1",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
"integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
"dev": true,
"requires": {
"is-core-module": "^2.9.0",
"path-parse": "^1.0.7",
"supports-preserve-symlinks-flag": "^1.0.0"
}
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"dev": true
},
"sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
"integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
"dev": true
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"requires": {
"has-flag": "^3.0.0"
}
},
"supports-preserve-symlinks-flag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
"dev": true
},
"tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
"dev": true
},
"tslint": {
"version": "6.1.3",
"resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz",
"integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
"builtin-modules": "^1.1.1",
"chalk": "^2.3.0",
"commander": "^2.12.1",
"diff": "^4.0.1",
"glob": "^7.1.1",
"js-yaml": "^3.13.1",
"minimatch": "^3.0.4",
"mkdirp": "^0.5.3",
"resolve": "^1.3.2",
"semver": "^5.3.0",
"tslib": "^1.13.0",
"tsutils": "^2.29.0"
}
},
"tsutils": {
"version": "2.29.0",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz",
"integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==",
"dev": true,
"requires": {
"tslib": "^1.8.1"
}
},
"typescript": {
"version": "4.9.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
"integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
"dev": true
},
"typescript-tslint-plugin": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/typescript-tslint-plugin/-/typescript-tslint-plugin-0.5.5.tgz",
"integrity": "sha512-tR5igNQP+6FhxaPJYRlUBVsEl0n5cSuXRbg7L1y80mL4B1jUHb8uiIcbQBJ9zWyypJEdFYFUccpXxvMwZR8+AA==",
"dev": true,
"requires": {
"minimatch": "^3.0.4",
"mock-require": "^3.0.3",
"vscode-languageserver": "^5.2.1"
}
},
"vscode-jsonrpc": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz",
"integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==",
"dev": true
},
"vscode-languageserver": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz",
"integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==",
"dev": true,
"requires": {
"vscode-languageserver-protocol": "3.14.1",
"vscode-uri": "^1.0.6"
}
},
"vscode-languageserver-protocol": {
"version": "3.14.1",
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz",
"integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==",
"dev": true,
"requires": {
"vscode-jsonrpc": "^4.0.0",
"vscode-languageserver-types": "3.14.0"
}
},
"vscode-languageserver-types": {
"version": "3.14.0",
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz",
"integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==",
"dev": true
},
"vscode-uri": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz",
"integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ==",
"dev": true
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"dev": true
}
}

View File

@ -68,6 +68,7 @@ static char *afl_environment_variables[] = {
"AFL_FRIDA_INST_NO_OPTIMIZE",
"AFL_FRIDA_INST_NO_PREFETCH",
"AFL_FRIDA_INST_NO_PREFETCH_BACKPATCH",
"AFL_FRIDA_INST_NO_SUPPRESS"
"AFL_FRIDA_INST_RANGES",
"AFL_FRIDA_INST_REGS_FILE",
"AFL_FRIDA_INST_SEED",

View File

@ -43,7 +43,7 @@ typedef enum NyxReturnValue {
Normal,
Crash,
Asan,
Timout,
Timeout,
InvalidWriteToPayload,
Error,
IoError,

View File

@ -1518,9 +1518,13 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
_is_sancov = 1;
__afl_auto_first();
__afl_auto_second();
__afl_auto_early();
if (!getenv("AFL_DUMP_MAP_SIZE")) {
__afl_auto_first();
__afl_auto_second();
__afl_auto_early();
}
if (__afl_debug) {
@ -1534,6 +1538,16 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
if (start == stop || *start) return;
x = getenv("AFL_INST_RATIO");
if (x) { inst_ratio = (u32)atoi(x); }
if (!inst_ratio || inst_ratio > 100) {
fprintf(stderr, "[-] ERROR: Invalid AFL_INST_RATIO (must be 1-100).\n");
abort();
}
// If a dlopen of an instrumented library happens after the forkserver then
// we have a problem as we cannot increase the coverage map anymore.
if (__afl_already_initialized_forkserver) {
@ -1554,74 +1568,34 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
while (start < stop) {
*(start++) = offset;
if (likely(inst_ratio == 100) || R(100) < inst_ratio)
*start = offset;
else
*start = 0; // write to map[0]
if (unlikely(++offset >= __afl_final_loc)) { offset = 4; }
}
}
}
x = getenv("AFL_INST_RATIO");
if (x) { inst_ratio = (u32)atoi(x); }
if (!inst_ratio || inst_ratio > 100) {
fprintf(stderr, "[-] ERROR: Invalid AFL_INST_RATIO (must be 1-100).\n");
abort();
return; // we are done for this special case
}
/* instrumented code is loaded *after* our forkserver is up. this is a
problem. We cannot prevent collisions then :( */
/*
if (__afl_already_initialized_forkserver &&
__afl_final_loc + 1 + stop - start > __afl_map_size) {
if (__afl_debug) {
fprintf(stderr, "Warning: new instrumented code after the forkserver!\n");
}
__afl_final_loc = 2;
if (1 + stop - start > __afl_map_size) {
*(start++) = ++__afl_final_loc;
while (start < stop) {
if (R(100) < inst_ratio)
*start = ++__afl_final_loc % __afl_map_size;
else
*start = 4;
start++;
}
return;
}
}
*/
/* Make sure that the first element in the range is always set - we use that
to avoid duplicate calls (which can happen as an artifact of the underlying
implementation in LLVM). */
if (__afl_final_loc < 3) __afl_final_loc = 3; // we skip the first 4 entries
*(start++) = ++__afl_final_loc;
while (start < stop) {
if (R(100) < inst_ratio)
if (likely(inst_ratio == 100) || R(100) < inst_ratio)
*start = ++__afl_final_loc;
else
*start = 4;
*start = 0; // write to map[0]
start++;

View File

@ -1152,10 +1152,14 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
b_op1 = SelectInst::Create(isMzero_op1, ConstantInt::get(intType, PlusZero),
bpre_op1);
#if LLVM_MAJOR >= 16
isMzero_op0->insertInto(nonan_bb, BasicBlock::iterator(nonan_bb->getTerminator()));
isMzero_op1->insertInto(nonan_bb, BasicBlock::iterator(nonan_bb->getTerminator()));
b_op0->insertInto(nonan_bb, BasicBlock::iterator(nonan_bb->getTerminator()));
b_op1->insertInto(nonan_bb, BasicBlock::iterator(nonan_bb->getTerminator()));
isMzero_op0->insertInto(nonan_bb,
BasicBlock::iterator(nonan_bb->getTerminator()));
isMzero_op1->insertInto(nonan_bb,
BasicBlock::iterator(nonan_bb->getTerminator()));
b_op0->insertInto(nonan_bb,
BasicBlock::iterator(nonan_bb->getTerminator()));
b_op1->insertInto(nonan_bb,
BasicBlock::iterator(nonan_bb->getTerminator()));
#else
nonan_bb->getInstList().insert(
BasicBlock::iterator(nonan_bb->getTerminator()), isMzero_op0);
@ -1192,7 +1196,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
t_s0->insertInto(nonan_bb, BasicBlock::iterator(nonan_bb->getTerminator()));
s_s1->insertInto(nonan_bb, BasicBlock::iterator(nonan_bb->getTerminator()));
t_s1->insertInto(nonan_bb, BasicBlock::iterator(nonan_bb->getTerminator()));
icmp_sign_bit->insertInto(nonan_bb, BasicBlock::iterator(nonan_bb->getTerminator()));
icmp_sign_bit->insertInto(nonan_bb,
BasicBlock::iterator(nonan_bb->getTerminator()));
#else
nonan_bb->getInstList().insert(
BasicBlock::iterator(nonan_bb->getTerminator()), s_s0);
@ -1239,8 +1244,10 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
Instruction::LShr, b_op1,
ConstantInt::get(b_op1->getType(), shiftR_exponent));
#if LLVM_MAJOR >= 16
s_e0->insertInto(signequal_bb, BasicBlock::iterator(signequal_bb->getTerminator()));
s_e1->insertInto(signequal_bb, BasicBlock::iterator(signequal_bb->getTerminator()));
s_e0->insertInto(signequal_bb,
BasicBlock::iterator(signequal_bb->getTerminator()));
s_e1->insertInto(signequal_bb,
BasicBlock::iterator(signequal_bb->getTerminator()));
#else
signequal_bb->getInstList().insert(
BasicBlock::iterator(signequal_bb->getTerminator()), s_e0);
@ -1251,15 +1258,16 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
t_e0 = new TruncInst(s_e0, IntExponentTy);
t_e1 = new TruncInst(s_e1, IntExponentTy);
#if LLVM_MAJOR >= 16
t_e0->insertInto(signequal_bb, BasicBlock::iterator(signequal_bb->getTerminator()));
t_e1->insertInto(signequal_bb, BasicBlock::iterator(signequal_bb->getTerminator()));
t_e0->insertInto(signequal_bb,
BasicBlock::iterator(signequal_bb->getTerminator()));
t_e1->insertInto(signequal_bb,
BasicBlock::iterator(signequal_bb->getTerminator()));
#else
signequal_bb->getInstList().insert(
BasicBlock::iterator(signequal_bb->getTerminator()), t_e0);
signequal_bb->getInstList().insert(
BasicBlock::iterator(signequal_bb->getTerminator()), t_e1);
#endif
if (sizeInBits - precision < exTySizeBytes * 8) {
@ -1270,8 +1278,10 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
Instruction::And, t_e1,
ConstantInt::get(t_e1->getType(), mask_exponent));
#if LLVM_MAJOR >= 16
m_e0->insertInto(signequal_bb, BasicBlock::iterator(signequal_bb->getTerminator()));
m_e1->insertInto(signequal_bb, BasicBlock::iterator(signequal_bb->getTerminator()));
m_e0->insertInto(signequal_bb,
BasicBlock::iterator(signequal_bb->getTerminator()));
m_e1->insertInto(signequal_bb,
BasicBlock::iterator(signequal_bb->getTerminator()));
#else
signequal_bb->getInstList().insert(
BasicBlock::iterator(signequal_bb->getTerminator()), m_e0);
@ -1312,7 +1322,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
icmp_exponents_equal =
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, m_e0, m_e1);
#if LLVM_MAJOR >= 16
icmp_exponents_equal->insertInto(signequal_bb, BasicBlock::iterator(signequal_bb->getTerminator()));
icmp_exponents_equal->insertInto(
signequal_bb, BasicBlock::iterator(signequal_bb->getTerminator()));
#else
signequal_bb->getInstList().insert(
BasicBlock::iterator(signequal_bb->getTerminator()),
@ -1332,7 +1343,9 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
icmp_exponent =
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGT, m_e0, m_e1);
#if LLVM_MAJOR >= 16
icmp_exponent->insertInto(signequal2_bb, BasicBlock::iterator(signequal2_bb->getTerminator()));
icmp_exponent->insertInto(
signequal2_bb,
BasicBlock::iterator(signequal2_bb->getTerminator()));
#else
signequal2_bb->getInstList().insert(
BasicBlock::iterator(signequal2_bb->getTerminator()),
@ -1346,7 +1359,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
icmp_exponents_equal =
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, m_e0, m_e1);
#if LLVM_MAJOR >= 16
icmp_exponents_equal->insertInto(signequal_bb, BasicBlock::iterator(signequal_bb->getTerminator()));
icmp_exponents_equal->insertInto(
signequal_bb, BasicBlock::iterator(signequal_bb->getTerminator()));
#else
signequal_bb->getInstList().insert(
BasicBlock::iterator(signequal_bb->getTerminator()),
@ -1366,7 +1380,9 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
icmp_exponent =
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_ULT, m_e0, m_e1);
#if LLVM_MAJOR >= 16
icmp_exponent->insertInto(signequal2_bb, BasicBlock::iterator(signequal2_bb->getTerminator()));
icmp_exponent->insertInto(
signequal2_bb,
BasicBlock::iterator(signequal2_bb->getTerminator()));
#else
signequal2_bb->getInstList().insert(
BasicBlock::iterator(signequal2_bb->getTerminator()),
@ -1381,7 +1397,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
}
#if LLVM_MAJOR >= 16
icmp_exponent_result->insertInto(signequal2_bb, BasicBlock::iterator(signequal2_bb->getTerminator()));
icmp_exponent_result->insertInto(
signequal2_bb, BasicBlock::iterator(signequal2_bb->getTerminator()));
#else
signequal2_bb->getInstList().insert(
BasicBlock::iterator(signequal2_bb->getTerminator()),
@ -1437,8 +1454,10 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
Instruction::And, b_op1,
ConstantInt::get(b_op1->getType(), mask_fraction));
#if LLVM_MAJOR >= 16
m_f0->insertInto(middle_bb, BasicBlock::iterator(middle_bb->getTerminator()));
m_f1->insertInto(middle_bb, BasicBlock::iterator(middle_bb->getTerminator()));
m_f0->insertInto(middle_bb,
BasicBlock::iterator(middle_bb->getTerminator()));
m_f1->insertInto(middle_bb,
BasicBlock::iterator(middle_bb->getTerminator()));
#else
middle_bb->getInstList().insert(
BasicBlock::iterator(middle_bb->getTerminator()), m_f0);
@ -1451,8 +1470,10 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
t_f0 = new TruncInst(m_f0, IntFractionTy);
t_f1 = new TruncInst(m_f1, IntFractionTy);
#if LLVM_MAJOR >= 16
t_f0->insertInto(middle_bb, BasicBlock::iterator(middle_bb->getTerminator()));
t_f1->insertInto(middle_bb, BasicBlock::iterator(middle_bb->getTerminator()));
t_f0->insertInto(middle_bb,
BasicBlock::iterator(middle_bb->getTerminator()));
t_f1->insertInto(middle_bb,
BasicBlock::iterator(middle_bb->getTerminator()));
#else
middle_bb->getInstList().insert(
BasicBlock::iterator(middle_bb->getTerminator()), t_f0);
@ -1474,8 +1495,10 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
t_f0 = new TruncInst(b_op0, IntFractionTy);
t_f1 = new TruncInst(b_op1, IntFractionTy);
#if LLVM_MAJOR >= 16
t_f0->insertInto(middle_bb, BasicBlock::iterator(middle_bb->getTerminator()));
t_f1->insertInto(middle_bb, BasicBlock::iterator(middle_bb->getTerminator()));
t_f0->insertInto(middle_bb,
BasicBlock::iterator(middle_bb->getTerminator()));
t_f1->insertInto(middle_bb,
BasicBlock::iterator(middle_bb->getTerminator()));
#else
middle_bb->getInstList().insert(
BasicBlock::iterator(middle_bb->getTerminator()), t_f0);
@ -1503,7 +1526,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
icmp_fraction_result =
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, t_f0, t_f1);
#if LLVM_MAJOR >= 16
icmp_fraction_result->insertInto(middle2_bb, BasicBlock::iterator(middle2_bb->getTerminator()));
icmp_fraction_result->insertInto(
middle2_bb, BasicBlock::iterator(middle2_bb->getTerminator()));
#else
middle2_bb->getInstList().insert(
BasicBlock::iterator(middle2_bb->getTerminator()),
@ -1516,7 +1540,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
icmp_fraction_result =
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_NE, t_f0, t_f1);
#if LLVM_MAJOR >= 16
icmp_fraction_result->insertInto(middle2_bb, BasicBlock::iterator(middle2_bb->getTerminator()));
icmp_fraction_result->insertInto(
middle2_bb, BasicBlock::iterator(middle2_bb->getTerminator()));
#else
middle2_bb->getInstList().insert(
BasicBlock::iterator(middle2_bb->getTerminator()),
@ -1542,13 +1567,13 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
if (FcmpInst->getPredicate() == CmpInst::FCMP_OGT ||
FcmpInst->getPredicate() == CmpInst::FCMP_UGT) {
icmp_fraction_result = CmpInst::Create(
Instruction::ICmp, CmpInst::ICMP_ULT, t_f0, t_f1);
icmp_fraction_result2 = CmpInst::Create(
Instruction::ICmp, CmpInst::ICMP_UGT, t_f0, t_f1);
icmp_fraction_result =
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_ULT, t_f0, t_f1);
icmp_fraction_result2 =
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGT, t_f0, t_f1);
#if LLVM_MAJOR >= 16
icmp_fraction_result->insertInto(negative_bb, negative_bb->end());
icmp_fraction_result2->insertInto(positive_bb, negative_bb->end());
icmp_fraction_result->insertInto(negative_bb, negative_bb->end());
icmp_fraction_result2->insertInto(positive_bb, negative_bb->end());
#else
negative_bb->getInstList().push_back(icmp_fraction_result);
positive_bb->getInstList().push_back(icmp_fraction_result2);
@ -1556,13 +1581,13 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
} else {
icmp_fraction_result = CmpInst::Create(
Instruction::ICmp, CmpInst::ICMP_UGT, t_f0, t_f1);
icmp_fraction_result2 = CmpInst::Create(
Instruction::ICmp, CmpInst::ICMP_ULT, t_f0, t_f1);
icmp_fraction_result =
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGT, t_f0, t_f1);
icmp_fraction_result2 =
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_ULT, t_f0, t_f1);
#if LLVM_MAJOR >= 16
icmp_fraction_result->insertInto(negative_bb, negative_bb->end());
icmp_fraction_result2->insertInto(positive_bb, negative_bb->end());
icmp_fraction_result->insertInto(negative_bb, negative_bb->end());
icmp_fraction_result2->insertInto(positive_bb, negative_bb->end());
#else
negative_bb->getInstList().push_back(icmp_fraction_result);
positive_bb->getInstList().push_back(icmp_fraction_result2);
@ -1581,7 +1606,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
PN2->addIncoming(icmp_fraction_result, negative_bb);
PN2->addIncoming(icmp_fraction_result2, positive_bb);
#if LLVM_MAJOR >= 16
PN2->insertInto(middle2_bb, BasicBlock::iterator(middle2_bb->getTerminator()));
PN2->insertInto(middle2_bb,
BasicBlock::iterator(middle2_bb->getTerminator()));
#else
middle2_bb->getInstList().insert(
BasicBlock::iterator(middle2_bb->getTerminator()), PN2);

View File

@ -0,0 +1,201 @@
# Fuzz ARM32 Python Native Extensions in Binary-only Mode (LLVM fork-based)
This is an example on how to fuzz Python native extensions in LLVM mode with deferred initialization on ARM32.
We use Ubuntu x86_64 to run AFL++ and an Alpine ARMv7 Chroot to build the fuzzing target.
Check [Resources](#resources) for the code used in this example.
## Setup Alpine ARM Chroot on your x86_64 Linux Host
### Use systemd-nspawn
1. Install `qemu-user-binfmt`, `qemu-user-static` and `systemd-container` dependencies.
2. Restart the systemd-binfmt service: `systemctl restart systemd-binfmt.service`
3. Download an Alpine ARM RootFS from https://alpinelinux.org/downloads/
4. Create a new `alpine_sysroot` folder and extract: `tar xfz alpine-minirootfs-3.17.1-armv7.tar.gz -C alpine_sysroot/`
5. Copy `qemu-arm-static` to Alpine's RootFS: `cp $(which qemu-arm-static) ./alpine/usr/bin/`
6. Chroot into the container: `sudo systemd-nspawn -D alpine/ --bind-ro=/etc/resolv.conf`
7. Install dependencies: `apk update && apk add build-base musl-dev clang15 python3 python3-dev py3-pip`
8. Exit the container with `exit`
### Alternatively use Docker
1. Install `qemu-user-binfmt` and `qemu-user-static`
2. Run Qemu container: ```$ docker run --rm --privileged multiarch/qemu-user-static --reset -p yes```
3. Run Alpine container: ```$ docker run -it --rm arm32v7/alpine sh```
## Build AFL++ Qemu Mode with ARM Support
First, build AFL++ as described [here](https://github.com/AFLplusplus/AFLplusplus/blob/dev/docs/INSTALL.md). Then, run the Qemu build script:
```bash
cd qemu_mode && CPU_TARGET=arm ./build_qemu_support.sh
```
## Compile and Build the Fuzzing Project
Build the native extension and the fuzzing harness for ARM using the Alpine container (check [Resources](#resources) for the code):
```bash
ALPINE_ROOT=<your-alpine-sysroot-directory>
FUZZ=<your-path-to-the-code>
sudo systemd-nspawn -D $ALPINE_ROOT --bind=$FUZZ:/fuzz
CC=$(which clang) CFLAGS="-g" LDSHARED="clang -shared" python3 -m pip install /fuzz
clang $(python3-config --embed --cflags) $(python3-config --embed --ldflags) -o /fuzz/fuzz_harness /fuzz/fuzz_harness.c
exit
```
Manually trigger bug:
```bash
echo -n "FUZZ" | qemu-arm-static -L $ALPINE_ROOT $FUZZ/fuzz_harness
```
## Run AFL++
Make sure to start the forkserver *after* loading all the shared objects by setting the `AFL_ENTRYPOINT` environment variable (see [here](https://aflplus.plus/docs/env_variables/#5-settings-for-afl-qemu-trace) for details):
Choose an address just before the `while()` loop, for example:
```bash
qemu-arm-static -L $ALPINE_ROOT $ALPINE_ROOT/usr/bin/objdump -d $FUZZ/fuzz_harness | grep -A 1 "PyObject_GetAttrString"
00000584 <PyObject_GetAttrString@plt>:
584: e28fc600 add ip, pc, #0, 12
--
7c8: ebffff6d bl 584 <PyObject_GetAttrString@plt>
7cc: e58d0008 str r0, [sp, #8]
...
```
Check Qemu memory maps using the instructions from [here](https://aflplus.plus/docs/tutorials/libxml2_tutorial/):
>The binary is position independent and QEMU persistent needs the real addresses, not the offsets. Fortunately, QEMU loads PIE executables at a fixed address, 0x4000000000 for x86_64.
>
> We can check it using `AFL_QEMU_DEBUG_MAPS`. You dont need this step if your binary is not PIE.
Setup Python environment variables and run `afl-qemu-trace`:
```bash
PYTHONPATH=$ALPINE_ROOT/usr/lib/python3.10/ PYTHONHOME=$ALPINE_ROOT/usr/bin/ QEMU_LD_PREFIX=$ALPINE_ROOT AFL_QEMU_DEBUG_MAPS=1 afl-qemu-trace $FUZZ/fuzz_harness
...
40000000-40001000 r-xp 00000000 103:03 8002276 fuzz_harness
40001000-4001f000 ---p 00000000 00:00 0
4001f000-40020000 r--p 0000f000 103:03 8002276 fuzz_harness
40020000-40021000 rw-p 00010000 103:03 8002276 fuzz_harness
40021000-40022000 ---p 00000000 00:00 0
40022000-40023000 rw-p 00000000 00:00 0
```
Finally, setup Qemu environment variables...
```bash
export QEMU_SET_ENV=PYTHONPATH=$ALPINE_ROOT/usr/lib/python310.zip:$ALPINE_ROOT/usr/lib/python3.10:$ALPINE_ROOT/usr/lib/python3.10/lib-dynload:$ALPINE_ROOT/usr/lib/python3.10/site-packages,PYTHONHOME=$ALPINE_ROOT/usr/bin/
export QEMU_LD_PREFIX=$ALPINE_ROOT
```
... and run AFL++:
```bash
mkdir -p $FUZZ/in && echo -n "FU" > $FUZZ/in/seed
AFL_ENTRYPOINT=0x400007cc afl-fuzz -i $FUZZ/in -o $FUZZ/out -Q -- $FUZZ/fuzz_harness
```
## Resources
### setup.py
```python
from distutils.core import setup, Extension
module = Extension("memory", sources=["fuzz_target.c"])
setup(
name="memory",
version="1.0",
description='A simple "BOOM!" extension',
ext_modules=[module],
)
```
### fuzz_target.c
```c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#pragma clang optimize off
static PyObject *corruption(PyObject* self, PyObject* args) {
char arr[3];
Py_buffer name;
if (!PyArg_ParseTuple(args, "y*", &name))
return NULL;
if (name.buf != NULL) {
if (strcmp(name.buf, "FUZZ") == 0) {
arr[0] = 'B';
arr[1] = 'O';
arr[2] = 'O';
arr[3] = 'M';
}
}
PyBuffer_Release(&name);
Py_RETURN_NONE;
}
static PyMethodDef MemoryMethods[] = {
{"corruption", corruption, METH_VARARGS, "BOOM!"},
{NULL, NULL, 0, NULL}
};
static struct PyModuleDef memory_module = {
PyModuleDef_HEAD_INIT,
"memory",
"BOOM!",
-1,
MemoryMethods
};
PyMODINIT_FUNC PyInit_memory(void) {
return PyModule_Create(&memory_module);
}
```
### fuzz_harness.c
```c
#include <Python.h>
#pragma clang optimize off
int main(int argc, char **argv) {
unsigned char buf[1024000];
ssize_t size;
Py_Initialize();
PyObject* name = PyUnicode_DecodeFSDefault("memory");
PyObject* module = PyImport_Import(name);
Py_DECREF(name);
if (module != NULL) {
PyObject* corruption_func = PyObject_GetAttrString(module, "corruption");
while ((size = read(0, buf, sizeof(buf))) > 0 ? 1 : 0) {
PyObject* arg = PyBytes_FromStringAndSize((char *)buf, size);
if (arg != NULL) {
PyObject* res = PyObject_CallFunctionObjArgs(corruption_func, arg, NULL);
if (res != NULL) {
Py_XDECREF(res);
}
Py_DECREF(arg);
}
}
Py_DECREF(corruption_func);
Py_DECREF(module);
}
// Py_Finalize() leaks memory on certain Python versions (see https://bugs.python.org/issue1635741)
// Py_Finalize();
return 0;
}
```

View File

@ -66,6 +66,8 @@ allows to move the forkserver to a different part, e.g., just before the file is
opened (e.g., way after command line parsing and config file loading, etc.)
which can be a huge speed improvement.
For an example, see [README.deferred_initialization_example.md](README.deferred_initialization_example.md).
## 4) Persistent mode
AFL++'s QEMU mode now supports also persistent mode for x86, x86_64, arm, and

View File

@ -1370,7 +1370,7 @@ afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
case Crash:
case Asan:
return FSRV_RUN_CRASH;
case Timout:
case Timeout:
return FSRV_RUN_TMOUT;
case InvalidWriteToPayload:
/* ??? */

View File

@ -41,7 +41,7 @@ void cmplog_exec_child(afl_forkserver_t *fsrv, char **argv) {
}
execv(argv[0], argv);
execv(fsrv->target_path, argv);
}

View File

@ -312,12 +312,18 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) {
if (notrim) {
if (mutator->afl_custom_init_trim || mutator->afl_custom_trim ||
mutator->afl_custom_post_trim) {
WARNF(
"Custom mutator does not implement all three trim APIs, standard "
"trimming will be used.");
}
mutator->afl_custom_init_trim = NULL;
mutator->afl_custom_trim = NULL;
mutator->afl_custom_post_trim = NULL;
ACTF(
"Custom mutator does not implement all three trim APIs, standard "
"trimming will be used.");
}

View File

@ -5691,6 +5691,7 @@ pacemaker_fuzzing:
} /* block */
++afl->queue_cur->fuzz_level;
return ret_val;
}
@ -5804,7 +5805,7 @@ void pso_updating(afl_state_t *afl) {
depending on the configuration. */
u8 fuzz_one(afl_state_t *afl) {
int key_val_lv_1 = 0, key_val_lv_2 = 0;
int key_val_lv_1 = -1, key_val_lv_2 = -1;
#ifdef _AFL_DOCUMENT_MUTATIONS
@ -5851,6 +5852,9 @@ u8 fuzz_one(afl_state_t *afl) {
}
if (unlikely(key_val_lv_1 == -1)) { key_val_lv_1 = 0; }
if (likely(key_val_lv_2 == -1)) { key_val_lv_2 = 0; }
return (key_val_lv_1 | key_val_lv_2);
}

View File

@ -1028,10 +1028,16 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
break;
case LIN:
// Don't modify perf_score for unfuzzed seeds
if (!q->fuzz_level) break;
factor = q->fuzz_level / (afl->n_fuzz[q->n_fuzz_entry] + 1);
break;
case QUAD:
// Don't modify perf_score for unfuzzed seeds
if (!q->fuzz_level) break;
factor =
q->fuzz_level * q->fuzz_level / (afl->n_fuzz[q->n_fuzz_entry] + 1);
break;

View File

@ -1624,6 +1624,8 @@ static void try_to_add_to_dictN(afl_state_t *afl, u128 v, u8 size) {
}
if (cons_0 > 1 || cons_ff > 1) { return; }
}
maybe_add_auto(afl, (u8 *)&v + off, size);

View File

@ -1298,6 +1298,12 @@ int main(int argc, char **argv_orig, char **envp) {
}
if (afl->is_main_node == 1 && afl->schedule != FAST && afl->schedule != EXPLORE) {
FATAL("-M is compatible only with fast and explore -p power schedules");
}
if (optind == argc || !afl->in_dir || !afl->out_dir || show_help) {
usage(argv[0], show_help);
@ -1346,12 +1352,11 @@ int main(int argc, char **argv_orig, char **envp) {
}
#endif
if (afl->sync_id && afl->is_main_node &&
afl->afl_env.afl_custom_mutator_only) {
if (!afl->skip_deterministic && afl->afl_env.afl_custom_mutator_only) {
WARNF(
"Using -M main node with the AFL_CUSTOM_MUTATOR_ONLY mutator options "
"will result in no deterministic mutations being done!");
FATAL(
"Using -D determinstic fuzzing is incompatible with "
"AFL_CUSTOM_MUTATOR_ONLY!");
}
@ -2106,6 +2111,7 @@ int main(int argc, char **argv_orig, char **envp) {
afl->cmplog_fsrv.qemu_mode = afl->fsrv.qemu_mode;
afl->cmplog_fsrv.frida_mode = afl->fsrv.frida_mode;
afl->cmplog_fsrv.cmplog_binary = afl->cmplog_binary;
afl->cmplog_fsrv.target_path = afl->fsrv.target_path;
afl->cmplog_fsrv.init_child_func = cmplog_exec_child;
if ((map_size <= DEFAULT_SHMEM_SIZE ||
@ -2574,6 +2580,7 @@ int main(int argc, char **argv_orig, char **envp) {
skipped_fuzz = fuzz_one(afl);
#ifdef INTROSPECTION
++afl->queue_cur->stats_selected;
if (unlikely(skipped_fuzz)) {
++afl->queue_cur->stats_skipped;

View File

@ -92,7 +92,7 @@ static u32 measure_preemption(u32 target_ms) {
volatile u32 v1, v2 = 0;
u64 st_t, en_t, st_c, en_c, real_delta, slice_delta;
s32 loop_repeats = 0;
//s32 loop_repeats = 0;
st_t = get_cur_time_us();
st_c = get_cpu_usage_us();
@ -113,7 +113,7 @@ repeat_loop:
if (en_t - st_t < target_ms * 1000) {
loop_repeats++;
//loop_repeats++;
goto repeat_loop;
}
@ -214,7 +214,13 @@ int main(int argc, char **argv) {
#if defined(__linux__)
if (sched_setaffinity(0, sizeof(c), &c)) {
PFATAL("sched_setaffinity failed for cpu %d", i);
const char *error_code = "Unkown error code";
if (errno == EFAULT) error_code = "EFAULT";
if (errno == EINVAL) error_code = "EINVAL";
if (errno == EPERM) error_code = "EPERM";
if (errno == ESRCH) error_code = "ESRCH";
PFATAL("sched_setaffinity failed for cpu %d, error: %s", i, error_code);
}