原理参考 3卷 23.7节等

本节实施流程参考Intel手册: 3卷 31.5节

1 vt整体框架;

首先 开锁:

1 开启 Cr4.[VMXE]:

上一节,检测了 VMX 需要的环境;最后一个 CR4.[13/VMXE] 只检测了是否已经被开启(有别的虚拟机);

但是 没有在 CR4.[13/VMXE] ==0 的时候去开启。

所以 这里 开始 开锁;打开 CR4.[13]

放在 驱动加载函数中。

  • 代码:

    NTSTATUS StartVirtualTechnology()

    {
    _CR4 uCr4;
    if(!IsVTEnabled())
    {
    return STATUS_UNSUCCESSFUL;
    }
    *((PULONG)&uCr4) = Asm_GetCr4();// 获取原来的 cr4;
    uCr4.VMXE =1;// VMXE =1 开启。
    Asm_SetCr4(*(PULONG)&uCr4); // 设置回去

    return STATUS_SUCCESS;
    }

2开始 进入 VMXON:

接下来的最简流程:(参考白皮书 3卷31.5节)

这里 红色部分是需要实现的部分:

即:

  • 需要申请一块最大4kb对齐的非分页内存;并且 确保大小够(直接申请4kb,先不考虑效率)

  • 用 VMCS revision identifier (在capability MSRs // MSR 480h 的低32位) 初始化 WMXON region (the first 31 bits)

  • 清理 第 31 bit 位0

首先需要一开内存来管理 host 信息(cpu 管理;我们提供内存即可)

然后需要设置版本号

代码:

NTSTATUS StartVirtualTechnology()

{
_CR4 uCr4;
_EFLAGS uEflags;
if(!IsVTEnabled())
{
return STATUS_UNSUCCESSFUL;
}
*((PULONG)&uCr4) = Asm_GetCr4();//get cr4;
uCr4.VMXE =1;// VMXE =1 enable
Asm_SetCr4(*(PULONG)&uCr4); // set

g_VMXCPU.pVMXONRegion = ExAllocatePoolWithTag(NonPagedPool,0x1000,'vmx');// para@3 is digit value
RtlZeroMemory(g_VMXCPU.pVMXONRegion,0x1000);// initial memory
*(PULONG)g_VMXCPU.pVMXONRegion =1;//set revision; -- the first 32bits of VMXONRegion; clear the no.32bit
g_VMXCPU.pVMXONRegion_PA = MmGetPhysicalAddress(g_VMXCPU.pVMXONRegion);// get physical address

Vmx_VmxOn(g_VMXCPU.pVMXONRegion_PA.LowPart,g_VMXCPU.pVMXONRegion_PA.HighPart);
*((PULONG)&uEflags) = Asm_GetEflags();

if(uEflags.CF!=0)// the flag to identify state of success or not
{
Log("ERROR:VMXON指令调用失败!",0);
ExFreePool(g_VMXCPU.pVMXONRegion);
return STATUS_UNSUCCESSFUL;
}

return STATUS_SUCCESS;

}

最后 关锁:

1 关闭 VMXOFF:

2 恢复 CR4.[VMXE]:

设置 CR4.[13/VMXE] ==0 的时候关闭;

放在驱动卸载函数中

  • 代码:

    NTSTATUS StopVirtualTechnology()

    {
    _CR4 uCr4;

    Vmx_VmxOff();

    *((PULONG)&uCr4) = Asm_GetCr4();// get cr4;
    uCr4.VMXE =0;// VMXE =0 disable
    Asm_SetCr4(*(PULONG)&uCr4); // set;

    // free page; in kernel nonpage its not freed automatic;
    ExFreePool(g_VMXCPU.pVMXONRegion);

    return  STATUS_SUCCESS;

    }

初步效果:

整体代码:

.cpp(开启 、关闭 VMX的函数实现)

#include "stdafx.h"


VMX_CPU g_VMXCPU;

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;
}

NTSTATUS StartVirtualTechnology()
{
_CR4 uCr4;
_EFLAGS uEflags;
if(!IsVTEnabled())
{
return STATUS_UNSUCCESSFUL;
}
*((PULONG)&uCr4) = Asm_GetCr4();//get cr4;
uCr4.VMXE =1;// VMXE =1 enable
Asm_SetCr4(*(PULONG)&uCr4); // set

g_VMXCPU.pVMXONRegion = ExAllocatePoolWithTag(NonPagedPool,0x1000,'vmx');// para@3 is digit value
RtlZeroMemory(g_VMXCPU.pVMXONRegion,0x1000);// initial memory
*(PULONG)g_VMXCPU.pVMXONRegion =1;//set revision; -- the first 32bits of VMXONRegion; clear the no.32bit
g_VMXCPU.pVMXONRegion_PA = MmGetPhysicalAddress(g_VMXCPU.pVMXONRegion);// get physical address

Vmx_VmxOn(g_VMXCPU.pVMXONRegion_PA.LowPart,g_VMXCPU.pVMXONRegion_PA.HighPart);
*((PULONG)&uEflags) = Asm_GetEflags();

if(uEflags.CF!=0)// the flag to identify state of success or not
{
Log("ERROR:VMXON指令调用失败!",0);
ExFreePool(g_VMXCPU.pVMXONRegion);
return STATUS_UNSUCCESSFUL;
}

return STATUS_SUCCESS;
}

NTSTATUS StopVirtualTechnology()
{
_CR4 uCr4;

Vmx_VmxOff();

*((PULONG)&uCr4) = Asm_GetCr4();// get cr4;
uCr4.VMXE =0;// VMXE =0 disable
Asm_SetCr4(*(PULONG)&uCr4); // set;

// free page; in kernel nonpage its not freed automatic;
ExFreePool(g_VMXCPU.pVMXONRegion);

return  STATUS_SUCCESS;

}

.c (驱动文件,调用VMX开启关闭函数)

#include "stdafx.h"

EXTERN_C void Asm_xx();
EXTERN_C BOOLEAN IsVTEnabled();
EXTERN_C NTSTATUS StartVirtualTechnology();
EXTERN_C NTSTATUS StopVirtualTechnology();
VOID DriverUnLoad(PDRIVER_OBJECT driver)
{

StopVirtualTechnology();
DbgPrint("VT stopping ....!\r\n");
DbgPrint("Driver is unloading...r\n");
}
NTSTATUS DriverEntry(
PDRIVER_OBJECT driver ,
PUNICODE_STRING RegistryPath)
{
Asm_xx();
DbgPrint("Driver Entered!\r\n");
StartVirtualTechnology();
DbgPrint("VT running....!\r\n");
driver->DriverUnload = DriverUnLoad;
return STATUS_SUCCESS;
}

感谢 周壑老师的讲解

3_基本框架_VMXON的更多相关文章

  1. Litepal【开源数据库ORM框架】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 好用的数据库框架. 效果图 代码分析 本篇主要是整理Litepal的引入和增删改查的简单操作,具体使用请阅读参考资料. 使用步骤 一 ...

  2. LitepalNewDemo【开源数据库ORM框架-LitePal2.0.0版本的使用】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 本Demo使用的是LitePal2.0.0版本,对于旧项目如何升级到2.0.0版本,请阅读<赶快使用LitePal 2.0版本 ...

  3. 避免重复造轮子的UI自动化测试框架开发

    一懒起来就好久没更新文章了,其实懒也还是因为忙,今年上半年的加班赶上了去年一年的加班,加班不息啊,好了吐槽完就写写一直打算继续的自动化开发 目前各种UI测试框架层出不穷,但是万变不离其宗,驱动PC浏览 ...

  4. ABP入门系列(1)——学习Abp框架之实操演练

    作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...

  5. 旺财速啃H5框架之Bootstrap(五)

    在上一篇<<旺财速啃H5框架之Bootstrap(四)>>做了基本的框架,<<旺财速啃H5框架之Bootstrap(二)>>篇里也大体认识了bootst ...

  6. Angular企业级开发(5)-项目框架搭建

    1.AngularJS Seed项目目录结构 AngularJS官方网站提供了一个angular-phonecat项目,另外一个就是Angular-Seed项目.所以大多数团队会基于Angular-S ...

  7. Scrapy框架爬虫初探——中关村在线手机参数数据爬取

    关于Scrapy如何安装部署的文章已经相当多了,但是网上实战的例子还不是很多,近来正好在学习该爬虫框架,就简单写了个Spider Demo来实践.作为硬件数码控,我选择了经常光顾的中关村在线的手机页面 ...

  8. 制作类似ThinkPHP框架中的PATHINFO模式功能

    一.PATHINFO功能简述 搞PHP的都知道ThinkPHP是一个免费开源的轻量级PHP框架,虽说轻量但它的功能却很强大.这也是我接触学习的第一个框架.TP框架中的URL默认模式即是PathInfo ...

  9. 旺财速啃H5框架之Bootstrap(四)

    上一篇<<旺财速啃H5框架之Bootstrap(三)>>已经把导航做了,接下来搭建内容框架.... 对于不规整的网页,要做成自适应就有点玩大了.... 例如下面这种版式的页面. ...

随机推荐

  1. lsof 详解

    lsof常用参数 lsof 如果不加任何参数,就会打开所有被打开的文件,建议加上一下参数来具体定位lsof -i 列出所有网络连接lsof -i tcp 列出所有tcp连接信息lsof -i udp  ...

  2. 在Panel上绘图的实现

    近期制作了FDS的一个建模工具,由于知识有限,做出的效果是2D的.昨天上课的时候看老师画一个长方体,突然想到,为什么不给普通的2D图形加画上几条直线,就能实现2D图形的3D视觉效果呢?于是回来马上做了 ...

  3. 微信小程序--跳转页面常用的两种方法

    一.bindtap="onProductsItemTap"绑定点击跳转事件 在.wxml文件中绑定 在.js文件中实现绑定事件函数 二.navigator标签配合URL跳转法 在w ...

  4. ARC032 D - アットコーダーモンスターズ

    https://arc032.contest.atcoder.jp/tasks/arc032_4# 切比雪夫距离,放在3000*3000的平面上, 一个集合就是恰好包含这个集合的矩形,价值是矩形长.宽 ...

  5. [转] 如何在vps上安装和登录Xwindows

    如何VPS也可以拥有像windows一样图形窗口,这里写个教程,据说xwindows是一个比微软windows还强大的linux图形界面,怎样强大,我也是听说的,你可以自己去试,然后告诉我. vps安 ...

  6. Android笔记之ExpandableListView(悬浮吸顶Demo)

    参考链接 ExpandableListView中item的定位问题 - RELY_ON_YOURSELF的博客 - CSDN博客(感觉写得很好,讲到了组位置.子位置及原始位置之间的转换) how to ...

  7. 面试系列38 分库分表之后,id主键如何处理?

    (1)数据库自增id 这个就是说你的系统里每次得到一个id,都是往一个库的一个表里插入一条没什么业务含义的数据,然后获取一个数据库自增的一个id.拿到这个id之后再往对应的分库分表里去写入. 这个方案 ...

  8. Window sevice +OWIN+webapi

    webapi正常都托管在iis上,这里引入owin,将其托管在window服务上. 第一步:创建一个服务,这里就不多描述. 第二步:引入OWIN 2.1引入bll 2.2加入api路由配置 publi ...

  9. MAMP 安装 php 扩展

    1.官网下载所对应的php 版本http://php.net/get/php-5.3.29.tar.gz/from/a/mirror 2.解压 找到需要的扩展目录 例如我要的是shmopcd ~/Do ...

  10. 引用数据类型 Scanner Random

    Scanner类 数据类型  变量名  =  new 数据类型(); 每种引用数据类型都有其功能,我们可以调用该类型实例的功能. 变量名.方法名(); Scanner类是引用数据类型的一种,我们可以使 ...