一、找到 MmIsAddressValid 函数
方法一:在windbg中输入 u MmIsAddressValid
方法二:在c:\windows\system32\ 中找到内核程序,用IDA分析。
ntkrnlpa.exe 2-9-9-12 分页内核
ntoskrnl.exe 10-10-12 分页内核
打开 ntoskrnl.exe 后,导入pdb文件,即可查看函数名称。
如果你没有pdb文件,请先安装对应系统版本的符号文件。
二、分析代码
先作一些说明,关于PAT位,我不清楚其作用,因此不做分析。
正式分析前,先聊聊函数头的 MOV EDI,EDI 指令。这条指令看起来什么也没做,但是很多系统函数开头都有这条指令,why?其实这是为了实现对函数行为的动态修改(热补丁),可以一下这篇文章 函数开始处的MOV EDI, EDI的作用
下面直接贴上我分析后的函数。
.text:0040C65C ; ---------------------------------------------------------------------------
.text:0040C65C nop
.text:0040C65D nop
.text:0040C65E nop
.text:0040C65F nop
.text:0040C660 nop
.text:0040C661 ; Exported entry 685. MmIsAddressValid
.text:0040C661
.text:0040C661 ; =============== S U B R O U T I N E =======================================
.text:0040C661
.text:0040C661 ; Attributes: bp-based frame
.text:0040C661
.text:0040C661 ; BOOLEAN __stdcall MmIsAddressValid(PVOID VirtualAddress)
.text:0040C661 public MmIsAddressValid
.text:0040C661 MmIsAddressValid proc near ; CODE XREF: sub_40D65E+Cp
.text:0040C661 ; sub_415459:loc_415470p ...
.text:0040C661
.text:0040C661 VirtualAddress = dword ptr 8
.text:0040C661
.text:0040C661 ; FUNCTION CHUNK AT .text:0041B856 SIZE 00000007 BYTES
.text:0040C661 ; FUNCTION CHUNK AT .text:0044A562 SIZE 00000019 BYTES
.text:0040C661
.text:0040C661 mov edi, edi
.text:0040C663 push ebp
.text:0040C664 mov ebp, esp
.text:0040C666 mov ecx, [ebp+VirtualAddress] ; ecx=VirtualAddress
.text:0040C669 mov eax, ecx ; eax = VirtualAddress
.text:0040C66B shr eax, 14h ; 右移20位 因为*4=左移2位补0,所以这里直接右移20位
.text:0040C66E mov edx, 0FFCh ; 除PDI外其他位清零 1111 1111 1100 保证补位的都是0
.text:0040C673 and eax, edx ; eax = PDI * 4
.text:0040C675 sub eax, 3FD00000h ; eax += 0xC0300000 此时eax指向PDE
.text:0040C67A mov eax, [eax] ; eax = PDE
.text:0040C67C test al, 1 ; if (P==0) JZ 意思是 P=0 则跳转到非法处理
.text:0040C67E jz loc_41B856
.text:0040C684 test al, al ;判断page size位 if (al < 0) JS 意思是 PS=1(大页)就返回1
.text:0040C686 js short loc_40C6AC ; 返回1,表示线性地址有效
.text:0040C688 shr ecx, 0Ah ; ecx(VirtualAddress) >> 10 右移10位
.text:0040C68B and ecx, 3FFFFCh ; 除PDI,PTI外的位清零 0000 0000 0011 1111 1111 1111 1111 1100
.text:0040C691 sub ecx, 40000000h ; ecx = 0xC0000000 + PDI * 4KB + PTI * 4 ecx指向PTE
.text:0040C697 mov eax, ecx
.text:0040C699 mov ecx, [eax] ; ecx = PTE
.text:0040C69B test cl, 1 ; if (P==0) 非法
.text:0040C69E jz loc_41B856
.text:0040C6A4 test cl, cl ; if (PAT == 1) JS 如果 PAT==1 另作判断,我就不分析了
.text:0040C6A6 js loc_44A562
.text:0040C6AC
.text:0040C6AC loc_40C6AC: ; CODE XREF: MmIsAddressValid+25j
.text:0040C6AC ; MmIsAddressValid+3DF0Fj
.text:0040C6AC mov al, 1 ; 返回1,表示线性地址有效
.text:0040C6AE
.text:0040C6AE loc_40C6AE: ; CODE XREF: MmIsAddressValid+F1F7j
.text:0040C6AE pop ebp
.text:0040C6AF retn 4
.text:0040C6AF MmIsAddressValid endp
MmIsAddressValid 函数和我们之前练习时做的事情是一样的,主要就是判断PDE和PTE是否 P=1。MmIsAddressValid 是系统函数,它的效率是很高的,位运算看起来有点费脑,目的也是减少指令数。
---------------------
作者:hambaga
来源:CSDN
原文:https://blog.csdn.net/Kwansy/article/details/108945068
版权声明:本文为作者原创文章,转载请附上博文链接!
内容解析By:CSDN,CNBLOG博客文章一键转载插件