HACK#38 从客户端操作系统识别虚拟机环境
本节介绍识别客户端操作系统在哪个管理程序上运行的方法。
在使用虚拟环境的过程中,有时会需要确认已启动的操作系统在虚拟环境下是如何运行的。有时也会想要识别是在哪个管理程序上运行的。但是,客户端通过操作系统设备仿真实现仿真,基本上没有什么可以判别的信息。本节将介绍用来判别的关键信息和工具。
CPUID命令
CPUID命令是根据输入到EAX寄存器的值,返回CPU识别信息或CPU功能信息的命令。例如,CPU的型号或主频就可以使用CPUID命令来得知。也有一些管理程序使用在Intel和AMD CPU中不使用的值(0x40000000等)来获取管理程序信息。
在客户端操作系统上发布如下CPUID命令,可以得到表5-6所示的返回值。
include<stdio.h>
include<stdint.h>
static void cpuid(uint32_t idx,
uint32_t*a,
uint32_t*b,
uint32_t*c,
uint32_t*d)
{
asm volatile("movl%1,%%eax;cpuid":"=a"(a),"=b"(b),"=c"(c),"=d"(d):"1"(idx));
}
static int check_with_cpuid(void)
{
uint32_t eax, ebx, ecx, edx;
char signature[13];
uint32_t base;
for(base=0x40000000;base<0x4000000f;base+=0x1)
{
eax=0;
ebx=0;
ecx=0;
edx=0;
cpuid(base,&eax,&ebx,&ecx,&edx);
(uint32_t)(signature+0)=ebx;
(uint32_t)(signature+4)=ecx;
(uint32_t)(signature+8)=edx;
signature[12]='\0';
if(ebx!=0||ecx!=0||edx!=0)
printf("%x:signature=%12s eax=%x ebx=%x ecx=%x edx=%x\n",
base, signature, eax, ebx, ecx, edx);
}
return 0;
}
int main(void)
{
return check_with_cpuid();
}
在RHEL5 Xen中还有xen-detect命令同样使用CPUID命令识别Xen的客户端操作系统。但需要注意的是,有一些版本(如旧的VMware等管理程序的版本)不支持对这个CPUID识别方法,因此不能使用这一功能。