Loading...
Loading...
Compare original and translation side by side
| Fuzzer | Best For | Complexity |
|---|---|---|
| Atheris | Python code and C extensions | Low-Medium |
| Hypothesis | Property-based testing | Low |
| python-afl | AFL-style fuzzing | Medium |
| 模糊测试工具 | 最佳适用场景 | 复杂度 |
|---|---|---|
| Atheris | Python 代码和 C 扩展 | 中低 |
| Hypothesis | 属性化测试 | 低 |
| python-afl | AFL 风格模糊测试 | 中 |
import sys
import atheris
@atheris.instrument_func
def test_one_input(data: bytes):
if len(data) == 4:
if data[0] == 0x46: # "F"
if data[1] == 0x55: # "U"
if data[2] == 0x5A: # "Z"
if data[3] == 0x5A: # "Z"
raise RuntimeError("You caught me")
def main():
atheris.Setup(sys.argv, test_one_input)
atheris.Fuzz()
if __name__ == "__main__":
main()python fuzz.pyimport sys
import atheris
@atheris.instrument_func
def test_one_input(data: bytes):
if len(data) == 4:
if data[0] == 0x46: # "F"
if data[1] == 0x55: # "U"
if data[2] == 0x5A: # "Z"
if data[3] == 0x5A: # "Z"
raise RuntimeError("You caught me")
def main():
atheris.Setup(sys.argv, test_one_input)
atheris.Fuzz()
if __name__ == "__main__":
main()python fuzz.pyuv pip install atherisuv pip install atherisundefinedundefined
Build and run:
```bash
docker build -t atheris .
docker run -it atheris
构建并运行:
```bash
docker build -t atheris .
docker run -it atherispython -c "import atheris; print(atheris.__version__)"python -c "import atheris; print(atheris.__version__)"import sys
import atheris
@atheris.instrument_func
def test_one_input(data: bytes):
"""
Fuzzing entry point. Called with random byte sequences.
Args:
data: Random bytes generated by the fuzzer
"""
# Add input validation if needed
if len(data) < 1:
return
# Call your target function
try:
your_target_function(data)
except ValueError:
# Expected exceptions should be caught
pass
# Let unexpected exceptions crash (that's what we're looking for!)
def main():
atheris.Setup(sys.argv, test_one_input)
atheris.Fuzz()
if __name__ == "__main__":
main()import sys
import atheris
@atheris.instrument_func
def test_one_input(data: bytes):
"""
模糊测试入口,接收随机字节序列作为输入。
参数:
data: 模糊测试器生成的随机字节
"""
# 如有需要,添加输入验证
if len(data) < 1:
return
# 调用目标函数
try:
your_target_function(data)
except ValueError:
# 捕获预期的异常
pass
# 让未预期的异常崩溃(这正是我们要找的问题!)
def main():
atheris.Setup(sys.argv, test_one_input)
atheris.Fuzz()
if __name__ == "__main__":
main()| Do | Don't |
|---|---|
Use | Forget to instrument target code |
| Catch expected exceptions | Catch all exceptions indiscriminately |
Use | Import modules after |
| Keep harness deterministic | Use randomness or time-based behavior |
See Also: For detailed harness writing techniques, patterns for handling complex inputs, and advanced strategies, see the fuzz-harness-writing technique skill.
| 建议做法 | 禁止做法 |
|---|---|
使用 | 忘记对目标代码进行插桩 |
| 捕获预期的异常 | 无差别捕获所有异常 |
对库使用 | 在 |
| 保持测试用例的确定性 | 使用随机性或基于时间的行为 |
另请参阅: 有关编写测试用例的详细技巧、处理复杂输入的模式以及高级策略,请查看 fuzz-harness-writing 技术文档。
import atheris
with atheris.instrument_imports():
import your_module
from another_module import target_function
def test_one_input(data: bytes):
target_function(data)
atheris.Setup(sys.argv, test_one_input)
atheris.Fuzz()atheris.instrument_funcatheris.instrument_imports()atheris.instrument_all()import atheris
with atheris.instrument_imports():
import your_module
from another_module import target_function
def test_one_input(data: bytes):
target_function(data)
atheris.Setup(sys.argv, test_one_input)
atheris.Fuzz()atheris.instrument_funcatheris.instrument_imports()atheris.instrument_all()export CC="clang"
export CFLAGS="-fsanitize=address,fuzzer-no-link"
export CXX="clang++"
export CXXFLAGS="-fsanitize=address,fuzzer-no-link"
export LDSHARED="clang -shared"export CC="clang"
export CFLAGS="-fsanitize=address,fuzzer-no-link"
export CXX="clang++"
export CXXFLAGS="-fsanitize=address,fuzzer-no-link"
export LDSHARED="clang -shared"CBOR2_BUILD_C_EXTENSION=1 python -m pip install --no-binary cbor2 cbor2==5.6.4--no-binarycbor2-fuzz.pyimport sys
import atherisCBOR2_BUILD_C_EXTENSION=1 python -m pip install --no-binary cbor2 cbor2==5.6.4--no-binarycbor2-fuzz.pyimport sys
import atheris
Run:
```bash
python cbor2-fuzz.pyImportant: When running locally (not in Docker), you must setmanually.LD_PRELOAD
运行:
```bash
python cbor2-fuzz.py重要提示: 在本地运行(非 Docker 环境)时,必须手动设置。LD_PRELOAD
mkdir corpusmkdir corpus
Run with corpus:
```bash
python fuzz.py corpus/
使用语料库运行:
```bash
python fuzz.py corpus/python fuzz.py -merge=1 new_corpus/ old_corpus/See Also: For corpus creation strategies, dictionaries, and seed selection, see the fuzzing-corpus technique skill.
python fuzz.py -merge=1 new_corpus/ old_corpus/另请参阅: 有关语料库创建策略、字典和种子选择,请查看 fuzzing-corpus 技术文档。
python fuzz.pypython fuzz.pypython fuzz.py corpus/python fuzz.py corpus/undefinedundefinedundefinedundefined| Output | Meaning |
|---|---|
| Found new coverage, corpus expanded |
| Periodic status update |
| Executions per second (throughput) |
| Corpus size: X inputs, Y bytes total |
| Crash detected |
| 输出内容 | 含义 |
|---|---|
| 发现新的覆盖率,语料库已扩展 |
| 定期状态更新 |
| 每秒执行次数(吞吐量) |
| 语料库大小:X 个输入,总大小 Y 字节 |
| 检测到崩溃 |
export CFLAGS="-fsanitize=address,fuzzer-no-link"
export CXXFLAGS="-fsanitize=address,fuzzer-no-link"export ASAN_OPTIONS="allocator_may_return_null=1,detect_leaks=0"export CFLAGS="-fsanitize=address,fuzzer-no-link"
export CXXFLAGS="-fsanitize=address,fuzzer-no-link"export ASAN_OPTIONS="allocator_may_return_null=1,detect_leaks=0"export LD_PRELOAD="$(python -c 'import atheris; import os; print(os.path.join(os.path.dirname(atheris.__file__), "asan_with_fuzzer.so"))')"See Also: For detailed sanitizer configuration, common issues, and advanced flags, see the address-sanitizer and undefined-behavior-sanitizer technique skills.
export LD_PRELOAD="$(python -c 'import atheris; import os; print(os.path.join(os.path.dirname(atheris.__file__), "asan_with_fuzzer.so"))')"另请参阅: 有关 sanitizer 详细配置、常见问题和高级标志,请查看 address-sanitizer 和 undefined-behavior-sanitizer 技术文档。
| Issue | Solution |
|---|---|
| Export |
| Memory allocation failures | Set |
| Leak detection noise | Set |
| Missing symbolizer | Set |
| 问题 | 解决方案 |
|---|---|
| 导出 |
| 内存分配失败 | 设置 |
| 内存泄漏检测噪音 | 设置 |
| 缺少符号解析器 | 设置 |
| Tip | Why It Helps |
|---|---|
Use | Ensures all imports are instrumented for coverage |
Start with small | Faster initial fuzzing, gradually increase |
| Use dictionaries for structured formats | Helps fuzzer understand format tokens |
| Run multiple parallel instances | Better coverage exploration |
| 技巧 | 优势 |
|---|---|
尽早使用 | 确保所有导入模块都被插桩以统计覆盖率 |
初始使用较小的 | 初始模糊测试速度更快,逐步增加 |
| 对结构化格式使用字典 | 帮助模糊测试器理解格式标记 |
| 运行多个并行实例 | 更好地探索覆盖率 |
import atherisimport atherisundefinedundefined| Setting | Impact |
|---|---|
| Smaller values = faster execution |
| Parallel fuzzing for faster coverage |
| Better stack traces, slower execution |
| 设置 | 影响 |
|---|---|
| 值越小,执行速度越快 |
| 并行模糊测试,提升覆盖率速度 |
| 堆栈跟踪更准确,但执行速度更慢 |
export CFLAGS="-fsanitize=address,undefined,fuzzer-no-link"
export CXXFLAGS="-fsanitize=address,undefined,fuzzer-no-link"export CFLAGS="-fsanitize=address,undefined,fuzzer-no-link"
export CXXFLAGS="-fsanitize=address,undefined,fuzzer-no-link"import sys
import atheris
import json
@atheris.instrument_func
def test_one_input(data: bytes):
try:
# Fuzz Python's JSON parser
json.loads(data.decode('utf-8', errors='ignore'))
except (ValueError, UnicodeDecodeError):
pass
def main():
atheris.Setup(sys.argv, test_one_input)
atheris.Fuzz()
if __name__ == "__main__":
main()import sys
import atheris
import json
@atheris.instrument_func
def test_one_input(data: bytes):
try:
# 对 Python 的 JSON 解析器进行模糊测试
json.loads(data.decode('utf-8', errors='ignore'))
except (ValueError, UnicodeDecodeError):
pass
def main():
atheris.Setup(sys.argv, test_one_input)
atheris.Fuzz()
if __name__ == "__main__":
main()import sys
import atheris
with atheris.instrument_imports():
from urllib3 import HTTPResponse
from io import BytesIO
def test_one_input(data: bytes):
try:
# Fuzz HTTP response parsing
fake_response = HTTPResponse(
body=BytesIO(data),
headers={},
preload_content=False
)
fake_response.read()
except Exception:
pass
def main():
atheris.Setup(sys.argv, test_one_input)
atheris.Fuzz()
if __name__ == "__main__":
main()import sys
import atheris
with atheris.instrument_imports():
from urllib3 import HTTPResponse
from io import BytesIO
def test_one_input(data: bytes):
try:
# 对 HTTP 响应解析进行模糊测试
fake_response = HTTPResponse(
body=BytesIO(data),
headers={},
preload_content=False
)
fake_response.read()
except Exception:
pass
def main():
atheris.Setup(sys.argv, test_one_input)
atheris.Fuzz()
if __name__ == "__main__":
main()| Problem | Cause | Solution |
|---|---|---|
| No coverage increase | Poor seed corpus or target not instrumented | Add better seeds, verify |
| Slow execution | ASan overhead or large inputs | Reduce |
| Import errors | Modules imported before instrumentation | Move imports inside |
| Segfault without ASan output | Missing | Set |
| Build failures | Wrong compiler or missing flags | Verify |
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 覆盖率无提升 | 种子语料库质量差或目标代码未被插桩 | 添加更好的种子,验证 |
| 执行速度慢 | ASan 开销或输入过大 | 减小 |
| 导入错误 | 模块在插桩前被导入 | 将导入操作移至 |
| 出现段错误但无 ASan 输出 | 缺少 | 设置 |
| 构建失败 | 编译器错误或缺少标志 | 验证 |
| Skill | Use Case |
|---|---|
| fuzz-harness-writing | Detailed guidance on writing effective harnesses |
| address-sanitizer | Memory error detection during fuzzing |
| undefined-behavior-sanitizer | Catching undefined behavior in C extensions |
| coverage-analysis | Measuring and improving code coverage |
| fuzzing-corpus | Building and managing seed corpora |
| 文档 | 适用场景 |
|---|---|
| fuzz-harness-writing | 编写高效测试用例的详细指南 |
| address-sanitizer | 模糊测试期间的内存错误检测 |
| undefined-behavior-sanitizer | 捕获 C 扩展中的未定义行为 |
| coverage-analysis | 测量并提升代码覆盖率 |
| fuzzing-corpus | 构建和管理种子语料库 |
| Skill | When to Consider |
|---|---|
| hypothesis | Property-based testing with type-aware generation |
| python-afl | AFL-style fuzzing for Python when Atheris isn't available |
| 工具 | 适用场景 |
|---|---|
| hypothesis | 支持类型感知生成的属性化测试 |
| python-afl | 当 Atheris 不可用时,用于 Python 的 AFL 风格模糊测试 |