Unicorn 和 QEMU:示例用例以了解差异

逆向工程 动态分析 奇木 仿真
2021-06-25 10:22:02

Unicorn网站列出了 Unicorn 和 QEMU 之间的一些差异,尤其是那些“Unicorn 闪耀的地方”的差异。

他们还写道:

Unicorn 和 QEMU 的一个显着区别是我们只专注于模拟 CPU 操作,而不像 QEMU 那样处理计算机机器的其他部分。

[...] 我们剥离了所有不涉及 CPU 仿真的子系统。

我试图理解这实际上意味着什么,即何时选择 QEMU 以及何时选择 Unicorn。特别是,哪些具体示例用例(在逆向工程领域)不能使用 Unicorn*),但 QEMU 可以?

*) 或任何基于 Unicorn 的工具,例如usercorn

1个回答

(不)模拟 CPU 以外的硬件”是什么意思?

这意味着每当被模拟的软件访问硬件时,它在 Unicorn 中的工作方式与实际硬件上的不同。

我们有几个关于在 QEMU 上模拟固件的问题。一般的答案是,当您尝试在 QEMU 中启动固件内核时,该内核将访问一些 I/O 端口,但在模拟环境中,这些 I/O 端口不会以它们应该的方式做出反应。例如,表示“设备就绪”的输入位将停留在一种状态,而不是在真假之间切换。

为了使您的软件按预期工作,您还需要模拟此硬件 - 例如,您的模拟器需要知道以下内容:

输入端口 at0x124的第3 位是“就绪”位,当它设置为 时1,端口 有一个字节的串行输入等待0x125读端口0x125会将就绪位重置为0,并保持状态0直到下一个字节到达串行线上。

如果您想模拟软件如何对串行接口上​​的某些特定输入做出反应,则必须建立在该规范的基础上,并使模拟器在这些 I/O 端口上提供您的输入。

但是当然,您首先需要有关硬件的信息,因此这对逆向工程不是很有用。尽管找到一些难以在实际硬件上重现或监控的错误,但它可能对硬件设计人员很有用。

作为特定示例,请考虑16/32 位 PC 上A20 门确实,同样的指令:

mov ax,0ffffh
mov es,ax
mov ax,es:[01234h]

根据您写入键盘控制器的某些位,可以访问不同的内存。除非您也模拟硬件,否则您无法在模拟器中做到这一点。

QEMU 什么时候更有用?

主要用于与 RE 无关的任务。

如果你想模拟一个旧的 MS DOS 程序,你需要 QEMU,因为这些程序本身做了很多硬件操作,因为操作系统缺少 API。(当然,在这种情况下,DOSBox可能比 QEMU 更适合)。

或者,如果您想为 Gameboy、C64 或任何其他类型的老式硬件制作模拟器,您还需要模拟硬件,因此您需要这些 QEMU 功能。

独角兽什么时候更有用?

对于 RE 任务,您通常不需要硬件仿真,因为无论如何您都无法访问硬件设计文档。因此,省略 QEMU 的这些部分并改进其他部分的模拟器可能比 QEMU 更适合 RE。特别是“不需要环境”部分可以使事情变得更容易。

举一个具体的例子,举一个“帮我做作业”的问题——这个这个当您假设函数的作用时,您可能希望运行它以检查某些特定输入是否产生您假设的输出。使用 QEMU,您需要将其编译为 ELF 文件,并设置操作系统来运行您的程序;使用 Unicorn,您似乎可以直接运行代码片段(当然您仍然需要组装它,并且需要以合理的方式初始化寄存器,但您不需要所有其余的膨胀)。

或者,另一个示例,您有一个处理受 DRM 保护的数据的程序,并包含一些解密 DRM 的函数。如果该程序在 ARM Android 或 I/OS 上运行,并且您想让您的 PC 进行解密,您可以尝试将程序加载到内存中并告诉您的模拟器“在地址处开始模拟0x12345678”。如果您不必提供 QEMU 所需的所有环境和依赖项,那么执行此操作似乎要容易得多。