New Anti-VM technique observed in the wild
The SonicWall Capture Labs Threat Research team recently observed a new virtual machine detection method employed by malware to evade sandbox replication. In this technique, malware uses certain CPU instructions for which some of the CPU flag values are undefined. For these CPU instructions, the undefined CPU flag values can be different between a real machine and a virtual machine.
For example, according to Intel CPU Instruction documentation, for IMUL instruction only carry flag (CF) and overflow flag (OF) get affected after execution and status of all other flags are undefined. These undefined flag values change (set or reset) according to the execution environment. In a real machine these undefined flags do not get affected, but in case of virtual machine these flag values change. Malware exploits this behavior to detect the virtual environment.
The following are the instructions which were observed to detect virtual environment:
- MUL
- IMUL
Demonstration of technique to detect virtual environment using IMUL
In case of IMUL instruction when executed in normal environment which results accumulator (EAX) to 0, ZF flag does not get affected. But in case of virtual environment when IMUL instruction executed which results accumulator (EAX) to 0, ZF flag gets reset.
Figure 1 depicts the malware code to detect virtual environment. In the code shown in Fig1, IMUL instruction has been used with EAX as operand. We need to take value of EAX in such a way so it results accumulator (EAX) to 0 after executing IMUL instruction. So here we have taken 0x130000 as EAX value.
In Figure 1, instruction pointer is pointing to IMUL instruction. In this instruction both operands are EAX having value as 0x130000 and Zero flag (ZF) is set. As per the documentation of IMUL instruction only carry flag (CF) and overflow flag (OF) should be affected after execution.
Figure 1. Snap before IMUL instruction execution in VM
But when IMUL instruction is executed here, it results accumulator to 0 as well as resets value of ZF. Now this ZF value has been used to identify the virtual environment.
Figure 2 shows a snippet after execution of IMUL instruction. In Figure 2 IMUL instruction has been executed and ZF flag has been reset, now instruction pointer is pointing to next POPAD instruction. After POPAD, next statement is JNZ which identifies virtual environment using ZF flag and Jump is taken accordingly.
Figure 2. Snap after IMUL instruction execution in VM
Figure 3. Snap after IMUL instruction execution in Normal system
Figure 3 shows a snippet after execution of IMUL instruction in normal system. In Figure 3, IMUL instruction has been executed and ZF flag has no change, now instruction pointer is pointing to next POPAD instruction. This ZF value change is different in Figure 2 and Figure 3. After POPAD, next statement is JNZ which identifies virtual environment using ZF flag and Jump is taken accordingly.