贵阳网站建设方案维护,公司网站如何进入后台,开通域名后怎样建设网站,免费logo图标在线制作设计VT技术(编写一个VT框架)
1.VT技术介绍
1.技术介绍
1.VT技术
VT技术是Intel提供的虚拟化技术#xff0c;全称为Intel Virtualization Technology。它是一套硬件和软件的解决方案#xff0c;旨在增强虚拟化环境的性能、可靠性和安全性。VT技术允许在一台物理计算机上同时运…VT技术(编写一个VT框架)
1.VT技术介绍
1.技术介绍
1.VT技术
VT技术是Intel提供的虚拟化技术全称为Intel Virtualization Technology。它是一套硬件和软件的解决方案旨在增强虚拟化环境的性能、可靠性和安全性。VT技术允许在一台物理计算机上同时运行多个虚拟机每个虚拟机都可以运行不同的操作系统和应用程序。 Intel VTIntel Virtualization Technology可以使单个CPU在虚拟化环境下模拟多个逻辑处理器Virtual CPU从而实现多个操作系统同时运行的能力。 VT技术分为软件虚拟化、容器虚拟化、虚拟化层翻译
软件虚拟化Software Virtualization这种虚拟化技术是基于软件实现的它在一个宿主操作系统上运行虚拟化软件如Vmware Workstation、Virtual PC通过模拟硬件环境来创建和管理虚拟机。每个虚拟机运行的操作系统和应用程序都不需要进行修改。容器虚拟化Container Virtualization容器虚拟化是一种轻量级的虚拟化技术它将操作系统内核的特性如Linux容器LXC或Docker容器用于隔离应用程序和它们的运行环境。容器共享宿主操作系统的内核因此不需要进行完全的操作系统虚拟化。
2.抽象的Ring-1层
在传统的计算机体系结构中没有明确定义的Ring -1层。通常计算机体系结构中的Ring层级是指特权级别或权限级别用于控制对系统资源的访问。常见的层级包括Ring 0内核态和Ring 3用户态。 然而VT技术Intel的虚拟化技术Virtualization Technology它允许在一台物理计算机上同时运行多个虚拟机。虚拟化技术引入了新的软件和硬件层级以管理虚拟机的创建、运行和资源分配。 在虚拟化技术中可以将主机操作系统视为Ring 0并将虚拟机的操作系统视为Ring 3。这种情况下可以认为虚拟化技术引入了一种抽象的Ring -1层用于管理虚拟机的创建和资源分配。这个抽象的层级位于主机操作系统和虚拟机操作系统之间可以看作是一种虚拟化管理的层级。 需要注意的是Ring -1只是一种抽象概念用于解释虚拟化技术中的层级关系并不是传统计算机体系结构中的标准术语。实际上不同的虚拟化技术可能采用不同的层级结构和术语具体情况取决于所使用的虚拟化平台和技术。
2.关键词介绍
1.VMM(Virtual Machine Monitor)
虚拟机器监视器是指在电脑上的软件固件或者是硬件用来建立与执行虚拟机器
2.VMX(Virtual Machine Extensions)
处理器对虚拟化的处理器支持由一种称为VMX Opreation的处理器操作形式提供VMX Opreation 有2种VMX Root Opreation以及VMX Non-root Opreation一般来说一个VMM将在VMX Root Opreation中运行而客户软件运行在VMX Non-root Opreation
3.VM(Virtual Machine)
VM指的是Virtual Machin 虚拟机
4.VMCS(Virtual Machine Control Structures)
逻辑处理器在执行VMX操作时会使用虚拟机控制数据结构VMCSs。这些操作可以管理进出VMX Non-root Opreation的转换VM条目和VM退出的转换以及VMX非根操作中的处理器行为。该结构由新的指令VMCLEAR、VMPTRLD、VMREAD和VMWRITE操作。
5.VMX Root Opreation
通常VMM将会在这种模式下运行
6.VMX Non-root Opreation
通常客户软件虚拟机将在这种环境下运行。两种类型的操作之间的转换称作VMX转换从根操作模式转换到非根操作模式称作VMX进入VMX Entry相反从非根操作模式转换到根操作模式称作VMX退出VMX Exit
7.Guest software
每个虚拟机VM就是一个客户软件运行环境。
3.VMM软件的生命周期 以上图来描述VMM软件的生命周期
启用VMXVMX操作的生命周期始于启用VMX扩展。在计算机启动时虚拟机监视器VMM通过设置处理器的控制寄存器来启用VMX扩展。这个过程通常在操作系统引导期间或虚拟化软件加载时完成。进入VMX操作模式启用VMX后处理器进入VMX操作模式。在这个模式下处理器支持运行虚拟机和虚拟机监视器之间的切换。VMM负责管理虚拟机的创建、配置和执行。虚拟机的创建和运行在VMX操作模式下VMM可以创建虚拟机实例并配置虚拟机的资源。虚拟机监视器通过VMCSVirtual Machine Control Structure来管理虚拟机的状态和控制信息。VMM在虚拟机和虚拟机监视器之间进行切换使虚拟机可以在物理处理器上运行。虚拟机监控和控制在虚拟机运行期间虚拟机监视器监控虚拟机的行为并提供必要的控制。它负责处理虚拟机的中断、异常和特权指令并确保虚拟机之间和虚拟机与物理机之间的资源隔离。退出VMX操作模式当虚拟机执行完成或发生特定事件时虚拟机监视器将控制权从虚拟机切换回虚拟机监视器。这个过程称为VMX退出。在退出过程中虚拟机监视器可以读取和更新虚拟机的状态信息并进行必要的处理。禁用VMXVMX操作的生命周期在虚拟化环境不再需要时结束。在关闭虚拟化软件或关闭计算机时处理器的VMX扩展将被禁用处理器将恢复到普通的非虚拟化模式。
总的来说VMX Operation的生命周期涵盖了启用VMX扩展、进入VMX操作模式、虚拟机的创建和运行、虚拟机监控和控制、退出VMX操作模式以及禁用VMX扩展等关键阶段以实现硬件虚拟化的支持和管理。
2.VT技术(二)检测CPU支持
1.使用CPUID指令检测CPU是否支持虚拟化
在进入VMX Opreation之前需要对CPU进行一系列检测用于判断CPU硬件是否支持虚拟化技术。 CPUID指令在Ring3也可以使用不需要进入Ring0层进行检测以下为CPUID指令的使用详细说明
1.CPUID指令使用说明
语法
CPUID在执行时需要将所需要的查询编号传入eax寄存器当中
xor rax,rax
cpuid功能
CPUID指令返回处理器的信息和功能支持包括处理器厂商、处理器系列、功能位、缓存配置、支持的扩展功能等。
寄存器使用
输入EAX寄存器用于传递查询的功能编号。输出EAX、EBX、ECX、EDX寄存器用于返回处理器的信息和功能。
2.CPUID指令参数说明
查询处理器厂商信息 通过将EAX设置为0执行CPUID指令处理器厂商的标识符将返回在EBX、EDX和ECX寄存器中以ASCII编码的形式表示。查询扩展功能支持 通过将EAX设置为7执行CPUID指令处理器支持的扩展功能信息将返回在EBX、ECX和EDX寄存器中。查询缓存配置 通过将EAX设置为2执行CPUID指令处理器的缓存配置信息将返回在EAX、EBX、ECX和EDX寄存器中。查询CPUID最大支持功能编号 通过将EAX设置为0x80000000执行CPUID指令最大支持的功能编号将返回在EAX寄存器中。
以上简单列出常用的几个指令参数如果需要查询详细参数可参考Intel白皮书卷二第三章(指令A-L)中的CPUID章节(书中详细介绍) 3.查询CPU是否支持VT技术
由于本文基于的系统是x64位操作系统VS编译器中的编译器默认支持内联汇编(当然可以写asm文件)但是考虑到代码的兼容性在代码中使用的是VS自带的内建函数下方放出VS的内建函数查询表 VS x64 内建函数大全 VMX指令函数介绍 在汇编中执行的指令应该是
mov rax,1
cpuid执行结束之后查询ECX第五位是否被置为1如果被置为1表示当前的CPU支持虚拟化技术 代码
EXTERN_C BOOLEAN Check_CPUID() {int Ecx[4];__cpuid(Ecx,1);return (Ecx[2] 5) 1; //Ecx 第六位是否为1
}2.读取MSR字段检查BIOS是否打开VT技术
MSRModel Specific Register是一种特殊类型的寄存器它包含了处理器的模型特定信息和配置参数。MSR寄存器是处理器架构的一部分由处理器制造商定义和实现。 每个处理器都可能具有不同的MSR寄存器集合这些寄存器对应于特定的功能和配置选项。MSR寄存器通常用于控制处理器的某些特性、性能调整、电源管理和虚拟化支持等。 与通用寄存器如通用目的寄存器不同MSR寄存器不可直接访问而是通过特殊的指令如RDMSR和WRMSR进行读取和写入。这些指令用于将MSR的地址加载到指定寄存器如ECX中然后执行相应的操作。 通过读取MSR_IA32_FEATURE_CONTROL字段对得到的值进行检测检测第0位是否为0如果为0VMX进入保护异常无法直接执行指令进入VMX Opreation需要在bios中设置打开VT技术
1.RDMSR/WRMSR指令
该2条指令用于操作MSR寄存器对MSR寄存器进行读写 RDMSR
mov eax,msr_index
rdmsr该指令用于读取MSR的值将MSR索引号放入eax寄存器执行指令之后会将MSR的高32位值存储在EDX寄存器中低32位值存储在EAX寄存器中 WRMSR
mov eax,values
mov ecx,msr_index
wrmsr该指令负责对MSR寄存器进行写入操作将需要写入的数据放入eax将msr寄存器的索引号放入ecx执行指令即可写入 C语言代码 考虑到需要验证的结果是二进制数字我们知道奇数的第0位一遍位1偶数的第0位一遍位0因此只需要判断奇偶性即可
BOOLEAN Check_CPUID() {int Ecx[4];__cpuid(Ecx,1);return (Ecx[2] 5) 1; //Ecx 第六位是否为1
}3.读取CR0与CR4检查是否已经成功进入VMX
以上工作做好之后代表从硬件层面已经支持进入VMX了但是还需要打开CR4寄存器的字段锁允许运行VT且该锁在进入VMX之后无法更改否则直接蓝屏直到关闭VMX。 此处先介绍一下六个CR(Control Register)寄存器的作用,但其实只有五个CR1寄存器在真实情况中不采用
CR0控制与保护模式、实模式、分页以及其他系统操作相关的设置。CR1保留不采用CR2存储引发页错误异常的线性地址CR3存储页表的物理地址用于地址转换和分页机制CR4控制处理器的特定功能和扩展如分页扩展、物理地址扩展等CR8用于控制中断和异常处理的优先级仅在64位操作系统下使用
如果对CR寄存器感兴趣的师傅可以移步到这位大佬的这篇文章CR寄存器的位介绍 事实上CR寄存器的每个位都有自己的名称而控制是否成功进入VMX的位则是CR4寄存器的正是CR4的VMXE位在运行VT驱动代码之前可以先检测是否已经进入了VT如果进入了VT则需要避免一些不必要的操作否则导致主机蓝屏
3.VMXON 进入VMX
在完成了2中所说的对CPU进行支持检查之后就可以正式开始写进入VMX的代码了
1.VMXON与VMXOFF指令
进入VMX Opreation模式的方式是执行VMXON指令退出在的指令则是VMXOFF VMXON 在执行该指令之前需要初始化申请一段内存该段内存大小为自然对齐为1KB大小被称之为VMX_Region
mov ecx,VMX_Region_Physical
vmxon ecx该指令执行的要求是需要将VMX_Region对应的物理内存地址放入寄存器中再执行指令
PVOID VMX_Region ExAllocatePoolWithTag(NonePagePool,0x1000,VMX);
ULONG_PTR VMX_Region_Phy MmGetPhysicalAddress(VMX_Region).QuadPart;
//需要设置VMX Region
__vmx_on(VMX_Region_Phy);VMXOFF VMXON指令直接在退出VMX的时候执行即可 以上2条指令在VS编译器中使用__vmx_off() 、__vmx_on()即可
2.设置VMX_Region
该段内存需要分配为NonePagePool类型的内存 该段内存的前四个字节需要写入VMCS_ID(MSR index 0x480) 通过__readmsr()读取并将其写入至该内存
* (ULONG*)VMX_Region __readmsr(0x480);检查错误位置
在执行__vmx_on()之后需要对Eflags寄存器的相关位进行检测检测eflags寄存器CF字段是否被置为1如果被置为1则进入VMX失败
*(ULONG_PTR*)(eflags) __readeflags();
if (eflags.fields.cf ! 0) {DbgPrint([CPU:%d]VMXON ON Failed, index);
}4.设置VMCS字段
在阅读本章之前请先阅读第五章进入虚拟化 在成功进入VMX环境之后还需要一段VMCS(Virtual Machine Control Structure)内存,称之为VMCS_Region该内存主要的作用是存储和管理控制虚拟机的执行主要用于VMCS的相关信息
1.vmwrite与vmread指令
vmwrite指令
mov ecx,VMCS_Fields
mov eax,VMCS_Data
vmwrite ecx,eax该指令将需要写入的VMCS_Fields放入ecx将需要写入进字段的数据放入eax执行指令成功将需要写入的数据放入VMCS_Fields vmread指令
mov ecx,VMCS_Fields
vmread eax,ecx将需要读取的VMCS_Fields放入ecx执行指令将读取到的数据放入ecx中 VMCS中主要需要写入的有 Guest_State Host_State VM Execute State
1.VM Execute State设置
Pin Base
设置虚拟机的IA32_VMX_PINBASED_CTLS这个寄存器控制了大多数基于引脚的虚拟机执行控制的允许设置,寄存器的位31:0指示这些控制的允许的0设置。如果MSR中的位X被清除为0VM entry允许控制X基于引脚的虚拟机执行控制的第X位为0如果MSR中的位X设置为1如果控制X为0VM entry将失败。
CPU Base
用于设置 IA32_VMX_PROCBASED_CTLS这个寄存器控制大多数基于主处理器的虚拟机执行控件的允许设置读者如果想具体查看每个位的控制详见Intel白皮书卷三24章第6节第2点
VM Exit Controls
设置IA32_VMX_EXIT_CTLS 寄存器控制大部分VM Exit 允许的控制详见卷三24节第七节第一点
VM Entry Controls
用于设置 IA32_VMX_ENTRY_CTLS记录大部分VM Entry的允许设置详见卷三24节第8节第1点
Secondar Processor-Based
用于设置 IA32_VMX_PROCBASED_CTLS2主要用于设置次级处理器配置APIC EPT等详见卷三24节第6节第2点
2.Guest_State 设置
寄存器部分 需要设置的有段寄存器段选择子段限制AR段基址分别为(ES、CS、DS、FS、GS、FS、TR、GDTR、IDTR、LDTR、RIPRSP)等等文本会给一个文档具体的设置参数非寄存器 VMCS Link pointer
3.Host_State 设置
详情请看文末的文档 对与以上提到的字段对应的索引号通过查找Intel白皮书卷三附录B中查到
5.进入虚拟化
在设置完以上VMCS内容之前执行vmclear vmptrld这两条指令大概流程以代码表示为
__vmx_vmclear(VMCS_Phy);
__vmx_vmptrld(VMCS_Phy);
SetupVmcs(); //设置VMCS
__vmx_vmlaunch(); //进入虚拟化
DbgPrint(”Vmlaunch Failed“); //如果成功执行vmlaunch不会执行dbgprint函数在执行__vmx_vmlaunch之后如果程序没有发生意外会直接进入GUEST模式RIP/RSP变化为GUEST_RIP/GUEST_RSP地址,在发生VMX-Exit事件后产生异常RIP/RSP变为HOST_RIP/HOST_RSP指向的位置 如果成功执行了DbgPrint函数请检查VM_INSTRUCTION_ERROR的错误号可以在Intel白皮书的卷三第30章第4节查到
6.处理VM Exit
在成功进入GUEST之后RIP跳到GUEST_RIP位置继续执行代码 期间会产生大量VMX-Exit事件在产生VM-Exit之后虚拟机跳到HOST_RIP位置因此Host_RIP处需要设置一个回调函数称之为VMEXithandler 在VMExithandler函数中设置通过检测VM_EXIT_REASON的错误号来判断产生错误的代码以及读取GUEST_RIP以确定代码执行错误的位置联系代码上下文对错误进行排查检测
void ExitHandler(){DWORD64 ExitReason __readmsr(VM_EXIT_REASON);DWORD64 GUEST_RIP __readmsr(GUEST_RIP);__DebugBreak();
}通过断点断下程序获取ExitReason根据错误号进行排查(ExitReason错误号说明详见卷三附录B) 完整的流程则为 将hostrip的函数用asm文件写出将寄存器信息保存进入堆栈将首地址指针通过call指令传入Exithandler
EXTERN_C ExitHandler:PROC //从其他文件导入函数PUSHAQ MACROpush raxpush rcxpush rdxpush rbxpush -1 push rbppush rsipush rdipush r8push r9push r10push r11push r12push r13push r14push r15
ENDMPOPAQ MACROpop r15pop r14pop r13pop r12pop r11pop r10pop r9pop r8pop rdipop rsipop rbpadd rsp, 8 pop rbxpop rdxpop rcxpop rax
ENDMExithandlerEntry PROCpushaqmov rcx,rspsub rsp,50hcall ExitHandler····//后续处理rax通过rax控制接下来的流程popaqresume //返回GUEST
ExithandlerEntry ENDP通过switch case程序命中Exitreason 再设置函数在host模式中执行guest模式中无法执行的指令 再通过读取VM_EXIT_INSTRUCTION_LEN获取GUEST_RIP指向的当前指令长度通过GUEST_RIPVM_EXIT_INSTRUCTION_LEN 重新设置GUESTRIP void CpuidError(//接受GUEST寄存器信息){//在host模式中处理GUEST无法执行或产生异常的指令
}
void NextCode(){DWORD64 GUESTrip __readmsr(GUEST_RIP);DWORD64 VM_EXIT_INSTRUCTION __readmsr(VM_EXIT_INSTRUCTION_LEN);DWORD64 NextCode GUESTripVM_EXIT_INSTRUCTION;__vmx_vmwrite(GUEST_RIP,NextCode);
}EXTERN_C BOOLEAN ExitHandler(//设置一个结构体获取GUEST寄存器信息){DWORD64 ExitReason __readmsr(VM_EXIT_REASON);DWORD64 GUESTrip __readmsr(GUEST_RIP);switch(ExitReason):case CPUIDError: //命中函数{CpuidError();NextCode();break;}default:DbgPrint(Exit Reason %p\n,ExitReason); // 输出未处理的Exit事件__DebugBreak()// int 断点 break;return TURE; // 通过返回布尔值以确定rax是否为0
}通过以上流程设置VMXExitHandler处理vmexit事件
7.退出虚拟化
考虑到VT代码是以驱动加载至Windows当中的在需要关闭VT时需要执行卸载驱动的函数因此必须保证程序正常执行到DriverLoad函数的Return部分因此在进入Guest之前需要保存堆栈信息以及寄存器信息以便在成功进入GUEST之后恢复堆栈以及寄存器信息使程序正常执行下去。以保证正常执行卸载驱动的函数 GUEST允许执行VMCALL指令直接退出GUEST模式在UnloadVT函数中执行该代码,通过Exithandler命中vmcall错误,vmcall可以提供参数执行也可以不提供参数执行通过回调函数检测rax是否为设置的特殊参数如果是直接执行vmxon指令关闭vt
EXTERN_C void __fastcall AsmVmcall(ULONG_PTR num, ULONG_PTR param);void UnloadVt(){asmcall(vmxexit,0)
}在asm中对ExitHandler函数的返回值进行检测 ExithandlerEntry PROCpushaqmov rcx,rspsub rsp,50hcall ExitHandler····//后续处理rax通过rax控制接下来的流程test al,al //检测返回值是否为0jz ExitVT:popaq //将修改后的寄存器回弹resume //返回GUESTjmp Error
ExitVT:popaqvmxonjz Errorjc Errorpush raxpopfq // 恢复堆栈mov rsp, rdx push rcxret
Error:int 3
ExithandlerEntry ENDP在ExitHandler中设置 VT CloseVT(){//恢复一些段属性 限制 基址等
}
BOOLEAN vmcallhandler(GUEST寄存器信息){//如果rax为设定的预定值CloseVt();return FALSE;//如果不是 正常处理错误return TRUE;
}
EXTERN_C BOOLEAN ExitHandler(//设置一个结构体获取GUEST寄存器信息){DWORD64 ExitReason __readmsr(VM_EXIT_REASON);DWORD64 GUESTrip __readmsr(GUEST_RIP);ret TRUE;switch(ExitReason):case vmcall: //命中函数{ret vmcallhandler();break;}default:DbgPrint(Exit Reason %p\n,ExitReason); // 输出未处理的Exit事件__DebugBreak()// int 断点 break;return ret; // 通过返回布尔值以确定rax是否为0
}总结
代码已经上传到了Github仓库 欢迎各位大佬批评,觉得不错的师傅可以给个star https://github.com/yifaang/VTDemo 在文章中的代码可能会有一定的问题请以github项目源码参考 文章中需要的文档在这里 Intel白皮书全卷VMCS设置参考文档:: 链接https://pan.baidu.com/s/1cmTCIKwaT_eGlnmpO178ZQ 提取码yftx