argotorg/solidity-fuzzing
GitHub: argotorg/solidity-fuzzing
为 Solidity 编译器提供基于 AFL++ 的模糊测试基础设施,包含 protobuf 测试架、差分模糊测试器和崩溃复现调试运行器。
Stars: 9 | Forks: 1
# Solidity 模糊测试工具
[Solidity 编译器](https://github.com/argotorg/solidity)的模糊测试基础设施:包含 AFL++ 测试架(harness)、模糊测试器(fuzzer),以及用于复现问题的调试运行器(debug runner)。
## 两种构建树
所有内容均在宿主机上原生构建 —— 无需 Docker,无需 libc++。
- `build/` —— 宿主机 gcc/clang:`solc`、用于崩溃复现的 `*_debug_runner` 工具,以及 AFL 工具链(afl-clang-fast、afl-ts、grammar)。
- `build_afl/` —— `afl-clang-fast++`:AFL 模糊测试器 —— protobuf 测试架(`*_proto_ossfuzz_*`)和差分 `.sol` 模糊测试器(`sol_afl_diff_runner`)。
它们之间从不共享目标文件(object file);可以重新构建其中一个而不影响另一个。
## 环境设置
```
git clone --recurse-submodules \
https://github.com/argotorg/solidity-fuzzing.git
cd solidity-fuzzing # or: git submodule update --init --recursive
```
需要:gcc/g++ (C++20)、clang/clang++、llvm-dev、cmake (>=3.13)、make、ninja、boost(包含静态库)、protobuf + abseil、protoc、ccache、gdb。
应用本地的 Solidity 补丁(幂等操作):
```
for p in patches/*.patch; do
echo "Applying patch $p"
git apply --reverse --check "$p" 2>/dev/null || git apply "$p"
done
```
## 构建
```
# solc + debug runners (build/)
mkdir -p build && cd build && cmake .. && make -j$(nproc) && cd ..
# AFL 工具链 — afl-clang-fast, afl-ts, grammar(需要 llvm-dev)
make -C build -j$(nproc) aflplusplus afl_ts tree_sitter_solidity
# AFL fuzzers (build_afl/)
tools/ossfuzz/build_ossfuzz.sh # protobuf fuzzers + LPM mutators
tools/afl/build_instrumented.sh # differential .sol fuzzer
```
`tools/ossfuzz/build_ossfuzz.sh` 会将 libprotobuf-mutator 构建到 `deps_afl/` 目录中(基于系统的 protobuf),为每个语法构建一个 LPM 自定义变异器(custom mutator),并将模糊测试器构建到 `build_afl/` 目录中。详情请见 [tools/ossfuzz](tools/ossfuzz/README.md)。
## 运行
```
echo core | sudo tee /proc/sys/kernel/core_pattern # one-time, AFL needs it
# Protobuf fuzzers — afl-fuzz + 匹配的 LPM grammar mutator:
tools/ossfuzz/run_ossfuzz_afl.sh sol_proto_ossfuzz_evmone corpus_sol
tools/ossfuzz/run_ossfuzz_afl.sh yul_proto_ossfuzz_evmone corpus_yul
tools/ossfuzz/run_ossfuzz_afl.sh sol_ice_ossfuzz seeds_sol_ice
# Differential .sol fuzzer(afl-ts AST mutator):
tools/afl/run_afl.sh # or run_afl_parallel.sh -j 8
```
## 使用 ASAN 运行以查找模糊测试引擎中的 bug
LPM 语法变异器在 afl-fuzz *内部*运行。如果它(或 protobuf)破坏了堆(heap),工作进程会直接崩溃并提示 `malloc(): invalid next size`,且没有堆栈信息。
此变体仅使用 AddressSanitizer 重新构建变异器 `.so`,并将 runtime 预加载到 afl-fuzz 中,这样发生错误写入时就会中止并输出完整的追踪信息。
```
tools/ossfuzz/run_ossfuzz_afl_asan.sh yul_proto_ossfuzz_evmone_ssacfg corpus_yul
JOBS=8 tools/ossfuzz/run_ossfuzz_afl_asan.sh yul_proto_ossfuzz_evmone_ssacfg corpus_yul
# 报告位于 /asan.(原始偏移量 — afl 强制 symbolize=0):
tools/ossfuzz/symbolize_asan.sh findings_asan_*/asan.*
```
关于模糊测试器列表、复现和分类(triage),请参见 [tools/ossfuzz](tools/ossfuzz/README.md) 和 [tools/afl](tools/afl/README.md)。
### AFL diff-runner 回归测试
```
make -C build -j$(nproc) sol_afl_diff_runner
tools/afl/tests/run.sh # every inputs/*.sol must exit 0
```
标签:AFL, Bash脚本, C++, Solidity, 安全测试, 攻击性安全, 数据擦除, 编译器测试