亚博在线娱乐官方网址论坛

快捷导航
广告联系qq1031180668广告位
查看: 197|回复: 0
打印 上一主题 下一主题

[逆向破解/内核驱动] 微软编译器关于VMX指令内置宏的指令生成规则

[复制链接]

classn_11

36

主题

36

帖子

74

积分

注册会员

Rank: 2

积分
74
跳转到指定楼层
楼主
发表于 2019-7-4 12:41:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近弄的产品要搞VT,由于不想抄网上的代码(有的有坑,比如HyperBone;有的很难编译,比如Intel的HAXM,官方的编译方案是用VC2017;还有些是用令人蛋疼的C艹写的,比如HyperPlatform),所以就准备自己设计一套可以让WDK7编译的VT框架。既然是VT,少不了调用VMX指令。微软提供了VMX指令相关的编译器内置宏,不过这些宏也是有坑的:
只有vmxoff指令和vmptrst指令有32位版本,其他的指令只有64位版。此外,invept, invvpid, vmcall指令既没有64位版,也没有32位版!
所以我们有必要自己动手写汇编去调用这些指令。
首先声明一点:微软的编译器是不支持VMX指令的助记符的,只有汇编器才支持!
此外,内联汇编看起来非常突兀,所以本人决定不去写内联汇编。
综上所述,方案是自己写外联汇编去调用VMX指令。

根据Intel架构手册,VMX指令的调用有如下规定:
当执行成功时,将CF,PF,AF,ZF,SF,OF位复位
当执行失败时,若当前VMCS有效,则将ZF置位,其他复位。
当执行失败时,若当前VMCS无效,则将CF置位,其他复位。
不存在指令执行后CF和ZF同时置位的情况。

对应MSDN上关于VMX宏的描述,我们可以得出下列结论:
当执行成功时,返回0。
当执行失败时,若当前VMCS有效,则返回1。
当执行失败时,若当前VMCS无效,则返回2。

很明显我们需要模仿MSDN的玩法。但我马上就发现一个问题:怎么写代码最有效?
放到三年前,由于对汇编十分生疏,我会直接把EFLAGS给pop到eax寄存器里然后搞位操作。
这个方法很明显代码量会很大。
放到一年前,稍微懂一点点汇编了,我会用jc和jz指令来分条件对eax寄存器进行赋值。
这个方法很明显代码量也会大。而且还会破坏Intel CPU乱序执行的指令队列。

怎么写最高效其实应该参考编译器的做法,经研究,编译器的做法如下:
调用VMX指令。
分别执行setc cl和setz al。这样一来,当CF置位时cl=1,当ZF置位时al=1。
执行adc al,cl指令,这相当于al+=(cl+EFLAGS.CF)。于是有当CF置位时al=2,ZF置位时al=1。
若返回值不是八位变量,则执行movzx指令将高位清零。

这样一来,如果我们要用MASM写一个专门调用VMX指令的函数,按照上面的规则来就行。

以在32位下调用vmxon指令为例,这个指令对应__vmx_on宏,我们可以这么写代码:

[C] syntaxhighlighter_viewsource syntaxhighlighter_copycode
__vmx_on proc vmxon_region:dword
 
        vmxon qword ptr[vmxon_region]
        setc cl
        setz al
        adc al,cl
        movzx eax,al
        ret
 
__vmx_on endp

顺便一提,MASM中invept和invvpid指令是有坑的,它的指令操作数顺序和Intel手册上的描述是相反的。
以在64位下调用invept指令为例,我们可以这么写代码:
[C] syntaxhighlighter_viewsource syntaxhighlighter_copycode
__vmx_invept proc
 
        invept xmmword ptr[rdx],rcx
        setc cl
        setz al
        adc al,cl
        movzx eax,al
        ret
 
__vmx_invept

可能有人要问,参数呢?因为MASM64的参数是老式的stdcall风格的,且不支持fastcall,所以就干脆直接上rcx rdx寄存器了。
参数定义了啥,自己去看Intel手册吧,不多说了。
invvpid和invept指令相似,照着写就行。
vmcall的函数爱怎么定义怎么定义。只要你的Exit-Handler可以正确地Handle它就行了。
由于VMX指令是特殊的指令集,所以在MASM32里我们要在代码文件的头上加一行.686p才能让汇编器正确识别VMX指令。
游客
yabo88手机版 回复
您需要登录后才可以回帖 登录 | 立即注册

手机版|Archiver|小黑屋|sitemap| 从零开始,亚博在线娱乐官方网址论坛 - 一个单纯的亚博在线娱乐官方网址学习交流论坛 ( 豫ICP备15032706号 )

GMT+8, 2019-8-11 09:39 , Processed in 1.191963 second(s), 22 queries .

Powered by Discuz! X3.4

? 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表