Mechanisms to determine if software is running in a VMware virtual machine
search cancel

Mechanisms to determine if software is running in a VMware virtual machine

book

Article ID: 340368

calendar_today

Updated On:

Products

VMware VMware Desktop Hypervisor VMware vSphere ESXi

Issue/Introduction

This KB article documents the mechanisms that programs should use to determine if software is running in a VMware virtual machine.

Resolution

Detecting when software is running in a VMware virtual machine relies on two mechanisms:

  • Testing the CPUID hypervisor present bit
  • Testing the virtual BIOS DMI information and the hypervisor port

Testing the CPUID hypervisor present bit

Intel and AMD CPUs have reserved bit 31 of ECX of CPUID leaf 0x1 as the hypervisor present bit. This bit allows hypervisors to indicate their presence to the guest operating system. Hypervisors set this bit and physical CPUs (all existing and future CPUs) set this bit to zero. Guest operating systems can test bit 31 to detect if they are running inside a virtual machine.
Intel and AMD have also reserved CPUID leaves 0x40000000 - 0x400000FF for software use. Hypervisors can use these leaves to provide an interface to pass information from the hypervisor to the guest operating system running inside a virtual machine. The hypervisor bit indicates the presence of a hypervisor and that it is safe to test these additional software leaves. VMware defines the 0x40000000 leaf as the hypervisor CPUID information leaf. Code running on a VMware hypervisor can test the CPUID information leaf for the hypervisor signature. VMware stores the string "VMwareVMware" in EBX, ECX, EDX of CPUID leaf 0x40000000.

Sample code

int cpuid_check() {         unsigned int eax, ebx, ecx, edx;         char hyper_vendor_id[13];          cpuid(0x1, &eax, &ebx, &ecx, &edx;;         if  (bit 31 of ecx is set) {                 cpuid(0x40000000, &eax, &ebx, &ecx, &edx;;                 memcpy(hyper_vendor_id + 0, &ebx, 4);                 memcpy(hyper_vendor_id + 4, &ecx, 4);                 memcpy(hyper_vendor_id + 8, &edx, 4);                 hyper_vendor_id[12] = '\0';                 if (!strcmp(hyper_vendor_id, "VMwareVMware"))                         return 1;               // Success - running under VMware         }         return 0; } 

Testing the virtual BIOS DMI information and the hypervisor port

Apart from the CPUID-based method for VMware virtual machine detection, VMware also provides a fallback mechanism for the following reasons:

  • This CPUID-based technique will not work for guest code running at CPL3 when VT/AMD-V is not available or not enabled.
  • The hypervisor present bit and hypervisor information leaf are only defined for products based on VMware hardware version 7.

Virtual BIOS DMI information

The VMware virtual BIOS has many VMware-specific identifiers which programs can use to detect hypervisors. For the DMI string check, use the BIOS serial number and check for either string "VMware-" or "VMW" (for Mac OS X guests running on Fusion).

Sample code

int dmi_check(void) {         char string[10];         GET_BIOS_SERIAL(string);          if (!memcmp(string, "VMware-", 7) || !memcmp(string, "VMW", 3))                 return 1;                       // DMI contains VMware specific string.         else                 return 0; } 

Performing just the DMI check is insufficient because the BIOS' serial number might, by chance, contain the string "VMware-" or "VMW". You should also test the hypervisor port.

Hypervisor port

VMware implements an I/O port that programs can query to detect if software is running in a VMware hypervisor. This hypervisor port behaves differently depending on magic values in certain registers and modifies some registers as a side effect. VMware hypervisor is detected by performing an IN operation to port 0x5658 (the VMware hypervisor port).

Doing a IN on port 0x5658 with

eax = 0x564D5868 (VMware hypervisor magic value)
ebx = 0xFFFFFFFF (UINT_MAX)
ecx = 10 (Getversion command identifier)
edx = 0x5658 (hypervisor port number)

On VMware, this operation modifies the value of register ebx to 0x564D5868 (the VMware hypervisor magic value).

Sample code

#define VMWARE_HYPERVISOR_MAGIC 0x564D5868 #define VMWARE_HYPERVISOR_PORT  0x5658  #define VMWARE_PORT_CMD_GETVERSION      10  #define VMWARE_PORT(cmd, eax, ebx, ecx, edx)                            \         __asm__("inl (%%dx)" :                                          \                         "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) :    \                         "0"(VMWARE_HYPERVISOR_MAGIC),                   \                         "1"(VMWARE_PORT_CMD_##cmd),                     \                         "2"(VMWARE_HYPERVISOR_PORT), "3"(UINT_MAX) :    \                         "memory");  int hypervisor_port_check(void) {         uint32_t eax, ebx, ecx, edx;         VMWARE_PORT(GETVERSION, eax, ebx, ecx, edx);         if (ebx == VMWARE_HYPERVISOR_MAGIC)                 return 1;               // Success - running under VMware         else                 return 0; } 
Although this port lies outside the x86 ISA space, a physical system might have a device that uses the same port number as VMware's hypervisor port. Accessing the physical device port on such systems might have an undefined effect on that device. To prevent this, test the virtual BIOS information before querying the hypervisor port.

Recommended code

int Detect_VMware(void) {         if (cpuid_check())                 return 1;               // Success running under VMware.         else if (dmi_check() && hypervisor_port_check())                 return 1;         return 0; } 

Additional Information

For translated versions of this article, see: