我需要检测我的应用程序是否在虚拟化OS实例中运行.
我发现了一篇文章,其中包含有关该主题的一些有用信息.同一篇文章出现在多个地方,我不确定原始来源.VMware实现了一个特定的无效x86指令来返回有关自身的信息,而VirtualPC使用幻数和带有IN指令的I/O端口.
这是可行的,但在两种情况下似乎都是无证件行为.我想VMWare或VirtualPC的未来版本可能会改变机制.有没有更好的办法?这两种产品都有支持的机制吗?
同样,有没有办法检测Xen或VirtualBox?
我并不担心平台故意试图隐藏自己的情况.例如,蜜罐使用虚拟化,但有时会掩盖恶意软件用来检测它的机制.我并不在乎我的应用程序会认为它在这些蜜罐中没有虚拟化,我只是在寻找"尽力而为"的解决方案.
该应用程序主要是Java,但我希望在这个特定的功能中使用本机代码和JNI.Windows XP/Vista支持是最重要的,尽管参考文章中描述的机制是x86的通用功能,并且不依赖于任何特定的OS工具.
你听说过蓝色药丸,红色药丸吗?.这是一种用于查看您是否在虚拟机内运行的技术.该术语的起源源于矩阵电影,其中Neo被提供蓝色或红色药丸(留在矩阵内=蓝色,或进入'真实'世界=红色).
以下是一些代码,可以检测到你在"矩阵"内部运行的是什么:(
从这个站点借来的代码,其中也包含一些关于手头主题的很好的信息):
int swallow_redpill () { unsigned char m[2+4], rpill[] = "\x0f\x01\x0d\x00\x00\x00\x00\xc3"; *((unsigned*)&rpill[3]) = (unsigned)m; ((void(*)())&rpill)(); return (m[5]>0xd0) ? 1 : 0; }
当你在虚拟机器内运行时,该函数将返回1,否则返回0.
在Linux下我使用了命令:dmidecode(我在CentOS和Ubuntu都有它)
来自男人:
dmidecode是一种以人类可读的格式转储计算机的DMI(某些说SMBIOS)表内容的工具.
所以我搜索了输出,发现它可能是Microsoft Hyper-V
Handle 0x0001, DMI type 1, 25 bytes System Information Manufacturer: Microsoft Corporation Product Name: Virtual Machine Version: 5.0 Serial Number: some-strings UUID: some-strings Wake-up Type: Power Switch Handle 0x0002, DMI type 2, 8 bytes Base Board Information Manufacturer: Microsoft Corporation Product Name: Virtual Machine Version: 5.0 Serial Number: some-strings
另一种方法是搜索eth0的MAC地址与哪个制造商相关:http://www.coffer.com/mac_find/
如果它返回微软,vmware等等,那么它可能是一个虚拟服务器.
不可以.完全准确无法检测到.某些虚拟化系统(如QEMU)将整个机器模拟到硬件寄存器.让我们来看看:你想做什么?也许我们可以帮忙.
VMware有一个机制来确定软件是否在VMware虚拟机知识库文章中运行,该文章包含一些源代码.
Microsoft还有一个"确定是否安装了管理程序"的页面.MS在他们的"服务器虚拟化验证测试"文档的" IsVM TEST"部分中阐述了虚拟机管理程序的这一要求
VMware和MS文档都提到使用CPUID指令检查虚拟机管理程序存在位(寄存器ECX的第31位)
RHEL bugtracker有一个"应该为CPUID叶片0x00000001设置ISVM位(ECX:31)"来设置Xen内核下的寄存器ECX的第31位.
因此,如果没有进入供应商细节,看起来您可以使用CPUID检查来了解您是否正在运行.
我认为,继续前进,依靠像破坏的SIDT虚拟化这样的技巧并没有真正帮助,因为硬件插入了奇怪和凌乱的x86架构所留下的所有漏洞.最好的方法是游说Vm提供商以标准方式告诉您在虚拟机上 - 至少在用户明确允许的情况下.但是,如果我们假设我们明确允许检测VM,我们也可以将可见标记放在那里,对吗?我建议只更新VM上的磁盘,并提供一个文件,告诉您自己在VM上 - 例如,文件系统根目录中的一个小文本文件.或者检查ETH0的MAC,并将其设置为给定的已知字符串.
在virtualbox上,假设您可以控制VM guest虚拟机并且有dmidecode,则可以使用以下命令:
dmidecode -s bios-version
它会回来的
VirtualBox
我想推荐一篇发表在Usenix HotOS '07上的论文,Comptibility is Not Transparency:VMM Detection Myths and Realities,它总结了几种技术来判断应用程序是否在虚拟化环境中运行.
例如,使用sidt指令作为redpill(但是这条指令也可以通过动态转换使其透明),或者将cpuid的运行时与其他非虚拟化指令进行比较.
在Linux下,您可以报告/ proc/cpuinfo.如果它在VMware中,它通常与裸机上的不同,但并非总是如此.Virtuozzo显示了底层硬件的传递.
尝试读取SMBIOS结构,尤其是带有BIOS信息的结构。
在Linux中,您可以使用dmidecode实用程序来浏览信息。
在安装新手Ubuntu时,我发现了名为imvirt的软件包.请访问http://micky.ibh.net/~liske/imvirt.html查看
此C函数将检测VM Guest OS:
(在Windows上测试,使用Visual Studio编译)
#includebool isGuestOSVM() { unsigned int cpuInfo[4]; __cpuid((int*)cpuInfo,1); return ((cpuInfo[2] >> 31) & 1) == 1; }