重磅推出McSema 2.0 - Trail of Bits博客
巨龙登场
今天我们正式发布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比以往任何时候都更容易和更便捷。
见证翱翔:使用McSema 2
McSema最大的变化是改用Remill处理指令语义,以及随后对AArch64的支持。这一改进的一个很好的演示是展示McSema能够反汇编AArch64二进制文件,将其提升为位码,然后将该位码重新编译为x86-64机器代码。让我们开始吧!
获取McSema
第一步是下载并安装代码。目前,Linux是McSema支持的主要平台;但是,我们正在努力支持macOS和Windows构建。如果你的目标是提升Windows二进制文件,那也没问题!Linux构建的McSema可以愉快地分析Windows二进制文件。
上述链接的说明提供了更多你应该遵循的细节(例如获取依赖项、解决常见错误等),但下载和安装McSema的基本步骤如下:
|
|
这些命令将克隆Remill和McSema,调用一个通用的构建脚本,在~/data/remill-build目录中编译这两个项目,然后将项目安装到系统上。
反汇编我们的第一个二进制文件
使用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文件。
提升到位码
第二步是使用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。
将位码编译回可运行程序
终于到了让魔法发生的时候了——我们将从AArch64程序获取位码,并使其在x86-64上运行。我们已方便地确保在安装McSema的同时安装了Clang编译器,并且以不与您已安装的任何其他编译器冲突的方式安装。以下是使用该Clang将提升的位码编译为名为/tmp/maze.aarch64.lifted的可执行文件的方法:
|
|
注意:如果由于某种原因remill-clang-3.9对你不起作用,那么你也可以使用~/data/remill-build/libraries/llvm/bin/clang。
解决迷宫
我们现在已成功将一个AArch64程序二进制文件转译为一个x86-64程序二进制文件。等等,什么?是的,我们真的做到了。运行转译版本显示正确的输出,提示我们如何玩游戏。
|
|
但是,如果——尽管我们尽力——我们无法解决迷宫呢?那不会是个问题,因为我们总是可以使用KLEE符号执行器来为我们解决迷宫。
你的新锻炼计划
我们已经练习了所有动作,你的新锻炼计划准备好了。你计划的第一天是反汇编二进制文件并制作CFG文件。
|
|
第二天是你的提升日,我们将CFG文件提升为LLVM位码。
|
|
第三天以一些紧张的编译结束你的一周,从提升的位码生成新的机器代码可执行文件。
|
|
最后,不要忘记你的伸展运动。我们想确保那些肌肉仍然工作。
|
|
如果你想提升,就跟我来
Maze转译和符号执行演示仅仅触及了你可以用McSema 2做什么的表面。最终目标始终是使二进制文件能够像源代码一样被对待。随着McSema 2中的众多改进,我们正越来越接近这一理想。在接下来的几个月里,我们将更多地讨论McSema 2的其他激动人心的功能(如堆栈和全局变量恢复)以及Trail of Bits和其他人如何使用McSema。
我们很乐意与你讨论McSema以及它如何解决你的二进制分析和转换问题。我们始终在Empire Hacking Slack和通过我们的联系页面上可用。
不过现在,系好你的腰带——是时候进行一些繁重的工作了。McSema版本2已为你的二进制文件准备好。