• 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中执行下面的指令:
    ");
    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位修改成功.
    ");
    61     printf("*(PDWORD)0x8003f048 = %08x
    ", *(PDWORD)0x8003f048);
    62     *(PDWORD)0x8003f048 = 0x12345678;
    63     printf("*(PDWORD)0x8003f048 = %08x
    ", *(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. 动手能力没有别的师傅那么厉害,在这里在谢谢一下,博客写的真的很好,需要向他学习
  • 相关阅读:
    (基于Java)编写编译器和解释器第5章:解析表达式和赋值语句第一部分(连载)
    (基于Java)编写编译器和解释器第6章:解释执行表达式和赋值语句(连载)
    (基于Java)编写编译器和解释器第9章:解析声明第一部分(连载)
    (基于Java)编写编译器和解释器第5章:解析表达式和赋值语句第二部分(连载)
    (基于Java)编写编译器和解释器第4章:符号表(连载)
    (基于Java)编写编译器和解释器第8A章:基于Antlr解析&解释执行Pascal控制语句(连载)
    (基于Java)编写编译器和解释器第7章:解析(Parsing)控制语句第一部分(连载)
    (基于Java)编写编译器和解释器第5A章:基于Antlr解析表达式和赋值语句及计算(连载)
    (基于Java)编写编译器和解释器第7章:解析(Parsing)控制语句第二部分(连载)
    (基于Java)编写编译器和解释器第8章:解释Pascal控制语句(连载)
  • 原文地址:https://www.cnblogs.com/pppyyyzzz/p/13870009.html
Copyright © 2020-2023  润新知