在R3下獲取一個進程加載的相關模塊兒還是比較簡單的,直接通過ToolHelp32庫API就能夠獲取到進程關聯的模塊兒了,但是既然已經在R0下混了再去使用R3層的東西就沒什么意義了,所以這里小悠在這里將會一部一部的介紹如何在R0下通過EPROCESS結構獲取到進程加載的模塊.
首先這里我們先介紹一下我們通過EPROCESS查詢的大概思路
① 通過EPROCESS 獲取到對應的PEB 結構
② 通過PEB找到 _PEB_LDR_DATA這貨
③ 在_PEB_LDR_DATA內部有3個LIST_ENTRY,這也就是進程加載的模塊兒信息的鏈表頭,_PEB_LDR_DATA內部的3個鏈表其實只是模塊兒的排列順序不一樣而已,里面的內容是一致的,本文中采用的是LoadOrder這個按照加載順序排列的鏈表.
④ 知道了鏈表頭,只需要知道鏈表的結點的就夠就行了,這里我們遍歷的鏈表結點是_LDR_DATA_TABLE_ENTRY結構,在這個結構內部有一個FullDllName,也就是模塊兒的路徑,就是我們要找的東西,只要遍歷鏈表我們就能枚舉出所有的加載模塊兒.
我用一幅圖來描述我們的過程
從圖中可以看出,只需要找到最終的那個鏈表遍歷一下就OK了。
知道了上面的基本思路,現在我們開始動手操作了,首先准備好你的Windbg調試工具,先通過Windbg正確查找一個進程的模塊兒鏈表,后面我在介紹使用代碼的方式。
我的虛擬機是Win7 x86的,這里以進程dwm.exe為例.
① 命令 !process 0 0 dwm.exe 先獲取到dwm.exe的EPROCESS的地址,如圖我們可以看到EPROCESS的地址為:0x87ede940 ,PEB的地址為:0x7ffdf000
② 注意PEB的地址小於0x80000000,屬於用戶地址空間,是不能夠直接訪問的,要是直接訪問的話就只能看到???????,所以我們需要切換到這個應用程序后才能夠訪問用戶地址空間,使用下面的命令 .process /p /r 87ede940 切換到dwm.exe這個進程,如圖所示:
③ 已經切換到dwm.exe,我們開始按照步驟來操作吧,命令dt _EPROCESS 87ede940 查看EPROCESS,如圖所示在偏移0x1a8的位置找到了_PEB,地址為0x7ffdf000
④ 跟進_PEB,使用命令 dt _PEB 0x7ffdf000 查看PEB的信息,如圖所示在偏移0x0c的位置找到了_PEB_LDR_DATA,地址為: 0x77307880
⑤ 繼續跟進_PEB_LDR_DATA,使用命令dt _PEB_LDR_DATA 0x77307880 查看_PEB_LDR_DATA的信息,如圖所示,一共有3個_LIST_ENTRY,前面我已經說過這三個鏈表只是結點的順序不一樣,我采用的是第一個InLoadOrderModuleList按照加載順序的這個鏈表.
⑥ 我們已經找到了鏈表的頭部,但是我們現在可不知道_LDR_DATA_TABLE_ENTRY這貨的結構是神馬,所以我們使用命令dt _LDR_DATA_TABLE_ENTRY 來看一下_LDR_DATA_TABLE_ENTRY的結構,如圖所示:
從結構中可以看到InLoadOrderModuleList位於結構體的首部,所以我們獲取到的_LIST_ENTRY地址就直接指向了_LDR_DATA_TABLE_ENTRY,無需再次轉換了
⑦ 回到⑤看一下了鏈表的第一個結點的地址(FLink方向遍歷),第一個地址為0x3017b8,OK我們使用命令dt _LDR_DATA_TABLE_ENTRY 0x3017b8 跟進看一下,如圖所示
是不是看到dwm.exe這個進程本身的路徑了? 那就對了,我們是按照模塊兒加載的順序遍歷的,第一個模塊兒就是本身嘛,不信的話那我們再往后看一個,命令dt _LDR_DATA_TABLE_ENTRY 0x301838 ,自己看下面的圖吧,我就不多說了~~