使用模拟器反汇编

逆向工程 拆卸 仿真
2021-07-08 07:46:22

我从这个链接中了解到了反汇编的挑战该文章列出了以下六个挑战:

  1. 嵌入代码区域的数据
  2. 可变指令大小
  3. 间接分支指令
  4. 在可执行文件的代码段中没有显式 CALL 站点的函数
  5. 位置无关代码 (PIC) 序列
  6. 手工制作的汇编代码。

但是,我正在考虑以下似乎可以解决上述挑战的反汇编方法。假设我们有一个要反汇编的可执行文件、一个可以 100% 覆盖代码的输入集和一个模拟器(例如 QEMU)。然后,我们可以对仿真器进行检测,以输出被仿真 CPU 执行的每条指令和相应的内存地址。之后,我们可以将每条指令翻译成汇编指令,现在整个程序就被反汇编了。

你能告诉我为什么这个想法行不通吗?

4个回答

一个可以 100% 覆盖代码的输入集

这可能是非常难以实现,尤其是在代码的行为取决于东西,你不直接控制(时间,内存,操作系统版本/环境,随机数发生器等)。补充意见:

  1. 实际上执行所有这些代码可能需要比你能承受的更多的时间
  2. 执行代码的某些部分可能需要您无法满足的条件(例如特定的硬件外设)
  3. 您将错过以二进制形式存在但永远不会执行的代码(死代码)。在某些情况下,此类代码可以揭示有关二进制文件的其他信息
  4. 您的方法可能会发现所有代码,但可能会遗漏大量数据

然而,这并不意味着该方法完全没有用。事实上,这方面已经有一些工作。例如,查看 S2E(选择性符号执行)项目:

https://sites.google.com/site/dslabepfl/proj/s2e

从概念上讲,S2E 是一个带有模块化路径分析器的自动路径浏览器:浏览器驱动目标系统沿着所有感兴趣的执行路径,而分析器检查每个这样的路径的属性(例如,寻找错误)或简单地收集信息(例如,计数页错误)。可以通过多种方式指定所需的路径,可以结合现有分析器来构建自定义分析工具,也可以使用 S2E API 编写新的分析器。

S2E 有助于使基于符号执行的分析适用于在真实环境中运行的大型软件,而无需对这些环境进行显式建模。

我们可以使用动态分析(或仅使用模拟器)来实现 100% 的代码覆盖率吗?

不,如果我是对的,它等于图灵停机问题。

基于模拟器的反汇编方法

恐怕这可能不是一个很新的想法,代码覆盖率是一个大问题。

但你总有可能找到不同的角度,在相关领域做出一些贡献。

去年的一级安全会议 CCS 2013 Obfuscation Resilient Binary Code Reuse through even push 相关想法未来的一篇有趣论文

它利用模拟器反汇编代码,动态污点分析将具体值提升为符号,并以某种方式重用反汇编的 asm 代码(嵌入在 C 代码中)。

我希望它会有所帮助

如果你想要一个简单的答案。代码覆盖。如果你只跟踪调用/执行的代码,你怎么知道你找到了所有的代码。

当代码具有内存改变行为或理解代码时,仿真有助于理解代码。就像在我的一个项目中,我知道我在软件中实现了一些双重数学函数。因此,运行 emu 以查看结果对于查看结果以识别除法和加法函数很有用。但是如果从入口点开始,emu 将进入无限循环,因为外部中断没有在预期的时间触发。

反汇编作为一种技术不是问题只要您知道二进制文件的边界(数据/代码开始的地方)并且您知道信任集。

如果你知道你在 x86 上有 UNIX ELF 文件,你可以运行objdump它来获得反汇编的输出:

objdump -d <file>

他们的研究是关于安全的他们想阅读代码边界,了解代码的某些部分做了什么,然后覆盖其中的一些。这是一个更难的问题(例如:你什么时候知道被覆盖的片段实际上不应该在那里?