How an application can detect if is running inside a VMware virtual machine

After my post about discovering Microsoft VM running, here the same for VMware VMs.
Credits to SecuriTeam.

Background:
VMware contains a program called “VMware Command Line Tools”, these tools need to communicate with the host via the VMware virtual machine (the same method is used by the official VMware-Tools).

The basic idea is that the communication is done through a special I/O port specific to the VMware virtual machines. The following sequence is used to call VMware?s environment:

MOV EAX, 564D5868h ; Magic Number
MOV EBX, COMMAND_SPECIFIC_PARAMETER
MOV ECX, BACKDOOR_COMMAND_NUMBER
MOV DX, 5658h ; Port Number

IN EAX, DX

Though it may appear to be an ordinary I/O access routine at first glance, several VMware specific mechanisms are involved in this. What is not apparent from this example is that data can be transferred to both directions with this routine. As shown in the example, the Magic number is stored in EAX and other certain values are stored in EBX and ECX prior to executing IN instruction. Although values in these registers have no effect on IN instruction in real machines, VMware?s environments use these values as their input parameters. Also some functions return their results in EBX, ECX and EDX as well as in EAX. Consequently, you can not use C library functions to access this Backdoor port (e.g. _inp() function in MSVC runtime library), because those functions never expect these registers to be changed by IN instruction.

Technical Details:
As the above I/O port doesn’t exist on non-VMware environments, a malicious code can detect whether it runs under VMware or not, and act accordingly.

Proof of Concept:
Andrew Hintz has created a small Linux based program that detects whether it runs under the VMware environment:
/*
* 4tphi-vmchk.c
* Detects if you are in a VMWare virtual machine.
*
* Written by Andrew Hintz
* and AAron Walters
* Fortify Research Laboratories
*
* “Oft at the hives of his tame bees
* They would their sugary thirst appease.”
*
* This program is based on info and code from:
* http://chitchat.tripod.co.jp/vmware/
* by chitchat@lycos.jp
*
* Notes:
* The program can be run as a normal user.
* We tested the program only in x86 Linux.
* The m4dn3ss lives on!
*/

#include
#include

#if __INTSIZE == 2 /* 16 bit environment */
typedef unsigned int uint16;
typedef unsigned long uint32;
#else /* 32 bit environment */
typedef unsigned short uint16;
typedef unsigned int uint32;
#endif /* __INTSIZE */

void segfault(){
printf(“Not running inside VMware.\n”);
exit(1);
}

int main(){
uint32 verMajor, verMinor, magic, dout;

signal(SIGSEGV, segfault);

__asm__ __volatile__ (”
mov $0x564D5868, %%eax; /* magic number */
mov $0x3c6cf712, %%ebx; /* random number */
mov $0x0000000A, %%ecx; /* specifies command */
mov $0x5658, %%edx; /* VMware I/O port */

in %%dx, %%eax;

mov %%eax, %0;
mov %%ebx, %1;
mov %%ecx, %2;
mov %%edx, %3;

: “=r”(verMajor), “=r”(magic), “=r”(verMinor), “=r”(dout)
);

if (magic == 0x564D5868) {
printf(“Running inside VMware. “);
printf(“(Version %lu,%lu)\n”, verMajor, verMinor);
/* I’m not really sure what the versions mean. */
}

return 0;

}/* end main */

/* end of file */