专业丰富的破解论坛技术交流,提供软件安全,病毒分析,脱壳破解,安卓破解,加密解密等,由无数热衷于软件爱好者共同维护
 
发新帖
楼主: 零五零八
查看: 925|回复: 0

[技术文章] 逆向win10 1909的MmIsAddressValidEx分析 999912分页

[复制链接]
零五零八 发表于 2020-10-15 12:15:28 | 显示全部楼层
本帖最后由 零五零八 于 2020-10-15 12:18 编辑

  通过逆向win10 1909的MmIsAddressValidEx函数,对windows内存分页管理的理解上有很大帮助。通过win7和xp下对比 win10 1909下此函数对自映射的体现非常明显。废话不对说,直接开始:

简单聊下函数原理

  这个函数是通过判断物理页的P为是否为1来判断是否存在物理页,从而判断虚拟地址是否有效。
因为个人表达能力有限,怕后面逆向的时候一笔带过,对他人不友好,特从Intel白皮和潘爱民老师的windows内核原理与实现里摘出来自映射和分页结构图(大佬们请忽略)


windows分页

1.png

自映射
就从自映射的资料,供参考:

2.png

3.png

4.png

接下来我们逆向分析
MmIsAddressValid函数原型如下:

  1. NTKERNELAPI
  2. BOOLEAN
  3. MmIsAddressValid (
  4.     _In_ PVOID VirtualAddress
  5.     );
复制代码

5.png

  可以从上图看出 MmIsAddressValid调用了MmIsAddressValidEx,通过x64和上图可以看出调用约定是fastcall,那么我们得参数VirtualAddress在rcx中。MmIsAddressValid函数并没有做什么事,那我们开始分析MmIsAddressValidEx。


6.png

接下来我截图一块块分析

8.png .

  从我红框处可以看出 rax就是我们传入的参数VirtualAddress,右移0x2F(47位)+1 这里在验证我们传入的地址是否有效,但是我们知道x64地址是否有效是判断前面16位是否是FFFF或者0000,那么按理来说应该右移48位,为何只右移了47位?
这里我不得不提windows的三环和0环地址,X64 地址空间分开成2部分
用户模式地址的范围:0x0000000000000000~0x00007FFFFFFFFFFF;
内核模式地址的范围:0xFFFF800000000000~0xFFFFFFFFFFFFFFFF。
从上面可以看出 算数右移47位 如果地址是有效的那么我们得到的结果一定是内核:0xFFFFFFFFFFFFFFFF,用户:0,所以+1之后要么就是0要么就是1,如果大于1 地址一定无效,比如0xffff700000000000,这个地址既不在内核地址范围,也不在用户地址范围,右移47位的结果是0xFFFFFFFFFFFFFFFE,如果这个值+1等于0xFFFFFFFFFFFFFFFF,ja是无符号大于跳转,所以就跳转直接返回了。
过滤完上述情况后

9.png

  这里我们可以看到rdi这个值就是PTEBASE,(在x64上这个PTEBASE的值每次重启都会随机生成),通过从PTEBASE来寻找到对应得物理页的PTE,shr rdx,9这句意思是相当于得到虚拟地址的PTE索引再8,也就是先右移12位然后8。
接下来我们就看到自映射的原理了

10.png

这段代码似曾相识,其实是通过pte映射的虚拟地址,得到PTE的物理页,也就是PDE。然后接下来我们看到的其实也是相似的。

11.png


通过PDE映射的虚拟地址得到PPE

12.png

通过PPE映射的虚拟地址得到PML4也有人成为PXE

13.png

接下来通过这段来循环判断是否是大页,物理页的P为是否为1。

因个人表达能力有限,敬请谅解


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