How to detect if my application is running in a virtual machine?

This is what I use:

using (var searcher = new System.Management.ManagementObjectSearcher("Select * from Win32_ComputerSystem"))
{
  using (var items = searcher.Get())
  {
    foreach (var item in items)
    {
      string manufacturer = item["Manufacturer"].ToString().ToLower();
      if ((manufacturer == "microsoft corporation" && item["Model"].ToString().ToUpperInvariant().Contains("VIRTUAL"))
          || manufacturer.Contains("vmware")
          || item["Model"].ToString() == "VirtualBox")
      {
        return true;
      }
    }
  }
}
return false;

Edit 2014-12-02: Updated code so that it no longer detects a Microsoft Surface Pro as a VM. Thanks to Erik Funkenbusch for pointing this out.

Edit 2017-06-29: Updated code so that it also checks the value of the HypervisorPresent property.

Edit 2018-02-05: removed check for the HypervisorPresent property since it's incorrect. This property could return true if running on the host O/S on a hyper-V server.


According to Virtual PC Guy's blog post "Detecting Microsoft virtual machines", you can use WMI to check the manufacturer of the motherboard. In PowerShell:

 (gwmi Win32_BaseBoard).Manufacturer -eq "Microsoft Corporation"

This C function will detect VM Guest OS: (Tested on Windows, compiled with Visual Studio)

#include <intrin.h>

    bool isGuestOSVM()
    {
        unsigned int cpuInfo[4];
        __cpuid((int*)cpuInfo,1);
        return ((cpuInfo[2] >> 31) & 1) == 1;
    }

Jay Abuzi showed the solution in powershell. Here's the same as a c# function:

   /// <summary>
    /// Detect if this OS runs in a virtual machine
    /// 
    /// http://blogs.msdn.com/b/virtual_pc_guy/archive/2005/10/27/484479.aspx
    /// 
    /// Microsoft themselves say you can see that by looking at the motherboard via wmi
    /// </summary>
    /// <returns>false</returns> if it runs on a fysical machine
    public bool DetectVirtualMachine()
    {
        bool result = false;
      const  string  MICROSOFTCORPORATION ="microsoft corporation";
        try
        {
            ManagementObjectSearcher searcher =
                new ManagementObjectSearcher("root\\CIMV2","SELECT * FROM Win32_BaseBoard");

            foreach (ManagementObject queryObj in searcher.Get())
            {
               result =  queryObj["Manufacturer"].ToString().ToLower() == MICROSOFTCORPORATION.ToLower();
            }
            return result;
        }
        catch (ManagementException ex)
        {
            return result;
        }
    }

For Lower level Tests I recommend looking at ScoopyNG [1]. It is a collection of known low-level, well working vm detection methods, albeit being a little dated.

If you really want to rely on other things, like installed tools (VM* Additions) , these are much easier to "fake".

This [2] Blog Post also has a pretty nice overview, from low level asm stuff, checking for specific DLLs, filepaths and registry keys to check.

[1] http://trapkit.de/research/vmm/scoopyng/index.html

[2] http://securitykitten.github.io/vm-checking-and-detecting/