-
Notifications
You must be signed in to change notification settings - Fork 1
QEMU
QEMU is a machine emulator. QEMU allows a full system, a CPU architecture with all its peripherals, to be emulated on a different CPU architecture. One of its popular uses is as Android Emulator for Android SDK. DECAF modifies QEMU code to include VMI, taint analysis, callback mechanism through binary instrumentation and instruction logging. QEMU is a dynamic translator; it translates the guest code step by step at the run time. Figure 1 shows the general structure of QEMU. Simplifying the process, the following steps will be conducted:
- QEMU reads a block of the guest code and then it translates the code to an intermediate language. The translated code is put in a code cache
- QEMU interprets the translated code. The interpretation is necessary because the translation is generic. The interpretation, on the other hand, is based on the host architecture. We further explain this in Block interpretation.
- Qemu executes the guest code up to the end of the block and then control is transferred back to the emulation manager
- The emulation manager checks to see if the next block is previously translated. It does so by checking the Address Lookup Table (ALT) that its entries show the translated address of the branch targets i.e. the jump address for the next block. If ALT does not have an entry for the new block, it again goes to (1). Otherwise, it jumps to the translated block in the code cache. We further explain this in Block chaining and patching.
Figure 1. QEMU execution structure
The above description is a simplification of the real emulation process. There are several important notes. First, QEMU must give an illusion that the guest has access to the hardware it requires. This means that QEMU must provide a software way of answering interrupts. Further, the above execution structure should answer interrupts in a timely manner. Second, jumping back and forth to the emulation manager needs some extra works. In particular, before jumping to the emulation, the CPU state must be stored and after returning the state must be restored. Third, QEMU doesn’t directly translate the guest code to the host code. In fact, QEMU uses an intermediate language called TCG and then interprets from this intermediate language to the host code.
The translation is the task of preparing an intermediate code that can be compiled into different platforms. The intermediates language is called tcg. Tcg instructions in nature are C macros. Figure 2 shows an example of the block translation to the intermediate language. Note that TCG contains only the opcodes for an instruction. While translating (or disassembling), we need to keep the arguments (or variables) in a buffer and load them when interpreting the tcg code.
Figure 2. Intermediate translation of a block of guest code
Qemu translates and interprets one block at a time. After executing one block, we have to jump to the next block. Qemu chains a block to its following after it translates the following black. Henceforth, after all the code is covered (seen and translated), the blocks are chained together and then further translation is not required; after one block is executed to the end, it jumps to the next chained block.