Knowledge Base

The VMware Knowledge Base provides support solutions, error messages and troubleshooting guides
 
Search the VMware Knowledge Base (KB)   View by Article ID
 

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

Details

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

Solution

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;
}

 

Tags

deploy-virtual-application  deploy-virtual-application-fails  how-to  invalid-virtual  software-issue  start-virtual-application-fails  third-party-software  virtual-application  virtual-application-isolation

Request a Product Feature

To request a new product feature or to provide feedback on a VMware product, please visit the Request a Product Feature page.

Feedback

  • 17 Ratings

Did this article help you?
This article resolved my issue.
This article did not resolve my issue.
This article helped but additional information was required to resolve my issue.
What can we do to improve this information? (4000 or fewer characters)
  • 17 Ratings
Actions
KB: