交互式反编译新体验:Magnifier工具深度解析

本文详细介绍了Trail of Bits开发的交互式反编译工具Magnifier,通过LLVM IR转换和实时C代码生成技术,显著提升逆向工程效率。工具支持函数内联、值替换和常量折叠等高级优化功能。

Magnifier:交互式反编译的实验

反编译在Trail of Bits的实践

Trail of Bits正在开发多个与程序反编译相关的开源项目:Remill、Anvill、Rellic以及现在的Magnifier。Trail of Bits的反编译策略是通过多层中间表示(IR)逐步提升编译程序;Remill、Anvill和Rellic协同工作实现这一目标。这种多阶段方法有助于将问题分解为更小的组件:

  • Remill将机器指令表示为LLVM IR
  • Anvill将机器代码函数转换为LLVM函数
  • Rellic通过Clang AST将LLVM IR转换为C代码

理论上,程序可以在任何流水线阶段进行转换,Magnifier验证了这一理论。使用Magnifier,研究人员可以交互式地转换Anvill的LLVM IR,并即时查看Rellic生成的C代码。

从REPL开始

Magnifier最初是一个命令行读取-求值-打印循环(REPL),允许用户使用简洁的命令执行各种LLVM IR转换。这些转换包括:

  • 使用LLVM进行函数优化
  • 函数内联
  • 带/不带常量折叠的值替换
  • 函数指针去虚拟化

Magnifier的第一个目标是描述被转换的目标;根据转换类型,这些目标可以是指令、函数或其他对象。为了统一描述这些目标并隐藏某些实现细节,Magnifier为所有函数、函数参数、基本块和IR指令分配了唯一的不透明ID。

Magnifier的下一个重要目标是跟踪转换过程中的指令来源,并了解操作如何影响指令。为此,它引入了额外的源ID(对于未修改的函数,源ID与当前ID相同)。然后在每次转换期间,创建一个新函数来传播源ID,但生成新的唯一当前ID。此解决方案确保没有函数被原地修改,便于在跟踪来源的同时进行转换前后的比较。

最后,对于值替换等转换,Magnifier能够以常量折叠的形式执行额外转换。这些额外转换通常是可取的。为适应不同用例,Magnifier以通用替换接口的形式提供对每个转换的精细控制。该接口允许用户监控所有转换,并根据需要选择允许、拒绝或修改替换步骤。

MagnifierUI:更直观的界面

虽然共享库加REPL的组合是一个简单灵活的解决方案,但对于只想将Magnifier作为反编译二进制文件工具的研究人员来说,这并不是最理想的设置。这就是MagnifierUI的用武之地。

MagnifierUI包含Vue.js前端和C++后端,并使用多会话WebSocket促进两者之间的通信。MagnifierUI不仅暴露了Magnifier提供的大部分功能,还集成了LLVM IR到C代码的反编译器Rellic,以显示并排的C代码反编译结果。

与使用REPL相比,MagnifierUI更加可视化和直观。特别是并排视图和指令高亮显示使代码阅读更加容易。

利用LLVM优化捕获标志

如上简要演示,我们可以以各种方式利用LLVM库,包括其花哨的IR优化来简化代码。这个例子展示了Magnifier在简化逆向工程过程和使研究人员生活更轻松方面的巨大潜力。通过利用LLVM优化背后的所有工程智慧,Magnifier甚至可以将包含循环和条件语句的相对复杂函数(如"fibIter")简化为常量。

展望Magnifier的未来

我希望这篇博文能够从高层次上阐明Trail of Bits如何应对程序反编译挑战,并展示交互式编译器通过Magnifier项目可以实现的目标。

Magnifier当然需要额外的工作,从添加转换类型支持(希望最终能表达完整的补丁集)到将MagnifierUI与Anvill等工具集成以直接摄取二进制文件。尽管如此,我为自己在项目中取得的成就感到非常自豪,并期待Magnifier的未来发展。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计