0x0 前言
机场无聊,将这段时间逆向的Windows HyperV打算写一个系列文章出来(当然,过了这个兴趣点,就没兴趣写了),包括三块:
1.有的是网上东拼西凑的资料,有的是根据逆向,自己总结出来的原理,这个是没有官方资料的,各位仅当参考资料。
2.根据whpx机制,无需在开启VT的情况下,接管CR3的切换。
3.Window HyperV的内存穿透读写。
0x1 HyperV介绍
一种类型 1(原生)的虚拟机监控器,它运行在主机的硬件上,并管理运行在 Hyper-V 控制下的“根” Windows 操作系统。这是 Hyper-V 的核心组件,它负责创建和管理分区、虚拟 CPU、虚拟设备等,并与底层的虚拟化硬件接口(如 Intel VT-x 或 AMD SVM)进行交互。
定义了“分区”,作为主要的隔离单元,用于执行操作系统。这是 Hyper-V 中的一个基本概念,它表示一个运行在 Hyper-V 上的操作系统实例,可以是父分区(运行在主机上的 Windows Server)或子分区(运行在虚拟机上的客户机操作系统)。
一个“分区”由一些物理内存、一个或多个虚拟 CPU 和一些虚拟化的外设组成。这是 Hyper-V 中用于描述分区的属性和资源的方式,其中物理内存是分配给分区的一段连续的内存空间,虚拟 CPU 是分配给分区的一组逻辑处理器,虚拟化的外设是分配给分区的一些模拟或合成的设备,如网卡、磁盘、键盘、鼠标等。
“分区”按照一个层次结构进行组织,其中主要的父分区是“根”。这是 Hyper-V 中用于管理分区之间的关系和权限的方式,其中根分区是运行在主机上的 Windows Server,它负责创建和监控其他子分区,并与 Hyper-V 通信;子分区是运行在虚拟机上的客户机操作系统,它们只能访问自己所属的资源,并通过父分区来与 Hyper-V 通信。
一个父分区可以接收来自子分区的一些事件。这是 Hyper-V 中用于实现父子分区之间交互和协作的机制,其中子分区可以向父分区发送一些请求或通知,如创建或销毁分区、配置虚拟设备、设置内存映射等;父分区可以根据子分区发出的事件来执行相应的操作或返回相应的结果。
大部分的物理硬件访问都是在“根”分区中直通的,而大部分的硬件都是在子分区中虚拟化的。这是 Hyper-V 中用于实现硬件访问的方式,其中根分区可以直接访问主机上的物理硬件,如 CPU、内存、磁盘等,以提高性能和兼容性;子分区则只能访问由 Hyper-V 或根分区提供的虚拟化的硬件,如虚拟 CPU、虚拟内存、虚拟磁盘等,以实现隔离和保护。
从 Windows Server 2016 开始,Hyper-V 支持嵌套虚拟化。这是 Hyper-V 中的一个新特性,它允许在一个子分区中运行另一个 Hyper-V 实例,并在该 Hyper-V 实例中创建和管理更多的子分区,从而实现多层次的虚拟化。
0x1 HyperV架构
HyperCall – 客户机操作系统用于与虚拟机监控器(Hypervisor)通信的接口。通过 VMCALL 硬件指令实现(参见 Intel 手册)。这是 Hyper-V 中用于实现父子分区之间通信的一种机制,它类似于系统调用,允许子分区向父分区发出请求,如创建或销毁分区、配置虚拟设备、设置内存映射等。VMCALL 是一种专门用于虚拟化的硬件指令,它可以将控制权从子分区转移到父分区,从而触发 HyperCall 的处理。
VMBus – 用于分区间通信的通信机制。通过“vmbus.sys”驱动中的逻辑“合成中断控制器”(SynIC)实现。这是 Hyper-V 中用于实现分区间高效数据传输的一种机制,它基于内存共享和事件通知的原理,通过一个虚拟总线来连接不同的分区,并提供一些标准化和定制化的虚拟设备协议。SynIC 是一种软件虚拟控制器,它负责接收来自硬件(在虚拟机监控器中)的中断,并正确地分发到目标分区。
SynIC – 合成中断控制器是一种软件虚拟控制器,它负责接收来自硬件(在虚拟机监控器中)的中断,并正确地分发到目标分区。这是 Hyper-V 中用于实现分区间事件通知和消息传递的一种组件,它由两部分组成:合成中断源(SINT)和合成消息传递(SMSG)。SINT 负责为每个分区提供 16 个可配置的中断源,用于接收来自其他分区或虚拟机监控器的事件通知;SMSG 负责为每个分区提供一个消息队列,用于接收来自其他分区或虚拟机监控器的消息数据。
VMMS – 虚拟机管理服务是负责管理每个虚拟机的状态的服务。它与 Hyper-V 管理控制台(使用 COM)连接,并负责为每个虚拟机生成一个 VMWP 实例。这是 Hyper-V 中用于实现虚拟机的创建、配置、启动、停止、暂停、恢复等操作的一个服务,它运行在根分区中,通过 WMI 接口与 Hyper-V 管理控制台进行交互,并通过 WinHv 驱动与虚拟机监控器进行通信。
VMWP – 虚拟机工作进程:协调虚拟机的生命周期,并负责与 VID 驱动进行通信。这是 Hyper-V 中用于实现虚拟机的运行和监控的一个进程,它运行在根分区中,由 VMMS 服务为每个虚拟机生成一个实例,并与 VID 驱动进行交互,以处理一些内存相关的事件和请求
VID - 虚拟化基础设施驱动 - 为分区提供分区管理服务、虚拟处理器管理服务和内存管理服务。这是 Hyper-V 中用于实现分区的创建、配置、销毁、运行和监控的一个驱动程序,它运行在根分区中,通过 WinHv 驱动与虚拟机监控器进行通信。
WinHv – 为根分区和子分区实现每个 HyperCall(两个不同的版本)。这是 Hyper-V 中用于实现 HyperCall 的处理的一个驱动程序,它运行在根分区中,通过虚拟化硬件接口(如 Intel VT-x 或 AMD SVM)与虚拟机监控器进行交互
WinHv 有两个不同的版本,一个是为根分区使用的,另一个是为子分区使用的。
>为根分区使用的 WinHv 驱动可以直接访问虚拟化硬件接口,而不需要经过虚拟机监控器。
>为子分区使用的 WinHv 驱动需要经过虚拟机监控器来访问虚拟化硬件接口.
Enlightenments启发式(这个就有点复杂了)
Hyper-V Enlightenments 是一些用于提高虚拟机性能和兼容性的特性,它们让 Windows 和 Hyper-V 的客户机运行在 Hyper-V 虚拟化平台上,并使用 Hyper-V 特定的功能。Hyper-V 是一种虚拟化技术,它可以在一个物理机器上运行多个虚拟机,每个虚拟机都有自己的操作系统和应用程序。
以下是 Hyper-V Enlightenments 的一些主要特性:
1、启发式内存管理(Enlightened Memory Management):Hyper-V 在虚拟机中使用一种称为“动态内存”的技术,它允许虚拟机根据需要动态分配和释放内存。这种内存管理方式能够提供更好的性能和资源利用率。Hyper-V 使用了一种称为“气球驱动程序”(Balloon Driver)的技术,它可以在虚拟机之间动态地调整内存分配,以达到最优的内存利用率。
2、启发式网络(Enlightened Networking):Hyper-V 虚拟机可以直接访问物理网络,而无需通过虚拟交换机。这种直接访问网络的方式可以提供更低的延迟和更高的网络吞吐量。Hyper-V 使用了一种称为“SR-IOV”(Single Root I/O Virtualization)的技术,它可以让虚拟机直接访问物理网络设备,而无需通过虚拟交换机。这样可以提高网络性能和安全性。
3、启发式存储(Enlightened Storage):Hyper-V 支持虚拟机中的虚拟磁盘(VHD)和虚拟固态硬盘(VHDX)。通过使用启发式存储功能,虚拟机可以利用物理存储设备的高级功能,例如 Trim 命令和数据去重。Hyper-V 支持了一种称为“直通磁盘”(Pass-through Disk)的技术,它可以让虚拟机直接访问物理磁盘或者 SAN 设备,而无需使用 VHD 或 VHDX 文件。这样可以提高存储性能和灵活性。
4、启发式计时器(Enlightened Timer):Hyper-V 虚拟机中的计时器可以通过与物理主机的时钟同步来提供更准确的时间保持。这对于需要高精度计时的应用程序和服务非常重要。
5、快速一致性(Fast Consistency):Hyper-V Enlightenments 提供了一种快速的一致性机制,用于在虚拟机和宿主机之间进行数据和状态的同步。这可以减少虚拟机和宿主机之间的通信延迟,并提高虚拟机的性能。
通过启用 Hyper-V Enlightenments,虚拟机可以更好地利用物理主机的硬件资源,并获得更高的性能和效率。虚拟机操作系统和 Hyper-V 之间的协作改进了虚拟化的性能,并提供了更接近于物理机的体验。
0x2 引导过程
1、检查启动选项:如果系统不是在安全模式下,并且如果虚拟机监控器启动类型设置为自动,那么就启动虚拟机监控器设置的第 0 阶段。这是 Hyper-V 启动过程的第一步,它由 Windows 启动加载程序(Winload)执行,用于检测系统是否需要启动虚拟机监控器,并进行一些准备工作,如分配内存、设置页表、加载虚拟机监控器镜像等。
2、HvLoader 是负责检测合适的硬件,验证其能力,并将合适的 Hyper-V 镜像加载到内存中的模块。这是 Hyper-V 启动过程的第二步,它由虚拟机监控器设置的第 0 阶段执行,用于检测系统是否支持虚拟化硬件接口(如 Intel VT-x 或 AMD SVM),并根据系统的架构(如 x86 或 x64)选择合适的 Hyper-V 镜像文件(如 hvax64.exe 或 hvix64.exe),并将其加载到内存中。
3、执行控制权返回给 Winload。这是 Hyper-V 启动过程的第三步,它由 HvLoader 执行,用于将执行控制权交还给 Winload,以便 Winload 继续执行其标准的初始化工作。
4、Winload 继续其标准的初始化工作(Mm, ASLR, CI, Boot modules 等),调用 ExitBootServices UEFI API,并最终启动虚拟机监控器(OslArchHypervisorSetup 最终阶段 1)。这是 Hyper-V 启动过程的第四步,它由 Winload 执行,用于完成 Windows 内核和其他启动模块的加载和验证工作,并在退出 UEFI 启动服务后,调用 OslArchHypervisorSetup 的最终阶段 1 来正式启动虚拟机监控器。
5、Hyper-V 的主可执行文件是一个迷你操作系统。在 INIT 阶段之后,它创建一个根分区和虚拟处理器(VP),并执行 VMLAUNCH。新的虚拟机从 Winload* 开始。这是 Hyper-V 启动过程的第五步,它由虚拟机监控器执行,用于初始化虚拟机监控器的内部结构和组件,并创建一个根分区和一个虚拟处理器(VP),然后执行 VMLAUNCH 指令来启动根分区的虚拟机。新的虚拟机从 Winload* 开始,这是一个与 Winload 类似的启动加载程序,但是专门用于虚拟机的启动。
6、Winload 正常地执行 Windows 内核(在第 4 步加载)。这是 Hyper-V 启动过程的第六步,它由根分区的 Winload* 执行,用于加载和执行 Windows 内核,从而完成根分区的启动。根分区是运行在主机上的 Windows Server,它负责创建和监控其他子分区,并与 Hyper-V 通信。
0x3 HyperV进程和线程
1、Hyper-V 用一个分区数据结构(Partition)来表示一个虚拟机。这是 Hyper-V 中用于描述虚拟机的属性和资源的一种数据结构,它包含了一些字段,如分区 ID、分区类型、分区状态、分区权限、分区内存、分区 CPU 等。Hyper-V 通过 HyperCall API 来创建和管理分区。
2、虚拟机中的每个 CPU 都由一个“虚拟处理器”结构来表示。这是 Hyper-V 中用于描述虚拟机中的逻辑处理器的一种数据结构,它包含了一些字段,如 VP ID、VP 状态、VP 上下文、VP 运行时间等。Hyper-V 通过 VID 驱动来创建和管理 VP。
3、Hyper-V 操作系统应该能够在不同虚拟机的每个 VP 之间进行上下文切换。这是 Hyper-V 中用于实现虚拟处理器的调度和运行的一种机制,它涉及到两个层次:Hypervisor 层和 Root Partition 层。Hypervisor 层负责在物理处理器(PP)上调度 VP,并在 PP 上执行 VMLAUNCH 或 VMRESUME 指令来启动或恢复 VP 的运行;Root Partition 层负责在 VMWP 进程中协调 VP 的生命周期,并与 VID 驱动进行交互,以处理一些内存相关的事件和请求。
常规认识上的区别:
进程 - > 虚拟地址空间/正在执行的程序的容器 - > 在 Hyper-V 中是物理地址空间/正在执行的虚拟机的容器。这是 Hyper-V 中用于比较 Windows NT 内核中的进程概念和 Hyper-V 操作系统中的进程概念的一种方式,它说明了两者之间有很大的区别,它们不能直接相互比较或转换。Windows NT 内核中的进程是指一个运行在用户模式或内核模式下的应用程序实例,它有自己的虚拟地址空间、句柄表、安全上下文等;Hyper-V 操作系统中的进程是指一个运行在 Hypervisor 模式下的虚拟机实例,它有自己的物理地址空间、客户机物理地址空间、客户机状态区域等。
线程 - > 基本的执行单元 - > 在 Hyper-V 中也是一样,它表示一个可以由虚拟机监控器调度的虚拟处理器。这是 Hyper-V 中用于比较 Windows NT 内核中的线程概念和 Hyper-V 操作系统中的线程概念的一种方式,它说明了两者之间有一定的相似性,但也有一些区别。Windows NT 内核中的线程是指一个运行在用户模式或内核模式下的执行单元,它有自己的上下文、栈、优先级等;Hyper-V 操作系统中的线程是指一个运行在 Hypervisor 模式下的虚拟处理器,它有自己的上下文、栈、运行时间等。
写到这里,上面已经简单的介绍了一下HyperV是个什么东西了,从这里开始,就要写一些具体的应用在windows上面的东西了。
0x4 Windows上的应用
Windows 10 20H1是微软在2020年5月发布的一次重大的Windows 10更新,也被称为Windows 10 2004或Windows 10 May 2020 Update。这次更新带来了许多新的功能和改进,其中最引人注目的是VA-backed虚拟机和容器化技术,这些技术使得Windows 10成为了第一个为云计算而设计的Windows内核。
VA-backed虚拟机是一种使用主机的虚拟地址空间来支持客户机的虚拟内存的虚拟机。这种虚拟机可以提高主机的内存利用率,减少内存浪费,提高虚拟机的密度和性能。VA-backed虚拟机的一个应用场景是容器化,即在被称为容器的隔离环境中运行传统的软件。容器可以共享同一个虚拟机的固件、操作系统和一些应用程序,从而降低内存占用。容器也可以提供完全的隔离,保护浏览器或沙盒中的数据安全。
(VA-backed虚拟机是由VID驱动程序创建的,它使用了一些Hyper-V的特性,如SLAT表、GPA和SPA映射、VMEXIT和内存拦截等。VID驱动程序通过调用NtAllocateVirtualMemory API来分配主机的虚拟地址空间,并通过调用HvMapGpaPages hypercall来将客户机的物理地址空间映射到一个特殊的无效SPA。当客户机访问这些无效SPA时,会触发VMEXIT到hypervisor,然后hypervisor会向根分区注入内存拦截,由VID驱动程序处理。VID驱动程序会根据客户机的需求来分配或释放主机的物理内存,并更新SLAT表中的映射关系。)
容器化技术是一种将软件和其依赖项打包在一起的技术,使得软件可以在不同的环境中快速、轻量地运行。容器化技术可以提高软件的可移植性、可扩展性、安全性和效率。Windows 10 20H1支持了两种类型的容器:Hyper-V容器(Hyper-V container)和Windows Server容器(Windows Server container)。
Hyper-V容器是一种基于VA-backed虚拟机的容器,它提供了完全的隔离和安全性,适合运行敏感或不受信任的软件。
Windows Server容器是一种基于共享内核的容器,它提供了更高的性能和密度,适合运行可信或轻量的软件。
Windows 10 20H1还提供了一些工具和服务来支持VA-backed虚拟机和容器化技术,例如:
- VMMEM(Virtual Machine Memory):一种新的进程类型,用于管理VA-backed虚拟机和容器的内存资源。VMMEM进程可以动态地分配或释放主机的物理内存,并与客户机进行内存压缩、解压缩和交换。
- VID(Virtualization Infrastructure Driver):一种新的驱动程序,用于创建和控制VA-backed虚拟机和容器。VID驱动程序可以与Hyper-V hypervisor进行通信,并处理客户机发起的VMEXIT和内存拦截。
- WinHv Platform API Library 一种新的API库,用于允许第三方开发者创建和管理EXO分区。EXO分区是一种与Hyper-V兼容并可以同时运行的虚拟机分区,用于支持第三方开发者的虚拟化解决方案,如VirtualBox、Qemu、VMware等。
- Windows Defender Application Guard 一种新的安全服务,用于在一个隔离的Hyper-V容器中运行Microsoft Edge浏览器,以防止恶意网站或文件对主机造成损害。
- Windows Sandbox 一种新的沙盒工具,用于在一个隔离的Hyper-V容器中运行任意软件,以测试其功能或安全性。
Prtn分区和EXO分区(Prtn和exo):Prtn是根据逆向得到名词,非官方
ptrn分区和exo分区是两种不同类型的虚拟机分区。
ptrn分区是由VID驱动程序创建的,用于支持VA-backed虚拟机,即使用主机的虚拟地址空间来支持客户机的虚拟内存的虚拟机。
exo分区是由WinHv平台API库创建的,用于支持第三方开发者的虚拟化解决方案,使其与Hyper-V兼容,并允许同时运行它们。
ptrn分区和exo分区的主要区别是,ptrn分区使用Prtn结构来存储Partition对象和分区句柄,而exo分区使用ExoPartition结构来存储ExoPartition对象和分区句柄。
0x5 结束
快要上飞机了,那HyperV的基本先介绍到这里,后续会将实验和各个点再来分享(有时间的情况下),了解了原理后,就可以自己写一个基于HyperV的调试插件出来,最后再截一张图(读写vmwp.exe很重要,通过他来得到关键结构)。