为 Linux 内核构建完整的控制流图

Constructing a complete control flow graph for Linux kernel

是否有任何工具可以为整个 Linux 内核二进制文件构建控制流图?例如,考虑为 x86 架构编译的 Linux 内核(vmlinux 文件)。是否可以使用静态分析和动态分析来确定所有执行路径(关于间接调用)?有没有适合的工具?

我假设你的意思是分析用于生成 Linux 二进制文件的源代码。

希望您为大量工作做好准备。您无法将其下架是有原因的。

您需要两种工具:

  1. 构造单个 C 源文件的控制流图的机制,适用于 Linux 内核使用的 C 的真实方言。

  2. 可以构建包括间接调用在内的全局调用图的东西;如果你不能很好地处理间接调用,你的调用图要么连接过度(著名的“涂鸦”图),要么连接不足(大多数功能无法访问)。

对于 [1],

  • 您可以从头开始构建您自己的自定义工具,毕竟,您“只需要一个解析器”。这条路简直是疯狂。参见 http://www.semdesigns.com/Products/DMS/LifeAfterParsing.html
  • 大多数现代 C 编译器会将此作为编译源文件过程的一部分,因此这是一个很有前途的地方。鉴于 GCC 用于编译 Linux,这是最明显的地方:https://gcc.gnu.org/ Getting GCC to cough up that control flow graph in some usable form for your purpose may be harder; GCC's internals are famously hard to work with. Clang can compile C programs; I don't know about its compatibility with the GCC dialect but I'd guess it was highly probable. Clang (https://clang.llvm.org/) 似乎是为了定制而构建的,因此 CFG 提取在技术上可能很简单,我会我敢打赌 Google 已经为内部项目做到了这一点。还有其他 C 编译器(例如 Intel 的),但是如果它们不使用 Linux 上使用的 GCC 方言,您会发现自己首先必须适应它们,而不是提取您想要的东西,然后获得这些编译器的源代码,因此您可以进行这些更改可能很困难。
  • 您可以尝试适配一些安全扫描工具,例如Coverity或KlocWork。我怀疑您是否会以可以适应的形式获得这样的工具取得很大进展。
  • 您可以使用(商业)通用程序转换工具,例如我们的 DMS Software Reengineering Toolkit。 DMS 是一种可定制的编译器技术,旨在供积极的工程师在内部访问。 DMS可以处理很多GCC方言,已经在真正的几千万行代码的嵌入式软件系统上使用。 DMS的GCC前端构造控制和数据流图; see http://www.semdesigns.com/products/DMS/FlowAnalysis.html#DataFlowAnalysis. Another (research) program transformation tool is RascalMPL https://www.rascal-mpl.org/ 可能有用,但我还没有听说它被应用于 GCC 方言或以这种规模运行;它可能会这样做。

对于 [2],

  • 您可以构建您的 call-graph 构造工具自定义工具。在这种规模下进行 pointer-sensitive 流分析并不像构建流图结构那么难,但它在完成它所需的胆量方面非常接近。 (Google 可能有胆量)。
  • DMS 有一个 points-to 分析子系统,已在 1600 万行嵌入式系统上使用(对于客户,为他们启用自定义代码生成任务)。它还具有使用此 points-to 信息的 call-graph 结构。参见 http://www.semdesigns.com/products/DMS/FlowAnalysis.html#CallGraphAnalysis。具体看Sample Call图link,里面显示了points-to分析的结果。

一旦你有了这些片段,你就可以考虑如何处理结果了。我可以告诉你,百万线系统的流程图将覆盖 1 英寸分辨率的足球场; traverse/analyze 这样的图表需要强大的计算能力。

如果您的目的是分析 Linux 二进制文件(好吧,您希望直接处理 linker 模块),那么构建控制流图,因为您不必处理大部分编译器的内容。现在你只需要担心整个英特尔指令集。但是,如果您准确地对机器指令建模,您的 CFG 可能是源代码的 10 倍大小,并且在将任何问题追溯回源方面的帮助要小得多。