1.检测CPU是否支持VT

1.CPUID指令检测

在进入VMX Opreation之前必须要检测CPU是否支持VMX技术,可以通过CPUID指令进行查询,在执行CPUID指令之后,返回值存入EAX,EBX,ECX,EDX中,查看ECX.VMX[5]位是否为1,否则不支持VMX技术,关于CPUID指令的介绍可以参考Intel白皮书卷二第三章第三节 Instruction-CPUID Identification详细介绍了CPUID的参数

简单概述一下CPUID的常用参数

1.输入代码为0x0时

收到的结果用来获取厂商标识字符串信息

2.输入代码为0x1时

当输入参数为01H时,在返回值EAX寄存器中就可以获得处理器的 DisplayFamily_DisplayModel,DisplayFamily_DisplayModel 信息通常用以识别特定的处理器。

第六位不为1时,说明该cpu支持VT技术

执行cpuid指令之后会更改eax,ebx,ecx,edx寄存器的值

3.输入代码为0x80000002

当输入参数为0x80000002H,0x80000003H,0x80000004H时用来获取处理器品牌字符串

4.输入参数为0x80000008H

当输入参数为0x80000008H时,获取物理地址大小信息和虚拟地址信息大小。

2.代码实现(执行CPUID不需要Ring0)

放一个Visual Studio的内建函数的查询方式,

https://learn.microsoft.com/zh-cn/cpp/intrinsics/cpuid-cpuidex?view=msvc-170

因为Visual Studio x64不支持内嵌汇编

mov eax,1
cpuid

执行上述指令之后查看ECX第五位[从0开始数]是否被置1,如果为1表示支持该VT

代码方式实现

BOOLEAN Check_CPUID() {
	int Ecx[4];
	__cpuid(Ecx,1);
	return (Ecx[2] >> 5) & 1;	//Ecx 第六位是否为1
}

2.MSR寄存器检测(需要Ring0权限)

VMXON由IA32_FEATURE_CONTROL控制,查询MSR(0x3a) IA32_FEATURE_CONTROL MSR字段

  • 第0位为锁:如果该位被清零,VMXON进入保护异常,无法使用VMXON进入VMX Opreation 需要在BIOS中修改并打开VT

当进入VMX Opreation时需要分配一个自然对齐的4KB内存来控制VMX,这个区域被称为VMXON 区域(VMX Region)

BOOLEAN Check_MSR() {
	__int64 VMX_Control_feild = __readmsr(MSR_IA32_FEATURE_CONTROL);
	return (VMX_Control_feild % 2);
}

取余2用于验证奇偶数,奇树的第零位自然会为1,C语言中非0为True

3.CR寄存器检测

1.CR寄存器介绍

CR0:控制处理器操作模式和状态的系统控制标志

CR1:保留不用

CR2:含有导致页错误的線性位址

CR3:含有页目录表物理内存基地址,因此该寄存器也被称为页目录基地址寄存器PDBR

CR4:它介绍在计算机处理器中负责控制各种功能,可以控制访问特权级、保护模式等

详情可以移步该文章:https://blog.csdn.net/qq_37414405/article/details/84487591

x86_32的CR为32bit。X86_64下为64bit,其中低32bit与x86_32的CR保持一致,高32bit没有定义,作保留使用,除了bit 4其他所有位都是可读可写的。

2.CR0检测

CR0寄存器需要满足PG位、PE位、NE位等于1,也就是说需要开启分页机制的保护模式,X87 FPU数字异常的处理模式需要使用native模式

3.CR4检测

在进入VMX Opreation之前,通过设置CR4来启用VMX,然后可以执行VMXON指令,在进入VMXON之后,该位不可变动,直到执行VMXOFF退出VMX Opreation。Cr4.VMXE[bit:13]该位负责上述控制

写成代码

BOOLEAN VT_Enable() {
	_CR0* cr0 = (_CR0*)__readcr0();
	_CR4* cr4 = (_CR4*)__readcr4();
	if (cr0->PE==1 &&cr0->NE==1&&cr0->PG == 1)
	{
		if (cr4->VMXE==1)  //VMX Lock
		{
			return TRUE;
		}
	}
	return FALSE;
}

代码会上传到Github

https://github.com/yifaang/VTDemo