检测CPU是否具备VT的功能,并开启
1.cpuid 指令:
EFLAGS寄存器中的ID标志(位21)表示对CPUID指令的支持。如果一个软件程序可以设置和清除这个标志,那么执行该程序的处理器支持CPUID指令。这条指令在非64位模式和64位模式下操作相同。
CPUID在EAX、EBX、ECX和EDX寄存器中返回处理器识别和特征信息。
__cpuid 函数在 #include <intrin.h>
intel提供了非常方便的头文件
传入数组,功能号为1
就能得到相关的信息,我们这里只关注返回后,ecx的第5个位,这里为了简单就做了下与操作。(后面如果有深入VT的额外课程,会使用其他功能号的位,intel手册上cpuid指令有祥细的说明,可将这些定义为结构体,注释起来方便使用,一劳永逸)
返回值是真就代表支持VMX.
2.__rdmsr 指令 -- 从特定型号寄存器读取
cpu 有很多特殊寄存器 统称为MSR
MSR_IA32_FEATURE_CONTROL -- 地址是0x3A.(手册上第四卷有祥细的说明)
指令同样也在intel提供的头文件里。
第0位说明:
锁定位(R/WO):(1 = 锁定)。设置后,锁定此 MSR 不被写入;写入此位将导致GP(0)。
注意:一旦设置了锁定位,就无法修改此寄存器的内容。
因此,在配置对英特尔虚拟化技术的支持之后,以及在将控制权转移到选项 ROM 或操作系统之前,必须设置锁定位。因此,一旦设置了锁定位,当 PWRGOOD 未取消断言时,整个IA32_FEATURE_CONTROL内容将在整个 RESET 中保留。
结构体我已经定义好了(一劳永逸)。我们这里要检查锁定位是否为0,为0的话VMXON会失败,这个地方可在BIOS设置开启,大家型号可能不一样,网上查一下自己的bios怎么开启叭~。
返回值是真表示可以开启VMX。
设置CR4:
在系统软件可以进入 VMX 操作之前,它通过设置 CR4 启用 VMX。VMXE[位 13] = 1。然后通过执行 VMXON 指令进入 VMX 操作。如果未开启此位,VMXON 会导致无效操作码异常(#UD)。一旦进入 VMX 操作,就无法清除 CR4.VMXE(请参见第 23.8 节)。系统软件通过执行 VMXOFF 指令离开 VMX 操作。执行 VMXOFF 后,可以在 VMX 操作之外清除 VMXE。
这一步只是检查VMXE是否已经开启,未对它进行设置,如果未开启的话,就由我们来开启。
下面修正CR4,CR0设置会开启VMXE。
修正CR0,CR4:
VMX 操作对处理器操作施加了限制。具体如下:
* 在 VMX 操作中,处理器可能会将 CR0 和 CR4 中的某些位固定为特定值,而不支持其他值。如果这些位中的任何一个包含不受支持的值,则 VMXON 将失败(请参见第 30 章中的“VMXON-Enter VMX 操作”)。在 VMX 操作(包括 VMX 根操作)中使用任何 CLTS、LMSW 或 MOV CR 指令时,尝试将这些位之一设置为不受支持的值会导致常规保护异常。VM Entry或 VM Exit无法将这些位中的任何一个设置为不受支持的值。软件应参考 VMX 功能 MSR IA32_VMX_CR0_FIXED0和IA32_VMX_CR0_FIXED1,以确定如何修复 CR0 中的位(请参阅附录 A.7)。对于 CR4,软件应参考 VMX 功能 MSR IA32_VMX_CR4_FIXED0和IA32_VMX_CR4_FIXED1(请参阅附录 A.8)。
IA32_VMX_CR0_FIXED0MSR(索引 486H)和 IA32_VMX_CR0_FIXED1 MSR(索引487H)指示如何在 VMX 操作中设置 CR0 中的位。它们报告 CR0 中允许在 VMX 操作中分别为 0 和 1 的位。如果位 X 在IA32_VMX_CR0_FIXED0中为 1,则CR0 的位在 VMX 操作中固定为 1。同样,如果位 X 在 IA32_VMX_CR0_FIXED1 中为0,则 CR0 位在 VMX 操作中固定为 0。总是这样,如果位 X 是 1 IA32_VMX_CR0_FIXED0,那么该位也是 1 IA32_VMX_CR0_FIXED1;如果位 X 在IA32_VMX_CR0_FIXED1中为 0,则该位在IA32_VMX_CR0_FIXED0中也是 0。因此,CR0 中的每个位要么固定为 0(两个 MSR 中的值均为 0),要么固定为 1(两个 MSR 中的值均为 1),要么灵活(IA32_VMX_CR0_FIXED0 为 0,IA32_VMX_CR0_FIXED1中为 1)。
How to 理解?
也就是说 CR0_FIXED0 中的任意一位是1,CR0的该位就必须是1,CR0_FIXED1 中的任意一位是0,CR0的该位就必须是0
不关心CR0_FIXED0 中的0值的位,不关心CR0_FIXED1 中的1值的位。
组合起来就是以下:
CR0_FIXED0=486H,CR0_FIXED1=487H。
CR4也同样需要一份这样的代码,CR4_FIXED0=488H,CR4_FIXED1=489H。
每个CPU核都有自己CR0,CR4哦,所以每个核都要设置。
以上我们已经检查并开启了VMX。进入下一节。
#include <ntifs.h>
#include <intrin.h>#define CPUID_ECX_VMX_ABILITY 5
#define MSR_IA32_FEATURE_CONTROL 0x3A#define MSR_IA32_VMX_CR0_FIXED0 0x486
#define MSR_IA32_VMX_CR0_FIXED1 0x487
#define MSR_IA32_VMX_CR4_FIXED0 0x488
#define MSR_IA32_VMX_CR4_FIXED1 0x489#pragma pack(1)
typedef union {struct {ULONG Lock : 1; //bit-0 Lock bit (0 = unlocked, 1 = locked). When set to '1' further writes to this MSR are blocked.ULONG EnableVmxInsideSmx : 1; //bit-1 Enable VMX in SMX operation.ULONG EnableVmxOutsideSmx : 1; //bit-2 Enable VMX outside SMX operation.ULONG Reserved1 : 5; //bit-3:7 ReservedULONG SenterLocalFunctionEnables : 7; //bit-8:14 SENTER Local Function Enables: When set, each bit in the field represents an enable control for a corresponding SENTER function.ULONG SenterGlobalEnable : 1; //bit-15 SENTER Global Enable: Must be set to ‘1’ to enable operation of GETSEC[SENTER].ULONG Reserved2 : 1; //bit-16 ReservedULONG SgxLaunchControlEnable : 1; //bit-17 SGX Launch Control Enable: Must be set to ‘1’ to enable runtime re-configuration of SGX Launch Control via the IA32_SGXLEPUBKEYHASHn MSR.ULONG SgxEnable : 1; //bit-18 SGX Global Enable: Must be set to ‘1’ to enable Intel SGX leaf functions.ULONG Reserved3 : 1; //bit-19 ReservedULONG LmceOn : 1; //bit-20 LMCE On: When set, system software can program the MSRs associated with LMCE to configure delivery of some machine check exceptions to a single logical processor.ULONG Reserved4 : 11; //bit-21:31 ReservedULONG Reserved5 : 32; //bit-32:64 Reserved} Bits;LARGE_INTEGER value;
} MSR_IA32_FEATURE_CONTROL_REGISTER, * PMSR_IA32_FEATURE_CONTROL_REGISTER;typedef union {struct {ULONG PE : 1; ///< Protection Enable.ULONG MP : 1; ///< Monitor Coprocessor.ULONG EM : 1; ///< Emulation.ULONG TS : 1; ///< Task Switched.ULONG ET : 1; ///< Extension Type.ULONG NE : 1; ///< Numeric Error.ULONG Reserved_0 : 10; ///< Reserved.ULONG WP : 1; ///< Write Protect.ULONG Reserved_1 : 1; ///< Reserved.ULONG AM : 1; ///< Alignment Mask.ULONG Reserved_2 : 10; ///< Reserved.ULONG NW : 1; ///< Mot Write-through.ULONG CD : 1; ///< Cache Disable.ULONG PG : 1; ///< Paging.} Bits;LARGE_INTEGER value;
} IA32_CR0, * PCR0;
typedef union {struct {ULONG64 VME : 1; //Bit-0ULONG64 PVI : 1; //Bit-1ULONG64 TSD : 1; //Bit-2ULONG64 DE : 1; //Bit-3ULONG64 PSE : 1; //Bit-4ULONG64 PAE : 1; //Bit-5ULONG64 MCE : 1; //Bit-6ULONG64 PGE : 1; //Bit-7ULONG64 PCE : 1; //Bit-8ULONG64 OSFXSR : 1; //Bit-9ULONG64 OSXMMEXCPT : 1; //Bit-10ULONG64 UMIP : 1; //Bit-11ULONG64 LA57 : 1; //Bit-12ULONG64 VMXE : 1; //Bit-13ULONG64 SMXE : 1; //Bit-14ULONG64 NOP_15 : 1; //Bit-15ULONG64 FSGSBASE : 1; //Bit-16ULONG64 PCIDE : 1; //Bit-17ULONG64 OSXSAVE : 1; //Bit-18ULONG64 KL : 1; //Bit-19ULONG64 SMEP : 1; //Bit-20ULONG64 SMAP : 1; //Bit-21ULONG64 PKE : 1; //Bit-22ULONG64 CET : 1; //Bit-23ULONG64 PKS : 1; //Bit-24ULONG64 NOP_25_31 : 7; //These are zeroULONG64 Reserved_64 : 32;}Bits;LARGE_INTEGER value;
}IA32_CR4, * PCR4;
#pragma pack()IA32_CR0 SaveCr0[10] = { 0 };
IA32_CR4 SaveCr4[10] = { 0 };ULONG64 CheckCPUID() {int ctx[4] = { 0 };//顺序:eax,ebx,ecx,edx__cpuid(ctx, 1);return ctx[2] & CPUID_ECX_VMX_ABILITY; //Bit-5
}ULONG64 SetCr0(ULONG64 IndexCpu) {IA32_CR0 uCr0 = { 0 };uCr0.value.QuadPart = __readcr0();SaveCr0[IndexCpu].value.QuadPart = uCr0.value.QuadPart;uCr0.value.QuadPart |= __readmsr(MSR_IA32_VMX_CR0_FIXED0);uCr0.value.QuadPart &= __readmsr(MSR_IA32_VMX_CR0_FIXED1);__writecr0(uCr0.value.QuadPart);return TRUE;
}
ULONG64 SetCr4(ULONG64 IndexCpu) {IA32_CR4 uCr4 = { 0 };uCr4.value.QuadPart = __readcr4();SaveCr4[IndexCpu].value.QuadPart = uCr4.value.QuadPart;uCr4.value.QuadPart |= __readmsr(MSR_IA32_VMX_CR4_FIXED0);uCr4.value.QuadPart &= __readmsr(MSR_IA32_VMX_CR4_FIXED1);__writecr4(uCr4.value.QuadPart);return TRUE;
}ULONG64 CheckMsr() {MSR_IA32_FEATURE_CONTROL_REGISTER msr = { 0 };msr.value.QuadPart = __readmsr(MSR_IA32_FEATURE_CONTROL);return msr.Bits.Lock;
}VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{for (ULONG CpuIndex = 0; CpuIndex < KeNumberProcessors; CpuIndex++){KeSetSystemAffinityThread((KAFFINITY)(1 << CpuIndex));__writecr0(SaveCr0[CpuIndex].value.QuadPart);__writecr4(SaveCr4[CpuIndex].value.QuadPart);KdPrint(("CPU:[%d],关闭VMX\n", CpuIndex));KeRevertToUserAffinityThread();}ULONG64 Cr4 = __readcr4();KdPrint(("卸载驱动,当前CR4.VMEX=%I64X,1==打开,0==关闭\n", ((IA32_CR4*)&Cr4)->Bits.VMXE));
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING RegisterPath)
{if (CheckCPUID() == FALSE) {KdPrint(("CPU不支持\n"));}if (CheckMsr() == FALSE) {KdPrint(("BIOS未开启VMX\n"));}for (ULONG CpuIndex = 0; CpuIndex < KeNumberProcessors; CpuIndex++){KeSetSystemAffinityThread((KAFFINITY)(1 << CpuIndex));SetCr0(CpuIndex);SetCr4(CpuIndex);KdPrint(("CPU:[%d],开启VMX\n", CpuIndex));KeRevertToUserAffinityThread();}ULONG64 Cr4 = __readcr4();KdPrint(("加载驱动,当前CR4.VMEX=%I64X,1==打开,0==关闭\n", ((IA32_CR4*)&Cr4)->Bits.VMXE));pDriverObject->DriverUnload = DriverUnload;return STATUS_SUCCESS;
}
检测CPU是否具备VT的功能,并开启相关推荐
- 检测cpu是否支持VT
检测cpu是否支持VT 最近研究云,一个前提基本就是是否支持VT,以前我以为外面的cpu,基本都支持,不过发现不是.只是我的笔记本的cpu,不支持,去年才买的. 检测这个,通过cpu-z好像是不行,需 ...
- [VT虚拟化驱动]安装DPC回调检测CPU对VT的支持
文章目录 前言 一.驱动基本框架 二.安装DPC回调 三.检测CPU对VT的支持 本章代码 def.h: DriverEntry.cpp util.cpp 前言 对于VT的介绍网上有很多详细的介绍,这 ...
- 单点水位检测触摸芯片/单通道高灵敏度液体(水位)检测IC-VK36W1D,4S检测无水进入待机模式,具备抗电压波动功能
产品型号:VK36W1D 产品品牌:永嘉微电/VINKA 封装形式:SOT23-6 产品年份:新年份 概述: VK36W1D STO23-6具有1个触摸检测通道,可用来检测水从无到有和水从有到无.该芯 ...
- 使用Modernizr 检测HTML5和CSS3浏览器支持功能
http://www.adobe.com/cn/devnet/dreamweaver/articles/using-modernizr.html 传统浏览器目前不会被完全取代,令你难以将最新的 CSS ...
- 13 种在 Linux 系统上检测 CPU 信息的工具
13 种在 Linux 系统上检测 CPU 信息的工具 问题: 我想要了解我的电脑关于CPU处理器的详细信息,查看CPU信息比较有效地方法是什么? 根据你的需要,有各种各样的关于你的CPU处理器信息你 ...
- 万兆以太网测试仪应该具备的测试功能
自1982年以太网协议被IEEE采纳成为标准后,到目前为止,已经经历了40年的风风雨雨.在这40年中,以太网技术作为局域网链路层标准战胜令牌.令牌总线等技术.以太网技术在当前局域网市场范围占有使用率9 ...
- 计算机硬件功能作用,cpu的作用和主要功能是什么
CPU是计算机的核心单位,也是最重要部件,学习计算机硬件的朋友们,一定会学到CPU,那么CPU的作用是什么呢?分别有哪些功能?和小编一起看看! [cpu的作用] cpucpu的内部结构可分为控制单元, ...
- linux 系统硬件信息检测工具,9种在Linux系统上检测CPU信息的工具
在Linux中,有许多命令行或基于GUI的工具就能来展示你的CPU硬件的相关具体信息.下面是学习啦小编收集整理的9 种在 Linux 系统上检测 CPU 信息的工具,希望对大家有帮助~~ 9 种在 L ...
- 查看电脑CPU是否支持VT虚拟化的几个软件
安装虚拟机 CPU支持虚拟化 可提供更多的功能及更好的性能,怎么查看电脑CPU是否支持虚拟化呢? 1.如果CPU品牌为Interl,可使用Inter官方工具 Intel® Processor Iden ...
最新文章
- 0基础该如何学Python?这些方法你必须了解
- 架构师之路 — 软件架构 — 应用架构设计模式
- ThinkCMF 5.1.0 发布:支持 swoole、协议变更为 MIT
- 局网计算机无法访问,局域网计算机不能访问服务器的原因是什么
- Python 项目实践三(Web应用程序)第四篇
- 哪个Java线程消耗了我的CPU?
- 6.IDA-重命名、注释
- 计算机图形学中向量点乘和叉乘的用途_图形学笔记(一):基础知识
- Gym 100796B Wet Boxes(思维)题解
- MyEclipse详细使用教程
- ubuntu22.04 运行qq音乐闪退
- 一文搞懂激活函数(Sigmoid/ReLU/LeakyReLU/PReLU/ELU)
- 色环电阻、色环电容的识别方法
- IIS发布网站 后台接口404
- 2022-2027年中国酒店餐饮行业市场调研及未来发展趋势预测报告
- 上课笔记-机器学习(5)-美国人口普查数据进行收入预测分类
- 小饶学编程之JAVA SE第二部分——Web 前端基础:09CSS3
- QQ跨站漏洞巧利用一例【强迫别人帮你买QQ秀】【应该以失效】
- h5互动小游戏定制开发流程
- java在字符串开头添加字符串_string - java:使用StringBuilder在开头插入