VT 是先开为大,谁先开谁上层,谁上层 谁权限大。
intel 白皮书 第3卷
传入 参数eax =1, 返回值 ecx 的第5位 = 1 则 surpported VMX。
使用 x32dbg 测试:
测试结果: 支持!
即:
Cr4.[13] =1 ;不然会产生一个 非法代码异常
这个相当于一把锁,软件可操作:使用VT过程中 这个不能改动,默认一般没开,需要手动开开启;待VT结束,就可以将此位 置为0。
MSR 3Ah 的 0,1,2 位 必须 是1 ;否则会产生保护异常。
第0 位 如果被请0 则表示 在BIOS 中被禁用。而且 只能在开机的时候修改,在关机复位之前都不能修改。
所以 CR0.[PE]、 CR0.[PG] 必须为 1; 标识着处于页保护模式,VMX 在此模式中支持。
后面添加的特殊寄存器 都是MSR; 不同 CPU 对应不同数目的MSR。
要用的时候去查就行了
DriverEntry.c:
#include "stdafx.h"EXTERN_C void Asm_xx();EXTERN_C BOOLEAN IsVTEnabled();VOID DriverUnLoad(PDRIVER_OBJECT driver){ __asm { int 3; } DbgPrint("Driver is unloading...r\n");}NTSTATUS DriverEntry( PDRIVER_OBJECT driver , PUNICODE_STRING RegistryPath){ IsVTEnabled(); // 这个 函数检测 是否 开启并支持 VMX; DbgPrint("Driver Entered!\r\n"); driver->DriverUnload = DriverUnLoad; return STATUS_SUCCESS;}Check.cpp
#include "stdafx.h"BOOLEAN IsVTEnabled(){ ULONG uRet_EAX, uRet_RCX,uRet_EDX,uRet_EBX; _CPUID_ECX uCPUID; _CR0 uCr0; _CR4 uCr4; IA32_FEATURE_CONTROL_MSR msr; // 1. check CPUID .[5] VMXON is enabled? Asm_CPUID(1,&uRet_EAX,&uRet_EBX,&uRet_RCX,&uRet_EDX); // eax-->1 ; cpuid; check retRegValues; *((PULONG)&uCPUID) = uRet_RCX; if(uCPUID.VMX !=1) { Log("ERROR:当前 CPU 不支持VT",0); return FALSE; } // 2. check MSR 3ah *((PULONG)&msr) = (ULONG) Asm_ReadMsr(MSR_IA32_FEATURE_CONTROL);// 0x3ah if(msr.Lock!=1) { Log("ERROR:VT 指令未被锁定",0); return FALSE; } // 3. check CR0\CR4 *((PULONG)&uCr0) = Asm_GetCr0(); *((PULONG)&uCr4) = Asm_GetCr4(); if(uCr0.PE!=1 || uCr0.PG!=1 || uCr0.NE!=1) { Log("ERROR:这个CPU 所处的环境不是页保护模式",0); return FALSE; } if(uCr4.VMXE ==1) { Log("ERROR:这个CPU 已经开启了VT,可能有别的驱动占用;请检查关闭再试!",0); return FALSE; } else { // 这里 可以手动开启;也可以后面封装函数开启; } Log("Checked, the Env is Prepared!",0); return TRUE;}// 还有一些使用汇编封装的函数; 这里篇幅限制就不贴了。
感谢 周壑老师的讲解
