内存使用,无非就是申请、复制、设置、释放。在 C 语言里,它们对应的函数是:malloc、memcpy、memset、free;在内核编程里,他们分别对应 ExAllocatePool、RtlMoveMemory、RtlFillMemory、ExFreePool。它们的原型分别是:
PVOID ExAllocatePool(POOL_TYPE PoolType, SIZE_T NumberOfBytes);
VOID RtlMoveMemory(PVOID Destination, PVOID Source, SIZE_T Length);
VOID RtlFillMemory(PVOID Destination, SIZE_T Length, UCHAR Fill);
VOID ExFreePool(PVOID P);
需要注意的是,RtlFillMemory 和 memset 的原型不同、ExAllocatePool 和 malloc 的原型也不同。前者只是参数前后调换了一下位置,但是后者则多了一个参数:PoolType。这个PoolType 也是必须了解的。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 之类的函数。
在内核里想要写入“别人的”内存(一般指 NTOS 等系统模块的内存空间),还有另外的规矩,这里又涉及到另外两个概念:IRQL 和内存保护。IRQL 成为中断请求级别,从 0~31 共32 个级别;内存保护可以打开和关闭,如果在内存处于保护状态时写入,会导致蓝屏。一般来说,要写入“别人的”内核内存,必须关闭内存写保护,并把 IRQL 提升到 2 才行(绝大多数时候 IRQL 都为 0,当 IRQL=2 时,会阻断大部分线程执行,防止执行出错)。内存是否处于写保护的状态记录在 CR0 寄存器上,因此直接修改 CR0 寄存器的值即可;而提升或降低IRQL 则使用 KeRaiseIrqlToDpcLevel 和 KeLowerIrql 实现(WIN64 的 IRQL 值记录在 CR8 寄存器上,而 WIN32 的 IRQL 值记录在 KPCR 上)
代码如下
KIRQL WPOFFx64()
{
KIRQL irql=KeRaiseIrqlToDpcLevel();
UINT64 cr0=__readcr0();
cr0 &= 0xfffffffffffeffff;
__writecr0(cr0);
_disable();
return irql;
}
void WPONx64(KIRQL irql)
{
UINT64 cr0=__readcr0();
cr0 |= 0x10000;
_enable();
__writecr0(cr0);
KeLowerIrql(irql);
}
void test()
{
KIRQL irql=WPOFF();
RtlMoveMemory(NtOpenProcess,HookCode,15);
WPON(irql);
}
至于写入“别人的”内存,还有一种微软推荐的安全方式,就是 MDL 映射内存的方式。这个比较麻烦,大概方法是申请一个 MDL(类似句柄的玩意),然后尝试锁定页面,如果成功,则让系统分配一个“安全”的虚拟地址再行写入,写入完毕后解锁页面并释放掉 MDL。
BOOLEAN SafeCopyMemory( PVOID pDestination, PVOID pSourceAddress, SIZE_T SizeOfCopy )
{
PMDL pMdl = NULL;
PVOID pSafeAddress = NULL;
if( !MmIsAddressValid(pDestination) || !MmIsAddressValid(pSourceAddress) )
return FALSE;
pMdl = IoAllocateMdl(pDestination, (ULONG)SizeOfCopy, FALSE, FALSE, NULL );
if( !pMdl )
return FALSE;
__try
{
MmProbeAndLockPages( pMdl, KernelMode, IoReadAccess );
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
IoFreeMdl( pMdl );
return FALSE;
}
pSafeAddress = MmGetSystemAddressForMdlSafe( pMdl, NormalPagePriority );
if( !pSafeAddress )
return FALSE;
__try
{
RtlMoveMemory(pSafeAddress, pSourceAddress, SizeOfCopy );
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
;
}
MmUnlockPages( pMdl );
IoFreeMdl( pMdl );
return TRUE;
}
版权属于: 顾锦歌——发现生活的美!
本文链接: https://main.huat.fun/index.php/archives/31/
本文最后更新于2022年05月09日 ,已超过989天没有更新,若内容或图片失效,请留言反馈。
本文允许转载,但请在转载时请以超链接或其它形式标明文章出处
Your go-to source for leads. We can provide business to business and business to consumer leads, custom-tailored to your needs. CustomDatabases.org
Hi, It is with sad regret to inform you TopDataList.com is shutting down. We are ceasing operations on TopDataList.com and have made our leads available at a $149 once off fee. Visit us on TopDataList.com Regards, Otilia
Hello, from CustomData.click we are a provider of unique databases that could help your business. Please visit us at CustomData.click to see if we can help you. Regards, Ervin
Hello. It is with sad regret to inform you TopDataList.com is shutting down. We have made all our databases available for you for a once off fee. Visit us on TopDataList.com
ZippyLeads.org is running an easter special till the 18th of April. Get all the leads you need for your company with our easter special.
Hello. My name is Johan Fourie and I am looking to sell DataList.biz. We are a data company that has been in the industry for 12 years. We do around $170k/year in revenue. 1) I am looking to sell 50% of the business for $5k. 2) It would be helpful if you are knowledgeable about the Data Business. 3) I am looking for someone that is willing to take over administration, support, client relations. 4) I will continue to do the marketing for new products. 5) You will accept all future income and pay me from it. Please contact me on WhatsApp +27 72 280 1952 or my personal email: johanfourieinc@gmail.com if you are interested in this and we can have a call. Regards, Johan Fourie
Hi, I am interested in some of your products. Please give me a call on +1 304-873-4360
欢迎加入 Typecho 大家族