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. 【译】在React中实现条件渲染的7种方法

    原文地址:https://scotch.io/tutorials/7-ways-to-implement-conditional-rendering-in-react-applications 借助R ...

  2. 常见面试题之*args

    这个地方理解即可,只是面试的时候会被问到,单独做了一下知识点的整理,不推荐使用. def self_max(a,b,c,d,e,f,g,h,k,x=1,y=3,z=4): #默认参数 print(a, ...

  3. springcloud-微服务架构基础

    一 前言 学习微服务要从基础的架构学起,首先你要有个微服务的概念才能学习对吧!!如果你都不知道啥是微服务,就一头扎进去学习,你自己也觉得自己也学不会对吧.本篇文章主要让大家快速了解基础的架构分格,以便 ...

  4. CSS flex 布局快速入门

    以前已经学过flex了,一直没做笔记,现在做下笔记再回忆下. 首先,flex布局的迷之属性们,如果一知半解,机械记忆的话,那不到半个月基本忘光光.先感受一下这12个flex布局属性,是不是很“迷”人. ...

  5. github pages 子域名 ( subdomain ) https 认证

    目录 说明 github pages 上的创建子域名 https 认证 说明 转载请注明出处https://www.cnblogs.com/bllovetx/p/12013462.html 欢迎访问我 ...

  6. Java设计模式13:责任链模式

    前言 来菜鸟这个大家庭10个月了,总得来说比较融入了环境,同时在忙碌的工作中也深感技术积累不够,在优秀的人身边工作必须更加花时间去提升自己的技术能力.技术视野,所以开一个系列文章,标题就轻松一点叫做最 ...

  7. 中移动物联手机端APP软件

    https://open.iot.10086.cn/doc/book/device-develop/multpro/sdk-doc-tool/APP.html

  8. 使用函数计算三步实现深度学习 AI 推理在线服务

    目前深度学习应用广发, 其中 AI 推理的在线服务是其中一个重要的可落地的应用场景.本文将为大家介绍使用函数计算部署深度学习 AI 推理的最佳实践,  其中包括使用 FUN 工具一键部署安装第三方依赖 ...

  9. 3.java基础之关键字instanceof

    1. instanceof 使用:对象引用名 instanceof 类名 作用:来判读引用的对象和类名是否兼容(是否继承该类,或爷爷辈的类) 例子: Team team = new Team(); t ...

  10. JavaScript 日期格式

    有四种 JavaScript 日期输入格式: 类型 实例 ISO 日期 "2018-02-19" (国际标准) 短日期 "02/19/2018" 或者 &quo ...