VT系列二:檢測是否支援虛擬化
阿新 • • 發佈:2018-11-10
本文只是學習此視訊後的一些總結 不當之處還請指出
視訊作者:小寶來了
視訊連線:http://bbs.pediy.com/showthread.php?t=211973
約定:
本文中出現的名詞
虛擬機器 客戶機 GUEST 都是被監控的作業系統或應用程式
宿主機 HOST Hypervisor都是指監控虛擬機器的“原”作業系統
VMM:當客戶機發生退出事件時,進入的就是VMM
VM:當客戶機正常執行時就是VM
VMM監控VM
步驟在Intel手冊35.1章
1.使用CPUID指令檢視CPU資訊
需要關注的是ECX(RCX)暫存器
這裡只講x86
返回的ecx是一個
typedefunion { struct { unsigned SSE3:1; unsigned PCLMULQDQ:1; unsigned DTES64:1; unsigned MONITOR:1; unsigned DS_CPL:1; unsigned VMX:1; unsigned SMX:1; unsigned EIST:1; unsigned TM2:1; unsigned SSSE3:1; unsigned Reserved:22; }; }_CPUID_ECX;
我們需要判斷其中VMX位是否為1 是支援VT 否則不支援
2.檢視CR0 CR4控制暫存器
CR0暫存器的PE、PG、NE位必須為1
如果不為1 則是在BIOS中沒有啟用VT
CR4暫存器的VMXE位是否為1
如果為1則說明已經有VT存在了
用到的結構圷:
typedefunion { 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 union { 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;
3.檢查MSR暫存器(MSR_IA32_FEATURE_CONTROL)
MSR_IA32_FEATURE_CONTROL的lock位是否為1
如果不為1則VT指令沒有開啟無法使用某些VT指令
用到的結構如下:
typedefstruct _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;
程式碼如下:
#pragma once
#include <ntddk.h>
#include "vtsystem.h"
#include "vtasm.h"
BOOLEAN bCheckCpuSuppert()
{
//1.執行CPUID
ULONG uRet_Eax, uRet_Ebx, uRet_Ecx , uRet_Edx;
_CR0 cr0;
_CR4 cr4;
_CPUID_ECX uCpuId_Ecx;
IA32_FEATURE_CONTROL_MSR msr;
Asm_CPUID(1, &uRet_Eax, &uRet_Ebx, &uRet_Ecx, &uRet_Edx);
*((PULONG)&uCpuId_Ecx) = uRet_Ecx;
if (uCpuId_Ecx.VMX != 1)
{
DbgPrint("當前CPU不支援VT!\n");
return FALSE;
}
//2.CR0 CR4
cr0 = Asm_GetCr0Ex();
if (cr0.PE != 1 || cr0.PG != 1 || cr0.NE != 1)
{
DbgPrint("請在Bios裡面設定VT選項!\n");
return FALSE;
}
cr4 = Asm_GetCr4Ex();
if (cr4.VMXE == 1)
{
DbgPrint("已經有VT啦!\n");
return FALSE;
}
//3.Msr
Asm_ReadMsrEx(MSR_IA32_FEATURE_CONTROL, (PMSR)&msr);
if (msr.Lock != 1)
{
DbgPrint("VT 指令沒有鎖定!\n");
return FALSE;
}
DbgPrint("當前CPU支援VT!\n");
return TRUE;
}
下一章將講退出事件的分發