申请内存
在c语言中我们使用malloc 来分配内存块,但是Windows内核模式下不能使用,没有c runtime。
在内核中,使用ExAllocCatePoolWithTag函数,返回PVOID指针,
它有3个参数,内存类型,长度标签:
- ExAllocatePoolWithTag(NonPagedPool,length,tag);
- 如果空闲内存不够,函数会返回null,我们需要用if语句判断释放申请成功
- 内存有多种类型,常用的是NopagedPool和PagedPool
- 内存是非常稀缺的,使用时才分配,不用就释放掉
- length:申请内存大小
- tag参数可以帮助调试程序
- tag是ascii 字符的 0x20(空格)到0x126 波浪号范围内的值
释放内存
可以使用ExFreePool 释放,也可以使用ExFreeWithTag 释放
ExFreePool()只有一个参数,申请内存的地址
填充内存
RtlZeroMemory(deststring.Buffer,length);
RtlFillMemory(deststring.Buffer, length,0x90); //填充为nop
复制内存
RtlCopyMemory(deststring.Buffer,sourstring.Buffer,length);
RtlMoveMemory(deststring.Buffer, sourstring.Buffer, length);
两者区别:当源地址和目的地址内存重叠时,RtlCopyMemory会失败,但是rtlmoveMemory会成功,
因此,不确定内存是否重叠时,应该使用RtlMoveMemory
代码
#include <ntddk.h>
#define Mytag 'abc'
VOID Unload(IN PDRIVER_OBJECT DriverObject) {
DbgPrint("driver unload\r\n");
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegisteryPath) {
DriverObject->DriverUnload = Unload;
UNICODE_STRING sourstring = RTL_CONSTANT_STRING(L"hello drivertyty");
UNICODE_STRING deststring = { 0 };
ULONG length;
length = sourstring.Length;
deststring.Buffer = (PWCHAR)ExAllocatePoolWithTag(NonPagedPool,length,Mytag);
if (NULL!=deststring.Buffer)
{
RtlZeroMemory(deststring.Buffer,length);
RtlFillMemory(deststring.Buffer, length,0x90);
deststring.Length = deststring.MaximumLength = length;
RtlCopyUnicodeString(&deststring, &sourstring);
RtlCopyMemory(deststring.Buffer,sourstring.Buffer,length);
RtlMoveMemory(deststring.Buffer, sourstring.Buffer, length);
DbgPrint("string is %wZ \r\n", &deststring);
ExFreePool(deststring.Buffer);
}
return STATUS_SUCCESS;
}