VT技术对于除零异常的拦截与派发到3号中断
Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html
VT技术对于除零异常的拦截与派发到3号中断
1. 异常的拦截与处理
①异常的拦截
VMCS域中有一个32位的Exception Bitmap域,bit 13表示要拦截 13号中断,产生VmExit,然后自己自行处理;
想要修改Exception BitMap,必须使用 __vmx_vmwrite() API来进行修改,Exception BitMap的控制字段ID为 4004H;
因此,如果想对除零异常进行拦截,要这么写: __vmx_vmwrite(4004H,1);
②Vm-Exit的拦截与处理
Vm-Exit异常对于异常的拦截分为三类:#DB、#PF、直接向量事件类。
这个除零异常显然属于“直接向量事件类”,其存在两个信息类字段:
我们现在来看看VM_EXIT_INTERRUPTION_INFORMATION字段的定义:
我们根据 valid值 来判断这个字段是否有效;
根据 error code 判断是否有错误码,如果存在错误码,则读取 vm-exit interrupt error code 来获取响应值 ;
根据 type 来判断是 硬件异常 还是 软件异常;
根据 vector == 0 ?来判断其是否属于除零异常,来进行下步操作。
③ 对于 trap类型 与 fault 类型处理
我们在中断异常中遇到过两种类型 trap 与 fault ,其明显区别是是否重新执行该条指令;
我们在vmexit_handler中显然不必过于担心这个,因为我们返回到guest机的RIP或EIP是由我们自己决定的;
因此我们resume前指定好该值就好。
2. 事件注入
VT中存在一个特性是“事件注入”,其在执行guest指令前,注入事件,则resume恢复前,其会先执行注入事件。
有关注入事件,其在 VM-Entry 的控制域,可以查阅有关手册来查找信息。
我们所需要的就是注入一个int 3的事件,我们看 VM-entry interruption-information field 的构成。
因此我们填充好该域之后执行 vmresume恢复运行,即可触发 int 3 中断。
值得注意的是,在resume前,Guest->Rip要加上指定长度来跳过除零异常,否则就会无限死循环。
3. 测试代码与测试效果