从零构建LLVM Sanitizer:编译器插桩技术实战指南

本文详细解析LLVM Sanitizer的实现机制,涵盖编译器驱动架构、LLVM IR转换、运行时库集成等核心技术,通过实际案例展示如何构建自定义程序分析工具,为静态分析和动态检测提供实践指导。

从希望与梦想构建LLVM Sanitizer - Trail of Bits博客

Carson Harmon
2019年6月25日
编译器, 实习项目, 静态分析

每年,Trail of Bits都会举办为期一个月的冬季实习项目(称为"winternship")。今年我们很高兴接待了4名实习生,他们参与了3个项目。这个项目来自Carson Harmon,普渡大学新毕业生,对编译器和系统工程感兴趣,现为我们研究实践部门的全职成员。

我最初计划在LLVM中实现动态指向分析(points-to analysis)作为冬季实习项目。指向分析能够告诉我们,在程序中给定地址或指针处,内存中存储的数据类型,以及可能的内存分配位置。这很有用,因为它有助于评估静态分析的准确性,用额外事实增强静态分析,并提供某些对象创建时间和位置的上下文。

LLVM sanitizer基础架构为实现此类分析提供了天然场所。Sanitizer可以在编译时检测程序,并包含一个运行时支持库,具有libc实现、函数替换接口、内存和线程管理、操作系统特定的系统调用支持等功能。值得注意的是,许多开发者日常使用的现有错误查找工具都是作为sanitizer实现的,包括:

  • AddressSanitizer:识别无效的堆栈和堆访问、释放后使用和其他类型的内存访问错误
  • MemorySanitizer:检测未初始化的读取
  • LeakSanitizer:定位内存泄漏
  • UndefinedBehaviorSanitizer:检测未定义行为(例如整数溢出和过度移位)

遗憾的是,由于缺乏关于LLVM sanitizer的文档,我的指向分析没有取得很大进展。相反,我将提供LLVM的高级概述以及如何使用它来制作sanitizer,重述我在冬季实习期间经历的步骤。

如何编写自己的LLVM sanitizer

我首先查阅了Eli Bendersky的博客和GitHub仓库、Adrian Sampson博士的博客、EuroLLVM的会议记录以及LLVM广泛的工具链文档。我找到的一些信息已经过时,但它帮助确定了构建自己的sanitizer需要交互的模块。

编译器驱动程序是LLVM中所有模块之间的粘合剂;任何需要在模块之间传递的信息都通过驱动程序传递。构建sanitizer可能需要修改这些组件中的任意数量。我发现理解驱动程序设计对于系统开发很重要。

clang前端、LLVM IR、compiler-rt和编译器驱动程序之间的高层关系

如果分析过程或sanitizer想要修改LLVM类型生成过程,它们需要修改驱动程序的代码生成过程。

代码生成过程中clang类型的数据流

驱动程序还负责调度和运行LLVM通道。LLVM通道修改IR以插入、删除或替换指令,这特别有用,因为它允许sanitizer修改指令和插入函数调用,而无需开发人员付出任何额外努力。驱动程序根据传递给前端的配置设置注册通道。Sanitizer通道应该最后运行,因为驱动程序可能会运行优化通道、分析通道或其他可能影响你插桩的转换通道。

通道管理器和驱动程序之间的交互

最后,驱动程序负责链接sanitizer的运行时组件compiler-rt。Compiler-rt是一个库,为sanitizer提供在执行期间与目标程序交互的能力。这种交互可以通过LLVM转换通道插入对compiler-rt中定义的函数的调用来实现,或者通过使用compiler-rt的函数挂钩接口。

转换通道和运行时组件之间的交互

制作自己的sanitizer

我创建了一个教程来帮助制作自己的sanitizer,其中包括预构建的测试sanitizer、关于开发和集成通道及运行时组件的分步指南,以及用于在LLVM上开发的其他有用资源。我认为冬季实习是在寒假学习新东西的好方法,我希望更多公司提供类似的项目。

如果你喜欢这篇文章,请分享: Twitter LinkedIn GitHub Mastodon Hacker News


页面内容
如何编写自己的LLVM sanitizer
制作自己的sanitizer

最近文章
我们构建了MCP一直需要的安全层
在废弃硬件中利用零日漏洞
EthCC[8]内幕:成为智能合约审计员
使用Vendetect大规模检测代码复制
构建安全消息传递很难:关于Bitchat安全辩论的细致分析

© 2025 Trail of Bits.
使用Hugo和Mainroad主题生成。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计