如何在编译时检测 XNU 内核二进制文件?

Posted

技术标签:

【中文标题】如何在编译时检测 XNU 内核二进制文件?【英文标题】:How to instrument XNU kernel binary at compile time? 【发布时间】:2017-12-12 16:38:21 【问题描述】:

我想在编译时将我的代码块插入 XNU 内核中每个函数的序言。

为 IR 转换编写 LLVM 通行证可能是最好的选择,但我找不到任何有关使用 LLVM 通行证构建 XNU 内核的信息。

是否可以使用我自己的LLVM pass 插件构建 XNU 内核?如果是这样,你能告诉我如何做到这一点或提供任何链接吗?

还有其他方法可以在编译时使用我的代码块检测 XNU 内核吗?

This 链接描述了如何构建 XNU 内核。

谢谢。

【问题讨论】:

【参考方案1】:

我不确定这是否是一个足够的答案,但 cmets 中没有足够的空间。

一般来说,如果您想通过自定义 LLVM 优化传递传递任何内容,您需要 1) 生成位码并在其上使用传递,或者 2) 让 clang 为您运行该传递。

对于 1),这意味着您需要使用相同的选项和标志对程序进行预处理和编译,并在链接阶段执行相同的操作(当您处理完生成的位码时)。 AFAIK,最简单且侵入性较小的是使用 wllvm 实用程序(尤其是因为 xnu 使用 make)。

对于 2),您需要向 clang 的通行证管理器注册您的插件。根据documentation,有各种注册表,但没有提到clang。看看LLVM 是如何做到的,例如llvm/Transforms/IPO/PassManagerBuilder.h

#include "llvm/Transforms/IPO/PassManagerBuilder.h"
// using llvm::PassManagerBuilder
// using llvm::RegisterStandardPasses

static void registerHello(const llvm::PassManagerBuilder &Builder, 
                          llvm::legacy::PassManagerBase &PM) 
  PM.add(new HelloPass());

  return;


static llvm::RegisterStandardPasses RegisterHello(llvm::PassManagerBuilder::EP_EarlyAsPossible, registerHello);

并将其称为

clang -Xclang -load -Xclang [path to plugin]/libHelloPass.so foo.c -o foo

【讨论】:

解决这个问题会很有帮助。感谢您的回复! 假设我有一个自定义的 llvm pass,xnu 内核树中的文件(makefile)的哪一部分需要修改才能使 pass 工作? 或者使用哪个make选项? CFLAGS? 我猜是这样。这是你可以在玩具/虚拟项目上尝试的东西,对吧?您甚至不必在尝试之前询问每一个细节,请参阅this

以上是关于如何在编译时检测 XNU 内核二进制文件?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 32 位内核可以运行 64 位二进制文​​件?

iOS系统分析Mach-O二进制文件解析

Objcopy 获取目标文件 64 位二进制文​​件

从二进制文件中删除 protobuf c++ 编译的路径字符串

linux软件编译流程

关于Linux内核编译中的Makefile