Posts

Showing posts with the label

Windows安全 之 內存映射文件(Section對像)MmCreateSection與MmMapViewOfSection 流程分析

Image
MmCreateSection 內存區(Section)內核對像有兩種,但都是基於分頁內存的: 一種是基於頁面文件的 一種是基於其他文件,以文件空間作為基礎的 如EXE在硬盤上的空間 MmCreateSection主要目的: 1. 填充CONTROL_AREA對像 2. 填充SEGMENT對像 3. 調用ObCreateObject創建Section內核對像 4. 返回Section內核對像 SEGMENT是真正描述映射區域的對像 , 內核函數MmCreateSection中有三種創建方式: 1. MiCreatePagingFileMap //以PageFile(頁面文件)為基礎的文件共享 2. MiCreateImageFileMap //以可執行映像作文件共享 3. MiCreateDataFileMap //以普通數據文件作為基 p.s. 後兩者雖表面內核文件對像, 從函數內部邏輯可發現, 如果映射同一個文件時, Section對像會共用同一個Segment對像 由於Section對像的創建完全是建基於SEGMENT對像, 因此探討SEGMENT對像才是正確方向 了解共享實現 SEGMENT(段對像,分配在分頁內存): 1. 分配的共享空間頁面總數量大小的MMPTE陣列緊隨著SEGMENT對像(用於建立映射視圖時) 2. 指向CONTROL_AREA指針(CONTROL_AREA, 分配在非分頁內存,即物理內存, 它亦會指向SEGMENT對像, 建立互指的關係) 3. 記錄對應節中的所有頁面的數量 4. 全部MMPTE最終指向節的起始地址 建數內部會再次創建真正的: CONTROL_AREA(控制區對象,分配在分頁內存) 1. 指向文件對像指針 2. 尾隨著多個SUBSECTION對像 (指PE中各個節的起始地址,使用Segment的MMPTE進行初始化->再讓VAD中會使用SubSection) 3. SUBSECTION形成鏈表,其中一個指針會指回CONTROL_DATA SubSection結構如下: typedef struct _SUBSECTION { PCONTROL_AREA ControlArea; PMMPTE SubsectionB...

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

Image
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, ...