Unicorn 和 QEMU:示例用例以了解差异
“ (不)模拟 CPU 以外的硬件”是什么意思?
这意味着每当被模拟的软件访问硬件时,它在 Unicorn 中的工作方式与实际硬件上的不同。
我们有几个关于在 QEMU 上模拟固件的问题。一般的答案是,当您尝试在 QEMU 中启动固件内核时,该内核将访问一些 I/O 端口,但在模拟环境中,这些 I/O 端口不会以它们应该的方式做出反应。例如,表示“设备就绪”的输入位将停留在一种状态,而不是在真假之间切换。
为了使您的软件按预期工作,您还需要模拟此硬件 - 例如,您的模拟器需要知道以下内容:
输入端口 at
0x124
的第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 所需的所有环境和依赖项,那么执行此操作似乎要容易得多。