Qemu Fuzzer 学习
本文章来自于开源软件供应链点亮计划的Openeuler社区项目
项目名称:No.112 qemu设备fuzz测试完善
前言
一提到 Qemu + Fuzz 的组合,我首先想起的是AFL的Qemu模式,或者是各种使用虚拟化技术对IoT设备进行Fuzzing的工具。
而本文学习的是Qemu自身的Fuzzing框架,即对Hypervisor的Fuzzing。它借助Qtest框架模拟Guest OS对设备的读写,并使用LibFuzzer的启发式算法提供数据驱动。该框架最早源于Google Summer of Code 2019
项目,在Qemu5.0.0版本后被加入到master分支中。
Qemu 设备模拟原理
Qemu
是一款开源的虚拟化和仿真工具,由Fabrice Bellard
实现。Qemu支持两种模式的仿真:
system mode
:对于CPU,内存以及外设的全系统仿真,提供KVM,Hyper-V等加速方式user mode
:通过指令翻译在一种架构的CPU上运行另一种CPU架构的二进制程序
首先需要理解虚拟化的本质在于:使用一个用户态的程序,在只使用用户态内存的情况下,来处理模拟设备对内存以及其他特殊硬件的访问。由于Qemu需要仿真不同架构,不同指令集的设备,所以其采用了OOP的编程思想,实现了Qemu Object Model
来描述设备模型。
- 设备模型:每个模拟出来的设备都对应一个TypeInfo对象,由设备名唯一标识,并存储在hash table中
- 设备启动:启动设备需要经过设备注册,设备类型初始化,设备实例化等步骤,
- 指令翻译:真正运行时,Qemu通过TCG(软件)或者KVM(硬件)等方式,接受模拟设备的指令,并翻译到物理设备上执行。这样会带来性能开销,相比起来硬件虚拟化带来的开销更低
- 内存模拟:Qemu负责提供内存映射给客户机。当客户机访问这部分内存以便写磁盘时,Qemu会捕获访问,并且将请求传送给qemu的IDE控制器设备模型,模型会解析I/O请求并且通过宿主机的系统调用来模拟指令。最终将客户机的内存拷贝至宿主机的磁盘中。
总之,在Guest OS中,它认为自己可以直接和Host OS上的硬件设备打交道,Qemu充当了中间人的角色,可以用下图来概括:
+----------+ +----------+ +----------+ +----------+ +----------+
| UserSpace| | UserSpace| | UserSpace| | UserSpace| | UserSpace|
+----------+ +----------+ +----------+ +----------+ +----------+
| Linux | | Mac OS | | Windows | | Linux | | Solaris |
+----------+ +----------+ +----------+ +----------+ +----------+
| Drivers | | Drivers | | Drivers | | Drivers | | Drivers |
+----------+ +----------+ +----------+ +----------+ +----------+
+----------+ +----------+ +----------+ +----------+ +----------+
| QEMU x86 | | QEMU x86 | | QEMU ARM | | QEMU PPC | | QEMU MIPS|
+----------+ +----------+ +----------+ +----------+ +----------+
+----------+-+----------+-+----------+-+----------+-+----------+
| Host System:Linux,Mac OS,Windows |
+--------------------------------------------------------------+
+--------------------------------------------------------------+
| Hardware:CPU,memory,disk,networking,USB,etc |
+--------------------------------------------------------------+
关于Qemu设备模拟的方法,可以参考
User Documentation
关于Qemu设备模拟的理解,可以参考understanding Qemu devices
Qemu作者的论文:QEMU, a Fast and Portable Dynamic Translator
Qemu Fuzzer 的使用方法
实验环境
采用了本机的WSL上的Docker环境
root@31b23c4c00b7:~/qemu# lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 16
root@31b23c4c00b7:~/qemu# cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.2 LTS (Focal Fossa)"
环境问题
- 描述:Qemu的Fuzzing还没有适配AArch64架构,虽然编译成功,但运行报错。