在本節中,我們將學習驅動層的記憶體管理,介紹記憶體管理中常用的API,並與應用程式層內管理API相對應。
核心中常用的記憶體管理API與應用程式層記憶體管理API對應關係如下:
核心API |
應用程式層C API |
說明 |
RtlCopyMemory |
memcpy |
記憶體拷貝 |
RtlCopyBytes |
memcpy |
記憶體拷貝 |
RtlMoveMemory |
memmove |
記憶體移動 |
RtlZeroMemory |
memset |
記憶體初始化 |
RtlFillMemory |
memset |
記憶體初始化 |
RtlEqualMemory |
memcmp |
記憶體比較 |
ExAllocatePool/ExAllocatePoolWithTag |
alloc |
記憶體配置 |
ExFreePool/ExFreePoolWithTag |
free |
記憶體釋放 |
如果想在核心中運用new, delete c++的方式分配記憶體,那麼需要重載new,delete關鍵字。如下:
void * __cdecl operator new(size_t size,POOL_TYPE PoolType=PagedPool){KdPrint(("global operator new\n"));KdPrint(("Allocate size :%d\n",size));return ExAllocatePoolWithTag(PagedPool,size, 1);}//重載delete void __cdecl operator delete(void* pointer){KdPrint(("Global delete operator\n"));ExFreePool(pointer);}
下面有一個核心記憶體應用的執行個體:
VOID memtest(){ VOID UNALIGNED *d;VOID UNALIGNED *s;SIZE_T Length=8;ULONG ulRet;char *buffer=new (PagedPool) char[111];//delete buffer; //為s指標分配大小為8位元組的核心 記憶體 s=ExAllocatePoolWithTag(PagedPool,Length, 1); KdPrint(("s=%x \n",(int*)s)); // __asm int 3 db //為d指標分配大小為8位元組的核心 記憶體 d=ExAllocatePoolWithTag(PagedPool,Length, 1); // __asm int 3 db KdPrint(("d=%x \n",(int*)d)); //用0來填充s指標 指向的記憶體 填充長度為Length=8 RtlFillMemory(s,Length,'s'); // __asm int 3 db KdPrint(("RtlFillMemory 1 \n" )); //複製S指標指向的內容到 D地址 複製長度為Length=8 RtlCopyMemory(d,s,Length); //memcpy// __asm int 3 KdPrint(("RtlCopyMemory s to d \n" )); //複製S指標指向的內容到 D地址 複製長度為Length=8 RtlCopyBytes(d,s,Length); //判斷記憶體是否一致 ulRet = RtlCompareMemory(d,s,Length); // 可用//RtlEqualMemory(d,s,Length);// 和此函數時請用build if (ulRet==Length) //如果傳回值 { KdPrint(("111 D和S 記憶體塊相同.\n")); }else KdPrint(("111 D和S 記憶體塊不相同\n")); //清空S指標指向地址 RtlZeroBytes(s,Length); ulRet = RtlCompareMemory(d,s,Length); if (ulRet==Length) //如果傳回值{KdPrint(("222 D和S 記憶體塊相同.\n"));}else KdPrint(("222 D和S 記憶體塊不相同\n")); ExFreePool(s) ; return;}
具體參看完整源碼。