透过MmIsAddressValid看Windows分页机制.docx
《透过MmIsAddressValid看Windows分页机制.docx》由会员分享,可在线阅读,更多相关《透过MmIsAddressValid看Windows分页机制.docx(11页珍藏版)》请在冰豆网上搜索。
![透过MmIsAddressValid看Windows分页机制.docx](https://file1.bdocx.com/fileroot1/2023-1/23/4a047edb-43c0-4bf2-bf59-21e6a8434b60/4a047edb-43c0-4bf2-bf59-21e6a8434b601.gif)
透过MmIsAddressValid看Windows分页机制
这两天在逆向分析MmIsAddressValid这个函数,学习了下PAE分页机制,并且也发现了一个问题。
就是本机ntoskrnl中导出的MmIsAddressValid函数是采用非PAE方式的,而本机XPSP2系统采用的却是PAE方式的分页机制。
这个可以通过windbg中看到。
在这里写出来与大家分享。
关于PAE(PhysicalAddressExtension物理地址扩展)是Intelx86PentiumPro处理器引入的一种内存映射模式。
在此模式下CPU可以访问多达64GB的物理内存。
在PAE模式下PDE和PTE为64位,而不是原来的32位。
其结构如下:
lkd>dt_hardware_pte
nt!
_HARDWARE_PTE
+0x000Valid:
Pos0,1Bit
+0x000Write:
Pos1,1Bit
+0x000Owner:
Pos2,1Bit
+0x000WriteThrough:
Pos3,1Bit
+0x000CacheDisable:
Pos4,1Bit
+0x000Accessed:
Pos5,1Bit
+0x000Dirty:
Pos6,1Bit
+0x000LargePage:
Pos7,1Bit
+0x000Global:
Pos8,1Bit
+0x000CopyOnWrite:
Pos9,1Bit
+0x000Prototype:
Pos10,1Bit
+0x000reserved0:
Pos11,1Bit
+0x000PageFrameNumber:
Pos12,26Bits
+0x000reserved1:
Pos38,26Bits
+0x000LowPart:
Uint4B
+0x004HighPart:
Uint4B
以上具体理论部分可以看下intel的v3.SystemProgrammingGuide。
上面有这两种分页方式的介绍。
非PAE分页,理论部分,看图,分4K和4M两种页。
下面是ida看到的ntoskrnl.exe中导出的MmIsAddressValid。
.text:
0040C661;BOOLEAN__stdcallMmIsAddressValid(PVOIDVirtualAddress)
.text:
0040C661publicMmIsAddressValid
.text:
0040C661MmIsAddressValidprocnear;CODEXREF:
sub_40D65E+Cp
.text:
0040C661;sub_415459:
loc_415470p...
.text:
0040C661
.text:
0040C661VirtualAddress=dwordptr8
.text:
0040C661
.text:
0040C661;FUNCTIONCHUNKAT.text:
0041B84ESIZE00000007BYTES
.text:
0040C661;FUNCTIONCHUNKAT.text:
0044A4F2SIZE00000019BYTES
.text:
0040C661
.text:
0040C661movedi,edi
.text:
0040C663pushebp
.text:
0040C664movebp,esp
.text:
0040C666movecx,[ebp+VirtualAddress]
.text:
0040C669moveax,ecx
.text:
0040C66Bshreax,14h;右移20位
.text:
0040C66Emovedx,0FFCh;取高10位
.text:
0040C673andeax,edx
.text:
0040C675subeax,3FD00000h;加上0xc0300000
.text:
0040C675;PDE=((VA>>22)<<2)&0xffc+0xc0300000
.text:
0040C67Amoveax,[eax]
.text:
0040C67Ctestal,1;present位
.text:
0040C67Ejzloc_41B84E
.text:
0040C684testal,al
.text:
0040C686jsshortloc_40C6AC;判断pagesize位
.text:
0040C688shrecx,0Ah;右移10位
.text:
0040C68Bandecx,3FFFFCh
.text:
0040C691subecx,40000000h
.text:
0040C697moveax,ecx;PTE=((VA>>12)<<2)&0x3FFFC+0xc0000000
.text:
0040C699movecx,[eax];ecx=PTEContext
.text:
0040C69Btestcl,1;判断present位
.text:
0040C69Ejzloc_41B84E
.text:
0040C6A4testcl,cl
.text:
0040C6A6jsloc_44A4F2;判断pagesize位
.text:
0040C6AC
.text:
0040C6ACloc_40C6AC:
;CODEXREF:
MmIsAddressValid+25j
.text:
0040C6AC;MmIsAddressValid+3DE9Fj
.text:
0040C6ACmoval,1
.text:
0040C6AE
.text:
0040C6AEloc_40C6AE:
;CODEXREF:
MmIsAddressValid+F1EFj
.text:
0040C6AEpopebp
.text:
0040C6AFretn4
.text:
0040C6AFMmIsAddressValidendp
.text:
0040C6AF
还原为c代码为:
BOOLEANMmIsAddressValid(PVOIDVirtualAddress)
{
BYTEPresentSign=0x1;
BYTEPageSizeSign=0x80;
BYTEPresentAndPageSizeSign=0x81;
PVOIDlVirtualAddress;
ULONGPDE,PDEContext;
ULONGPTE,PTEContext;
lVirtualAddress=VirtualAddress;
PDE=(((ULONG)lVirtualAddress>>22)<<2)&0xffc+0xC0300000;
PDEContext=(ULONG)*(PVOID)PDE;
if(!
(PDEContext&PresentSign))
returnFALSE;
if(PDEContext&PageSizeSign)
returnTRUE;
PTE=(((ULONG)lVirtualAddress>>12)<<2)&0x3FFFc+0xC0000000;
PTEContext=(ULONG)*(PVOID)PTE;
if(!
(PTEContext&PresentSign))
returnFALSE;
if(!
(PTEContext&PageSizeSign))
returnTRUE;
else
{
PDE=(ULONG)PTE&0xffc+0xc0300000;
PDEContext=(ULONG)*(PVOID)PDE;
if(PDEContext&PresentAndPageSizeSign)
returnTRUE;
}
returnFALSE;
}
它是非PAE分页模式.从代码中得出PDE,PTE的计算公式为:
PDE=((VA>>22)<<2)&0xffc+0xc0300000;
PTE=((VA>>12)<<2)&0x3FFFFC+0xc0000000;
PAE分页,理论部分,看图,分4K和2M两种页。
接下来看看Windbg中反编译得到的。
lkd>uMmIsAddressValidl50
nt!
MmIsAddressValid:
80510fa08bffmovedi,edi
80510fa255pushebp
80510fa38becmovebp,esp
80510fa551pushecx;申请空间EBP-4
80510fa651pushecx;申请空间EBP-8
80510fa78b4d08movecx,dwordptr[ebp+8];取参数,虚拟地址
80510faa56pushesi
80510fab8bc1moveax,ecx
80510fadc1e812shreax,12h;右移12H(18位,相当于>>21<<3),即线性地址高11位(32-21)代表页目录索引,而页目录中每
;个索引占8个字节,故该索引在页目录中的相对偏移位置是页目录索引*8,也就是<<3。
找到其
;PDE
80510fb0bef83f0000movesi,3FF8h;3FF8H=11111111111000,标示取高11位
80510fb523c6andeax,esi
80510fb72d0000a03fsubeax,3FA00000h;页目录对应的虚拟地址0-3FA00000=c0600000h,页目录地址+原有的eax的偏移=
;PDE,每个PDE中有8字节,代表64位的页表
80510fbc8b10movedx,dwordptr[eax];取PDE低4字节
80510fbe8b4004moveax,dwordptr[eax+4];取PDE高4字节
80510fc18945fcmovdwordptr[ebp-4],eax;暂存
80510fc48bc2moveax,edx
80510fc657pushedi
80510fc783e001andeax,1;页面存在标志Present位
80510fca33ffxoredi,edi
80510fcc0bc7oreax,edi
80510fce7461jent!
MmIsAddressValid+0x91(80511031);如果页面存在标志Present位=0,表示该页没有加载到对应的
;物理页面,不是有效地址。
80510fd0bf80000000movedi,80h;80H=10000000
80510fd523d7andedx,edi;取Pagesize位,Pagesize位=1,表示LargePage
80510fd76a00push0
80510fd98955f8movdwordptr[ebp-8],edx
80510fdc58popeax;EAX=0
80510fdd7404jent!
MmIsAddressValid+0x43(80510fe3);最高位=0,非LargePage
80510fdf85c0testeax,eax
80510fe17452jent!
MmIsAddressValid+0x95(80511035);最高位=1,LargePage的情况,跳转
80510fe3c1e909shrecx,9;ecx=线性地址,右移9位,相当于>>12<<3。
即地址中的高20位代表pte偏移,低12位表示属性
80510fe681e1f8ff7f00andecx,7FFFF8h;7FFFF8h=011111111111111111111000,20位,第31到第12位,即前面20位
80510fec8b81040000c0moveax,dwordptr[ecx-3FFFFFFCh];
80510ff281e900000040subecx,40000000h;pte=((VA>>12)<<3)&0x7FFFF8+0xc0000000;(-0x40000000means+0xc0000000)
80510ff88b11movedx,dwordptr[ecx];PTEcontext
80510ffa8945fcmovdwordptr[ebp-4],eax
80510ffd53pushebx
80510ffe8bc2moveax,edx
8051100033dbxorebx,ebx
8051100283e001andeax,1;pte页面存在标志Present位
805110050bc3oreax,ebx
805110075bpopebx
805110087427jent!
MmIsAddressValid+0x91(80511031);无效位跳转
8051100a23d7andedx,edi;edx=pte,edi=80h,取Pagesize位,Pagesize位=1,表示LargePage
8051100c6a00push0
8051100e8955f8movdwordptr[ebp-8],edx;暂存
8051101158popeax
805110127421jent!
MmIsAddressValid+0x95(80511035);notLargePage,valid
8051101485c0testeax,eax;LargePage
80511016751djnent!
MmIsAddressValid+0x95(80511035)
8051101823ceandecx,esi;ecx=pte,esi=3FF8h3FF8H=11111111111000,表示取高11位2M分页的情况
8051101a8b89000060c0movecx,dwordptr[ecx-3FA00000h];0-3FA00000=c0600000h;ecx=PDEContext
80511020b881000000moveax,81h;判断Pagesize位和Present位
8051102523c8andecx,eax
8051102733d2xoredx,edx
805110293bc8cmpecx,eax
8051102b7508jnent!
MmIsAddressValid+0x95(80511035)
8051102d85d2testedx,edx;notvalid
8051102f7504jnent!
MmIsAddressValid+0x95(80511035)
8051103132c0xoral,al
80511033eb02jmpnt!
MmIsAddressValid+0x97(80511037)
80511035b001moval,1
805110375fpopedi
805110385epopesi
80511039c9leave
8051103ac20400ret4
还原为c的代码为:
BOOLEANMmIsAddressValid(PVOIDVirtualAddress)
{
BYTEPresentSign=0x1;
BYTEPageSizeSign=0x80;
BYTEPresentAndPageSizeSign=0x81;
PVOIDlVirtualAddress;
ULONGPDE,PDEContext;
ULONGPTE,PTEContext;
lVirtualAddress=VirtualAddress;
PDE=(((ULONG)lVirtualAddress>>21)<<3)&0x3FF8+0xC0600000;
PDEContext=(ULONG)*(PVOID)PDE;
if(!
(PDEContext&PresentSign))
returnFALSE;
if(PDEContext&PageSizeSign)
returnTRUE;
PTE=(((ULONG)lVirtualAddress>>12)<<3)&0x7FFFF8+0xC0000000;
PTEContext=(ULONG)*(PVOID)PTE;
if(!
(PTEContext&PresentSign))
returnFALSE;
if(!
(PTEContext&PageSizeSign))
returnTRUE;
else
{
PDE=(ULONG)PTE&0x3ff8+0xc0600000;
PDEContext=(ULONG)*(PVOID)PDE;
if(PDEContext&PresentAndPageSizeSign)
returnTRUE;
}
returnFALSE;
}
现在PAE模式,PDE,PTE地址的计算公式是:
intPDE=((lVirtualAddress>>21)<<3)&0x3FF8+0xC0600000;
intPTE=((lVirtualAddress>>12)<<3)&0x7FFFF8+0xC0000000;
以上VA表示virtualaddress
看看本机pte和pde的基地址
lkd>!
pte
VA00000000
PDEat00000000C0600000PTEat00000000C0000000
contains000000004D5C1067contains0000000000000000
pfn4d5c1---DA--UWEV