mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-24 14:43:22 +00:00
Compare commits
59 Commits
Author | SHA1 | Date | |
---|---|---|---|
c340a022e2 | |||
06219b4d56 | |||
c5b8f4250e | |||
779cb5d942 | |||
fb1a41f5af | |||
8352f0a89f | |||
9935190c7b | |||
e3ee26262f | |||
737c13b460 | |||
9836598d65 | |||
63509fb696 | |||
d1c44e12a8 | |||
f78ed6eabc | |||
64c942d0c9 | |||
50e343a0d0 | |||
55719ab23b | |||
d12c5edd59 | |||
1b82d6b904 | |||
61201fbbb8 | |||
b9458e72e7 | |||
5045f9e615 | |||
6cd8a0168f | |||
448c6c212d | |||
05f4762894 | |||
0a06e36788 | |||
9b1f80c277 | |||
787a332a73 | |||
7d85047fd9 | |||
fa8dc2028f | |||
619aa70414 | |||
247e8241b4 | |||
0bb64e4bc9 | |||
7b84ec97e2 | |||
20a6cdabad | |||
0d286c9e19 | |||
db94ec9cad | |||
05dfb70787 | |||
7f2becba72 | |||
13b27bb59e | |||
ecdbdc3164 | |||
788e70a01a | |||
938ed60ea9 | |||
5b9d2cc38b | |||
e305bc15d3 | |||
0b12c7e0cc | |||
4bd492f212 | |||
be8393f201 | |||
aec90c7227 | |||
1960352310 | |||
03169b2b67 | |||
dee51213a7 | |||
1d2de1cb6d | |||
5ed187b517 | |||
757184e611 | |||
27b18e6267 | |||
f3b15d6340 | |||
0134a23046 | |||
542233e1ce | |||
8e4823e7ed |
@ -21,12 +21,15 @@ import os
|
||||
# import re # TODO: for future use
|
||||
import shutil
|
||||
import importlib.metadata
|
||||
import hashlib
|
||||
|
||||
# string_re = re.compile('(\\"(\\\\.|[^"\\\\])*\\")') # TODO: for future use
|
||||
|
||||
CURRENT_LLVM = os.getenv('LLVM_VERSION', 18)
|
||||
CLANG_FORMAT_BIN = os.getenv("CLANG_FORMAT_BIN", "")
|
||||
|
||||
FORMAT_CACHE_DIR = '.format-cache'
|
||||
os.makedirs(FORMAT_CACHE_DIR, exist_ok=True)
|
||||
|
||||
def check_clang_format_pip_version():
|
||||
"""
|
||||
@ -69,6 +72,8 @@ to install via pip.")
|
||||
if CLANG_FORMAT_PIP:
|
||||
CLANG_FORMAT_BIN = shutil.which("clang-format")
|
||||
|
||||
CLANG_FORMAT_VERSION = subprocess.check_output([CLANG_FORMAT_BIN, '--version'])
|
||||
|
||||
COLUMN_LIMIT = 80
|
||||
for line in fmt.split("\n"):
|
||||
line = line.split(":")
|
||||
@ -86,9 +91,10 @@ def custom_format(filename):
|
||||
out = ""
|
||||
|
||||
for line in src.split("\n"):
|
||||
define_start = False
|
||||
if line.lstrip().startswith("#"):
|
||||
if line[line.find("#") + 1:].lstrip().startswith("define"):
|
||||
in_define = True
|
||||
define_start = True
|
||||
|
||||
if (
|
||||
"/*" in line
|
||||
@ -126,9 +132,7 @@ def custom_format(filename):
|
||||
and last_line.strip() != ""
|
||||
):
|
||||
line = (" " * define_padding + "\\" if in_define else "") + "\n" + line
|
||||
|
||||
if not line.endswith("\\"):
|
||||
in_define = False
|
||||
in_define = (define_start or in_define) and line.endswith("\\")
|
||||
|
||||
out += line + "\n"
|
||||
last_line = line
|
||||
@ -136,6 +140,38 @@ def custom_format(filename):
|
||||
return out
|
||||
|
||||
|
||||
def hash_code_and_formatter(code):
|
||||
hasher = hashlib.sha256()
|
||||
|
||||
hasher.update(code.encode())
|
||||
hasher.update(CLANG_FORMAT_VERSION)
|
||||
with open(__file__, 'rb') as f:
|
||||
hasher.update(f.read())
|
||||
|
||||
return hasher.hexdigest()
|
||||
|
||||
|
||||
def custom_format_cached(filename):
|
||||
filename_hash = hashlib.sha256(filename.encode()).hexdigest()
|
||||
cache_file = os.path.join(FORMAT_CACHE_DIR, filename_hash)
|
||||
|
||||
if os.path.exists(cache_file):
|
||||
with open(filename) as f:
|
||||
code = f.read()
|
||||
code_hash = hash_code_and_formatter(code)
|
||||
with open(cache_file) as f:
|
||||
if f.read() == code_hash:
|
||||
return code
|
||||
|
||||
code = custom_format(filename)
|
||||
|
||||
code_hash = hash_code_and_formatter(code)
|
||||
with open(cache_file, 'w') as f:
|
||||
f.write(code_hash)
|
||||
|
||||
return code
|
||||
|
||||
|
||||
args = sys.argv[1:]
|
||||
if len(args) == 0:
|
||||
print("Usage: ./format.py [-i] <filename>")
|
||||
@ -151,7 +187,7 @@ if args[0] == "-i":
|
||||
args = args[1:]
|
||||
|
||||
for filename in args:
|
||||
code = custom_format(filename)
|
||||
code = custom_format_cached(filename)
|
||||
if in_place:
|
||||
with open(filename, "w") as f:
|
||||
f.write(code)
|
||||
|
2
.github/workflows/rust_custom_mutator.yml
vendored
2
.github/workflows/rust_custom_mutator.yml
vendored
@ -18,7 +18,7 @@ jobs:
|
||||
working-directory: custom_mutators/rust
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-22.04, ubuntu-20.04]
|
||||
os: [ubuntu-22.04]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install Rust Toolchain
|
||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -7,6 +7,7 @@
|
||||
*.so
|
||||
*.swp
|
||||
.DS_Store
|
||||
.format-cache
|
||||
.sync_tmp
|
||||
.test
|
||||
.test2
|
||||
@ -113,4 +114,4 @@ utils/replay_record/persistent_demo_replay_argparse
|
||||
utils/plot_ui/afl-plot-ui
|
||||
vuln_prog
|
||||
argv_fuzz_demo
|
||||
argv_fuzz_persistent_demo
|
||||
argv_fuzz_persistent_demo
|
||||
|
29
GNUmakefile
29
GNUmakefile
@ -289,7 +289,7 @@ ifneq "$(findstring OpenBSD, $(SYS))" ""
|
||||
override LDFLAGS += -lpthread -lm
|
||||
endif
|
||||
|
||||
COMM_HDR = include/alloc-inl.h include/config.h include/debug.h include/types.h
|
||||
COMM_HDR = include/alloc-inl.h include/config.h include/debug.h include/types.h include/afl-fuzz.h include/hash.h include/sharedmem.h include/forkserver.h include/common.h include/list.h
|
||||
|
||||
ifeq "$(shell echo '$(HASH)include <Python.h>@int main() {return 0; }' | tr @ '\n' | $(CC) $(CFLAGS) -x c - -o .test $(PYTHON_INCLUDE) $(LDFLAGS) $(PYTHON_LIB) 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||
PYTHON_OK=1
|
||||
@ -472,32 +472,32 @@ endif
|
||||
ready:
|
||||
@echo "[+] Everything seems to be working, ready to compile. ($(shell $(CC) --version 2>&1|head -n 1))"
|
||||
|
||||
src/afl-performance.o : $(COMM_HDR) src/afl-performance.c include/hash.h
|
||||
$(CC) $(CFLAGS) $(CFLAGS_OPT) $(SPECIAL_PERFORMANCE) -Iinclude -c src/afl-performance.c -o src/afl-performance.o
|
||||
src/afl-performance.o: $(COMM_HDR) src/afl-performance.c
|
||||
$(CC) $(CFLAGS) $(CFLAGS_FLTO) $(CFLAGS_OPT) $(SPECIAL_PERFORMANCE) -Iinclude -c src/afl-performance.c -o src/afl-performance.o
|
||||
|
||||
src/afl-common.o : $(COMM_HDR) src/afl-common.c include/common.h
|
||||
src/afl-common.o: $(COMM_HDR) src/afl-common.c include/envs.h
|
||||
$(CC) $(CFLAGS) $(CFLAGS_FLTO) $(SPECIAL_PERFORMANCE) -c src/afl-common.c -o src/afl-common.o
|
||||
|
||||
src/afl-forkserver.o : $(COMM_HDR) src/afl-forkserver.c include/forkserver.h
|
||||
src/afl-forkserver.o: $(COMM_HDR) src/afl-forkserver.c
|
||||
$(CC) $(CFLAGS) $(CFLAGS_FLTO) $(SPECIAL_PERFORMANCE) -c src/afl-forkserver.c -o src/afl-forkserver.o
|
||||
|
||||
src/afl-sharedmem.o : $(COMM_HDR) src/afl-sharedmem.c include/sharedmem.h
|
||||
src/afl-sharedmem.o: $(COMM_HDR) src/afl-sharedmem.c include/android-ashmem.h include/cmplog.h
|
||||
$(CC) $(CFLAGS) $(CFLAGS_FLTO) $(SPECIAL_PERFORMANCE) -c src/afl-sharedmem.c -o src/afl-sharedmem.o
|
||||
|
||||
afl-fuzz: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.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 src/afl-performance.o include/cmplog.h include/envs.h | test_x86
|
||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) $(SPECIAL_PERFORMANCE) $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(PYFLAGS) $(LDFLAGS) -lm
|
||||
ifdef IS_IOS
|
||||
@ldid -Sentitlements.plist $@ && echo "[+] Signed $@" || { echo "[-] Failed to sign $@"; }
|
||||
endif
|
||||
|
||||
afl-showmap: src/afl-showmap.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o $(COMM_HDR) | test_x86
|
||||
afl-showmap: src/afl-showmap.c src/afl-fuzz-mutators.c src/afl-fuzz-python.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o $(COMM_HDR) | test_x86
|
||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) $(SPECIAL_PERFORMANCE) src/$@.c src/afl-fuzz-mutators.c src/afl-fuzz-python.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(PYFLAGS) $(LDFLAGS)
|
||||
ifdef IS_IOS
|
||||
@ldid -Sentitlements.plist $@ && echo "[+] Signed $@" || { echo "[-] Failed to sign $@"; }
|
||||
endif
|
||||
|
||||
afl-tmin: src/afl-tmin.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o $(COMM_HDR) | test_x86
|
||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) $(SPECIAL_PERFORMANCE) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(LDFLAGS)
|
||||
afl-tmin: src/afl-tmin.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o src/afl-fuzz-python.o src/afl-fuzz-mutators.o $(COMM_HDR) | test_x86
|
||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) $(SPECIAL_PERFORMANCE) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o src/afl-fuzz-python.o src/afl-fuzz-mutators.o -o $@ $(PYFLAGS) $(LDFLAGS)
|
||||
ifdef IS_IOS
|
||||
@ldid -Sentitlements.plist $@ && echo "[+] Signed $@" || { echo "[-] Failed to sign $@"; }
|
||||
endif
|
||||
@ -535,20 +535,20 @@ ifdef IS_IOS
|
||||
endif
|
||||
|
||||
test/unittests/unit_hash.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_hash.c $(AFL_FUZZ_FILES) src/afl-performance.o
|
||||
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) $(SPECIAL_PERFORMANCE) -c test/unittests/unit_hash.c -o test/unittests/unit_hash.o
|
||||
@$(CC) $(CFLAGS) $(CFLAGS_FLTO) $(ASAN_CFLAGS) $(SPECIAL_PERFORMANCE) -c test/unittests/unit_hash.c -o test/unittests/unit_hash.o
|
||||
|
||||
unit_hash: test/unittests/unit_hash.o src/afl-performance.o
|
||||
@$(CC) $(CFLAGS) $(SPECIAL_PERFORMANCE) -Wl,--wrap=exit -Wl,--wrap=printf $^ -o test/unittests/unit_hash $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
|
||||
@$(CC) $(CFLAGS) $(CFLAGS_FLTO) $(SPECIAL_PERFORMANCE) -Wl,--wrap=exit -Wl,--wrap=printf $^ -o test/unittests/unit_hash $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
|
||||
./test/unittests/unit_hash
|
||||
ifdef IS_IOS
|
||||
@ldid -Sentitlements.plist $@ && echo "[+] Signed $@" || { echo "[-] Failed to sign $@"; }
|
||||
endif
|
||||
|
||||
test/unittests/unit_rand.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_rand.c $(AFL_FUZZ_FILES) src/afl-performance.o
|
||||
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) $(SPECIAL_PERFORMANCE) -c test/unittests/unit_rand.c -o test/unittests/unit_rand.o
|
||||
@$(CC) $(CFLAGS) $(CFLAGS_FLTO) $(ASAN_CFLAGS) $(SPECIAL_PERFORMANCE) -c test/unittests/unit_rand.c -o test/unittests/unit_rand.o
|
||||
|
||||
unit_rand: test/unittests/unit_rand.o src/afl-common.o src/afl-performance.o
|
||||
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) $(SPECIAL_PERFORMANCE) -Wl,--wrap=exit -Wl,--wrap=printf $^ -o test/unittests/unit_rand $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
|
||||
@$(CC) $(CFLAGS) $(CFLAGS_FLTO) $(ASAN_CFLAGS) $(SPECIAL_PERFORMANCE) -Wl,--wrap=exit -Wl,--wrap=printf $^ -o test/unittests/unit_rand $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
|
||||
./test/unittests/unit_rand
|
||||
ifdef IS_IOS
|
||||
@ldid -Sentitlements.plist $@ && echo "[+] Signed $@" || { echo "[-] Failed to sign $@"; }
|
||||
@ -684,6 +684,7 @@ deepclean: clean
|
||||
rm -rf unicorn_mode/unicornafl
|
||||
rm -rf qemu_mode/qemuafl
|
||||
rm -rf nyx_mode/libnyx nyx_mode/packer nyx_mode/QEMU-Nyx
|
||||
rm -rf .format-cache
|
||||
ifeq "$(IN_REPO)" "1"
|
||||
git checkout coresight_mode/coresight-trace
|
||||
git checkout unicorn_mode/unicornafl
|
||||
|
@ -240,7 +240,7 @@ ifeq "$(LLVM_LTO)" "1"
|
||||
else
|
||||
ifneq "$(shell command -v ld.lld 2>/dev/null)" ""
|
||||
AFL_REAL_LD = $(shell command -v ld.lld)
|
||||
TMP_LDLDD_VERSION = $(shell $(AFL_REAL_LD) --version | awk '{ print $$2 }')
|
||||
TMP_LDLDD_VERSION = $(shell $(AFL_REAL_LD) --version | sed -E -ne '/^.*LLD\ ([12]?[0-9]\.[0-9]\.[0-9]).*/s//\1/p')
|
||||
ifeq "$(LLVMVER)" "$(TMP_LDLDD_VERSION)"
|
||||
$(warning ld.lld found in a weird location ($(AFL_REAL_LD)), but its the same version as LLVM so we will allow it)
|
||||
else
|
||||
|
@ -2,9 +2,9 @@
|
||||
|
||||
<img align="right" src="https://raw.githubusercontent.com/AFLplusplus/Website/main/static/aflpp_bg.svg" alt="AFL++ logo" width="250" height="250">
|
||||
|
||||
Release version: [4.31c](https://github.com/AFLplusplus/AFLplusplus/releases)
|
||||
Release version: [4.32c](https://github.com/AFLplusplus/AFLplusplus/releases)
|
||||
|
||||
GitHub version: 4.32a
|
||||
GitHub version: 4.32c
|
||||
|
||||
Repository:
|
||||
[https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)
|
||||
@ -16,7 +16,6 @@ AFL++ is maintained by:
|
||||
* Andrea Fioraldi <andreafioraldi@gmail.com>
|
||||
* Heiko "hexcoder-" Eissfeldt <heiko.eissfeldt@hexco.de>
|
||||
* frida_mode is maintained by @Worksbutnottested
|
||||
* Documentation: Jana Aydinbas <jana.aydinbas@gmail.com>
|
||||
|
||||
Originally developed by Michal "lcamtuf" Zalewski.
|
||||
|
||||
@ -230,7 +229,8 @@ Thank you! (For people sending pull requests - please add yourself to this list
|
||||
Ruben ten Hove Joey Jiao
|
||||
fuzzah @intrigus-lgtm
|
||||
Yaakov Saxon Sergej Schumilo
|
||||
Ziqiao Kong
|
||||
Ziqiao Kong Ryan Berger
|
||||
Sangjun Park
|
||||
```
|
||||
|
||||
</details>
|
||||
|
2
afl-cmin
2
afl-cmin
@ -331,7 +331,7 @@ BEGIN {
|
||||
}
|
||||
|
||||
if (0 == system ( "grep -aq AFL_DUMP_MAP_SIZE " target_bin )) {
|
||||
echo "[!] Trying to obtain the map size of the target ..."
|
||||
print "[!] Trying to obtain the map size of the target ..."
|
||||
get_map_size = "AFL_DUMP_MAP_SIZE=1 " target_bin
|
||||
get_map_size | getline mapsize
|
||||
close(get_map_size)
|
||||
|
@ -3,15 +3,22 @@
|
||||
This is the list of all noteworthy changes made in every public
|
||||
release of the tool. See README.md for the general instruction manual.
|
||||
|
||||
### Version ++4.32a (dev)
|
||||
### Version ++4.32c (release)
|
||||
- Fixed a bug where after a fast restart of a full fuzzed corpus afl-fuzz
|
||||
terminates with "need at least one valid input seed that does not crash"
|
||||
- Small improvements to afl-*-config
|
||||
- afl-fuzz:
|
||||
- memory leak fixes by @kcwu - thanks!
|
||||
- some more nits and small memory saves thanks to @kcwu
|
||||
- many more nits and small memory saves thanks to @kcwu
|
||||
- remove deprecated files from queue/.state
|
||||
- fix bitmap update function if no current trace is present
|
||||
- fix for afl_custom_queue_get
|
||||
- various small nits
|
||||
- afl-cc:
|
||||
- fix pass support for LLVM 20 (passes were run too early)
|
||||
- dropped plugin support for LLVM 13
|
||||
- fix AFL_OLD_FORKSERVER
|
||||
- various minor fixes
|
||||
- frida_mode:
|
||||
- fixes for new MacOS + M4 hardware
|
||||
|
||||
@ -22,7 +29,7 @@
|
||||
- afl-fuzz:
|
||||
- splicing phase is now DISABLED by default because research showed
|
||||
it is counterproductive. New command line parameter `-u` to enable
|
||||
it. Splicing is auto-enabled if two cycles without finds happen.
|
||||
it.
|
||||
- Python 3.13+ support
|
||||
- loose file and shared memory permissions on Android and iPhone
|
||||
- afl-cc:
|
||||
|
@ -1344,7 +1344,6 @@ static inline u32 rand_below(afl_state_t *afl, u32 limit) {
|
||||
|
||||
ck_read(afl->fsrv.dev_urandom_fd, &afl->rand_seed, sizeof(afl->rand_seed),
|
||||
"/dev/urandom");
|
||||
// srandom(afl->rand_seed[0]);
|
||||
afl->rand_cnt = (RESEED_RNG / 2) + (afl->rand_seed[1] % RESEED_RNG);
|
||||
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
/* Version string: */
|
||||
|
||||
// c = release, a = volatile github dev, e = experimental branch
|
||||
#define VERSION "++4.32a"
|
||||
#define VERSION "++4.32c"
|
||||
|
||||
/******************************************************
|
||||
* *
|
||||
|
@ -3169,7 +3169,7 @@ static xxh_u32 XXH32_avalanche(xxh_u32 hash) {
|
||||
*/
|
||||
static XXH_PUREF xxh_u32 XXH32_finalize(xxh_u32 hash, const xxh_u8 *ptr,
|
||||
size_t len, XXH_alignment align) {
|
||||
\
|
||||
|
||||
#define XXH_PROCESS1 \
|
||||
do { \
|
||||
\
|
||||
|
@ -226,20 +226,28 @@ llvmGetPassPluginInfo() {
|
||||
using OptimizationLevel = typename PassBuilder::OptimizationLevel;
|
||||
#endif
|
||||
#if LLVM_VERSION_MAJOR >= 16
|
||||
PB.registerOptimizerEarlyEPCallback([](ModulePassManager &MPM,
|
||||
OptimizationLevel OL
|
||||
#if LLVM_VERSION_MAJOR >= 20
|
||||
PB.registerPipelineStartEPCallback(
|
||||
#else
|
||||
PB.registerOptimizerEarlyEPCallback(
|
||||
,
|
||||
ThinOrFullLTOPhase Phase
|
||||
#endif
|
||||
) {
|
||||
|
||||
MPM.addPass(ModuleSanitizerCoverageAFL());
|
||||
|
||||
});
|
||||
|
||||
#else
|
||||
PB.registerOptimizerLastEPCallback(
|
||||
#endif
|
||||
[](ModulePassManager &MPM, OptimizationLevel OL) {
|
||||
|
||||
MPM.addPass(ModuleSanitizerCoverageAFL());
|
||||
|
||||
});
|
||||
|
||||
#endif
|
||||
|
||||
}};
|
||||
|
||||
}
|
||||
|
@ -891,10 +891,10 @@ static void __afl_start_forkserver(void) {
|
||||
/* 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 (!__afl_old_forkserver) {
|
||||
// return because possible non-forkserver usage
|
||||
if (write(FORKSRV_FD + 1, msg, 4) != 4) { return; }
|
||||
|
||||
// return because possible non-forkserver usage
|
||||
if (write(FORKSRV_FD + 1, msg, 4) != 4) { return; }
|
||||
if (!__afl_old_forkserver) {
|
||||
|
||||
if (read(FORKSRV_FD, reply, 4) != 4) { _exit(1); }
|
||||
if (tmp != status2) {
|
||||
|
@ -121,15 +121,16 @@ extern "C" LLVM_ATTRIBUTE_WEAK PassPluginLibraryInfo llvmGetPassPluginInfo() {
|
||||
using OptimizationLevel = typename PassBuilder::OptimizationLevel;
|
||||
#endif
|
||||
#if LLVM_VERSION_MAJOR >= 16
|
||||
#if LLVM_VERSION_MAJOR >= 20
|
||||
PB.registerPipelineStartEPCallback(
|
||||
#else
|
||||
PB.registerOptimizerEarlyEPCallback(
|
||||
#endif
|
||||
#else
|
||||
PB.registerOptimizerLastEPCallback(
|
||||
#endif
|
||||
[](ModulePassManager &MPM, OptimizationLevel OL) {
|
||||
[](ModulePassManager &MPM, OptimizationLevel OL
|
||||
#if LLVM_VERSION_MAJOR >= 20
|
||||
,
|
||||
ThinOrFullLTOPhase Phase
|
||||
#endif
|
||||
) {
|
||||
|
||||
MPM.addPass(AFLCoverage());
|
||||
|
||||
|
@ -130,15 +130,16 @@ llvmGetPassPluginInfo() {
|
||||
using OptimizationLevel = typename PassBuilder::OptimizationLevel;
|
||||
#endif
|
||||
#if LLVM_VERSION_MAJOR >= 16
|
||||
#if LLVM_VERSION_MAJOR >= 20
|
||||
PB.registerPipelineStartEPCallback(
|
||||
#else
|
||||
PB.registerOptimizerEarlyEPCallback(
|
||||
#endif
|
||||
#else
|
||||
PB.registerOptimizerLastEPCallback(
|
||||
#endif
|
||||
[](ModulePassManager &MPM, OptimizationLevel OL) {
|
||||
[](ModulePassManager &MPM, OptimizationLevel OL
|
||||
#if LLVM_VERSION_MAJOR >= 20
|
||||
,
|
||||
ThinOrFullLTOPhase Phase
|
||||
#endif
|
||||
) {
|
||||
|
||||
MPM.addPass(CompareTransform());
|
||||
|
||||
|
@ -190,15 +190,16 @@ llvmGetPassPluginInfo() {
|
||||
using OptimizationLevel = typename PassBuilder::OptimizationLevel;
|
||||
#endif
|
||||
#if LLVM_VERSION_MAJOR >= 16
|
||||
#if LLVM_VERSION_MAJOR >= 20
|
||||
PB.registerPipelineStartEPCallback(
|
||||
#else
|
||||
PB.registerOptimizerEarlyEPCallback(
|
||||
#endif
|
||||
#else
|
||||
PB.registerOptimizerLastEPCallback(
|
||||
#endif
|
||||
[](ModulePassManager &MPM, OptimizationLevel OL) {
|
||||
[](ModulePassManager &MPM, OptimizationLevel OL
|
||||
#if LLVM_VERSION_MAJOR >= 20
|
||||
,
|
||||
ThinOrFullLTOPhase Phase
|
||||
#endif
|
||||
) {
|
||||
|
||||
MPM.addPass(SplitComparesTransform());
|
||||
|
||||
|
@ -138,15 +138,17 @@ llvmGetPassPluginInfo() {
|
||||
using OptimizationLevel = typename PassBuilder::OptimizationLevel;
|
||||
#endif
|
||||
#if LLVM_VERSION_MAJOR >= 16
|
||||
#if LLVM_VERSION_MAJOR >= 20
|
||||
PB.registerPipelineStartEPCallback(
|
||||
#else
|
||||
PB.registerOptimizerEarlyEPCallback(
|
||||
#endif
|
||||
#else
|
||||
PB.registerOptimizerLastEPCallback(
|
||||
#endif
|
||||
[](ModulePassManager &MPM, OptimizationLevel OL) {
|
||||
[](ModulePassManager &MPM, OptimizationLevel OL
|
||||
#if LLVM_VERSION_MAJOR >= 20
|
||||
,
|
||||
ThinOrFullLTOPhase Phase
|
||||
#endif
|
||||
|
||||
) {
|
||||
|
||||
MPM.addPass(SplitSwitchesTransform());
|
||||
|
||||
|
@ -40,7 +40,7 @@ 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
|
||||
clang $(python3-config --embed --cflags) -o /fuzz/fuzz_harness /fuzz/fuzz_harness.c $(python3-config --embed --ldflags)
|
||||
exit
|
||||
```
|
||||
|
||||
|
72
src/afl-cc.c
72
src/afl-cc.c
@ -253,7 +253,11 @@ static inline void load_llvm_pass(aflcc_state_t *aflcc, u8 *pass) {
|
||||
|
||||
#if LLVM_MAJOR >= 11 /* use new pass manager */
|
||||
#if LLVM_MAJOR < 16
|
||||
#if LLVM_MAJOR < 15
|
||||
insert_param(aflcc, "-fno-legacy-pass-manager");
|
||||
#else
|
||||
insert_param(aflcc, "-fexperimental-new-pass-manager");
|
||||
#endif
|
||||
#endif
|
||||
insert_object(aflcc, pass, "-fpass-plugin=%s", 0);
|
||||
#else
|
||||
@ -1534,7 +1538,8 @@ void add_defs_selective_instr(aflcc_state_t *aflcc) {
|
||||
if (aflcc->plusplus_mode) {
|
||||
|
||||
insert_param(aflcc,
|
||||
"-D__AFL_COVERAGE()=int __afl_selective_coverage = 1;"
|
||||
"-D__AFL_COVERAGE()=int __afl_selective_coverage "
|
||||
"__attribute__ ((weak)) = 1;"
|
||||
"extern \"C\" void __afl_coverage_discard();"
|
||||
"extern \"C\" void __afl_coverage_skip();"
|
||||
"extern \"C\" void __afl_coverage_on();"
|
||||
@ -1543,7 +1548,8 @@ void add_defs_selective_instr(aflcc_state_t *aflcc) {
|
||||
} else {
|
||||
|
||||
insert_param(aflcc,
|
||||
"-D__AFL_COVERAGE()=int __afl_selective_coverage = 1;"
|
||||
"-D__AFL_COVERAGE()=int __afl_selective_coverage "
|
||||
"__attribute__ ((weak)) = 1;"
|
||||
"void __afl_coverage_discard();"
|
||||
"void __afl_coverage_skip();"
|
||||
"void __afl_coverage_on();"
|
||||
@ -2161,7 +2167,11 @@ void add_optimized_pcguard(aflcc_state_t *aflcc) {
|
||||
|
||||
/* Since LLVM_MAJOR >= 13 we use new pass manager */
|
||||
#if LLVM_MAJOR < 16
|
||||
#if LLVM_MAJOR < 15
|
||||
insert_param(aflcc, "-fno-legacy-pass-manager");
|
||||
#else
|
||||
insert_param(aflcc, "-fexperimental-new-pass-manager");
|
||||
#endif
|
||||
#endif
|
||||
insert_object(aflcc, "SanitizerCoveragePCGUARD.so", "-fpass-plugin=%s", 0);
|
||||
|
||||
@ -3589,6 +3599,64 @@ int main(int argc, char **argv, char **envp) {
|
||||
|
||||
}
|
||||
|
||||
// We only support plugins with LLVM 14 onwards
|
||||
#if LLVM_MAJOR < 14
|
||||
if (aflcc->instrument_mode != INSTRUMENT_LLVMNATIVE &&
|
||||
aflcc->compiler_mode != GCC_PLUGIN) {
|
||||
|
||||
aflcc->instrument_mode = INSTRUMENT_LLVMNATIVE;
|
||||
aflcc->compiler_mode = LLVM;
|
||||
|
||||
}
|
||||
|
||||
if (aflcc->compiler_mode == LLVM) {
|
||||
|
||||
if (aflcc->cmplog_mode) {
|
||||
|
||||
WARNF("CMPLOG support requires LLVM 14+");
|
||||
aflcc->cmplog_mode = 0;
|
||||
|
||||
}
|
||||
|
||||
if (getenv("AFL_LLVM_DICT2FILE")) {
|
||||
|
||||
WARNF("DICT2FILE support requires LLVM14+");
|
||||
unsetenv("AFL_LLVM_DICT2FILE");
|
||||
|
||||
}
|
||||
|
||||
if (getenv("AFL_LLVM_LAF_SPLIT_SWITCHES") ||
|
||||
getenv("AFL_LLVM_LAF_SPLIT_COMPARES") ||
|
||||
getenv("AFL_LLVM_LAF_SPLIT_FLOATS") ||
|
||||
getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES") ||
|
||||
getenv("AFL_LLVM_LAF_ALL")) {
|
||||
|
||||
WARNF("AFL_LLVM_LAF support requires LLVM14+");
|
||||
unsetenv("AFL_LLVM_LAF_SPLIT_SWITCHES");
|
||||
unsetenv("AFL_LLVM_LAF_SPLIT_COMPARES");
|
||||
unsetenv("AFL_LLVM_LAF_SPLIT_FLOATS");
|
||||
unsetenv("AFL_LLVM_LAF_TRANSFORM_COMPARES");
|
||||
unsetenv("AFL_LLVM_LAF_ALL");
|
||||
|
||||
}
|
||||
|
||||
if (getenv("AFL_LLVM_INJECTIONS_ALL") ||
|
||||
getenv("AFL_LLVM_INJECTIONS_SQL") ||
|
||||
getenv("AFL_LLVM_INJECTIONS_LDAP") ||
|
||||
getenv("AFL_LLVM_INJECTIONS_XSS")) {
|
||||
|
||||
WARNF("AFL_LLVM_INJECTIONS support requires LLVM14+");
|
||||
unsetenv("AFL_LLVM_INJECTIONS_ALL");
|
||||
unsetenv("AFL_LLVM_INJECTIONS_SQL");
|
||||
unsetenv("AFL_LLVM_INJECTIONS_LDAP");
|
||||
unsetenv("AFL_LLVM_INJECTIONS_XSS");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
mode_notification(aflcc);
|
||||
|
||||
if (aflcc->debug) debugf_args(argc, argv);
|
||||
|
@ -1004,7 +1004,7 @@ inline u64 get_cur_time_us(void) {
|
||||
Will return buf for convenience. */
|
||||
|
||||
u8 *stringify_int(u8 *buf, size_t len, u64 val) {
|
||||
\
|
||||
|
||||
#define CHK_FORMAT(_divisor, _limit_mult, _fmt, _cast) \
|
||||
do { \
|
||||
\
|
||||
@ -1168,7 +1168,7 @@ u8 *stringify_time_diff(u8 *buf, size_t len, u64 cur_ms, u64 event_ms) {
|
||||
Will return buf for convenience. */
|
||||
|
||||
u8 *u_stringify_int(u8 *buf, u64 val) {
|
||||
\
|
||||
|
||||
#define CHK_FORMAT(_divisor, _limit_mult, _fmt, _cast) \
|
||||
do { \
|
||||
\
|
||||
|
@ -686,7 +686,7 @@ u8 __attribute__((hot)) save_if_interesting(afl_state_t *afl, void *mem,
|
||||
#else
|
||||
|
||||
queue_fn = alloc_printf(
|
||||
"%s/queue/id_%06u", afl->out_dir, afl->queued_items,
|
||||
"%s/queue/id_%06u%s%s", afl->out_dir, afl->queued_items,
|
||||
afl->file_extension ? "." : "",
|
||||
afl->file_extension ? (const char *)afl->file_extension : "");
|
||||
|
||||
|
@ -2227,10 +2227,17 @@ int check_main_node_exists(afl_state_t *afl) {
|
||||
fn = alloc_printf("%s/%s/is_main_node", afl->sync_dir, sd_ent->d_name);
|
||||
int res = access(fn, F_OK);
|
||||
free(fn);
|
||||
if (res == 0) return 1;
|
||||
if (res == 0) {
|
||||
|
||||
closedir(sd);
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
closedir(sd);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
@ -356,7 +356,12 @@ u8 fuzz_one_original(afl_state_t *afl) {
|
||||
if (el->afl_custom_queue_get &&
|
||||
!el->afl_custom_queue_get(el->data, afl->queue_cur->fname)) {
|
||||
|
||||
return 1;
|
||||
/* Abandon the entry and return that we skipped it.
|
||||
If we don't do this then when the entry is smallest_favored then
|
||||
we get caught in an infinite loop calling afl_custom_queue_get
|
||||
on smallest_favored */
|
||||
ret_val = 1;
|
||||
goto abandon_entry;
|
||||
|
||||
}
|
||||
|
||||
|
@ -1011,7 +1011,7 @@ void recalculate_all_scores(afl_state_t *afl) {
|
||||
if (likely(!afl->queue_buf[i]->disabled)) {
|
||||
|
||||
in_buf = queue_testcase_get(afl, afl->queue_buf[i]);
|
||||
(void)write_to_testcase(afl, in_buf, afl->queue_buf[i]->len, 1);
|
||||
(void)write_to_testcase(afl, (void **)&in_buf, afl->queue_buf[i]->len, 1);
|
||||
(void)fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
|
||||
|
||||
for (j = 0; j < afl->fsrv.map_size; ++j) {
|
||||
|
@ -592,11 +592,11 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
|
||||
// note: from_queue seems to only be set during initialization
|
||||
if (afl->afl_env.afl_no_ui || from_queue) {
|
||||
|
||||
WARNF("instability detected during calibration");
|
||||
WARNF("instability detected during calibration: %s", q->fname);
|
||||
|
||||
} else if (afl->debug) {
|
||||
|
||||
DEBUGF("instability detected during calibration\n");
|
||||
DEBUGF("instability detected during calibration: %s\n", q->fname);
|
||||
|
||||
}
|
||||
|
||||
@ -867,7 +867,14 @@ void sync_fuzzers(afl_state_t *afl) {
|
||||
|
||||
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
|
||||
|
||||
if (afl->stop_soon) { goto close_sync; }
|
||||
if (afl->stop_soon) {
|
||||
|
||||
munmap(mem, st.st_size);
|
||||
close(fd);
|
||||
|
||||
goto close_sync;
|
||||
|
||||
}
|
||||
|
||||
afl->syncing_party = sd_ent->d_name;
|
||||
afl->queued_imported += save_if_interesting(afl, mem, new_len, fault);
|
||||
|
@ -762,6 +762,8 @@ void afl_state_deinit(afl_state_t *afl) {
|
||||
afl_free(afl->in_buf);
|
||||
afl_free(afl->in_scratch_buf);
|
||||
afl_free(afl->ex_buf);
|
||||
afl_free(afl->alias_table);
|
||||
afl_free(afl->alias_probability);
|
||||
|
||||
ck_free(afl->virgin_bits);
|
||||
ck_free(afl->virgin_tmout);
|
||||
|
@ -1555,13 +1555,6 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
#endif
|
||||
|
||||
// silently disable deterministic mutation if custom mutators are used
|
||||
if (!afl->skip_deterministic && afl->afl_env.afl_custom_mutator_only) {
|
||||
|
||||
afl->skip_deterministic = 1;
|
||||
|
||||
}
|
||||
|
||||
if (afl->fixed_seed) {
|
||||
|
||||
OKF("Running with fixed seed: %u", (u32)afl->init_seed);
|
||||
|
@ -1261,8 +1261,6 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
break;
|
||||
|
||||
/* FIXME: We want to use -P for consistency, but it is already unused for
|
||||
* undocumenetd feature "Another afl-cmin specific feature." */
|
||||
case 'A': /* CoreSight mode */
|
||||
|
||||
#if !defined(__aarch64__) || !defined(__linux__)
|
||||
|
297
src/afl-tmin.c
297
src/afl-tmin.c
@ -37,6 +37,8 @@
|
||||
#include "forkserver.h"
|
||||
#include "sharedmem.h"
|
||||
#include "common.h"
|
||||
#include "afl-fuzz.h"
|
||||
#include "list.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
@ -48,6 +50,7 @@
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#include <sys/wait.h>
|
||||
#include <sys/time.h>
|
||||
@ -57,8 +60,30 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/resource.h>
|
||||
#ifdef USE_PYTHON
|
||||
#include <Python.h>
|
||||
#endif
|
||||
|
||||
static u8 *mask_bitmap; /* Mask for trace bits (-B) */
|
||||
extern void destroy_custom_mutators(afl_state_t *);
|
||||
void list_init(list_t *list) {
|
||||
|
||||
if (list) {
|
||||
|
||||
list->element_prealloc_count = 0;
|
||||
memset(list->element_prealloc_buf, 0, sizeof(list->element_prealloc_buf));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void setup_custom_mutators(afl_state_t *);
|
||||
struct custom_mutator *load_custom_mutator(afl_state_t *, const char *);
|
||||
#ifdef USE_PYTHON
|
||||
struct custom_mutator *load_custom_mutator_py(afl_state_t *, char *);
|
||||
#endif
|
||||
|
||||
static afl_state_t *afl; /* State for custom mutators */
|
||||
static u8 *mask_bitmap; /* Mask for trace bits (-B) */
|
||||
|
||||
static u8 *in_file, /* Minimizer input test case */
|
||||
*out_file, *output_file; /* Minimizer output file */
|
||||
@ -135,6 +160,52 @@ static sharedmem_t *deinit_shmem(afl_forkserver_t *fsrv,
|
||||
|
||||
}
|
||||
|
||||
/* dummy functions */
|
||||
u32 write_to_testcase(afl_state_t *afl, void **mem, u32 a, u32 b) {
|
||||
|
||||
(void)afl;
|
||||
(void)mem;
|
||||
return a + b;
|
||||
|
||||
}
|
||||
|
||||
void show_stats(afl_state_t *afl) {
|
||||
|
||||
(void)afl;
|
||||
|
||||
}
|
||||
|
||||
void update_bitmap_score(afl_state_t *afl, struct queue_entry *q,
|
||||
bool add_to_queue) {
|
||||
|
||||
(void)afl;
|
||||
(void)q;
|
||||
(void)add_to_queue;
|
||||
|
||||
}
|
||||
|
||||
fsrv_run_result_t fuzz_run_target(afl_state_t *afl, afl_forkserver_t *fsrv,
|
||||
u32 i) {
|
||||
|
||||
(void)afl;
|
||||
(void)fsrv;
|
||||
(void)i;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
#ifndef USE_PYTHON
|
||||
struct custom_mutator *load_custom_mutator_py(afl_state_t *afl, char *module) {
|
||||
|
||||
(void)afl;
|
||||
(void)module;
|
||||
FATAL("Python support not available in this build");
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Apply mask to classified bitmap (if set). */
|
||||
|
||||
static void apply_mask(u32 *mem, u32 *mask) {
|
||||
@ -153,7 +224,7 @@ static void apply_mask(u32 *mem, u32 *mask) {
|
||||
|
||||
}
|
||||
|
||||
static void classify_counts(afl_forkserver_t *fsrv) {
|
||||
void classify_counts(afl_forkserver_t *fsrv) {
|
||||
|
||||
u8 *mem = fsrv->trace_bits;
|
||||
u32 i = map_size;
|
||||
@ -209,6 +280,13 @@ static void at_exit_handler(void) {
|
||||
afl_fsrv_killall();
|
||||
if (remove_out_file) unlink(out_file);
|
||||
|
||||
if (afl) {
|
||||
|
||||
destroy_custom_mutators(afl);
|
||||
ck_free(afl);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Read initial file. */
|
||||
@ -259,14 +337,72 @@ static s32 write_to_file(u8 *path, u8 *mem, u32 len) {
|
||||
|
||||
}
|
||||
|
||||
/* Helper function to handle custom mutators for testcase writing */
|
||||
static void pre_afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *mem,
|
||||
u32 len) {
|
||||
|
||||
static u8 buf[MAX_FILE];
|
||||
u32 sent = 0;
|
||||
|
||||
if (afl && afl->custom_mutators_count) {
|
||||
|
||||
ssize_t new_size = len;
|
||||
u8 *new_mem = mem;
|
||||
u8 *new_buf = NULL;
|
||||
|
||||
LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
|
||||
|
||||
if (el->afl_custom_post_process) {
|
||||
|
||||
new_size =
|
||||
el->afl_custom_post_process(el->data, new_mem, new_size, &new_buf);
|
||||
|
||||
if (!new_buf || new_size <= 0) {
|
||||
|
||||
return;
|
||||
|
||||
} else {
|
||||
|
||||
new_mem = new_buf;
|
||||
len = new_size;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
if (new_mem != mem && new_mem != NULL) {
|
||||
|
||||
mem = buf;
|
||||
memcpy(mem, new_mem, new_size);
|
||||
|
||||
}
|
||||
|
||||
LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
|
||||
|
||||
if (el->afl_custom_fuzz_send) {
|
||||
|
||||
el->afl_custom_fuzz_send(el->data, mem, len);
|
||||
sent = 1;
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
if (!sent) { afl_fsrv_write_to_testcase(fsrv, mem, len); }
|
||||
|
||||
}
|
||||
|
||||
/* Execute target application. Returns 0 if the changes are a dud, or
|
||||
1 if they should be kept. */
|
||||
|
||||
static u8 tmin_run_target(afl_forkserver_t *fsrv, u8 *mem, u32 len,
|
||||
u8 first_run) {
|
||||
|
||||
afl_fsrv_write_to_testcase(fsrv, mem, len);
|
||||
|
||||
pre_afl_fsrv_write_to_testcase(fsrv, mem, len);
|
||||
fsrv_run_result_t ret =
|
||||
afl_fsrv_run_target(fsrv, fsrv->exec_tmout, &stop_soon);
|
||||
|
||||
@ -357,14 +493,132 @@ static u8 tmin_run_target(afl_forkserver_t *fsrv, u8 *mem, u32 len,
|
||||
static void minimize(afl_forkserver_t *fsrv) {
|
||||
|
||||
static u32 alpha_map[256];
|
||||
|
||||
u8 *tmp_buf = ck_alloc_nozero(in_len);
|
||||
u32 orig_len = in_len, stage_o_len;
|
||||
|
||||
u32 del_len, set_len, del_pos, set_pos, i, alpha_size, cur_pass = 0;
|
||||
u8 *tmp_buf = ck_alloc_nozero(in_len);
|
||||
u32 orig_len = in_len, stage_o_len;
|
||||
u32 del_len, set_len, del_pos, set_pos, i, alpha_size, cur_pass = 0;
|
||||
u32 syms_removed, alpha_del0 = 0, alpha_del1, alpha_del2, alpha_d_total = 0;
|
||||
u8 changed_any, prev_del;
|
||||
|
||||
#ifdef USE_PYTHON
|
||||
// Try to load python module
|
||||
char *py_module = getenv("AFL_PYTHON_MODULE");
|
||||
if (py_module) {
|
||||
|
||||
// We cannot use Python custom mutators in tmin
|
||||
if (debug) WARNF("Python custom mutator support not available in afl-tmin");
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Custom mutator trimming
|
||||
if (afl && afl->custom_mutators_count) {
|
||||
|
||||
LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
|
||||
|
||||
if (el->afl_custom_init_trim && el->afl_custom_trim &&
|
||||
el->afl_custom_post_trim) {
|
||||
|
||||
ACTF("Performing custom trim with %s...", el->name);
|
||||
|
||||
// Initialize the trimmer
|
||||
s32 initial_steps = el->afl_custom_init_trim(el->data, in_data, in_len);
|
||||
|
||||
if (initial_steps <= 0) {
|
||||
|
||||
WARNF("Custom trimmer %s returned %d, skipping", el->name,
|
||||
initial_steps);
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
ACTF("Custom trimmer initialized, %d steps planned", initial_steps);
|
||||
|
||||
u32 trim_rounds = 0;
|
||||
u32 trimmed_successfully = 0;
|
||||
|
||||
// Trim loop
|
||||
s32 cur_step = 0;
|
||||
while (cur_step < initial_steps) {
|
||||
|
||||
u8 *trimmed_buf = NULL;
|
||||
size_t trimmed_size;
|
||||
|
||||
u8 *retbuf = NULL;
|
||||
trimmed_size = el->afl_custom_trim(el->data, &retbuf);
|
||||
|
||||
// If trimmed_size equals or exceeds original size, skip
|
||||
if (trimmed_size >= in_len) {
|
||||
|
||||
SAYF("[Custom trim] Round %u: no improvements over %u bytes.\n",
|
||||
trim_rounds, in_len);
|
||||
el->afl_custom_post_trim(el->data, 0);
|
||||
cur_step++;
|
||||
trim_rounds++;
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
trimmed_buf = retbuf;
|
||||
|
||||
// Test if the trimmed case still works
|
||||
if (!tmin_run_target(fsrv, trimmed_buf, trimmed_size, 0)) {
|
||||
|
||||
SAYF(
|
||||
"[Custom trim] But the testcase no longer reproduces - "
|
||||
"skipping this reduction.\n");
|
||||
el->afl_custom_post_trim(el->data, 0);
|
||||
if (trimmed_buf != in_data) { ck_free(trimmed_buf); }
|
||||
|
||||
} else {
|
||||
|
||||
// Accept the reduction
|
||||
u8 *old_in_data = in_data;
|
||||
in_data = trimmed_buf;
|
||||
in_len = trimmed_size;
|
||||
|
||||
trimmed_successfully = 1;
|
||||
el->afl_custom_post_trim(el->data, 1);
|
||||
|
||||
SAYF("[Custom trim] Successful reduction to %u bytes\n", in_len);
|
||||
|
||||
if (old_in_data != in_data && old_in_data != trimmed_buf) {
|
||||
|
||||
ck_free(old_in_data);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cur_step++;
|
||||
trim_rounds++;
|
||||
|
||||
}
|
||||
|
||||
ACTF("Custom trimming with %s complete after %u rounds, reduced: %s",
|
||||
el->name, trim_rounds, trimmed_successfully ? "yes" : "no");
|
||||
|
||||
if (trimmed_successfully) {
|
||||
|
||||
if (tmp_buf) { ck_free(tmp_buf); }
|
||||
return; // Skip standard minimization if successful
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// Skip built-in minimization if in_len is too small
|
||||
if (in_len <= 1) {
|
||||
|
||||
if (tmp_buf) { ck_free(tmp_buf); }
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/***********************
|
||||
* BLOCK NORMALIZATION *
|
||||
***********************/
|
||||
@ -747,7 +1001,7 @@ static void set_up_environment(afl_forkserver_t *fsrv, char **argv) {
|
||||
|
||||
/* Setup signal handlers, duh. */
|
||||
|
||||
static void setup_signal_handlers(void) {
|
||||
void setup_signal_handlers(void) {
|
||||
|
||||
struct sigaction sa;
|
||||
|
||||
@ -1243,6 +1497,29 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
read_initial_file();
|
||||
|
||||
// Initialize AFL state for custom mutators
|
||||
afl = calloc(1, sizeof(afl_state_t));
|
||||
if (afl) {
|
||||
|
||||
list_init(&afl->custom_mutator_list);
|
||||
afl->custom_mutators_count = 0;
|
||||
|
||||
afl->fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY);
|
||||
if (afl->fsrv.dev_urandom_fd < 0) { PFATAL("Unable to open /dev/urandom"); }
|
||||
|
||||
afl->afl_env.afl_custom_mutator_library =
|
||||
getenv("AFL_CUSTOM_MUTATOR_LIBRARY");
|
||||
afl->afl_env.afl_python_module = getenv("AFL_PYTHON_MODULE");
|
||||
|
||||
afl->shm = shm;
|
||||
afl->out_dir = dirname(in_file);
|
||||
|
||||
memcpy(&afl->fsrv, fsrv, sizeof(afl_forkserver_t));
|
||||
|
||||
setup_custom_mutators(afl);
|
||||
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
if (!fsrv->nyx_mode) { (void)check_binary_signatures(fsrv->target_path); }
|
||||
#else
|
||||
|
Reference in New Issue
Block a user