6

The Unicorn website lists some differences between Unicorn and QEMU, especially those differences "where Unicorn shines".

They furthermore write:

A notable difference between Unicorn and QEMU is that we only focus on emulating CPU operations, but do not handle other parts of computer machine like QEMU.

[...] we stripped all the subsystems that do not involve in CPU emulation.

I am trying to understand what this actually means, i.e. when to choose QEMU and when Unicorn. Especially, what are concrete example use cases (in the area of reverse engineering) in which Unicorn*) cannot be used, but QEMU can ?

*) or any tools based on Unicorn such as usercorn

8

What does "(not) emulating hardware other than the CPU" mean?

This means that whenever the software being emulated accesses hardware, it won't work in Unicorn in the same way as on actual hardware.

We have several questions about emulating firmware on QEMU. The general answer is that, when you try booting a firmware kernel in QEMU, that kernel will access some I/O ports, but in the emulated environment, those I/O ports won't react in the way they should. For example, an input bit that signals "device ready" will be stuck in one state, instead of toggling between true and false.

To make your software work as intended, you need to emulate this hardware as well - for example, your emulator needs to know something like:

Bit 3 of the input port at 0x124 is the "ready" bit, when it's set to 1, there's one byte of serial input waiting at port 0x125. Reading port 0x125 will reset the ready bit to 0, and it will stay in state 0 until the next byte arrives on the serial line.

And if you want to emulate how a software reacts on some particular input on the serial interface, you'll have to build on that specification and make the emulator provide your input at these I/O ports.

But of course, you need information about the hardware first, so this isn't very useful to reverse engineering. It may be useful to the hardware designer though to find some bugs that are difficult to reproduce or monitor on actual hardware.

As a specific example, consider the A20 gate on 16/32 bit PCs. Indeed, the same instructions:

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

May access different memory depending on some bits you wrote to the keyboard controller. You can't get this right in an emulator unless you emulate hardware as well.

When is QEMU more useful?

Mostly for not RE-related tasks.

If you want to emulate an old MS DOS program, you'd need QEMU, just because those programs did so much hardware manipulation themselves as the OS lacked the APIs. (Of course, in this case DOSBox would probably be more suited than QEMU).

Or, if you want to make an emulator for a Gameboy, C64, or just any other kind of vintage hardware, you need to simulate the hardware as well, so you'd need these QEMU features.

When is Unicorn more useful?

For RE tasks, you typically don't need hardware emulation, because you don't have access to hardware design documents anyway. So, an emulator that omits these parts of QEMU, and improves other parts, is probably more suited to RE than QEMU is. Especially the "does not need an environment" part can make stuff easier.

As a concrete example, take one of those "do my homework for me" questions - this, and this. When you have an assumption what a function does, you may want to run it to check if some specific input produces the output you assume. With QEMU, you need to compile this to an ELF file, and set up an operating system to run your program; with Unicorn, it seems like you can run the snippet directly (of course you still have to assemble it, and need to initialize registers in a sensible way, but you don't need all the rest of the bloat).

Or, another example, you have a program that deals with DRM protected data, and includes some functions to decrypt the DRM. If that program runs on ARM Android or I/OS, and you want to have your PC do the decryption, you can try loading the program into memory and tell your emulator "start emulating at address 0x12345678". It seems to be much easier to do this if you don't have to provide all the environment, and dependencies, that QEMU requires.

| improve this answer | |
  • But can I use unicorn like a debugger? E.g. do things like starting the program (i.e. automatically loading the binary into memory, loading and resolving the libraries, ...) setting a breakpoint, continuing the program. What if the program uses system APIs, e.g. network IO? – langlauf.io Apr 27 '16 at 13:05
  • 2
    No, you wouldn't be able to use Unicorn to run an executable file (PE file, ELF file, etc.) because loading those files relies on an underlying operating system and libraries. Unicorn is instead meant to deal with small snippets of assembly where no system APIs, network I/O, etc. is performed. See here for an example of how Unicorn is used -- you initialize memory, initialize registers, and then execute some assembly instructions. – Jason Geffner Apr 27 '16 at 14:53
  • @Jason Thanks for the clarification. This means QEMU has another advantage, besides the hardware emulation: It allows to really "run" (loading, shared libs, ...) the target executable (and thus also to debug it). Yet, maybe it makes more sense to compare QEMU and usercorn then, right? – langlauf.io Apr 27 '16 at 17:16
  • 2
    QEMU runs a real OS in the virtualized environment, whereas usercorn runs a simulated Linux OS in the virtualized environment. – Jason Geffner Apr 27 '16 at 19:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.