可以使用MS提供的x86 内部函数列表(见https://docs.microsoft.com/zh-cn/previous-versions/hh977023(v=vs.120)
)来使用支持跨平台的汇编-
查看是否支持VT技术
(Intel手册第三卷23.6中)
如果通过1号CPUID
指令返回的ECX的第五位为1,则支持VT -
如果CR4的VMXE位为0,则禁用VT,(即BIOS设置中的禁用VT),此时,任何其他位都无法开启VT。
(Intel手册第三卷23.7中)
23.7 开启并且进入VMX操作
1: 在软件进入VMX操作前,它开启VMX通过设置CR4.VMXE[bit13] = 1,然后通过VMXON指令进入
2: 如果执行的时候,CR4.VMXE=0,则会发生UD异常(无效的操作码),一旦进入VMX操作中,就不能清除CR4.VMXE。只有执行VMXON指令离开VMX操作后,才能清除
3: VMXON指令也受IA32_FEATURE_CONTROL_MSR (3AH) 控制,虚拟处理器被重置的时候,这个MSR会被清零
4: Bit0是lock位,如果这个位为0,那么VMXON指令则会发生GP异常,如果这个位是1,对这个MSR进行WRMSR也会造成GP异常,这个MSR不会被修改,直到电源重启
5: 系统BIOS可以使用这个位禁止对VMX的支持,为了开启对VMX的支持,BIOS必须设置Bit1 Bit2,或者这两个都置一
6: Bit1代表在SMX操作下执行VMXON,Bit2代表在SMX操作外执行VMXON,如果这两位是0,那么执行VMXON则会造成都会造成GP异常,在为0的情况下,强制这两个位为1,也会造成GP异常
7: 在执行VMXON之前,软件应该分配一个4KB大小的内存用来支持VMX操作,这个区域被叫做VMXON区域,这个区域的地址就是VMXON指令的操作数
23.8 VMX操作中的限制
1: 在VMX操作下,处理器可以将 CR0 和 CR4 中的某些位固定到特定的值, 而不支持其他的值。如果这些位中包含了不受支持的值,则VMXON失败 (看Chapter 30)
2: 在VMX操作下,任何设置这些位到不受支持的值,都会造成GP异常,比如CLTS, LMSW, MOV CR指令
3: 软件应该通过IA32_VMX_CR0_FIXED0和1 以及IA32_VMX_CR4_FIXD0和4来查询可以设置哪些只 (看附录A.7)
4: 支持 VMX 操作的第一个处理器要求以下位在 VMX 操作中为 1: CR0.PE CR0.NE CR0.PG CR4.VMXE
5: 对CR0.PE和CR0.PG的限制,主要代表了VMX操作只能在分页保护模式下进行(保护IA3-2e),因此客户机不能允许在非分页保护模式或者实地址模式下
6: 如果虚拟处理器在A20M模式下,VMXON也会失败。如果处理器在VMX操作下,A20中断将会被阻塞,因此,不可能既在A20M模式下,又在VMX模式下
7: 无论什么时候,VMX-ROOT操作都会阻塞INIT信号,只有在VMX-NON-ROOT操作下才不会被阻塞,而且INIT还会造成VM-EXIT
23.2 虚拟机架构
1: VMX为处理器上的虚拟机定义了处理器级的支持。VMX主要支持两类,VMM和VM
2: VMM作为HOST可以完全控制处理器和其他平台硬件。 每个VM都支持一个栈,并且由OS和普通程序组成
23.3 VMX操作的介绍
1: 处理器虚拟化是由VMX操作提供的,主要有两类VMX操作,VMX-ROOT操作和VMX-NON-ROOT操作,通常VMM运行在VMX-ROOT操作,VM运行在VMX-NON-ROOT操作
2: VMX-ROOT操作下与VMX操作外有很大不同,主要是在VMX-ROOT操作下,一组新的指令:VMX指令是有效的,并且可以加载进特定的控制器中
3: VMX-NON-ROOT模式下处理器行为受了限制,而且某些行为与原来的不同。因为特定的指令和事件会造成VM-EXIT,而且VM-EXIT替换了原来的行为
4: 并没有软件标志位标识逻辑处理器是否运行在VMX-NON-ROOT模式下,因此这种情况下VMM可以不让客户机软件知道它运行在虚拟机中
5: 因为VMM运行在R0上,客户机软件在原始特权级上运行,所以这有助于VMM的开发
23.4 VMM软件的生命周期
1: 软件通过VMXON指令进入VMX操作
2: 使用VMLAUNCH和VMRESUME指令,VMM可以进入到客户机 中,使用VM-EXIT恢复
3: VM-EXIT会转移到VMM指定的入口
4: VMM可以通过执行VMXOFF指令关闭它自己
总结:
1: 本章所说的VMX操作模式是指VMX-ROOT和VMX-NON-ROOT模式下
2: Bios中的MSR.3A[Bit0]为0,CPUID.ECX:VMX[Bit5]为0, CR4.VMXE[Bit13]为0,都会造成VMXON失败,如果这三个条件都通过,VMXON仍然失败,此时就去Chapter30 查看VMXON指令的伪码
几个结构体的定义
#define MSR_IA32_FEATURE_CONTROL 0x3A
typedef struct _IA32_FEATURE_CONTROL_MSR
{
unsigned Lock : 1; // Bit 0 is the lock bit - cannotbe modified once lock is set
unsigned Reserved1 : 1; //Undefined
unsigned EnableVmxon : 1; // Bit 2. Ifthis bit is clear, VMXON causes a general protection exception
unsigned Reserved2 : 29; //Undefined
unsigned Reserved3 : 32; //Undefined
} IA32_FEATURE_CONTROL_MSR;
typedef struct
{
unsigned PE : 1;
unsigned MP : 1;
unsigned EM : 1;
unsigned TS : 1;
unsigned ET : 1;
unsigned NE : 1;
unsigned Reserved_1 : 10;
unsigned WP : 1;
unsigned Reserved_2 : 1;
unsigned AM : 1;
unsigned Reserved_3 : 10;
unsigned NW : 1;
unsigned CD : 1;
unsigned PG : 1;
//unsigned Reserved_64:32;
}_CR0;
typedef struct {
unsigned VME : 1;
unsigned PVI : 1;
unsigned TSD : 1;
unsigned DE : 1;
unsigned PSE : 1;
unsigned PAE : 1;
unsigned MCE : 1;
unsigned PGE : 1;
unsigned PCE : 1;
unsigned OSFXSR : 1;
unsigned PSXMMEXCPT : 1;
unsigned UNKONOWN_1 : 1; //These are zero
unsigned UNKONOWN_2 : 1; //These are zero
unsigned VMXE : 1; //It's zero in normal
unsigned Reserved : 18; //These are zero
//unsigned Reserved_64:32;
}_CR4;
核心检测代码
IA32_FEATURE_CONTROL_MSR msr=0;
_CR0 cr0;
_CR4 cr4;
VOID Log(PCHAR msg) {
DbgPrint(msg);
}
BOOLEAN IsVTEnabled() {
//CPUID
int res[4];
__cpuid(res, 1); //EAX、EBX、ECX and EDX
if (!(res[3] & 0x10)) { //5bit
Log("ERROR: This machine doesn't support VT!");
return FALSE;
}
//MSR
*((PULONG)&msr) = __readmsr(MSR_IA32_FEATURE_CONTROL);
if (msr.Lock != 1) {
Log("ERROR: VT IS disabled");
return FALSE;
}
//CR0 CR4
*((PULONG)&cr0) = __readcr0();
*((PULONG)&cr4) = __readcr4();
if (cr0.PE != 1 || cr0.PG != 1 || cr0.NE != 1) {
Log("ERROR: THIS CPU doesn't enable VT with cr0!");
return FALSE;
}
if (cr4.VMXE == 1) {
Log("ERROR: This CPU has enable VT but it is occupied by other driver!");
return FALSE;
}
Log("SUCCESS: This CPU support VT!");
return TRUE;
}