线性地址管理

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. TDD与FDD技术对比
  2. ajax方式下载文件
  3. python 语言教程(3)变量之元组
  4. 企业级服务器固态硬盘,用户如何选择企业级SSD?_Intel服务器CPU_企业存储技术与评测-中关村在线...
  5. 推荐15个 JavaScript 和 CSS 库
  6. 可禁用计算机服务,win10哪些服务可以禁用 服务哪些可以禁止启动
  7. 尝试在UBUNTU环境下测试优盘读写速度
  8. 【Latex】一、TeX Live和TeXstudio安装及使用教程
  9. 朋友圈点赞截图在线生成源码
  10. 部分电商平台为防止爬虫竟然这样做?
  11. 微信小程序云开发(2)— 云数据库
  12. 如何用usb电缆连接到计算机,如何使用USB串行电缆将文件从计算机传输到树莓派...
  13. 什么是jQuery 怎么使用jQuery
  14. 采轩服饰工业园选择飞鱼星完成无线覆盖
  15. 禅道讲义之超级管理员
  16. android 电池20 提醒,当日修冷知识:滴咚!为啥手机电量低于20%就会自动提醒?...
  17. 单片机学习部分总结 AVR篇
  18. 怎么把flv转换成mp4格式?
  19. pmd 相机 系统标定
  20. 数学(1)初一上学期数学笔记

热门文章

  1. 学编程前博主是做测试的,当初在测试部作为一个小官还写了不少流程呢,今天突然翻到来跟大家分享一下测试流程(之测试内部流程)
  2. socket.js教程
  3. (28)【xss工具绕过】xss之burpsuite、前端、字典……
  4. 【光环国际】身边的项目,身边的管理
  5. 使用 jQuery.i18n.properties 实现 Web 前端的国际化
  6. 2015-1-11 【erlang】erl中的make -make 参数 以及 Emakefile
  7. 金现代面试题—— i++,++i, ,|自动装箱和自动拆箱(int,byte,float等)|取int等基本类型的最大值
  8. 云快充协议 - 共享充电桩平台APP
  9. 298高校毕业设计选题
  10. 理解Java线程状态(6种,6种,6种)