如何识别您在VM下运行?

时间:2008-09-02 13:39:48

标签: virtualization

有没有办法从VM中识别您的代码在VM中运行?

我想有多种或多种简单的方法来识别特定的VM系统,特别是如果VM安装了提供程序的扩展(例如VirtualBox或VMWare)。但有没有一种通用的方法可以确定您没有直接在CPU上运行?

12 个答案:

答案 0 :(得分:20)

许多关于此的研究致力于检测所谓的“蓝色药丸”攻击,即恶意的管理程序,它正在积极地试图逃避检测。

检测VM的经典技巧是填充ITLB,运行必须虚拟化的指令(当它控制管理程序时必须清除此类处理器状态),然后运行一些更多代码来检测ITLB是否仍然填充。关于它的第一篇论文位于here,而researcher's blog和替代Wayback Machine link to the blog article (images broken)的解释相当丰富。

讨论这个问题的最后一点是总有办法检测恶意虚拟机管理程序,并且检测一个不想隐藏的虚拟机管理程序要简单得多。

答案 1 :(得分:11)

Red Hat有一个程序可以检测它运行的虚拟化产品(如果有的话):virt-what

使用第三方维护的工具,这是一个比试图推出自己的检测逻辑更长远的策略:更多的眼睛(针对更多虚拟化产品进行测试)等。

答案 2 :(得分:6)

更经验的方法是检查已知的VM设备驱动程序。您可以编写WMI查询来查找VMware显示适配器,磁盘驱动器,网络适配器等。如果您知道只需要担心环境中已知的VM主机类型,那么这将是合适的。这是an example of doing this in Perl,可以移植到您选择的语言。

答案 3 :(得分:4)

这取决于你的目标:

  • 如果VM没有故意隐藏您,您可以使用一些已知的挂钩。 LIke寻找VmWare驱动程序或在内存中存在某些字符串或某些其他告示标志。

  • 如果VM真的希望你为它做特殊事情,它会有一些明显的钩子,比如修改处理器的ID或添加一些你可以访问的特殊寄存器来检测它。或者是内存中已知位置的特殊设备(假设您可以对您的世界的物理内存空间进行原始访问)。现代机器设计如IBM Power6和Sun UltraSparc T1 / T2的设计始终是运行虚拟机管理程序,而不是直接在原始硬件上运行。操作系统使用的“硬件”接口实际上是虚拟机管理程序软件层的接口,无法绕过它。在这种情况下,检测是微不足道的,因为它是常数“是”。这是可以承担开销的所有计算机系统的未来发展方向,例如,飞思卡尔QorIQ P4080芯片等最新设计中的支持(www.freescale.com/qoriq)。

  • 如果VM故意试图隐藏,并且你正在追逐它的存在,那就是一个猫捉老鼠的游戏,其中VM的时序干扰和不同的性能概况几乎总是会给它远。显然,这取决于VM的实现方式以及架构中有多少硬件支持(我认为zSeries大型机在隐藏特定操作系统下的VM或VM堆栈方面比常规x86更好例如,机器)。有关此主题的一些讨论,请参阅http://jakob.engbloms.se/archives/97。可以尝试隐藏为VM,但如果尝试足够努力,检测很可能总是会赢。

答案 4 :(得分:2)

我曾经遇到一个汇编代码片段,告诉你你是否在虚拟机中....我用Google搜索但找不到原始文章。

我确实找到了这个:Detect if your program is running inside a Virtual Machine

希望它有所帮助。

答案 5 :(得分:1)

在大多数情况下,你不应该尝试。除了少数特定情况外,您不应该关心某人是否在VM中运行您的代码。

如果需要,在Linux中,最常见的方法是查看/sys/devices/virtual/dmi/id/product_name,它将列出大多数实际系统上的笔记本电脑/主板的名称,以及大多数虚拟系统上的虚拟机管理程序。 dmidecode | grep Product是另一种常用方法,但我认为这需要root访问权限。

答案 6 :(得分:1)

这是一种( java + windows )解决方案,用于识别基础计算机是物理计算机还是虚拟计算机。

虚拟机示例:

制造商

  • Xen
  • 微软公司
  • innotek GmbH
  • 红帽
  • VMware,Inc。

模型

  • HVM domU
  • 虚拟机
  • VirtualBox
  • KVM
  • VMware虚拟平台

    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.util.ArrayList;
    import java.util.List;
    
    public abstract class OSUtil {
    
    public static final List<String> readCmdOutput(String command) {
        List<String> result = new ArrayList<>();
    
        try {
            Process p=Runtime.getRuntime().exec("cmd /c " + command);
            p.waitFor();
            BufferedReader reader=new BufferedReader(
                    new InputStreamReader(p.getInputStream())
                    );
            String line;
            while((line = reader.readLine()) != null) {
                if(line != null && !line.trim().isEmpty()) {
                    result.add(line);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    
        return result;
    }
    
    public static final String readCmdOutput(String command, int lineNumber) {
        List<String> result = readCmdOutput(command);
        if(result.size() < lineNumber) {
            return null;
        }
    
        return result.get(lineNumber - 1);
    }
    
    public static final String getBiosSerial() {
        return readCmdOutput("WMIC BIOS GET SERIALNUMBER", 2);
    }
    
    public static final String getHardwareModel() {
        return readCmdOutput("WMIC COMPUTERSYSTEM GET MODEL", 2);
    }
    
    public static final String getHardwareManufacturer() {
        return readCmdOutput("WMIC COMPUTERSYSTEM GET MANUFACTURER", 2);
    }
    
    public static void main(String[] args) {
        System.out.println("BIOS Serial: " + getBiosSerial());
        System.out.println("Hardware Model: " + getHardwareModel());
        System.out.println("Hardware Manufacturer: " + getHardwareManufacturer());
    }
    }
    

您可以使用输出来确定它是VM还是物理机:

物理机输出:

BIOS序列号:2HC3J12
硬件型号:Inspiron灵越7570
硬件制造商:Dell Inc.

虚拟机输出:

BIOS序列号:0
硬件型号:Innotec GmBH
硬件制造商:Virtual Box

答案 7 :(得分:0)

一个很好的例子就是显然是为主板制造商做了一个WMI查询,如果它返回“Microsoft”,你就在VM中。我以为我相信这只适用于VMWare。可能有不同的方法来判断每个VM主机软件。

这篇文章http://blogs.technet.com/jhoward/archive/2005/07/26/407958.aspx有一些很好的建议和链接,可以通过几种方法来检测你是否在虚拟机中(至少是VMWare和VirtualPC)。

答案 8 :(得分:0)

您可以通过查看网络连接的MAC地址来确定您是否在虚拟机中。例如,Xen通常建议使用特定范围的地址00:16:3e:xx:xx:xx。

这不能保证,因为由系统管理员来指定他们喜欢的MAC地址。

答案 9 :(得分:0)

TrapKIT provides ScoopyNG, a tool for VMware identification - 它试图解决逃避技术,但不一定针对VMware以外的任何虚拟化软件。源代码和二进制文件都可用。

答案 10 :(得分:0)

在Linux系统中,您可以尝试在/ proc。

上搜索公共文件

例如,/ proc / vz /的existente告诉你是一个OpenVZ。

Linux下的

Here's a full guide to detect VM's environent无需“喝药”:)

答案 11 :(得分:-1)

如果VM能够很好地完成工作,那么客户端对它进行虚拟化应该是不可见的。但是,人们可以看一下其他线索。

我认为寻找特定于VM环境的已知驱动程序或软件将是最佳方式。

例如,在运行Windows的VMWare客户端上,vmxnet.sys将是网络驱动程序,显示为VMware加速AMD PCNet适配器。