Windows內存布局 / MmPfnDataBase頁幀數據庫


Windows內核分析索引目錄:https://www.cnblogs.com/onetrainee/p/11675224.html

Windows內存布局 / MmPfnDataBase頁幀數據庫

1. Windows操作系統在X86下的內存布局如下圖所示

  

 

2. 進程工作集 (Hyperspace and process working set list)

  如上圖所示,在c0400000地址處存在一個進程工作集,其在EProcess+0x1f8 vm 表示,其是一個 _SUPPORT結構。

  

 

3. nt!MmNumberOfPhysicalPages 查看存在多少物理頁
  這是一個全局變量,表明操作系統當前可用的物理頁個數,我們在10-10-12分頁模式下一個頁以4KB為單位,我們查看該變量:

  dd nt!MmNumberOfPhysicalPages 0001ff6c

  我們從任務管理器中查看其可用的內存

  

   很容易發現滿足關系 0001ff6c*4 =  523696,因此可以驗證我們的說法:該變量代表當前進程中可用的物理頁數。

 

4. 頁幀數據庫 PfnDataBase

  1) mmpfndatabase 全局變量

    該全局變量以數組形式存儲對應的__MMPFN數據結構,整個可以看做 __MMPFN[x],x表示第x個物理頁,這是數組一次排序。

    其__MPFN數據結構如下(其中涉及大量的Union類型),其單個長度 0x14。(注意,其長度不確定,具體看詳細版本的長度)

    

   2) 物理頁的八種狀態(實際只有六個,其存在各自的鏈表)

    物理頁本來應該存在八種狀態,但其中只有六個可用,其存儲在 __MMPFN.u3

    u3中存在一個 __MMPFNENTRY,里面描述了有關該頁所處的狀態(空閑狀態,零化狀態,未分配狀態·····)。

    其根據物理頁的狀態,制作不同的鏈表,將相同屬性的物理頁串聯在一起,如下六個全局變量:

    ① MmZeroedPageListHead  // 可以使用並清零的內存

    ② MmFreePageListHead // 被釋放的內存,定期會檢測是否有數據,如果有就清空並且掛到第一個鏈表中

    ③ MmStandbyPageListHead  // 分頁內存,備份到虛擬文件中,如果①②用完其才會用到這個,緊急使用

    ④ MmModifiedPageListHead // 修改過屬性的頁

    ⑤ MmModifiednoWritePageListHead // 修改但是沒有寫出的鏈表

    ⑥ MmBadPageListHead // 壞頁的鏈表

   具體的存儲在 MmPageLocationList 這個數組中,我們在WRK中可以看到該數組的定義,我們可以看到,八個中確實只用到了六個。

    

    typedef enum _MMLISTS {
        ZeroedPageList,
        FreePageList,
        StandbyPageList,  //this list and before make up available pages.
        ModifiedPageList,
        ModifiedNoWritePageList,
        BadPageList,
        ActiveAndValid,
        TransitionPage
    } MMLISTS;

   3)__MMPFN的中存在 FlinkBlink 兩個成員,但其並不是指針而是ULONG類型,前面說過內存物理頁是依次排列的,那么這兩個成員有什么用呢?

    前面我們說過其存在六個鏈表,雖然物理頁的前后是確定的,但是相同屬性的物理頁卻是通過 Flink 與 Blink 連接起來的,其並不是連接而是在頁幀數據庫中的位置,這個很好理解。

    

    而 MmPageLocationList數組中存儲的各個屬性物理頁頭部的地址,這樣整個頁幀數據庫體系就很容易搭建起來了。

  4)Windbg 遍歷pfn 單個 __MMPFN數據結構

  使用windbg的 !pfn x 命令可以查看其存在多少對應的PFN對應的物理頁的屬性:

  

 

5. 驅動遍歷某一鏈表

  結合我們上面所講,其Pfn在內存中的布局如下,如果上面都看懂了,這部分應該很好理解,但其中MmPageLocationList與MmPfnDataBase並不是導出變量,我們通過IDA特征碼定位即可。

  

#include <ntifs.h>
#include <ntimage.h> #include <intrin.h> #include "tools.h" typedef struct _MMPFN { ULONG Flink; // 前一個節點索引 ULONG PteAddress; // 對應的pte地址 ULONG Blink; // 后一個節點索引 ULONG u3[3]; // 占位,總共0x14個字節 }MMPFN,*PMMPFN; typedef enum _MMLISTS { ZeroedPageList, FreePageList, StandbyPageList, //this list and before make up available pages.  ModifiedPageList, ModifiedNoWritePageList, BadPageList, ActiveAndValid, TransitionPage } MMLISTS; typedef struct _MMPFNLIST { PFN_NUMBER Total; MMLISTS ListName; PFN_NUMBER Flink; PFN_NUMBER Blink; } MMPFNLIST, *PMMPFNLIST; PULONG MmPageLocationList; // PULONG MmPfnDataBase; // 頁幀數據庫  VOID DriverUnload(PDRIVER_OBJECT pDriverObject) { DbgPrint("卸載完成\n"); } NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegsiterPath) { pDriverObject->DriverUnload = DriverUnload; // 定位 MmPageLocationList FindCode findcodes[1] = { 0 }; initFindCodeStruct(&findcodes[0], "8B******8B48*FF088B56*894D*8B0E83**894D*0F*****8B*****8D0C498954**8B5D*8B4D*", 0, 0); PUCHAR f = (PUCHAR)FindAddressByCode(findcodes, 1); MmPageLocationList = *(PULONG) ((PUCHAR)f + 3); // 定位 MmPfnDataBase FindCode findcodes2[1] = { 0 }; initFindCodeStruct(&findcodes2[0], "8B*****8D044956578D34C28B7E*A1****C1**83**85C0895D*894D*0F*****83******0F*****8B46*", 0, 0); f = (PUCHAR)FindAddressByCode(findcodes2, 1); PULONG MmPfnDataBase = *(PULONG)(*(PULONG)((PUCHAR)f + 2)); // 查詢空閑鏈表數據成員 MMLISTS PfnIndex = FreePageList; PMMPFNLIST ZeroedPageList = MmPageLocationList[PfnIndex]; DbgPrint("零化鏈表的總數為:%x,前一個節點為:%x,后一個節點為:%x\r\n", ZeroedPageList->Total,ZeroedPageList->Flink,ZeroedPageList->Blink); // 開始遍歷PfnDataBase頁幀數據庫 //DbgPrint("MmPfnDataBase地址為:%p\r\n", MmPfnDataBase); ULONG index = ZeroedPageList->Flink; // 獲取第一個節點索引  PMMPFN p; for (ULONG i = 0; i < ZeroedPageList->Total; i++) { p = (PMMPFN)((PUCHAR)MmPfnDataBase + sizeof(MMPFN) * index); // 獲取結點 DbgPrint("Current PteAddress:%x\r\n", p->PteAddress); index = p->Flink; // 更新下一個結點  } return STATUS_SUCCESS; }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM