Unicorn网站列出了Unicorn和QEMU之间的一些差异,尤其是那些“ Unicorn发光之处”的差异。
他们还写道: CPU操作,但不处理计算机机器的其他部分,例如QEMU。
[...]我们剥离了所有不涉及CPU仿真的子系统。这实际上意味着什么,即何时选择QEMU,何时选择Unicorn。特别是,哪些具体示例用例(在逆向工程领域)无法使用Unicorn *),但QEMU可以使用<< /> *)或​​任何基于Unicorn的工具,例如usercorn

#1 楼

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

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

要使软件按预期工作,您需要将该硬件模拟为好-例如,您的仿真器需要了解以下内容: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,因为这些程序本身就进行了大量硬件操作,因为OS缺少API。 (当然,在这种情况下,DOSBox可能比QEMU更适合。)或者,如果您想为Gameboy,C64或任何其他老式硬件制作模拟器,您可以还需要模拟硬件,因此需要这些QEMU功能。

什么时候Unicorn更有用?

对于RE任务,通常不需要硬件仿真,因为您仍然无权访问硬件设计文档。因此,忽略QEMU的这些部分并改进其他部分的仿真器可能比QEMU更适合RE。特别是“不需要环境”部分可以使工作变得更轻松。

作为一个具体的例子,举一个“为我做功课”问题-这个,这个。假设函数的功能时,您可能需要运行它以检查某些特定输入是否产生了您假设的输出。使用QEMU,您需要将其编译为ELF文件,并设置一个操作系统来运行您的程序。使用Unicorn,似乎您可以直接运行该代码段(当然,您仍然必须对其进行汇编,并且需要以一种明智的方式初始化寄存器,但是您不需要所有其他的工作)。

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

评论


但是我可以像调试器一样使用独角兽吗?例如。做诸如启动程序(即自动将二进制文件加载到内存中,加载并解析库等),设置断点,继续执行程序等操作。如果程序使用系统API,例如网络IO?

– gogo_gorilla
16-4-27在13:05



不,您将无法使用Unicorn运行可执行文件(PE文件,ELF文件等),因为加载这些文件依赖于基础操作系统和库。相反,Unicorn旨在处理不执行系统API,网络I / O等的小型汇编代码段。有关如何使用Unicorn的示例,请参见此处-初始化内存,初始化寄存器,然后执行一些汇编指令。

–詹森·格夫纳(Jason Geffner)
16-4-27的14:53

@Jason感谢您的澄清。这意味着QEMU除了硬件仿真之外,还有另一个优势:它允许真正地“运行”(加载,共享库等)目标可执行文件(从而也可以对其进行调试)。但是,比较QEMU和用户名也许更有意义,对吧?

– gogo_gorilla
16年4月27日在17:16

QEMU在虚拟环境中运行真实的操作系统,而usercorn在虚拟环境中运行模拟的Linux操作系统。

–詹森·格夫纳(Jason Geffner)
16年4月27日在19:23