`

《Windows内核编程》---内存管理基本概念

 
阅读更多

内存管理概念:

1)物理内存

PC上有三条总线:数据总线、地址总线和控制总线。32CPU的寻址能力是4GB个字节,用户最多可以使用4GB的真实物理内存。PC中很多设备都提供了自己的设备内存,例如显卡就提供了自己的显存。这部分内存会映射到PC的物理内存上,也就是读写这段物理地址,其实会读写的设备内存地址,而不会读写物理内存地址。

2)虚拟内存地址

Windows所有程序(包括Ring0层和Ring3层的程序)可以操作的都是虚拟内存。之所以称为虚拟内存,是因为对它的所有操作最终都会变成一系列对真实物理内存的操作。

CPU中有一个重要的寄存器CR0,它是32位的寄存器,其中的一个位(PG位)是负责告诉系统是否分页的。Windows在启动前会将它的PG位设为1,即允许分页。DDK中有个宏PAGE_SIZE记录着分页大小,一般为4KB4GB的虚拟内存会被分割成1M个分页单元。

其中,有一部分单元会和物理内存对应起来,即虚拟内存中第N个分页单元对应着物理内存第M个分页单元,这是一种多对一的映射,多个虚拟内存页可以映射到同一个物理内存页。还有一部分单元会被映射成磁盘上的文件,并标记为脏的(Dirty)。当读取这段虚拟内存时,系统会发出一个异常,此时会触发异常处理函数,异常处理函数会将这个页的磁盘文件读入内存,并标记为不脏。

Windows使用虚拟内存是基于以下原因:

1、虚拟的增加了内存的大小;

2、使不同进程的虚拟内存互不干扰,为了让系统可以同时运行不同的进程,Windows让每个进程看到的虚拟内存都不相同。

3)用户模式地址和内核模式地址

虚拟地址0~0x7FFFFFFF范围内的虚拟内存,即低2GB的虚拟地址被称为用户模式地址;而0x80000000~0xFFFFFFFF范围内的虚拟内存,即高2GB的虚拟内存被称为内核模式地址。Windows规定运行在用户态(Ring3层)的程序只能访问用户模式地址,而运行在核心态(Ring0层)的程序可以访问整个4GB的虚拟内存。

Windows的核心代码和Windows的驱动程序加载的位置都在高2GB的内核地址里。Windows在进程切换时,保持内核模式地址是完全相同的,只改变用户模式地址的映射。

4Windows驱动程序和进程的关系

驱动程序可以看成是一个特殊的DLL文件被应用程序加载到虚拟内存中,只不过加载地址是内核模式地址而不是用户模式地址。Windows驱动程序里的不同例程运行在不同的进程中,DriverEntry例程和AddDevice例程是运行在系统进程System中的。System进程是Windows第一个运行的进程。当需要加载驱动程序时,System进程中会有一个线程将驱动程序加载到内核模式地址空间中,并调用DriverEntry例程。而其他一些例程,如IRP_MJ_READ的派遣函数会运行于应用程序的上下文中。所谓运行在进程的上下文,指的是运行于某个进程的环境中,所能访问的虚拟地址是这个进程的虚拟地址。

下面的函数可以显示出当前进程的进程名:

VOID DisplayProcessName()

{

//得到当前进程

PEPROCESS process = PsGetCurrentProcess();

//得到当前进程名称

PTSTR ProcessName = (PTSTR)((ULONG)process + 0x174);

KdPrint(("%s/n", processName));

}

5)分页与非分页内存

Windows规定有些虚拟内存页面可以交换到文件中,这类内存被称为分页内存;而有些虚拟内存永远不会交换到文件中,这些内存被称为非分页内存。

当程序的中断请求级在DISPATCH_LEVEL之上时(包括DISPATCH_LEVEL层),程序只能使用非分页内存,否则将导致蓝屏死机。在编译DDK提供的例程时,可以指定某个例程和某个全局变量是载入分页内存还是非分页内存:

#define PAGEDCODE code_seg("PAGE")

#define LOCKEDCODE code_seg()

#define INITCODE code_seg("INIT")

#define PAGEDDATA data_seg("PAGE")

#define LOCKEDCODE code_seg()

#define INITDATA data_seg("INIT")

如果将某个函数载入到分页内存,我们这样使用:

#pragma PAGEDCODE

VOID ASCEFunction()

{

PAGED_CODE();

//do something

}

其中,PAGED_CODE()DDK提供的宏,只在Checked版本中生效。它检验这个函数是否运行低于DISPATCH_LEVEL的中断请求级,如果等于或高于这个中断请求级,将产生一个断言。

如果让函数加载到非分页内存中,我们这样使用:

#pragma LOCKEDCODE

VOID ASCEFunction()

{

//do something

}

如果某个例程需要在初始化时载入内存,然后就可以从内存中卸载掉(这种情况指出现在DriverEntry情况下,尤其是NT式驱动,DriverEntry会很长,占据很大的空间,为了节省内存,需要及时地从内存中卸载掉),我们这样使用:

#pragma INITCODE

extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,

IN PUNICODE_STRING RegistryPath)

{

//do something

}

6)分配内核内存

Windows驱动程序使用的内存资源非常珍贵,分配内存时要尽量节约。和应用程序一样,局部变量存放在栈空间中,但栈空间不像应用程序那么大,所以驱动程序不适合递归调用或这局部变量是大型结构体。若需要大型结构体,应该在堆上申请。

堆中申请内存的函数如下:

PVOID ExAllocatePoolWithTag(

__in POOL_TYPE PoolType,

__in SIZE_T NumberOfBytes,

__in ULONG Tag

);

PVOID ExAllocatePoolWithQuotaTag(

__in POOL_TYPE PoolType,

__in SIZE_T NumberOfBytes,

__in ULONG Tag

);

其中,PoolType是个枚举变量:

NonPagedPool //指定要求分配非分页内存

PagedPool //指定要求分配分页内存

NonPagedPoolMustSucceed //指定分配非分页内存,必须成功

DontUseThisType //未指定

NonPagedPoolCacheAligned //指定要求分配非分页内存,而且必须内存对齐

PagedPoolCacheAligned //指定分配分页内存,且必须内存对齐

NonPagedPoolCacheAlignedMustS //指定分配非分页内存,且必须内存对齐,且必须成功

NumberOfBytes是分配内存的大小,最好是4的倍数;

返回值分配的内存地址,一定是内核模式地址;如果返回0,表示分配失败。

函数以WithQuota结尾代表分配时按配额分配;以WithTag结尾的,多出的Tag参数,用在调试时,可以找出是否有标有这个Tag的内存没有被释放。

将分配的内存进行回收的函数是ExFreePoolExFreePoolWithTag

VOID ExFreePool(

__in PVOID P

);

VOID ExFreePoolWithTag(

__in PVOID P,

__in ULONG Tag

);

分享到:
评论

相关推荐

    寒江独钓--windows内核安全编程光盘源码_寒江独钓windows内核安全编程_

    总之,《寒江独钓--Windows内核安全编程光盘源码》提供了丰富的实践案例,是你深入理解Windows内核编程、提升安全编程能力的宝贵资料。通过仔细研究和实践其中的代码,你可以逐步提升自己的技术水平,为构建更安全、...

    从汇编语言到Windows内核编程_Windows编程_

    这本书将带领读者从最基本的汇编语言出发,逐步过渡到复杂的Windows内核编程技术。 1. **汇编语言基础**:汇编语言是计算机硬件与高级编程语言之间的桥梁,是理解和控制计算机底层运作的基础。书中会介绍基本的指令...

    寒江独钓-windows内核安全编程-源代码

    1. **Windows内核**:Windows内核是操作系统的核心部分,负责管理系统资源,如内存、进程和线程,以及设备驱动程序。它提供了系统调用接口,使得用户空间的应用程序可以访问内核服务。 2. **内核编程**:内核编程...

    寒江独钓-Windows内核安全编程(完整版)--源码

    在Windows内核安全编程领域,开发者需要掌握一系列关键概念和技术,以确保系统的稳定性和安全性。 首先,我们要了解Windows内核的基本结构。它是操作系统的核心部分,负责管理硬件资源,调度进程,以及提供系统服务...

    从汇编语言到Windows内核编程_Kernel_win32asm_Asm_

    Windows内核编程则是操作系统领域的核心内容,涉及到进程管理、线程调度、内存管理、设备驱动等复杂主题。通过阅读本书,读者可以了解Windows操作系统如何处理系统调用、如何维护进程和线程的状态、如何分配和管理...

    Windows内核安全编程从入门到实践(高级编程)

    1. **权限管理**:在Windows内核编程中,理解和使用正确的访问控制是至关重要的。这涉及到理解对象句柄、访问令牌和权限掩码,以及如何在代码中正确地检查和限制权限。 2. **内存管理**:内核模式下的内存管理不同...

    寒江独钓--Windows内核安全编程

    书中可能详细介绍了Windows内核架构,包括进程、线程、内存管理、中断处理机制以及I/O模型等内容。 在内核安全编程方面,书籍可能会讲解如何防止内核级别的崩溃和漏洞利用。这通常涉及到以下几个关键知识点: 1. ...

    寒江独钓windows内核安全编程源码

    在Windows内核编程中,理解系统调用、中断处理、线程调度、内存管理、设备驱动模型等基础知识是至关重要的。这份资料可能会详细解析这些核心概念,包括如何编写系统调用,如何处理硬件中断,以及如何在内核模式下...

    寒江独钓-windows内核安全编程(配套光盘)

    Windows内核编程是操作系统开发的核心部分,它涉及到系统调用、中断处理、进程管理、内存管理、设备驱动等多个关键领域。在Windows内核中编写代码需要对操作系统的内部工作原理有深入的理解,同时也要求开发者遵循...

    Windows驱动编程视频教程-Windows内存管理

    本视频教程将详细讲解这些概念,并通过屏幕录制的录像展示实际操作过程,帮助开发者深入理解Windows驱动编程和内存管理,提升驱动开发技能。通过学习,你可以更好地应对硬件驱动开发中的各种挑战,确保驱动程序高效...

    Windows内核安全编程从入门到实践[代码]

    在Windows内核编程中,首先要理解的是进程和线程的概念。进程是资源分配的基本单位,而线程则是执行的基本单元。在内核编程中,需要熟练掌握创建、管理和调度进程与线程的方法,同时考虑到多线程环境下的同步和互斥...

    [WINDOWS内核原理与实现].潘爱民.扫描版.pdf

    书中不仅介绍了Windows内核的基本概念和组件,比如进程管理、内存管理、I/O系统和安全机制,还对内核模式下的驱动程序开发和调试进行了深入讲解。潘爱民通过对内核源代码的分析,揭示了Windows内核如何高效地利用...

    windows internals 7th-2; windows 内核数据结构;内核编程参考;英文PDF转word原版

    7. **编程语言**:虽然书中未明确提及具体编程语言,但通常涉及Windows内核编程时,会用到C和C++,因为这两种语言可以直接操作内存和系统资源,适合编写低级别的系统代码。 8. **版权和法律声明**:书中明确指出,...

    windows内核安全编程源码

    1. **Windows内核基础**:Windows内核是操作系统的核心,负责管理硬件资源、调度进程、内存管理和系统安全。内核安全编程需要对Windows内核的工作原理有深入理解,包括进程、线程、对象管理、中断处理和设备驱动等。...

    Windows-via-C-Code-January-29-2008_Windows编程_windows核心编程_

    《Windows 核心编程》是一本深入探讨Windows操作系统编程的权威书籍,涵盖了Windows API、系统调用、进程、线程、内存管理、I/O操作等多个关键领域的内容。这本书的源代码集合提供了丰富的实例,帮助读者理解和实践...

    WIN64内核编程入门手册

    1. **Windows内核**:Windows操作系统的核心,负责系统资源的管理,包括进程、内存、设备驱动等。在64位环境下,Windows内核进行了诸多优化,以充分利用64位架构的优势,如更大的寻址空间和更高效的指令集。 2. **...

    window 内核编程与信息安全

    Windows内核采用了微内核设计,包括进程管理、内存管理、设备驱动管理、中断处理、系统调用等模块。内核编程涉及到编写驱动程序,这些程序运行在内核模式,享有更高的权限,能够直接访问硬件资源,但同时也要求...

    寒江独钓:Windows内核安全编程(光碟源码 第一章)

    1. **Windows内核基础**:首先,我们需要理解Windows内核的基本架构,包括执行体、调度程序、内存管理器、设备驱动模型等组成部分。这些组件如何协同工作以确保系统的稳定性和高效性。 2. **内核模式与用户模式**:...

    天书夜读——从汇编语言到Windows 内核编程

    楚狂人的著作《天书夜读——从汇编语言到Windows内核编程》便是开启这段旅程的钥匙。这本书不仅仅是一本普通的技术手册,它更像是一部指引着程序员深入计算机底层世界的指南。 汇编语言是理解计算机工作的基石,它...

    windows内核安全与驱动开发(pdf+源码).zip

    1. **权限管理**:Windows内核采用强制访问控制(MAC)和 discretionary access control(DAC)策略,通过权限令牌(Access Token)控制进程的访问权限。了解如何正确设置和管理这些权限是保障系统安全的基础。 2. ...

Global site tag (gtag.js) - Google Analytics