之前的 Hello,World! 程式是很簡單的。
但比較複雜一點的程式總免不了要動態配置記憶體,
在 NT Native Application 裡,
還是沒有你想要的 malloc() free() 等函式,來讓你使用。
所以需要自己 call RtlCreateHeap 去產生 Heap 來使用,
HANDLE hHeap = RtlCreateHeap(HEAP_GROWABLE, NULL, 0x100000, 0x1000, NULL, NULL);
之後就可以多次 call RtlAllocateHeap 來配置記憶體,
PVOID pRet = RtlAllocateHeap(g_hHeap, 0, ulSize);
而要釋放記憶體則是 call RtlFreeHeap ,
BOOLEAN bRet = RtlFreeHeap(g_hHeap, 0, pMem);
摧毀 Heap是 call RtlDestroyHeap
PVOID pRet = RtlDestroyHeap(hHeap);
但因為這是 Heap ,
所以有可能會有 fragment 的現象發生,
這時就需要寫個小 module 來管理記憶體,
來降低 fragment 的發生。
以下是 Hello, World! 程式的改良版:
使用動態配置記憶體。
#include "ntifs.h"
#include "ntddk.h"
NTSTATUS NTAPI NtDisplayString(PUNICODE_STRING String);
NTSTATUS NTAPI NtTerminateProcess(HANDLE ProcessHandle, LONG ExitStatus);
HANDLE g_hHeap = NULL;
HANDLE InitHeapMemory(void)
{
g_hHeap = RtlCreateHeap(HEAP_GROWABLE, NULL, 0x100000, 0x1000, NULL,
NULL);
return g_hHeap;
}
BOOLEAN DeinitHeapMemory()
{
PVOID pRet;
pRet = RtlDestroyHeap(g_hHeap);
if (pRet == NULL) {
g_hHeap = NULL;
return TRUE;
}
return FALSE;
}
void free(void *pMem)
{
RtlFreeHeap(g_hHeap, 0, pMem);
}
void *malloc(unsigned long ulSize)
{
return RtlAllocateHeap(g_hHeap, 0, ulSize);
}
void NtProcessStartup(PPEB pPEB)
{
PUNICODE_STRING pHelloWorld = NULL;
if (InitHeapMemory() == NULL) {
DbgPrint("%s:%d InitHeapMemory failed\n",__FILE__,__LINE__);
}
pHelloWorld = malloc(sizeof(UNICODE_STRING));
if (pHelloWorld) {
RtlInitUnicodeString(pHelloWorld,L"Hello World!\n");
NtDisplayString(pHelloWorld);
free(pHelloWorld);
}
DeinitHeapMemory();
NtTerminateProcess( NtCurrentProcess(), 0 );
}