PoolType在 MSDN的介绍上有 N 种, 其实常用的只有 2 种:
PagedPool 和NonPagedPool。PagedPool是分页内存,简单来说就是物理内存不够时,会把这片内存移动到硬盘上,而NonPagedPool是无论物理内存如何紧缺,都绝对不把这片内存的内容移动到硬盘上。 在往下讲之前,先补充一个知识, 就是我们操作的内存,都是虚拟内存,和物理内存是两码事。 但虚拟内存的数据是放在物理内存上的,两者存在映射关系, 一般来说,一片物理内存可以映射为多片虚拟内存, 但一片虚拟内存必定只对应一片物理内存。 假设虚拟内存是 0Xfffff80001234567 在物理内存的地址是 0x123456, 当物理内存不够用时, 物理内存0x123456的原始内容就挪到硬盘上,然后把另外一片急需要用的内容移到物理内存里。 此时, 当你再读取 0Xfffff80001234567 的内容时,就会引发缺页异常, 系统就会把在硬盘上的内容再次放到物理内存中(如果这个过程失败,一般就死机了)。
以上说了这么多废话,总结两句:1.NonPagedPool的总量是有限的( 具体大小和你物理内存的大小相关), 而PagedPool的总量较多。申请了内存忘记释放都会造成内存泄漏,但是很明显忘记释放NonPagedPool的后果要严重得多;2.一般来说,PagedPool用来放数据(比如你用ZwQuerySystemInformation枚举内核模块,可以申请一大片PagedPool存放返回的数据),而NonPagedPool用来放代码(你写内核shellcode并需要执行时, 必须使用NonPagedPool存放shellcode)。 以我的经验来说,访问到切换出去的内存没事,但是执行到切换出去的内存必然蓝屏( 这只是我的经验,正确性待定)。3.在用户态,内存是有属性的, 有的内存片只 能 读 不 能 写 不 能 执 行 (PAGE_READ), 有 的 内 存 片 可 以 读 可 以 写 也 可 以 执 行(PAGE_READ_WRITE_EXECUTE)。 在内核里,PagedPool和 NonPagedPool都是可读可写可执行的, 而且没有类似VirtualProtect之类的函数。