• R3环申请内存时页面保护与_MMVAD_FLAGS.Protection位的对应关系


    Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html

    R3环申请内存时页面保护与_MMVAD_FLAGS.Protection位的对应关系

    我们之前有过一篇关于 VAD 的介绍,其中 _MMVAD_FLAGS.Protection 中描述了页的属性。

    我们知道在R3下申请内存时也会定义内存的属性,但通过搜索数值,发现这俩并不相同,这很让人产生疑惑。

    下面就来解答这一疑惑。

     

    一、R3与R0的定义

      1)在R3环的定义

        #define PAGE_NOACCESS           0x01    
        #define PAGE_READONLY           0x02    
        #define PAGE_READWRITE          0x04    
        #define PAGE_WRITECOPY          0x08    
        #define PAGE_EXECUTE            0x10    
        #define PAGE_EXECUTE_READ       0x20    
        #define PAGE_EXECUTE_READWRITE  0x40    
        #define PAGE_EXECUTE_WRITECOPY  0x80   

      2)在R0环的定义

        #define MM_ZERO_ACCESS         0  // this value is not used.
        #define MM_READONLY            1
        #define MM_EXECUTE             2
        #define MM_EXECUTE_READ        3
        #define MM_READWRITE           4  // bit 2 is set if this is writable.
        #define MM_WRITECOPY           5
        #define MM_EXECUTE_READWRITE   6
        #define MM_EXECUTE_WRITECOPY   7

     

    二、内核函数 MiMakeProtectionMask

      该内核函数负责将这些定义在R3环的值转换为R0环。

      1)首先,将R3环的定义分为Field1(低字节)与Field2(高字节),比如 0x01,分为 Field1 = 1 / Field2 = 0。

      2)之后,其分别会去表中查找(在下面源码开头的两个数组),表中携带的就是真正在R0中定义的值。

      3)之后将R0的值赋在 _MMVAD_FLAGS.Protection位。

     

    三、分析验证:

      1)我们随便遍历一个进程的VAD树,选中一个结点,其为只读属性。

        81af63e8  9       3f0       3f2      0 Mapped       READONLY           WINDOWSsystem32ctype.nls
      2)我们查看其Protection值

        kd> dt _MMVAD_FLAGS 81af63e8+0x14
             +0x000 Protection       : 0y00001 (0x1)

      3)我们通过查看R0中的定义可知0x1对应的MM_READONLY,符合要求。

      4)MM_READONLY 又在 MmUserProtectionToMask1 表中的第三个位置(索引为2),故其在三环的定义应该为 0x02.

      5)查看定义, #define PAGE_READONLY     0x02  ,则符合要求,验证成功。

     

    四、Field表及MiMakeProtectionMask源码

      1 //
      2 // Protection data for MiMakeProtectionMask
      3 //
      4 
      5 CCHAR MmUserProtectionToMask1[16] = {
      6                                  0,
      7                                  MM_NOACCESS,
      8                                  MM_READONLY,
      9                                  -1,
     10                                  MM_READWRITE,
     11                                  -1,
     12                                  -1,
     13                                  -1,
     14                                  MM_WRITECOPY,
     15                                  -1,
     16                                  -1,
     17                                  -1,
     18                                  -1,
     19                                  -1,
     20                                  -1,
     21                                  -1 };
     22 
     23 CCHAR MmUserProtectionToMask2[16] = {
     24                                  0,
     25                                  MM_EXECUTE,
     26                                  MM_EXECUTE_READ,
     27                                  -1,
     28                                  MM_EXECUTE_READWRITE,
     29                                  -1,
     30                                  -1,
     31                                  -1,
     32                                  MM_EXECUTE_WRITECOPY,
     33                                  -1,
     34                                  -1,
     35                                  -1,
     36                                  -1,
     37                                  -1,
     38                                  -1,
     39                                  -1 };
     40 
     41 
     42 MM_PROTECTION_MASK
     43 FASTCALL
     44 MiMakeProtectionMask (
     45     IN WIN32_PROTECTION_MASK Win32Protect
     46     )
     47 
     48 /*++
     49 
     50 Routine Description:
     51 
     52     This function takes a user supplied protection and converts it
     53     into a 5-bit protection code for the PTE.
     54 
     55 Arguments:
     56 
     57     Win32Protect - Supplies the protection.
     58 
     59 Return Value:
     60 
     61     Returns the protection code for use in the PTE.  Note that
     62     MM_INVALID_PROTECTION (-1) is returned for an invalid protection
     63     request.  Since valid PTE protections fit in 5 bits and are
     64     zero-extended, it's easy for callers to distinguish this.
     65 
     66 Environment:
     67 
     68     Kernel Mode.
     69 
     70 --*/
     71 
     72 {
     73     ULONG Field1;
     74     ULONG Field2;
     75     MM_PROTECTION_MASK ProtectCode;
     76 
     77     if (Win32Protect >= (PAGE_WRITECOMBINE * 2)) {
     78         return MM_INVALID_PROTECTION;
     79     }
     80 
     81     Field1 = Win32Protect & 0xF;
     82     Field2 = (Win32Protect >> 4) & 0xF;
     83 
     84     //
     85     // Make sure at least one field is set.
     86     //
     87 
     88     if (Field1 == 0) {
     89         if (Field2 == 0) {
     90 
     91             //
     92             // Both fields are zero, return failure.
     93             //
     94 
     95             return MM_INVALID_PROTECTION;
     96         }
     97         ProtectCode = MmUserProtectionToMask2[Field2];
     98     }
     99     else {
    100         if (Field2 != 0) {
    101             //
    102             //  Both fields are non-zero, return failure.
    103             //
    104 
    105             return MM_INVALID_PROTECTION;
    106         }
    107         ProtectCode = MmUserProtectionToMask1[Field1];
    108     }
    109 
    110     if (ProtectCode == -1) {
    111         return MM_INVALID_PROTECTION;
    112     }
    113 
    114     if (Win32Protect & PAGE_GUARD) {
    115 
    116         if ((ProtectCode == MM_NOACCESS) ||
    117             (Win32Protect & (PAGE_NOCACHE | PAGE_WRITECOMBINE))) {
    118 
    119             //
    120             // Invalid protection -
    121             // guard and either no access, no cache or write combine.
    122             //
    123 
    124             return MM_INVALID_PROTECTION;
    125         }
    126 
    127         MI_ADD_GUARD (ProtectCode);
    128     }
    129 
    130     if (Win32Protect & PAGE_NOCACHE) {
    131 
    132         ASSERT ((Win32Protect & PAGE_GUARD) == 0);  // Already checked above
    133 
    134         if ((ProtectCode == MM_NOACCESS) ||
    135             (Win32Protect & PAGE_WRITECOMBINE)) {
    136 
    137             //
    138             // Invalid protection -
    139             // nocache and either no access or write combine.
    140             //
    141 
    142             return MM_INVALID_PROTECTION;
    143         }
    144 
    145         MI_ADD_NOCACHE (ProtectCode);
    146     }
    147 
    148     if (Win32Protect & PAGE_WRITECOMBINE) {
    149 
    150         ASSERT ((Win32Protect & (PAGE_GUARD|PAGE_NOACCESS)) == 0);  // Already checked above
    151 
    152         if (ProtectCode == MM_NOACCESS) {
    153 
    154             //
    155             // Invalid protection, no access and write combine.
    156             //
    157 
    158             return MM_INVALID_PROTECTION;
    159         }
    160 
    161         MI_ADD_WRITECOMBINE (ProtectCode);
    162     }
    163 
    164     return ProtectCode;
    165 }

     

     

     

     

     

  • 相关阅读:
    Java实现 蓝桥杯VIP 算法提高 快速幂
    Java实现 蓝桥杯VIP 算法提高 最长字符序列
    Java实现 蓝桥杯VIP 算法提高 最长字符序列
    Java实现 蓝桥杯VIP 算法提高 最长字符序列
    Java实现 蓝桥杯VIP 算法提高 最长字符序列
    Java实现 蓝桥杯VIP 算法提高 最长字符序列
    linux下配置QT(很全的步骤,从下载开始,配置QMAKESPEC)
    QT 读取文件夹下所有文件(超级简单的方法,不需要QDirIterator)
    Windows平台下的图形化的Ping工具
    Qt中的键盘事件,以及焦点的设置(比较详细)
  • 原文地址:https://www.cnblogs.com/onetrainee/p/11748885.html
Copyright © 2020-2023  润新知