2009 01 12 23 44 [winddk] 如何寫 NT native application (3)

之前的 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 );
}