Windows安全之 應用層(Ring3)的)內存管理(四) 堆(Heap)


4. Windows 最小單位的內存管理 - 堆

進程的默認堆是1MB, 透過修改鏈接器的/HEAP 屬性可以自定義大小

相比之前兩章, 堆是用來管理鏈表和樹的最好內存結構, 堆的優點就是可以不顧分配粒度, 和頁面邊界的事情, 但缺點就是分配及釋放比較慢一點, 而且也沒法再對物理存備器調撥進行直接控制。


4.1 創建額外的堆 
HANDLE WINAPI HeapCreate(
  _In_ DWORD  flOptions,
  _In_ SIZE_T dwInitialSize,
  _In_ SIZE_T dwMaximumSize 
);

使用創建HeapCreate額外的堆

使用額外的堆 可使線程開銷減低, 而且把儲存對象分類, 不然如果把鏈表及二叉樹的對象放在同一個堆中, 會發現鏈表的節點有可能會令二叉樹的節點被破壞,  如下圖



創建額外的堆的原因
假設NODE1 有代碼會覆蓋它的下8個字節的地方, 這樣就會使NODE1及BRAJNCH2,3 被破壞
所以我們是需要創建額外的堆來保護我們的組件, 不應把所有類別都在放同一個堆中

使用堆, 能夠快速釋放, 例如我們將一個二叉樹的所有節點 進行釋放, 需要遍歷所有節點進行釋放, 但現在 我們使用堆存放著所有節點, 我們只需要把這個堆釋放, 例如Windows的資源管理器使用二叉樹來遍歷系統所有進程, 那如果刷新一次, 他就需要重新遍歷一次系統 看進程是否已經存在, 但使用堆就可以直接清除, 最後重新遍歷, 不用再比對什麼

4.2 從堆中分配內存塊

使用以下函數
LPVOID WINAPI HeapAlloc(
  _In_ HANDLE hHeap,    //指定哪一塊堆中建立內存塊
  _In_ DWORD  dwFlags,
  _In_ SIZE_T dwBytes
);

使用創建HeapAlloc在堆中分配一塊內存,  如果成功返回內存塊地址, 若較大的內存分配應直接使用VirtualAlloc , 而不使用堆函數

LPVOID WINAPI HeapReAlloc(
  _In_ HANDLE hHeap,
  _In_ DWORD  dwFlags,
  _In_ LPVOID lpMem,
  _In_ SIZE_T dwBytes
);
亦可以使用HeapReAlloc函數對堆重整大小
以下是一些堆函數:
BOOL WINAPI HeapFree(     //釋放堆中分配的內存塊
  _In_ HANDLE hHeap,      //堆句柄
  _In_ DWORD  dwFlags,
  _In_ LPVOID lpMem       //內存塊指針
);

BOOL WINAPI HeapDestroy( //銷毀堆
  _In_ HANDLE hHeap      //堆句柄
);
SIZE_T WINAPI HeapSize( //獲取堆大小
  _In_ HANDLE  hHeap,
  _In_ DWORD   dwFlags,
  _In_ LPCVOID lpMem
);

Comments

Popular posts from this blog

Android Kernel Development - Kernel compilation and Hello World

How does Nested-Virtualization works?

Understanding ACPI and Device Tree