线性地址管理

Windows x86 进程空间地址划分

空指针赋值区:0x00000000~0x0000FFFF
用户模式区:0x00010000~0x7FFEFFFF
64KB禁入区:0x7FFF000~0X7FFFFFFF
内核:0x80000000~0xFFFFFFFF
特别说明:
1.线性地址有4G但未必都能访问。
2.所以需要记录,那些地方分配了

内存的分配

分配的内存可以分为两类,一类是VirtualAlloc分配的普通内存,
还有一类是Map映射(文件映射可以是Dll或者是EXE等)的内存。

内存属性

nt!MMVAD_FLAGS
+0x000 CommitCharge
+0x000 PhysicalMapping
+0x000 ImageMap    //1镜像文件 0其他
+0x000 UserPhysicalPages
+0x000 NoChange
+0x000 WriteWatch
+0x000 Protection
// 1 READONLY 2 EXECUTE 3 EXECUTE_READ 4 READWITER
//5 WRITECOPY 6 EXECUTE_READWITER 7 EXECUTE_WRITECOPY
+0x000 LargePages
+0x000 MemCommit
+0x000 PrivateMemory //1=PrivateMemory 2=Map

Private Memory

线性地址分为两种内存

1.Mapped内存
通过VirtualAlloc/VirtualAllocEx申请的内存:Private Memory
2.Private内存
通过CreateFileMapping映射的:Mapped Memory

malloc、new、VirtualAlloc

在C++中new的底层实现就是malloc,实现的底层API是
HeapAlloc从堆中分配一块内存,堆的本质上就是操作系统
通过VirtualAlloc分配的一块很大的内存,在应用程序运行的
时候已经分配好了一些内存,HeapAlloc就是从这块分配好的
很大内存中拿一块来用。
全局变量是在编译完成之后存储在PE文件的节中的,是Mapped映射的,
在函数中使用的malloc或者New或者局部变量是系统提前使用VirtualAlloc
申请好的。

Mapped Memory

Mapped映射内存

Mapped之所要映射内存是因为有些内存内容是一样的,
如果每个进程都要单独的使用一模一样的内存就会造成不必要的浪费。
1.映射文件
2.映射物理页

将文件使用Mapped方式映射到内存中

主要使用CreateFileMapping和MapViewOfFile两个API
创建例子:
//内核对象:1物理页、2文件
HANDLE g_hMapFile=CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,BUFSIZE,MapFileName(内核对象名称));
第一个参数指定欲在其中创建映射的一个文件句柄。0xFFFFFFFF(-1,即INVALID_HANDLE_VALUE)表示在页面文件中创建一个可共享的文件映射。
最后一个参数是内核对象名称,使用OpenFileMapping打开的便是该内核对象名称。
//将物理页与线性地址进行映射
LPTSTR g_lpBuff=(LPTSTR)MapViewOfFile(g_hMapFile,FILE_MAP_ALL_ACCESS,0,0,BUFSIZE);
*(PDWORD)g_lpBuff = 0x12345678
printf("A进程写入地址,内容:%p - %x",g_lpBuff,*(PWORD)g_lpBuff);
getchar();
打开例子:
使用OpenFileMapping和MapViewOfFing这两个API
HANDEL g_hMapFile=OpenFileMapping(FILE_MAP_ALL_ACCESS,FLASE,MapFileName(内核对象名称));
MapFileName即最后一个参数是CreateFileMapping创建的内核对象名称。
//需要将g_hMapFile通过映射的方式映射到自己的内存才可以使用
LPTSTR g_lpBuff=(LPTSTR)MapViewOfFile(g_hMapFile,FILE_MAP_ALL_ACCESS,0,0,BUFSIZ);
printf("B进程读取%x",*(PDWORD)g_lpBuff);
getchar();

Mapped Exe EXECUTE_WRITECOPY 类型

这种类型一般是LoadLibrary映射的类型,而自己使用CreateFileMapping就没有Exe这个标记,
之所以是采用可执行可写拷贝标记是因为向kernel32或者ntdll这种dll可能会被篡改导致其他进程崩溃,
因此要有这种属性最重要的是拷贝属性,这样修改自身的kernel32或者ntdll就不会导致其他进程崩溃了,
COPY标记实际上是在你修改这个Mapping的时候给你重新分配一个内存你改的是那个地方的内存而不是
映射共享的kernel32等dll,之后线性地址指向新的物理页。

镜像文件

HMODULE hModule=LoadLibrary("C:\\NOTEPAD.EXE");
1.LoadLibray就是通过内存映射的方式实现的。
2.为了避免影响别人,属性为写拷贝。

物理页内存的管理

物理内存(已XP为例)

10-10-12分页 最多识别物理内存为4GB
2-9-9-12分页 最多识别物理内存为64GB
为什么在xp中2-9-9-12分页模式仍然无法超过4GB,
2003/2008的服务器系统32位就可以超过4GB,
实际上就是因为操作系统内核中的几个函数限制的。
实际物理内存=MmNumberOfPhysicalPages*4=物理内存。

物理内存如何管理

1.全局数组
数组指针:_MMPFN* MmPfnDataBase
数组长度:MmNumberOfPhysicalPages=上述的实际物理内存
2.nt!_MMPFN结构体
一个物理页对应一个MMPFN结构体,如果有一万个物理页就有一万个
对应MMPFN结构体,之后通过MmPfnDatabase结构体数组进行组织。

物理页状态

位于_MMPFN中u3->PageLocation属性(处于空闲状态的六种模式)
0:MmZeroedPageListHead  零化链表系统空闲的时候进行零化的,不是程序自己清零的那种。
1:MmFreePageListHead    空闲页空闲链表(物理页是周转使用的,刚释放的物理页是没有清0,系统空闲的时候
有专门的线程从这个队列摘去物理页,加以清0后在挂入MmZeroedPageListHead)
2:MmStandbyPageListHead 备用链表系统内存不够的时候,操作系统会把物理内存中的数据交换到硬盘上
此时页面不是直接挂到空闲链表上的,而是挂到备用链表上,虽然我释放了,
但里边的呢绒还是有意义的。
3:MmModifiedPageListHead
4:MmModifedNoWritePageListHead
5:MmBadPageListHead 坏链

无处不在的缺页异常

什么是缺页异常

缺页异常是PTE中P位当前页是否有效,当CPU访问一个地址,其PTE的P位为0,此时会产生缺页异常。
Windows操作系统中运行的进程中的线性地址对应的物理页并不是一直占用的,只有当前使用这个线性地址
才会有对应的物理页,一段时间不使用线性内存地址就会把相应的物理页内容挂在到硬盘上。

缺页异常与虚拟内存(缺页异常时刻都在发生)

当前物理页不足时,会使用虚拟内存的磁盘文件位于C盘根目录下隐藏叫做pagefile.sys,这个时候虚拟内存
的PTE的P位为0并触发缺页异常,当缺页异常检查时10-11位0 1-4 PFN* 12-14是页面文件偏移,这个时候
操作系统便知道并不是真的缺页,而是将对应的物理页挂在到了虚拟内存中也就是pagefile.sys的磁盘文件中,
之后将P位设置为1并将硬盘物理页读到对应的物理页当中。

EXECUTE_WRITECOPY 执行写拷贝

像kernel32这种dll都是通过映射的方式映射到其他进程内存中的,如果对一个其中一个进程的kernel32.dll做
Hook的话就会造成其他进程也会被Hook,Windows系统为了防止这种情况出现使用了特殊的机制。
实现过程:
1.PTE只读
2.VAD写拷贝
3.修改页内容触发异常
4.异常处理函数
5.发现VAD为写拷贝
6.创建一个新的
如果实现绕过这种机制呢,非常简单只需要修改当前物理页改成可读可写即可就不会触发异常,只需要修改
本身进程内的DLL就是可以实现对有所进程DLL的修改因为他们修改的是同一份物理页。

Windows操作系统内存管理相关推荐

  1. 8g内存一般占用多少_8g内存开机占用一半|Windows操作系统内存使用率多少正常?...

    Windows操作系统内存使用率多少正常?内存使用率根据不同用户的使用习惯和软件安装,笔者总结并模拟了一下资源占用情况,可以根据数据预测XP.Win7.Win8.Win8.1.Win10的开机资源占用 ...

  2. 操作系统 内存管理总结

    目录 内存管理介绍 什么是虚拟内存(Virtual Memory)? 逻辑(虚拟)地址和物理地址 CPU 寻址了解吗?为什么需要虚拟地址空间? 局部性原理 操作系统是如何管理虚拟地址与物理地址之间的关 ...

  3. 面试题总结之windows/linux内存管理

    前言 请说说你对windows/linux内存管理的认识 解答 内存管理的必要性 出现在早期的计算机系统当中,程序是直接运行在物理内存中,每一个程序都能直接访问物理地址.如果这个系统只运行一个程序的话 ...

  4. Windows的内存管理机制

    Windows下的内存是如何管理的? Windows内存的管理可以分为两个层面:物理内存和虚拟内存 其中物理内存由系统管理,不允许应用程序直接访问,应用程序可见的只有一个2G的地址空间,而内存分配是通 ...

  5. 操作系统内存管理-Linux版

    引言 操作系统内存管理:总的来说,操作系统内存管理包括物理内存管理和虚拟内存管理. 物理内存管理: 包括程序装入等概念.交换技术.连续分配管理方式和非连续分配管理方式(分页.分段.段页式). 虚拟内存 ...

  6. 操作系统内存管理——分区、页式、段式管理

    操作系统内存管理--分区.页式.段式管理 标签: 内存管理操作系统数据结构算法 2010-07-05 11:26 20805人阅读 评论(5) 收藏 举报 分类: 操作系统(4) 版权声明:本文为博主 ...

  7. 操作系统内存管理-原理

    任何新技术都是在一点一点的积累中成熟并呈现在世人的面前,就像猿人进程成人也不是一簇而就的,而是在漫长的岁月中一点一点的进化与完善.还比如现代的吸尘器,当前发明吸尘器的那个人只是用了一台风扇的电机和叶片 ...

  8. 计算机操作系统 - 内存管理

    计算机操作系统 - 内存管理 目录 计算机操作系统 - 内存管理 虚拟内存 分页系统地址映射 页面置换算法 1. 最佳 2. 最近最久未使用 3. 最近未使用 4. 先进先出 5. 第二次机会算法 6 ...

  9. 操作系统内存管理及虚拟内存技术

    一.内存管理 操作系统的内存管理主要负责内存的分配与回收(malloc 函数:申请内存,free 函数:释放内存),另外地址转换也就是将逻辑地址转换成相应的物理地址等功能也是操作系统内存管理做的事情. ...

最新文章

  1. 大数据软件产品研发进展及挑战
  2. Weblogic12C 集群实现session同步
  3. Contest2071 - 湖南多校对抗赛(2015.03.28)
  4. ldap odbc mysql_Mysql+ODBC+OpenLDAP
  5. 《MS SQL Server 2000管理员手册》系列——8. 管理 Microsoft SQL Server 服务
  6. hdu 4333 Revolving Digits
  7. 不带parent指针的successor求解
  8. Linux中共享库(so)的几个名称及相关用法
  9. GitKraKenSetup工具——小章鱼
  10. GCN图卷积网络简单实现
  11. Windows快捷键盘
  12. 医学图像处理(三)ABIDE数据集下载
  13. oracle中imp命令详解
  14. 超鸿蒙 混希夷 寂寥,下列句子与“故凡为愚者.莫我若也 的句式不同的一项是 A.超鸿蒙.混希夷.寂寥而莫我知也 B.而良人未之知也 C.及长.不省所怙.惟兄嫂是依 D.王语暴以好乐...
  15. 华南理工计算机就业棒棒,国内3所校名“一字之差”的大学:均为理工大学,实力却天差地别...
  16. 【odroid-xu3】 ODROID-XU3软件环境搭建记录
  17. python分析谷歌浏览器的历史记录
  18. 【Spark Core】【RDD】【01】核心属性 执行原理
  19. 素数的定义法判断(含C++代码)
  20. 全面回顾2022年加密行业大事件:破后而立方能绝处逢生

热门文章

  1. MicroStrategy 9 - Extending Business Intelligence
  2. 【无线图传】基于FPGA的简易无线图像传输系统verilog开发,matlab辅助验证
  3. 上海宝付谈移动支付风头正劲行业期待统一“标准”
  4. 天语 W619 一键ROOT 教程
  5. Linux提示网络不可达
  6. 腾讯云AI人脸识别到底是什么
  7. Android开发工程师vs运维工程师
  8. 电子商务运营思路分享:乐天是如何用地域线索来吸引用户购物
  9. Android 7.0 分屏原理分析
  10. CSS3 linear-gradient线性渐变实现虚线等简单实用图形