Detecting VMWare

Disclaimer: I guess this is an old trick, but anyway…

I am learning some malware analysis using the *awesome* “Practical Malware Analysis” book from Michael Sikorski and Andrew Honig.

In case you haven’t done it already… go and buy it right now! (http://nostarch.com/malware). You won’t regret it :)

One cool thing about this book is the amount of exercises left to the reader, “practical” remember?

What takes me to the point of this brief post. At the end of chapter 0x05 we have to analyze a malicious DLL. One of the questions ask us to find the occurrence of the x86 ASM instruction “in” (0xED). This is used to read data from a port and one of the parameters is a magic number which serves as an identifier for that specific port.

In this particular case the “magic number” is 0x564D5868 (VMXh in ASCII). Apparently this is only present on VMWare systems and therefore can be used to check if we are running inside a VMWare machine. This is very important for malware developers since they don’t want to run inside malware analyst machines, for obvious reasons…

The code can be found within this function, which I conveniently renamed to cgp_checkVMWARE:

As you can see, the register ebx is initialized to zero and the magic number gets loaded into edx. After the “in” instruction gets executed the register ebx must be overwritten with the magic number value if it successfully connected to the port (that is, we are inside VMWare).

I found this trick really neat so I wanted to write a small program that performs exactly this check. But since I don’t understand exactly what is happening and I don’t know how to query the port from C using the Windows API… I took the shortest path.

It’s obvious that this malware is performing this check successfully so why don’t canibalize this code?

My first idea was to write a small C skeleton and embed this assembly, something like this:

#include <stdio.h>

int
main(int argc, char* argv[])
{
unsigned int vm_flag = 1;

/* The check will set the VM Flag to ZERO if successful */

__asm
{
mov eax, 0x564D5868 ; ascii: VMXh
mov edx, 0x5658 ; ascii: VX (port)
in eax, dx ; input from Port
cmp ebx, 0x564D5868 ; ascii: VMXh
setz ecx ; if successful -> flag = 0
mov vm_flag, ecx
}

if(vm_flag == 0)
printf(“Inside VMWARE!!! 8-X\n”);
else
printf(“VMWARE environment NOT detected\n”);
return 0;
}

It compiled fine but to my surprise it crashed in my laptop (native Win7, outside VMWare).

Hmmmm… maybe I did something wrong… So I fired up Immunity Debugger and traced the code. The problem was by the execution of the “in eax, dx” instruction and the exception was “0xC0000096: Privileged Instruction“.

Apparently the OS doesn’t like that Ring-3 code (user code) tries to access the hardware directly :)

But how does this work for the malware? Easy, I just needed to open my eyes and look what the function does before executing the forementioned code:

It is setting a SEH frame and registering a handler. Check Wikipedia for information about what lies at fs:[0]

This exception is expected to happen outside VMWare and therefore there is code to handle it. So could it be that easy? It turns out it can ;)

The modified code, with a {__try, __except} block to catch the exception is this:

#include <stdio.h>
#include <windows.h>
#define OOPS_PRIVILEGED_INSTRUCTION 0xC0000096
int
main(int argc, char* argv[])
{
unsigned int vm_flag = 1;

/* The check will set the VM Flag to ZERO if successful */

__try
{
__asm
{
mov eax, 0x564D5868 ; ascii: VMXh
mov edx, 0x5658 ; ascii: VX (port)
in eax, dx ; input from Port
cmp ebx, 0x564D5868 ; ascii: VMXh
setz ecx ; if successful -> flag = 0
mov vm_flag, ecx
}

if(vm_flag == 0)
printf(“Inside VMWARE!!! 8-X\n”);
}
__except(GetExceptionCode() == OOPS_PRIVILEGED_INSTRUCTION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
printf(“VMWARE environment NOT detected\n”);
}
return 0;
}

It works as expected, here is an screenshot of it running natively in my laptop (Win7) and within VirtualBox.

And here a screenshot of the program detecting VMWare Player 5 in this case.

It is straightforward to compile this code using Visual Studio but anyway here is the executable.

NOTE: WordPress doesn’t allow to upload .zip files so I change the extension to .pdf, just change it back to .zip and you are good to go! ;)

checkVM.zip

Advertisements

6 thoughts on “Detecting VMWare

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s