地址消毒器Skill address-sanitizer

地址消毒器是一种内存错误检测工具,用于在模糊测试中发现C/C++代码中的缓冲区溢出、使用后释放等内存安全漏洞。关键词包括:内存错误检测、模糊测试、C/C++、安全测试、ASan、软件测试、漏洞挖掘。

测试 0 次安装 0 次浏览 更新于 3/24/2026

name: address-sanitizer type: technique description: > 地址消毒器在模糊测试期间检测内存错误。 在模糊测试C/C++代码时使用,以查找缓冲区溢出和使用后释放错误。

地址消毒器 (ASan)

地址消毒器 (ASan) 是一个广泛采用的内存错误检测工具,在软件测试中,特别是模糊测试中广泛使用。它有助于检测可能被忽视的内存损坏错误,如缓冲区溢出、使用后释放错误和其他内存安全违规。

概述

ASan 是模糊测试中的标准实践,因为它能有效识别内存漏洞。它在编译时对代码进行检测,以跟踪内存分配和访问,在运行时检测非法操作。

关键概念

概念 描述
检测 ASan 在编译期间向内存操作添加运行时检查
影子内存 映射 20TB 虚拟内存以跟踪分配状态
性能成本 与非检测代码相比,大约有2-4倍的减速
检测范围 查找缓冲区溢出、使用后释放、双重释放和内存泄漏

何时应用

应用此技术当:

  • 模糊测试C/C++代码以查找内存安全漏洞
  • 测试带有不安全块的Rust代码
  • 调试与内存损坏相关的崩溃
  • 运行怀疑有内存错误的单元测试

跳过此技术当:

  • 运行生产代码(ASan可能降低安全性)
  • 平台是Windows或macOS(ASan支持有限)
  • 性能开销对您的用例不可接受
  • 模糊测试纯安全语言无FFI(例如纯Go、纯Java)

快速参考

任务 命令/模式
启用 ASan (Clang/GCC) -fsanitize=address
启用详细输出 ASAN_OPTIONS=verbosity=1
禁用泄漏检测 ASAN_OPTIONS=detect_leaks=0
错误时强制终止 ASAN_OPTIONS=abort_on_error=1
多个选项 ASAN_OPTIONS=verbosity=1:abort_on_error=1

分步指南

步骤 1: 使用 ASan 编译

使用 -fsanitize=address 标志编译和链接您的代码:

clang -fsanitize=address -g -o my_program my_program.c

建议使用 -g 标志,以便在 ASan 检测到错误时获得更好的堆栈跟踪。

步骤 2: 配置 ASan 选项

设置 ASAN_OPTIONS 环境变量以配置 ASan 行为:

export ASAN_OPTIONS=verbosity=1:abort_on_error=1:detect_leaks=0

步骤 3: 运行您的程序

执行 ASan 检测的二进制文件。当检测到内存错误时,ASan 将打印详细报告:

./my_program

步骤 4: 调整模糊测试器内存限制

ASan 需要大约 20TB 的虚拟内存。禁用模糊测试器的内存限制:

  • libFuzzer: -rss_limit_mb=0
  • AFL++: -m none

常见模式

模式: 基本 ASan 集成

用例: 标准模糊测试设置与 ASan

之前:

clang -o fuzz_target fuzz_target.c
./fuzz_target

之后:

clang -fsanitize=address -g -o fuzz_target fuzz_target.c
ASAN_OPTIONS=verbosity=1:abort_on_error=1 ./fuzz_target

模式: ASan 与单元测试

用例: 为单元测试套件启用 ASan

之前:

gcc -o test_suite test_suite.c -lcheck
./test_suite

之后:

gcc -fsanitize=address -g -o test_suite test_suite.c -lcheck
ASAN_OPTIONS=detect_leaks=1 ./test_suite

高级使用

提示与技巧

提示 为何有帮助
使用 -g 标志 为调试提供详细的堆栈跟踪
设置 verbosity=1 确认 ASan 在程序启动前已启用
在模糊测试期间禁用泄漏检测 泄漏检测不会导致立即崩溃,避免输出杂乱
启用 abort_on_error=1 某些模糊测试器需要 abort() 而不是 _exit()

理解 ASan 报告

当 ASan 检测到内存错误时,它会打印详细报告,包括:

  • 错误类型:缓冲区溢出、使用后释放等。
  • 堆栈跟踪:错误发生的位置
  • 分配/释放跟踪:内存分配/释放的位置
  • 内存映射:错误周围的影子内存状态

示例 ASan 报告:

==12345==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60300000eff4 at pc 0x00000048e6a3
READ of size 4 at 0x60300000eff4 thread T0
    #0 0x48e6a2 in main /path/to/file.c:42

组合消毒器

ASan 可以与其他消毒器组合以进行全面检测:

clang -fsanitize=address,undefined -g -o fuzz_target fuzz_target.c

平台特定考虑

Linux:完整的 ASan 支持,性能最佳 macOS:支持有限,某些功能可能无法工作 Windows:实验性支持,不建议用于生产模糊测试

反模式

反模式 问题 正确方法
在生产中使用 ASan 可能使应用程序安全性降低 仅将 ASan 用于测试
未禁用内存限制 模糊测试器可能因 20TB 虚拟内存而终止进程 设置 -rss_limit_mb=0-m none
忽略泄漏报告 内存泄漏表示资源管理问题 在模糊测试活动结束时审查泄漏报告

工具特定指导

libFuzzer

同时使用模糊测试器和地址消毒器编译:

clang++ -fsanitize=fuzzer,address -g harness.cc -o fuzz

以无限 RSS 运行:

./fuzz -rss_limit_mb=0

集成提示:

  • 总是结合 -fsanitize=fuzzer-fsanitize=address
  • 使用 -g 以获得崩溃报告中的详细堆栈跟踪
  • 考虑 ASAN_OPTIONS=abort_on_error=1 以更好地处理崩溃

参见: libFuzzer: AddressSanitizer

AFL++

使用 AFL_USE_ASAN 环境变量:

AFL_USE_ASAN=1 afl-clang-fast++ -g harness.cc -o fuzz

以无限内存运行:

afl-fuzz -m none -i input_dir -o output_dir ./fuzz

集成提示:

  • AFL_USE_ASAN=1 自动添加正确的编译标志
  • 使用 -m none 以禁用 AFL++ 的内存限制
  • 考虑 AFL_MAP_SIZE 用于具有大覆盖率图的程序

参见: AFL++: AddressSanitizer

cargo-fuzz (Rust)

使用 --sanitizer=address 标志:

cargo fuzz run fuzz_target --sanitizer=address

或在 fuzz/Cargo.toml 中配置:

[profile.release]
opt-level = 3
debug = true

集成提示:

  • ASan 对模糊测试不安全 Rust 代码或 FFI 边界有用
  • 安全 Rust 代码可能受益不多(编译器已预防许多错误)
  • 专注于不安全块、原始指针和 C 库绑定

参见: cargo-fuzz: AddressSanitizer

honggfuzz

使用 ASan 编译并与 honggfuzz 链接:

honggfuzz -i input_dir -o output_dir -- ./fuzz_target_asan

编译目标:

hfuzz-clang -fsanitize=address -g target.c -o fuzz_target_asan

集成提示:

  • honggfuzz 开箱即用地与 ASan 配合良好
  • 使用反馈驱动模式以获得更好的覆盖率与消毒器
  • 监控内存使用,因为 ASan 增加内存占用

故障排除

问题 原因 解决方案
模糊测试器立即终止进程 内存限制过低,无法满足 ASan 的 20TB 虚拟内存 使用 -rss_limit_mb=0 (libFuzzer) 或 -m none (AFL++)
“ASan 运行时未初始化” 链接顺序错误或缺少运行时 确保在编译和链接中都使用 -fsanitize=address
泄漏报告使输出杂乱 LeakSanitizer 默认启用 设置 ASAN_OPTIONS=detect_leaks=0
性能差 (>4倍减速) 调试模式或未优化构建 同时使用 -O2-O3-fsanitize=address 编译
ASan 未检测到明显错误 二进制未检测 使用 ASAN_OPTIONS=verbosity=1 检查 ASan 是否打印启动信息
误报 拦截器冲突 检查 ASan FAQ 以了解特定库的已知问题

相关技能

使用此技术的工具

技能 如何应用
libfuzzer 使用 -fsanitize=fuzzer,address 编译以集成模糊测试与内存错误检测
aflpp 在编译期间使用 AFL_USE_ASAN=1 环境变量
cargo-fuzz 使用 --sanitizer=address 标志以启用 Rust 模糊测试目标的 ASan
honggfuzz 使用 -fsanitize=address 编译目标以进行 ASan 检测的模糊测试

相关技术

技能 关系
undefined-behavior-sanitizer 常与 ASan 结合使用以全面检测错误(未定义行为 + 内存错误)
fuzz-harness-writing 必须设计测试框架以处理 ASan 检测的崩溃并避免误报
coverage-analysis 覆盖率引导的模糊测试有助于触发代码路径,使 ASan 能够检测内存错误

资源

关键外部资源

AddressSanitizer on Google Sanitizers Wiki

官方 ASan 文档涵盖:

  • 算法和实现细节
  • 检测到的错误类型的完整列表
  • 性能特征和开销
  • 平台特定行为
  • 已知限制和兼容性问题

SanitizerCommonFlags

所有消毒器共享的常见配置标志:

  • verbosity:控制诊断输出级别
  • log_path:将消毒器输出重定向到文件
  • symbolize:在报告中启用/禁用符号解析
  • external_symbolizer_path:使用自定义符号化器

AddressSanitizerFlags

ASan 特定配置选项:

  • detect_leaks:控制内存泄漏检测
  • abort_on_error:错误时调用 abort() 对比 _exit()
  • detect_stack_use_after_return:检测栈使用后返回错误
  • check_initialization_order:查找初始化顺序错误

AddressSanitizer FAQ

常见陷阱和解决方案:

  • 链接顺序问题
  • 与其他工具的冲突
  • 平台特定问题
  • 性能调整提示

Clang AddressSanitizer Documentation

Clang 特定指导:

  • 编译标志和选项
  • 与其他 Clang 功能的交互
  • 支持的平台和架构

GCC Instrumentation Options

GCC 特定 ASan 文档:

  • GCC 特定标志和行为
  • 与 Clang 实现的差异
  • GCC 中的平台支持

AddressSanitizer: A Fast Address Sanity Checker (USENIX Paper)

具有技术细节的原始研究论文:

  • 影子内存算法
  • 虚拟内存要求(历史上 16TB,现在约 20TB)
  • 性能基准测试
  • 设计决策和权衡