浅谈EPT无痕HOOK的方法
前言
目前过pg的主流方法
在进入VMX操作,一个很有用的功能就是在开启EPT机制后,进行1:1身份映射后HOST GUEST
进行EPT HOOK,通常作用有两种
- 无痕监控读写,类似调试器的内存读写断点
- 无痕Hook,类似调试器的调试断点
对于第一种实现起来很简单,方法也基本一致
通常是EPT Entry属性修改为不可读写,触发EPT Violation在其中进行MTF位
同时设置可读写,让这行代码可以执行。MTF Handler中设置为不可执行
从而实现无痕监控读写
而对于第二种EPT的应用方法,目前来说大概有三种
无需MTF置位的无痕Hook
方式和周壑的VT一样,思路如下
- 设置EPT页级Hook,使整读和写页无效,而只留下可执行属性
- 分配一个新的物理内存(P2),EPT中的EPT Pml1Entry的PhyFrameNumber(原来的P1)替换成新分配的
- 修改P2,使其变成一个绝对跳转,跳转到Hook的地方去执行
- 页面受到读写访问,EPT Violation,此时将此页面为可读写,不可执行
- 下次执行的时候,遇到不可执行内存,EPT Violation再次恢复可执行,不可读写
缺点
此Hook有个很大的缺陷,考虑如下。
1 | hook_4kb_addr: |
这样就会无限MTF,不断的切换不可读写,可读写,导致CPU卡死
仿内存执行断点的无痕Hook
方法如下:
- 设置页面HOOK,全程可读写,不可执行
- 这样有可能就会某一次到要HOOK的地方,但是页可能不到
- 如果没到,而是其他地址,恢复可执行,并设置MTF,在MTF Handler中恢复不可执行
- 直到遇到要Hook的地方,HOST中直接VMWRITE,修改GUEST_RIP
缺点
遇到4kb页面访问次数多的,会巨卡无比。
MTF置位全程可执行的无痕Hook
- 设置EPT页级Hook,使整读和写页无效,而只留下可执行属性
- 分配一个新的物理内存(P2),EPT中的EPT Pml1Entry的PhyFrameNumber(原来的P1)替换成新分配的
- 修改P2,使其变成一个绝对跳转,跳转到Hook的地方去执行
- 页面受到读写访问,EPT Violation,此时将此页面可读/写,并设置MTF位
- MTF VM Exit,判断是否是EPT Hook导致的,是则设置不可读写,并替换回P2物理内存。
缺点
缺点不太明显,适合Hook内核函数,而对于高频CRC校验的函数,不太适合,总的来说是最适合的EPT无痕Hook了。