2-9-9-12分页(下)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

附:找到pdt:pde最后一个看看是否有物理页

 1:)给0线性地址挂上物理页

打开windbg查看cr4

 

 

 查看0的物理地址,发现没有挂物理页

 

 

 利用写出代码,打印b的地址,并且把b的物理页也打印出来

 

 

 

 

 

 

 

 

 

 将0号地址修改为跟b的相同的物理页上

 

 打印相应地址的值

2:)逆向MnIsAddressValid

 源代码

 1 80514928 8bff            mov     edi,edi
 2 8051492a 55              push    ebp
 3 8051492b 8bec            mov     ebp,esp
 4 8051492d 51              push    ecx
 5 8051492e 51              push    ecx
 6 8051492f 8b4d08          mov     ecx,dword ptr [ebp+8]
 7 80514932 56              push    esi
 8 80514933 8bc1            mov     eax,ecx
 9 80514935 c1e812          shr     eax,12h    //将线性地址右移18位
10 80514938 bef83f0000      mov     esi,3FF8h    //0011 1111 1111 1000
11 8051493d 23c6            and     eax,esi    //
12 8051493f 2d0000a03f      sub     eax,3FA00000h    //+ c0600000
13 80514944 8b10            mov     edx,dword ptr [eax]    //低4字节给edx
14 80514946 8b4004          mov     eax,dword ptr [eax+4]//高4字节给eax
15 80514949 8945fc          mov     dword ptr [ebp-4],eax    //
16 8051494c 8bc2            mov     eax,edx
17 8051494e 57              push    edi
18 8051494f 83e001          and     eax,1    //获取最低位
19 80514952 33ff            xor     edi,edi
20 80514954 0bc7            or      eax,edi
21 80514956 7461            je      nt!MmIsAddressValid+0x91 (805149b9)//判断P位是否为1,验证地址是否有效
22 80514958 bf80000000      mov     edi,80h    //1000 0000 
23 8051495d 23d7            and     edx,edi    //把ps位给edx
24 8051495f 6a00            push    0
25 80514961 8955f8          mov     dword ptr [ebp-8],edx
26 80514964 58              pop     eax
27 80514965 7404            je      nt!MmIsAddressValid+0x43 (8051496b)    //判断低地址的ps位是否为1,为1则是大页否则是小页,小页便跳转到0x8051496b,否则跳转到805149bd
28 80514967 85c0            test    eax,eax    //判断是否为0
29 80514969 7452            je      nt!MmIsAddressValid+0x95 (805149bd)    
30 8051496b c1e909          shr     ecx,9
31 8051496e 81e1f8ff7f00    and     ecx,7FFFF8h    //0111 1111 1111 1111 1111 1000
32 80514974 8b81040000c0    mov     eax,dword ptr [ecx-3FFFFFFCh]
33 8051497a 81e900000040    sub     ecx,40000000h  //pte
34 80514980 8b11            mov     edx,dword ptr [ecx]
35 80514982 8945fc          mov     dword ptr [ebp-4],eax
36 80514985 53              push    ebx
37 80514986 8bc2            mov     eax,edx
38 80514988 33db            xor     ebx,ebx
39 8051498a 83e001          and     eax,1
40 8051498d 0bc3            or      eax,ebx
41 8051498f 5b              pop     ebx
42 80514990 7427            je      nt!MmIsAddressValid+0x91 (805149b9)
43 80514992 23d7            and     edx,edi
44 80514994 6a00            push    0
45 80514996 8955f8          mov     dword ptr [ebp-8],edx
46 80514999 58              pop     eax
47 8051499a 7421            je      nt!MmIsAddressValid+0x95 (805149bd)
48 8051499c 85c0            test    eax,eax
49 8051499e 751d            jne     nt!MmIsAddressValid+0x95 (805149bd)
50 805149a0 23ce            and     ecx,esi
51 805149a2 8b89000060c0    mov     ecx,dword ptr [ecx-3FA00000h]
52 805149a8 b881000000      mov     eax,81h
53 805149ad 23c8            and     ecx,eax
54 805149af 33d2            xor     edx,edx
55 805149b1 3bc8            cmp     ecx,eax
56 805149b3 7508            jne     nt!MmIsAddressValid+0x95 (805149bd)
57 805149b5 85d2            test    edx,edx
58 805149b7 7504            jne     nt!MmIsAddressValid+0x95 (805149bd)
59 805149b9 32c0            xor     al,al
60 805149bb eb02            jmp     nt!MmIsAddressValid+0x97 (805149bf)
61 805149bd b001            mov     al,1
62 805149bf 5f              pop     edi
63 805149c0 5e              pop     esi
64 805149c1 c9              leave
65 805149c2 c20400          ret     4

找到pte存储pde的pdt

 

 6 8051492f 8b4d08          mov     ecx,dword ptr [ebp+8]
 7 80514932 56              push    esi
 8 80514933 8bc1            mov     eax,ecx
 9 80514935 c1e812          shr     eax,12h    //将线性地址右移18位
10 80514938 bef83f0000      mov     esi,3FF8h    //0011 1111 1111 1000
11 8051493d 23c6            and     eax,esi    //
12 8051493f 2d0000a03f      sub     eax,3FA00000h    //+ c0600000
13 80514944 8b10            mov     edx,dword ptr [eax]    //低4字节给edx
14 80514946 8b4004          mov     eax,dword ptr [eax+4]//高4字节给eax
15 80514949 8945fc          mov     dword ptr [ebp-4],eax    //

 验证pde的p位和ps位是否为0,如果p位为0直接返回

17 8051494e 57              push    edi
18 8051494f 83e001          and     eax,1    //获取最低位
19 80514952 33ff            xor     edi,edi
20 80514954 0bc7            or      eax,edi
21 80514956 7461            je      nt!MmIsAddressValid+0x91 (805149b9)//判断P位是否为1,验证地址是否有效
22 80514958 bf80000000      mov     edi,80h    //1000 0000 
23 8051495d 23d7            and     edx,edi    //把ps位给edx
24 8051495f 6a00            push    0
25 80514961 8955f8          mov     dword ptr [ebp-8],edx
26 80514964 58              pop     eax
27 80514965 7404            je      nt!MmIsAddressValid+0x43 (8051496b)    //判断低地址的ps位是否为1,为1则是大页否则是小页,小页便跳转到0x8051496b,否则跳转到805149bd
28 80514967 85c0            test    eax,eax    //判断是否为0
29 80514969 7452            je      nt!MmIsAddressValid+0x95 (805149bd)    

找到存储物理地址的pte,并验证p位和ps位

8051496b c1e909          shr     ecx,9
8051496e 81e1f8ff7f00    and     ecx,7FFFF8h
80514974 8b81040000c0    mov     eax,dword ptr [ecx-3FFFFFFCh]
8051497a 81e900000040    sub     ecx,40000000h
80514980 8b11            mov     edx,dword ptr [ecx]
80514982 8945fc          mov     dword ptr [ebp-4],eax
80514985 53              push    ebx
80514986 8bc2            mov     eax,edx
80514988 33db            xor     ebx,ebx
8051498a 83e001          and     eax,1
8051498d 0bc3            or      eax,ebx
8051498f 5b              pop     ebx
80514990 7427            je      nt!MmIsAddressValid+0x91 (805149b9)
80514992 23d7            and     edx,edi
80514994 6a00            push    0
80514996 8955f8          mov     dword ptr [ebp-8],edx
80514999 58              pop     eax
8051499a 7421            je      nt!MmIsAddressValid+0x95 (805149bd)
8051499c 85c0            test    eax,eax
8051499e 751d            jne     nt!MmIsAddressValid+0x95 (805149bd)

 找到对应物理页,并验证属性

805149a0 23ce            and     ecx,esi
805149a2 8b89000060c0    mov     ecx,dword ptr [ecx-3FA00000h]
805149a8 b881000000      mov     eax,81h
805149ad 23c8            and     ecx,eax
805149af 33d2            xor     edx,edx
805149b1 3bc8            cmp     ecx,eax
805149b3 7508            jne     nt!MmIsAddressValid+0x95 (805149bd)
805149b5 85d2            test    edx,edx
805149b7 7504            jne     nt!MmIsAddressValid+0x95 (805149bd)
805149b9 32c0            xor     al,al
805149bb eb02            jmp     nt!MmIsAddressValid+0x97 (805149bf)
805149bd b001            mov     al,1
805149bf 5f              pop     edi
805149c0 5e              pop     esi
805149c1 c9              leave
805149c2 c20400          ret     4

 3、编写代码实现修改页属性,实现应用层读写高2G内存地址

这里先感谢一个师傅的博客,实验写的很详细

思路分析:

  1. 不管是页目录表还是页表基址都是属于高2G的内存,那我们肯定是需要通过门的提权来实现对高两G的写
  2. 由于修改了高2G的页属性,所以我们通过另一个应用程序来访问被修改的页属性,如果成功,代表修改成功,否则修改失败

 修改PDE和PTE公式

 1 2-9-9-12                    
 2 PDPTI-PDI-PTI-OFFSET                    
 3                     
 4 公式:                    
 5 pPDE = 0xc0600000 + (PDPTI*4KB) + (PDI*8)                    
 6 pPTE = 0xc0000000 + (PDPTI*2MB) + (PDI*4KB) + (PTI*8)                    
 7                     
 8 更高效的公式(MmIsAddressValid是这么干的)                    
 9 pPDE = 0xc0600000 + ((addr >> 18) & 0x3ff8)                    
10 pPTE = 0xc0000000 + ((addr >> 9) & 0x7ffff8)    

 测试代码(这里非常感谢那位师傅

 1 // Phy_Memory.cpp : Defines the entry point for the console application.
 2 //
 3 
 4 #include "stdafx.h"
 5 #include<stdlib.h>
 6 #include<windows.h>
 7 
 8 char buf[6]={0,0,0,0,0x48,0};
 9 
10 DWORD *GetPDE(DWORD addr)
11 {
12     //return (DWORD *)(0xc0600000 + ((addr >> 18) & 0x3ff8));
13     DWORD PDPTI = addr >> 30;
14     DWORD PDI = (addr >> 21) & 0x000001FF;
15     DWORD PTI = (addr >> 12) & 0x000001FF;
16     return (DWORD *)(0xC0600000 + PDPTI * 0x1000 + PDI * 8);
17 }
18 
19 DWORD *GetPTE(DWORD addr)
20 {
21     //return (DWORD *)(0xc0000000 + ((addr >> 9) & 0x7ffff8));
22     DWORD PDPTI = addr >> 30;
23     DWORD PDI = (addr >> 21) & 0x000001FF;
24     DWORD PTI = (addr >> 12) & 0x000001FF;
25     return (DWORD *)(0xC0000000 + PDPTI * 0x200000 + PDI * 0x1000 + PTI * 8);
26 }
27 
28 __declspec(naked) void func()
29 {
30     __asm
31     {
32         pushad
33         pushfd
34     }
35 
36     *GetPDE(0x8003f048) |=0x00000004;
37     *GetPTE(0x8003f048) |=0x00000004;
38     
39     *GetPTE(0x8003f048) &= 0xFFFFFEFF;
40 
41     __asm
42     {
43         popad
44         popfd
45         iretd
46     }
47 }
48 
49 
50 
51 int main(int argc, char* argv[])
52 {
53     
54     printf("在IDT表构建中断门,请在windbg中执行下面的指令:\n");
55     printf("eq 8003f500 %04xee00`0008%04x",(DWORD)func>>16,(DWORD)func&0x0000ffff);
56 
57     getchar();
58 
59     __asm int 0x20;
60     printf("0x8003f048 U/S,G位修改成功.\n");
61     printf("*(PDWORD)0x8003f048 = %08x\n", *(PDWORD)0x8003f048);
62     *(PDWORD)0x8003f048 = 0x12345678;
63     printf("*(PDWORD)0x8003f048 = %08x\n", *(PDWORD)0x8003f048);
64     getchar();
65 
66     return 0;
67 }

执行后

 

 

 知识总结

  • 2-9-9-12分页中,pte是0xc0000000,pde是0xc0600000
  • 两种在线性地址的计算方式
  • 公式:                    
    pPDE = 0xc0600000 + (PDPTI*4KB) + (PDI*8)                    
    pPTE = 0xc0000000 + (PDPTI*2MB) + (PDI*4KB) + (PTI*8)                    
                        
    更高效的公式(MmIsAddressValid是这么干的)                    
    pPDE = 0xc0600000 + ((addr >> 18) & 0x3ff8)                    
    pPTE = 0xc0000000 + ((addr >> 9) & 0x7ffff8)    

     

 不足处

  1. 看了上面那位师傅博客后,感觉自己的博客写的很烂
  2. 其次是自己对这些基础的了解远不如别人了解,需要每天都记忆一遍,来加深记忆
  3. 动手能力没有别的师傅那么厉害,在这里在谢谢一下,博客写的真的很好,需要向他学习
posted @ 2020-10-24 16:55  PYozo_free  阅读(261)  评论(0编辑  收藏  举报