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的内建函数的查询方式,
因为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