【问题标题】:Determine when running in a virtual machine确定何时在虚拟机中运行
【发布时间】:2010-10-21 06:03:15
【问题描述】:

是否有一种官方方法可以让应用程序确定它是在 VMWare 还是 Virtual PC(或 Microsoft 现在所称的任何东西)中运行?我看到的代码通常是利用特定版本的 VMWare 或 Virtual PC 中一些奇怪的行为副作用的 hack。

理想的 Delphi 代码,但如果你可以链接到官方解释,那么我相信我可以转换它。

【问题讨论】:

  • 只是好奇知道您在 VM 上的用例是什么?我一直认为 VM 的主要好处之一是(理想情况下)您不需要知道您是否使用物理硬件。
  • 真的很好奇。一位同事问,我记得读过它,但不确定最好的方法。尽管出于安全原因,我可以看到想要限制您的应用程序在 VM 中运行,但这对您的用户来说真的很烦人。我知道 Virtual PC 不会让你在 VMWare 中运行(至少在我尝试过时)。

标签: delphi vmware virtualization virtualbox virtual-pc


【解决方案1】:

我去年写了一系列关于此的文章,并附有源代码。 VMware 和 Wine 检测是here。虚拟 PC 是here。所有这三个都具有相当铁定的检测,因为记录了对管理程序的回调(在 Wine 的情况下,是标准 DLL 的扩展)。我在评论部分放置了一个未经测试的 VirtualBox 检测器(没有安装它来测试)。 Parallels 也可以使用回调检测到,但我没有安装它。文档的链接(由于它来自专注于漏洞利用的安全研究人员,因此很差),但如果您已安装并感兴趣,则位于 here。还有一个PPThere,里面有一些关于检测Sandbox、Bochs和Xen的信息。里面的代码不多,但如果你必须检测这些代码,它可能会给你一个起点。

【讨论】:

  • 这些是我记得读过的关于它的文章。谢谢!代码甚至在 Delphi 中。
  • 应该注意的是,它没有使用一些官方记录的方案来检测VirtualPC的存在。它使用的指令在真实硬件上应该是无效的,VPC 用于与外部通信。并不是说这些指令在未来不能改变,或者英特尔不能发布一个 CPU 来使用那些“未使用”的指令。
【解决方案2】:

代码项目展示了一种通往Detect if your program is running inside a Virtual Machine 的方法,其中详细介绍了如何完成它以提供良好的理解

【讨论】:

  • 我之前看过那个链接,但是因为它已经有 4 年历史了,并且没有真正找到任何来源,所以我不确定它是否仍然有效。从那时起,虚拟化软件发生了很大变化。
  • 它已经发生了很大变化,但是该示例检查了管理程序用于中断的寄存器,并且作为一个了解有关管理程序的一些信息的人,这部分仍然没有改变
  • 好的,我将在最新的虚拟机上测试这些。谢谢!
  • 这些测试适用于最新版本的 VMWare Workstation 5。我不使用 VPC。
【解决方案3】:

我认为最好的方法是检查硬件配置文件。虚拟化硬件通常使用公司名称的一部分。如果您在 Virtual PC 中查看主板说明,您会发现它是由“Microsoft Corporation”制造的。同样在 VMWare 中,您的以太网适配器将以 VMNet 为前缀。

【讨论】:

    【解决方案4】:

    This thread 在 SysInternals 论坛上有几个答案(当然是在 Delphi 中),包括一个 IsVM 函数。我已经在 VMWare 中的 XP 和 Vista 上托管的 XP 和 Win2003 上进行了测试,结果很好。

    【讨论】:

      【解决方案5】:

      这里发布了一个 WMI 方式: http://blogs.msdn.com/virtual_pc_guy/archive/2005/10/27/484479.aspx

      我已经检查了在 Virtual PC 上运行的 XP 映像,他们测试的值仍然相同。不过,我不能保证其他虚拟机会在这里返回什么...

      我实际上有一个我几年前编写的 Delphi 程序,用于获取列表并使用 WMI 更改默认打印机,而不需要 3rd 方组件或类似的任何东西。如果您不习惯使用 Delphi 的 WMI,我可以向您发送一份副本,以便您有一些工作要做(虽然它不一定与 Unicode 兼容,但升级它对我来说应该不会太难如果需要)。

      【讨论】:

      • 还有virtualbox,VMWare等等。
      • 正确,如果您还想检查这些,这就是一切都变得有点不确定的地方 - 您需要查看这些其他 VM 提供的硬件信息,看看您可以在那里寻找什么特殊值.但是,该问题要求 VPC,并且该代码会处理它。我认为无论 VM 是什么,WMI 都是获取所需信息的统一方式的最佳选择,因为您需要更改的只是您正在检查的查询和字段名称。
      【解决方案6】:

      我使用了RedPill 方法(翻译为Delphi,但代码并不难理解),效果很好。我还使用 WMI 调用进行了一些额外的检查,以获取网络适配器供应商名称和版权等信息,但这是为了检测特定版本的 Virtual PC。

      我对 RedPill 方法的理解是,它应该工作并根据其工作方式的性质检测所有虚拟机。也有可能产生误报,因为 Windows 7 的 Windows 中的新 Windows 功能可以配置为在 Windows 7 中无缝运行 Windows XP 副本中的选定程序。

      【讨论】:

      【解决方案7】:

      我很幸运只查看了 MAC 地址,因为所有制造商都被分配了一个块,并且前 3 个部分对他们来说是独一无二的。

      //look at the MAC address and determine if it's a Virtual Machine
      $temp = preg_split("/\s+/",exec("/sbin/ifconfig -a eth0 2>&1 | /bin/grep HWaddr"), -1, PREG_SPLIT_NO_EMPTY);
      //Virtual Box MACs all start with '08:00:27:xx:xx:xx'
      if (strpos($temp[4], '08:00:27') !== false) $_SESSION['DEVELOPMENT'] = true;  
      

      【讨论】:

      • 另外请记住,大多数虚拟化软件都允许您将 MAC 地址修改为您想要的任何内容。因此,这种技术并不可靠。
      【解决方案8】:

      判断机器是物理机还是虚拟机

      dmidecode | egrep -i 'manufacturer|product'
      

      如果找不到 dmidecode 命令,请安装相应的 rpm。

      这是在 EXSI、VMWARE 和 hyperv 机器下测试的。

      【讨论】:

        【解决方案9】:

        如果您想普遍检测是否存在任何类型的虚拟化,最好分析性能特征。采用在虚拟化中速度明显较慢的东西(例如 MMU 繁重的工作负载,如分叉炸弹),并将其与正常的 CPU 绑定用户空间应用程序进行比较。从比例上你可以很容易地看出。

        如果您只关心某些 VMM,最简单的工作就是寻找它们的硬件 - 即 VMware PCI 设备:

        00:07.3 桥接器:英特尔公司 82371AB/EB/MB PIIX4 ACPI(修订版 08) 子系统:VMware Inc 虚拟机芯片组

        15ad:1976

        供应商值为'15ad'

        还有一些特定的后门端口可以跨不同版本的各种 VMM 工作。 SIDT 技巧也不错,但如果 VMM 不在其代码正在检查的列表中怎么办?

        【讨论】:

          【解决方案10】:
          dmidecode -s system-product-name
          

          在 VirtualBox 上测试,结果:

          Virtualbox
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-12-26
            • 2013-06-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-10-17
            • 2019-11-05
            相关资源
            最近更新 更多