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();

}


HACK#38 从客户端操作系统识别虚拟机环境 - 图1

在RHEL5 Xen中还有xen-detect命令同样使用CPUID命令识别Xen的客户端操作系统。但需要注意的是,有一些版本(如旧的VMware等管理程序的版本)不支持对这个CPUID识别方法,因此不能使用这一功能。