Heavy lifting with McSema 2.0
四年前,我们发布了McSema,这是一个x86到LLVM位码的二进制转换器。自那时起,它不断扩展和优化;我们增加了x86-64支持,专注于性能提升,并改进了其可用性和文档。
然而,过去几年中,不仅仅是McSema在进步。同时,程序越来越多地采用现代x86特性,如高级向量扩展(AVX)指令,这些指令操作256位宽的向量寄存器。适应这些变化是艰巨但可实现的工作。随后,我们的提升目标扩展到包括AArch64,即现代智能手机使用的架构。那时我们意识到,需要退一步加强McSema的核心。这一重点转变带来了回报;现在McSema可以将AArch64二进制文件转译为x86-64!继续阅读以获取更多细节。
Enter the dragon
今天我们宣布McSema 2.0的正式发布!此版本极大地推进了McSema的核心,并为我们的二进制提升器带来了几个令人兴奋的新发展:
- Remill:指令语义现在完全分离到Remill,它们自己的库中。McSema是一个使用该库进行二进制提升的客户端。借用类比,McSema与Remill的关系就像Clang与LLVM的关系。请关注未来使用Remill的项目。
- 简化语义:McSema和Remill的分离使得添加对新指令的支持更加容易。在Remill中,指令语义可以直接用C++表达,并由Clang自动编译为LLVM位码。
- AArch64(64位ARMv8):转向使用Remill作为语义后端意味着McSema 2从一开始就支持多种架构。它不仅适用于x86和x86-64二进制文件,还支持提升64位ARMv8程序。
- SSE3/4和AVX支持:McSema现在支持提升利用高级向量指令集的程序。
- 更好的CFG恢复:提升错误的常见来源是控制流恢复不佳。我们改进了控制流恢复过程,使其更简单、更快、更准确。McSema的CFG恢复也开始纳入高级功能,如提升全局变量和堆栈变量。
- Binary Ninja支持:McSema现在具有通过Binary Ninja恢复程序控制流的测试版支持。
McSema 2.0正在积极开发中,并快速改进和增加功能。我们希望使使用和黑客攻击McSema比以往更容易和更易访问。
See it soar: Using McSema 2
McSema最大的变化是转向使用Remill进行指令语义,以及随后的AArch64支持。这一改进的一个很好演示是展示McSema可以反汇编AArch64二进制文件,将其提升到位码,然后将该位码重新编译为x86-64机器代码。让我们开始吧!
Getting McSema
第一步是下载并安装代码。目前,Linux是McSema支持的主要平台;然而,我们正在努力支持macOS和Windows构建。如果你的目标是提升Windows二进制文件,那么不用担心!Linux构建的McSema将乐意分析Windows二进制文件。
上述链接的说明提供了更多细节,你应该遵循(例如获取依赖项、解决常见错误等),但下载和安装McSema的基本步骤如下:
|
|
这些命令将克隆Remill和McSema,调用一个通用构建脚本,在~/data/remill-build目录中编译两个项目,然后将项目安装到系统上。
Disassembling our first binary
使用McSema通常是一个两步或三步过程。第一步总是使用mcsema-disass命令行工具将二进制文件反汇编为“控制流图”文件。此文件包含程序二进制的所有原始代码和数据,但组织成逻辑分组,如变量、函数、指令块及其之间的引用。
我们将使用Felipe Manzano的maze,编译为AArch64程序二进制文件,作为我们的运行示例。这是一个交互式命令行游戏,要求用户解决迷宫。maze的预编译二进制文件可以在McSema的examples/Maze/bin目录中找到。
|
|
上述步骤将从maze程序生成控制流图(CFG)文件,将CFG文件保存到/tmp/maze.aarch64.cfg。如果你在家跟随操作,没有许可版本的IDA Pro,但有Binary Ninja许可证,那么你可以更改传递给–disassembler选项的值,指向Binary Ninja可执行文件(即–disassembler /opt/binaryninja/binaryninja)。最后,如果你是radare2的坚持者,那么不用担心——我们已经为maze二进制文件制作了CFG文件。
Lifting to bitcode
第二步是使用mcsema-lift-3.9命令行工具将CFG文件提升为LLVM位码。这里的3.9不是McSema版本;它是LLVM工具链版本。LLVM是一个快速发展的项目,这有时意味着有趣的项目(例如KLEE)被遗留,只适用于较旧的LLVM版本。我们试图尽可能简单地让用户享受使用McSema的好处——这就是为什么McSema使用LLVM版本3.5及更高版本。事实上,使用McSema 2,你现在可以在系统上安装多个版本的McSema,每个版本针对不同的LLVM版本。关于这一点已经说得够多了,是时候提升一些重量了!
|
|
上述命令指示McSema将提升的位码保存到文件/tmp/maze.aarch64.bc。–explicit_args命令行标志是McSema 2的一个新功能,模拟了McSema 1的原始行为。如果你的目标是对提升的位码执行静态分析或符号执行,那么你将希望使用此选项。类似地,如果你正在将从一种架构(例如AArch64)提升的位码编译为另一种架构(例如x86-64)的机器代码,那么你也需要此选项。另一方面,如果你的目标是将提升的位码编译回相同架构的可执行程序(如Cyber Fault-tolerance Attack Recovery程序的情况),那么你不应使用–explicit_args。
Compiling bitcode back to runnable programs
终于到了让魔法发生的时候了——我们将从AArch64程序获取位码,并使其在x86-64上运行。我们方便地确保了一个Clang编译器与McSema一起安装,并且以不与任何其他已安装编译器冲突的方式。以下是如何使用该Clang将提升的位码编译为名为/tmp/maze.aarch64.lifted的可执行文件。
|
|
注意:如果由于某种原因remill-clang-3.9对你不起作用,那么你也可以使用~/data/remill-build/libraries/llvm/bin/clang。
Solving the maze
我们现在已成功将AArch64程序二进制文件转译为x86-64程序二进制文件。等等,什么?是的,我们真的做到了。运行转译版本显示正确的输出,提示我们如何玩游戏的说明。
|
|
但是,如果——尽管我们尽力——我们无法解决迷宫呢?那不会是一个问题,因为我们总是可以使用KLEE符号执行器来为我们解决迷宫。
Your new workout routine
我们已经练习了所有动作,你的新锻炼程序准备好了。你程序中的第1天是反汇编二进制文件并制作CFG文件。
|
|
第2天是你的提升日,我们将CFG文件提升为LLVM位码。
|
|
第3天以一些紧张的编译结束你的一周,从提升的位码生成新的机器代码可执行文件。
|
|
最后,不要忘记你的伸展运动。我们想确保那些肌肉仍然工作。
|
|
Come with me if you want to lift
Maze转译和符号执行演示只是你可以用McSema 2做的事情的表面。最终目标一直是使二进制文件能够像源代码一样被对待。随着McSema 2中的众多改进,我们正接近这一理想。在接下来的几个月里,我们将更多地讨论McSema 2的其他令人兴奋的功能(如堆栈和全局变量恢复)以及Trail of Bits和其他人如何使用McSema。
我们很乐意与你讨论McSema以及它如何解决你的二进制分析和转换问题。我们始终在Empire Hacking Slack和通过我们的联系页面上可用。
现在,系好你的腰带——是时候进行一些繁重的工作了。McSema版本2已为你的二进制文件准备好。
如果你喜欢这篇文章,请分享: Twitter LinkedIn GitHub Mastodon Hacker News