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 \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位的对应关系的更多相关文章
- 转:C语言申请内存时堆栈大小限制
一直都有一个疑问,一个进程可以使用多大的内存空间,swap交换空间以及物理内存的大小,ulimit的stack size对进程的内存使用有怎样的限制?今天特亲自动手实验了一次,总结如下: 开辟一片内存 ...
- 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 ...
- Linux下用信号量实现对共享内存的访问保护
转自:http://www.cppblog.com/zjl-1026-2001/archive/2010/03/03/108768.html 最近一直在研究多进程间通过共享内存来实现通信的事情,以便高 ...
- linux内核申请内存函数
kmap函数: 把某块高端内存映射到页表,然后返回给用户一个填好vitual字段的page结构 建立永久地址映射,不是简单的返回virtual字段的pageioremap: 驱动程序 ...
- 有关于malloc申请内存和free内存释放
malloc工作机制: malloc函数的实质体现在,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表(堆内存).调用malloc函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块. ...
- C++二维数组动态申请内存
好久没用C++刷题了,今天早上刷了几条题,感觉很陌生了.怪我,大二下实在太颓废了,没啥作为. 今天更新个关于c++二维数组内存申请的问题,当初作为菜鸟初学指针的时候,还是在这方面有点搞不通的.今天用到 ...
- free如何知道释放内存长度:vs与glibc分配内存时编译器内部处理
鉴于网上这个资料实在太少,将以前整理过却未完全的一篇文章贴出来,希望大牛指正vs下内存管理方式.可联系gaoshiqiang1987@163.com vs分配内存 vs没有源码,编译器在分配内存时,分 ...
- Delphi内存管理(Integer、Boolean、Record、枚举等都是在作用域内编译器自动申请内存,出了作用域自动释放;另外,字符串、Variant、动态数组、接口也是由Delphi自动管理)
一.什么是堆.栈? 程序需要的内存空间分为 heap(堆) 和 stack(栈),heap 是自由存储区, stack 是自动存储区,使用 heap 需要手动申请.手动释放, stack 是自动申请. ...
- 【VS开发】malloc申请内存错误分析
每个进程会有4G的虚拟地址空间, malloc得到的的地址都是虚拟地址, 并且当malloc的时候, 操作系统并不会将实际的内存分配给进程的, 所以malloc只会占用进程自身的虚拟地址空间.我以前也 ...
随机推荐
- CCPC Wannafly Winter Camp Div2 部分题解
Day 1, Div 2, Prob. B - 吃豆豆 题目大意 wls有一个\(n\)行\(m\)列的棋盘,对于第\(i\)行第\(j\)列的格子,每过\(T[i][j]\)秒会在上面出现一个糖果, ...
- vue+element 中 el-input框 限制只能输入数字及一位小数
仅个人经验,希望能帮到有需要的人. 第一次写 就话不多说了直接上代码. <el-input @keyup.native="proving(index)" v-model=&q ...
- 通过 Drone Rest API 获取构建记录日志
Drone是一款CICD工具,提供rest API,简单介绍下如何使用API 获取构建日志. 获取token 登录进入drone,点头像,在菜单里选择token 复制token即可 API 介绍 Dr ...
- aspnet boilerplate 随笔二
项目框架介绍: 1:Application: 在service里面事件具体业务,Dto相当于viewmodel实现了验证 2:Core:实现了数据层Model 3:EntityFrameworkC ...
- JS---DOM---事件冒泡和阻止事件冒泡,总结事件
事件冒泡: 多个元素嵌套, 有层次关系 ,这些元素都注册了相同的事件, 如果里面的元素的事件触发了, 外面的元素的该事件自动的触发了 事件有三个阶段: 1.事件捕获阶段 :从外向内 2.事件 ...
- bossplayersCTF 1: Vulnhub Walkthrough
主机扫描: http://10.10.202.130/ <!--WkRJNWVXRXliSFZhTW14MVkwaEtkbG96U214ak0wMTFZMGRvZDBOblBUMEsK--> ...
- delete误删数据使用SCN恢复
参考51CTO博客 问题描述:使用scn号恢复误删数据 1.查询系统闪回的scn值以及当前日志的scn值,因为我这个是测试,创建的表是在在后边,所以scn值要大于下边这两个scn值,所以对我恢复数据没 ...
- 常见SQL编写和优化
常见的SQL优化方式 对查询进行优化,应尽量避免全表扫描,首先应考虑在where及order by 涉及的列上建立索引. 应尽量避免在 where 子句中对字段进行null 值判断,否则将导致引擎放弃 ...
- idea常用快捷键大全
Idea常用快捷键大全,拿小本本记下来,忘记了可以方便查找. 编写代码 Ctrl+Shift + Enter,语句完成. “!”,否定完成,输入表达式时按 “!”键. Ctrl+E,最近的文件. Ct ...
- ElasticSearch 安装, 带视频
疯狂创客圈 Java 高并发[ 亿级流量聊天室实战]实战系列 [博客园总入口 ] 架构师成长+面试必备之 高并发基础书籍 [Netty Zookeeper Redis 高并发实战 ] 疯狂创客圈 高并 ...