我花了很多时间阅读 LLVM 源代码树。这是一项令人印象深刻的工程!
无论如何,我一直在尝试将我拥有的一些 MachO Arm 二进制文件转换为 LLVM 位代码以进行基本的静态分析。主要是,我想根据使用的寄存器在某些调用上创建向后静态切片。此外,我试图对明显的常量进行前向传播(例如,从符号表加载函数名称并传递到寄存器)。
此时,我已经能够使用以下命令行转储文件并在 native ARM 程序集中解析它:
bash-3.2$ llvm-objdump -d ~/code/osx/HelloWorldThin -triple=thumb
-mattr=+thumb2,+32bit,+v7,+v6t2,+thumb-mode,+neon
/Users/steve/code/osx/HelloWorldThin: file format Mach-O arm
Disassembly of section __TEXT,__text:
_main:
2fd4: f0 b5 push {r4, r5, r6, r7, lr}
2fd6: 03 af add r7, sp, #12
2fd8: 4d f8 04 8d str r8, [sp, #-4]!
2fdc: 0d 46 mov r5, r1
2fde: 06 46 mov r6, r0
2fe0: 00 f0 fe ef blx #4092
...剪掉了...
这太棒了,因为它节省了我编写解析器的大量时间!
查看 MachODump.cpp 后,我发现它们被降级为 MCInst,从我的理解来看,这只是一个带参数的解析操作码。
所以我的问题是:
1) 有没有办法从 ARM 转换为 LLVM(用于优化过程等)?不需要发回ARM,只需要有分析结果即可。
1.5) 我注意到所有分析操作都在指令而不是 MCInst 上进行,有没有办法输入 Promotion 并提供所需的信息?
2) 有没有办法模拟 ARM 或 LLVM 指令?我问这个问题是因为切片和恒定传播之类的事情需要数据流分析才能确定内存和寄存器中的内容。
像这样的操作需要跟踪数据从内存以及寄存器加载和存储的方式。 LLVM能否理解这些指令的副作用进行分析?
__text:000032DE LDR R1, [R0] ; "viewDidLoad"
__text:000032E0 MOV R0, SP
__text:000032E2 BLX _objc_msgSendSuper2
3)如果我对 LLVM 中发生的事情有根本性的误解,我希望得到任何反馈。
谢谢,如果我可以提供有关我的问题的更多信息,请告诉我。
最佳答案
用于 ARM 二进制文件的静态分析。最好将每个 ARM 指令的语义直接转换为 LLVM IR,然后对后者应用数据流分析。例如,ARM 中的 ADD rd, rd, rm
可以转换为 LLVM IR %rd2 = add i32 %rd1, %rm1
。
将 ARM 机器代码反编译为 C(为了将其重新编译回 LLVM IR)既麻烦又不必要。请注意,像 IDA Pro
这样的反编译器的重点是二进制理解,而不是重新编译本身。因此,您将很难重新编译软件,甚至更难以将分析结果链接到原始二进制文件。
以下链接可能有用:
- Fracture是一个开源项目,试图将 ARM 二进制文件直接转换为 LLVM IR。
- LLBT :是一个实现 ARM 到 LLVM IR 转换的研究项目。然而,他们的目标是静态二进制重写而不是二进制分析。
请注意,如果您正在考虑分析剥离的二进制文件,您需要一个强大的反汇编程序。 objdump
可能会在没有符号的二进制文件上发出过多的反汇编错误。
我正处于一个研究项目的早期阶段,我们开发了一种处理器描述语言,可以使在 LLVM IR 中描述指令语义变得更容易。当我们有更多结果时,我会更新这个答案。
关于arm - 用 LLVM 解释 ARM/MachO 进行分析和优化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14613517/