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           \WINDOWS\system32\ctype.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源码

 //
// Protection data for MiMakeProtectionMask
// CCHAR MmUserProtectionToMask1[] = {
,
MM_NOACCESS,
MM_READONLY,
-,
MM_READWRITE,
-,
-,
-,
MM_WRITECOPY,
-,
-,
-,
-,
-,
-,
- }; CCHAR MmUserProtectionToMask2[] = {
,
MM_EXECUTE,
MM_EXECUTE_READ,
-,
MM_EXECUTE_READWRITE,
-,
-,
-,
MM_EXECUTE_WRITECOPY,
-,
-,
-,
-,
-,
-,
- }; MM_PROTECTION_MASK
FASTCALL
MiMakeProtectionMask (
IN WIN32_PROTECTION_MASK Win32Protect
) /*++ Routine Description: This function takes a user supplied protection and converts it
into a 5-bit protection code for the PTE. Arguments: Win32Protect - Supplies the protection. Return Value: Returns the protection code for use in the PTE. Note that
MM_INVALID_PROTECTION (-1) is returned for an invalid protection
request. Since valid PTE protections fit in 5 bits and are
zero-extended, it's easy for callers to distinguish this. Environment: Kernel Mode. --*/ {
ULONG Field1;
ULONG Field2;
MM_PROTECTION_MASK ProtectCode; if (Win32Protect >= (PAGE_WRITECOMBINE * )) {
return MM_INVALID_PROTECTION;
} Field1 = Win32Protect & 0xF;
Field2 = (Win32Protect >> ) & 0xF; //
// Make sure at least one field is set.
// if (Field1 == ) {
if (Field2 == ) { //
// Both fields are zero, return failure.
// return MM_INVALID_PROTECTION;
}
ProtectCode = MmUserProtectionToMask2[Field2];
}
else {
if (Field2 != ) {
//
// Both fields are non-zero, return failure.
// return MM_INVALID_PROTECTION;
}
ProtectCode = MmUserProtectionToMask1[Field1];
} if (ProtectCode == -) {
return MM_INVALID_PROTECTION;
} if (Win32Protect & PAGE_GUARD) { if ((ProtectCode == MM_NOACCESS) ||
(Win32Protect & (PAGE_NOCACHE | PAGE_WRITECOMBINE))) { //
// Invalid protection -
// guard and either no access, no cache or write combine.
// return MM_INVALID_PROTECTION;
} MI_ADD_GUARD (ProtectCode);
} if (Win32Protect & PAGE_NOCACHE) { ASSERT ((Win32Protect & PAGE_GUARD) == ); // Already checked above if ((ProtectCode == MM_NOACCESS) ||
(Win32Protect & PAGE_WRITECOMBINE)) { //
// Invalid protection -
// nocache and either no access or write combine.
// return MM_INVALID_PROTECTION;
} MI_ADD_NOCACHE (ProtectCode);
} if (Win32Protect & PAGE_WRITECOMBINE) { ASSERT ((Win32Protect & (PAGE_GUARD|PAGE_NOACCESS)) == ); // Already checked above if (ProtectCode == MM_NOACCESS) { //
// Invalid protection, no access and write combine.
// return MM_INVALID_PROTECTION;
} MI_ADD_WRITECOMBINE (ProtectCode);
} return ProtectCode;
}

 

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

  1. 转:C语言申请内存时堆栈大小限制

    一直都有一个疑问,一个进程可以使用多大的内存空间,swap交换空间以及物理内存的大小,ulimit的stack size对进程的内存使用有怎样的限制?今天特亲自动手实验了一次,总结如下: 开辟一片内存 ...

  2. Linux就这个范儿 第15章 七种武器 linux 同步IO: sync、fsync与fdatasync Linux中的内存大页面huge page/large page David Cutler Linux读写内存数据的三种方式

    Linux就这个范儿 第15章 七种武器  linux 同步IO: sync.fsync与fdatasync   Linux中的内存大页面huge page/large page  David Cut ...

  3. Linux下用信号量实现对共享内存的访问保护

    转自:http://www.cppblog.com/zjl-1026-2001/archive/2010/03/03/108768.html 最近一直在研究多进程间通过共享内存来实现通信的事情,以便高 ...

  4. linux内核申请内存函数

    kmap函数:    把某块高端内存映射到页表,然后返回给用户一个填好vitual字段的page结构    建立永久地址映射,不是简单的返回virtual字段的pageioremap:    驱动程序 ...

  5. 有关于malloc申请内存和free内存释放

    malloc工作机制: malloc函数的实质体现在,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表(堆内存).调用malloc函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块. ...

  6. C++二维数组动态申请内存

    好久没用C++刷题了,今天早上刷了几条题,感觉很陌生了.怪我,大二下实在太颓废了,没啥作为. 今天更新个关于c++二维数组内存申请的问题,当初作为菜鸟初学指针的时候,还是在这方面有点搞不通的.今天用到 ...

  7. free如何知道释放内存长度:vs与glibc分配内存时编译器内部处理

    鉴于网上这个资料实在太少,将以前整理过却未完全的一篇文章贴出来,希望大牛指正vs下内存管理方式.可联系gaoshiqiang1987@163.com vs分配内存 vs没有源码,编译器在分配内存时,分 ...

  8. Delphi内存管理(Integer、Boolean、Record、枚举等都是在作用域内编译器自动申请内存,出了作用域自动释放;另外,字符串、Variant、动态数组、接口也是由Delphi自动管理)

    一.什么是堆.栈? 程序需要的内存空间分为 heap(堆) 和 stack(栈),heap 是自由存储区, stack 是自动存储区,使用 heap 需要手动申请.手动释放, stack 是自动申请. ...

  9. 【VS开发】malloc申请内存错误分析

    每个进程会有4G的虚拟地址空间, malloc得到的的地址都是虚拟地址, 并且当malloc的时候, 操作系统并不会将实际的内存分配给进程的, 所以malloc只会占用进程自身的虚拟地址空间.我以前也 ...

随机推荐

  1. NodeJS3-4基础API----fs(文件系统)

    异步的形式总是将完成回调作为其最后一个参数. 传给完成回调的参数取决于具体方法,但第一个参数始终预留用于异常. 如果操作成功完成,则第一个参数将为 null 或 undefined. 1.读取文件操作 ...

  2. Java设计模式整理

    一.创建型模式 1.抽象工厂模式(AbstractFactory): 提供一个接口, 用于创建相关或依赖对象的家族, 而不需要指定具体类. 案例:https://www.cnblogs.com/lfx ...

  3. C++程序设计实验考试准备资料(2019级秋学期)

    程序设计实验考试准备资料 ——傲珂 #include<bits/stdc++.h> C++常用函数: <math.h>头文件 floor() 函数原型:double floor ...

  4. uni-app实现图片和视频上传功能

    使用uni-app实现点击上传,既可以上传视频,有可以上传图片,图片预览,删除图片和视频功能,最终效果如下.uni-app里面没有提供同时上传视频和图片这个插件,只能靠自己手写,  1.页面布局 通过 ...

  5. Python之闭包and装饰器

    闭包和装饰器是Python中非常重要的一种语法格式,在日常工作中应用非常广泛. 首先,我先为大家简单的介绍一下闭包的概念. 闭包:闭包是在函数嵌套的基础上,内层函数使用到外层函数的变量,且外层函数返回 ...

  6. <深度学习>Tensorflow遇到的坑之一

    AttributeError: module 'tensorflow' has no attribute 'random_normal' AttributeError: module 'tensorf ...

  7. 形如 T(n) = a * T(n/b) + f(n) 的时间复杂度计算方法

    形如 T(n) = a * T(n/b) + f(n) 的时间复杂度计算方法 有一种方法叫做主方法(Master method)是用来专门计算这种形式的时间复杂度的,方法具体如下: 下边举例进行说明: ...

  8. 你竟然没用 Nuget 构建项目?

    想写这篇文章缘起于公众号文章里的一条留言: 对于一个现代化的开发平台,建立一种让开发者创建,分享与使用可复用代码的机制是十分必要的.这种"可复用代码"被打包后的文件通常被称作&qu ...

  9. flyway 非常坑爹的中文乱码问题

    flyway 也真是够了, 动不动乱码,烦死了! 我的 命令是这样的: flyway  -driver=com.mysql.jdbc.Driver -user=root -password=12345 ...

  10. mysql安装、使用

    一.下载.安装 1.下载 (1)下载地址 https://dev.mysql.com/downloads/mysql/ (2)此处我下载最新版(8.0.18) 2.安装 (1)解压.并配置环境变量 s ...