2. Hyper-V的结构
随着Hyper-V的发展,它内部的体系结构也渐渐成熟稳定。我们下面将介绍Hyper-V的体系结构,主要是了解Hyper-V内部虚拟化的大致原理。并且介绍Hyper-V主要组件的功能和这些组件之间的关系。
2.1. Hyper-V虚拟化原理和实现方式
Hyper-V和其他虚拟化产品例如KVM,VMware等都使用了相同的硬件虚拟化技术—Intel VT技术或者AMD-V技术。使用这种技术的虚拟化产品可以很好的提升虚拟机的性能,大幅提高虚拟化的性能,同时保证了虚拟化的完整性和安全性。
可以说Intel VT 或 AMD-V技术是Hyper-V虚拟化的核心。Hyper-V将这类硬件虚拟化技术用在宿主机和虚拟机的管理和数据交换上,也就是说,这类硬件虚拟化技术成为了宿主机和虚拟机之间的“信使”,掌管着虚拟机的状态信息以及宿主机和虚拟机之间的数据信息交换。如果将Hyper-V比喻为一棵大树的话,那么Intel VT 或 AMD-V技术就是大树的根,一切的虚拟化操作都离不开这棵“大树”的“根”。
在Hyper-V中,Intel VT 和 AMD-V实现了Hypervisor层的逻辑,并且将Hypervisor层的功能封装在一个可执行性文件中。如果宿主机为Intel CPU,那么Hyper-V将使用C:\Windows\System32\hvix64.exe文件作为Hypervisor层的实现;如果宿主机为AMD CPU,那么Hyper-V会使用C:\Windows\System32\hvax64.exe文件作为Hypervisor层的实现。
在安装了Hyper-V的Windows系统启动过程中,会先运行hvix64.exe或hvax64.exe来初始化Hypervisor层,然后再运行Windows内核ntoskrnl.exe进行Windows系统的初始化过程。这个过程里,Hypervisor层的代码级别要比Windows内核代码级别高,实际上,微软把Hypervisor层称之为Ring -1级别,而Windows内核代码级别为Ring 0。Windows宿主机也称为Root Partition,其他的虚拟机称之为Child Partition,事实上无论是宿主机还是虚拟机都是运行在同一个级别下的,也就是说宿主机系统内核代码和虚拟机系统内核代码运行级别是相同的。不同的是宿主机有管理虚拟机的状态的权限,可以对虚拟机进行开机关机增添设备等操作,但是底层代码运行级别却是一样的。宿主机和虚拟机之间的关系如图1-18。
图1-18
宿主机和虚拟机之间的通信是通过Intel VT特权指令实现的,无论是在宿主机还是虚拟机,当需要通知宿主机或虚拟机有数据需要传输或接收时,都会在内核态执行vmcall汇编指令。这时,宿主机/虚拟机引发了一个vm-exit事件,于是Hypervisor层的代码开始处理相关的请求。下面我们会介绍Hyper-V虚拟化的实现方式,但是在这之前,我们需要了解一些概念。
Intel VT指令
VM-EXIT:从VMX non-root operation切换到VMX root operation的行为。可以理解为:虚拟机/宿主机中的代码切换到了Hypervisor层的代码,并在Hypervisor层完成一些操作。
VM-ENTRY: 从VMX root operation切换到VMX non-root operation的行为。可以理解为:Hypervisor层的代码切换到了虚拟机/宿主机中的代码,即Hypervisor层完成了某些操作返回到虚拟机/宿主机中继续运行。
VMCALL指令:在虚拟机/宿主机中执行VMCALL指令会引发一个VM-EXIT事件,并且陷入Hypervisor层处理。VMCALL指令即调用服务例程指令。
Hypercall
Hyper-V中的Hypercall和XEN中的Hypercall是非常相似的,都是用于和Hypervisor层进行交互的接口。他们都调用了VMCALL指令,用来进入Hypervisor层的代码。VMCALL指令非常类似于系统调用SYSCALL指令,主要用于虚拟机/宿主机调用Hypervisor中的例程。
VMBus总线
VMBus总线是Hyper-V抽象出来用于数据传输的通信信道。VMBus起着虚拟机和宿主机之间的信息交流作用,并且所有虚拟设备的数据全部由VMBus总线进行处理和分发。每个虚拟设备都会分配自己的Channel,每个Channel都对应着一个环形的内存结构,每次从VMBus总线接收和发送数据,都要向这个环形内存中读写,而且,只有当这个环形内存读满一圈或者写满才会通知宿主机继续发送数据或者接收数据。
虚拟设备驱动
和QEMU模拟设备端口读写的方法不同的是,Hyper-V全部使用了虚拟设备,而不是模拟硬件端口。Hyper-V不再使用传统的读写模拟硬件端口的方式进行硬件设备的虚拟化,而是使用了虚拟设备作为设备模拟。例如,在虚拟机中网卡,硬盘等设备的驱动都是由微软提供,如果没有这些驱动程序,虚拟机则无法使用虚拟设备,就像是QEMU中的VIRTIO设备一样,需要加载特殊驱动,而不是使用和真实硬件一样的驱动。
这些虚拟设备都是由VMBus总线和宿主机进行通信。Hyper-V在虚拟机中的驱动收到虚拟机内核发送来的数据或请求时,会先在Hyper-V虚拟机驱动中做处理,然后将数据或请求通过VMBus总线传到宿主机。这样做的好处是相比于传统的模拟硬件端口有更高的效率并且更好的利用硬件资源。
图1-19是以Linux虚拟机举例,展示Hyper-V内部各部件之间的关系图。其中,虚拟机中的虚拟设备由Devices代替;虚拟设备在宿主机中对应的设备驱动由Host_vdevices代替。
图1-19
上图展示了Hyper-V内部虚拟化的结构。假设现在Linux Guest要发送一个网络数据包,首先Linux kernel将数据传入对应的虚拟网卡驱动中(图中Devices),之后网卡驱动处理从内核传来的数据便将处理后的数据准备经过VMBus总线发出;VMBus将数据处理后,便写入到虚拟网卡Channel对应的环形内存(图中Buffer Ring)中;数据写入完成后,通过Hypercall通知宿主机我有数据需要其接收,虚拟机产生VM-Exit事件,陷入Hypervisor层执行代码。
数据经过Hypervisor层处理完成后,便以触发宿主机中断方式来进行宿主机部分的处理。宿主机的中断处理例程会将包含环形内存地址的数据结构发送到VMBus总线,VMBus读取环形内存的数据,并解析数据,最后将解析后的数据发送到虚拟设备在宿主机(图中Host_vdevices)中对应的设备驱动中处理。
反之,宿主机有数据要发送至虚拟机也是同样的流程。
通过上面介绍可以发现Hyper-V中的虚拟机和宿主机确实是同一权限下运行的,并且,虚拟机可以发送数据到宿主机的驱动中。如果宿主机驱动在解析数据时发生了问题,哪怕只是简单的越界读到一个非法地址,都给宿主机带来的是例如蓝屏之类的严重后果。如果这时Hyper-V虚拟机中运行着各种业务,那带来的损失是不可估量的。但是,也正是因为Hyper-V这种把主要模块放在宿主机Ring0权限下运行的特性,也增大了安全人员对其调试和审计的难度。
以上是对Hyper-V虚拟化的原理和实现方法做一个大致的介绍,之后的内容还会做详细的介绍。
2.2. Hyper-V组件及组件功能
下面我们介绍Hyper-V的组件及功能。我们将Hyper-V使用的文件和系统文件区别开,并加以整理和描述其用途。下列收录的文件是Hyper-V常用功能使用的文件,不能代表Hyper-V使用的所有文件。这些描述主要用于学习,掌握Hyper-V结构,为下面的研究做准备。
同样的,下面组件共能的介绍还是以Linux虚拟机为例。
Hypervisor层
文件名称
文件位置
功能
虚拟机对应设备
hvax64.exe
hvix64.exe
C:\Windows\System32
Hypervisor层逻辑,这一层也被微软称之Ring -1层,主要负责Hyper-V虚拟化。
无
hvloader.exe
hvloader.efi
C:\Windows\System32
用于系统启动时,初始化Hypervisor。
无
表1-1 Hypervisor层组件介绍
内核空间层
文件名称
文件位置
功能
虚拟机对应设备
vmbusr.sys
vmbkmclr.sys
C:\Windows\System32\drivers
VMBus总线
hv_vmbus.ko
winhvr.sys
C:\Windows\System32\drivers
Hypervisor层与宿主机之间交互,并且初始化Hypercall。详细功能类似于Linux kernel中./drivers/hv/hv.c
hv_vmbus.ko
storvsp.sys
C:\Windows\System32\drivers
虚拟硬盘设备
hv_storvsc.ko
vmswitch.sys
vmsproxy.sys
C:\Windows\System32\drivers
虚拟网络交换机设备(网卡)
hv_netvsc.ko
vid.sys
C:\Windows\System32\drivers
虚拟化基础设施(Hyper-V Virtualization Infrastructure)
无
synth3dvsp.sys
C:\Windows\System32\drivers
RemoteFX显示加速
无
hvsocket.sys
C:\Windows\System32\drivers
Hyper-V Socket Provider
无
hvservice.sys
C:\Windows\System32\drivers
Hypervisor Boot Driver
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)