.net 如何检测我的应用程序是否在虚拟机中运行?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/498371/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 11:07:52  来源:igfitidea点击:

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

.netwinapivirtualization

提问by Jason

How can I detect (.NET or Win32) if my application is running in a virtual machine?

如何检测(.NET 或 Win32)我的应用程序是否在虚拟机中运行?

采纳答案by Jay Bazuzi

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:

根据Virtual PC Guy的博客文章“检测微软虚拟机”,可以使用 WMI 来检查主板的制造商。在 PowerShell 中:

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

回答by RobSiklos

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.

编辑 2014-12-02:更新代码,使其不再将 Microsoft Surface Pro 检测为 VM。感谢 Erik Funkenbusch 指出这一点。

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

编辑 2017-06-29:更新了代码,以便它还检查HypervisorPresent属性的值。

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

编辑 2018-02-05:删除了对该HypervisorPresent属性的检查,因为它不正确。如果在 Hyper-V 服务器上的主机 O/S 上运行,则此属性可能返回 true。

回答by Arthur Chaparyan

Here is an example of one way to do it. It only works with Microsoft's Virtual PC and VMWare, but it's a start: http://www.codeproject.com/KB/system/VmDetect.aspx

这是一种方法的示例。它仅适用于 Microsoft 的 Virtual PC 和 VMWare,但这是一个开始:http: //www.codeproject.com/KB/system/VmDetect.aspx

回答by user2242746

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

此 C 函数将检测 VM 来宾操作系统:(在 Windows 上测试,使用 Visual Studio 编译)

#include <intrin.h>

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

回答by real_yggdrasil

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

Jay Abuzi 在 powershell 中展示了解决方案。这里与 ac# 函数相同:

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

回答by Koorosh Ghorbani

this C++ code will detect Vmware Products such as express,esx,fusion or workstation

此 C++ 代码将检测 Vmware 产品,例如 express、esx、fusion 或工作站

// VMWareDetector.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include <conio.h>
void CheckVM(void); 
int main()
{
    CheckVM(); 
    _getch(); 
    return 0;
}

void CheckVM(void)
{
    unsigned int    a, b;

    __try {
        __asm {

            // save register values on the stack
            push eax
            push ebx
            push ecx
            push edx

            // perform fingerprint
            mov eax, 'VMXh' // VMware magic value (0x564D5868)
            mov ecx, 0Ah // special version cmd (0x0a)
            mov dx, 'VX' // special VMware I/O port (0x5658)

            in eax, dx // special I/O cmd

            mov a, ebx // data 
            mov b, ecx // data (eax gets also modified
                       // but will not be evaluated)

                       // restore register values from the stack
                       pop edx
                       pop ecx
                       pop ebx
                       pop eax
        }
    }
    __except (EXCEPTION_EXECUTE_HANDLER) {}
    printf("\n[+] Debug : [ a=%x ; b=%d ]\n\n", a, b);
    if (a == 'VMXh') { // is the value equal to the VMware magic value?
        printf("Result  : VMware detected\nVersion : ");
        if (b == 1)
            printf("Express\n\n");
        else if (b == 2)
            printf("ESX\n\n");
        else if (b == 3)
            printf("GSX\n\n");
        else if (b == 4)
            printf("Workstation\n\n");
        else
            printf("unknown version\n\n");
    }
    else
        printf("Result  : Not Detected\n\n");
}

回答by user815809

public static bool isVirtualMachine()
{
    const string MICROSOFTCORPORATION = "microsoft corporation";
    const string VMWARE = "vmware"; 

    foreach (var item in new ManagementObjectSearcher("Select * from Win32_ComputerSystem").Get())
    {
        string manufacturer = item["Manufacturer"].ToString().ToLower();
        // Check the Manufacturer (eg: vmware, inc)
        if (manufacturer.Contains(MICROSOFTCORPORATION) || manufacturer.Contains(VMWARE))  
        {
            return true;
        }

        // Also, check the model (eg: VMware Virtual Platform)
        if (item["Model"] != null)
        {
            string model = item["Model"].ToString().ToLower();
            if (model.Contains(MICROSOFTCORPORATION) || model.Contains(VMWARE)) 
            {
                return true;
            }
        }
    }
    return false;
}

回答by Badmaster

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.

对于较低级别的测试,我建议查看 ScoopyNG [1]。它是已知的低级、运行良好的 vm 检测方法的集合,尽管有点过时。

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

如果您真的想依赖其他东西,例如已安装的工具 (VM* Additions),则这些东西更容易“伪造”。

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.

这个 [2] 博客文章也有一个很好的概述,从低级 asm 的东西,检查特定的 DLL、文件路径和注册表项来检查。

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

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

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

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

回答by sOltan

The easiest way I found to figure out whether my C# app is running on a vmware VM or not is to check the MAC address of the NIC card(s). If it's a VMware VM it would always be: 00:50:56:XX:YY:ZZ

我发现确定我的 C# 应用程序是否在 vmware VM 上运行的最简单方法是检查 NIC 卡的 MAC 地址。如果是 VMware VM,则始终为:00:50:56:XX:YY:ZZ

You may enumerate through the NICs as resolved here.

您可以通过此处解决的 NIC 进行枚举