在驅動中實現進程遍歷
一、進程遍歷思路:
1)之前在用戶層,我們通過查看TEB結構體來實現進程遍歷;但在內核層,我們使用_EPROCESS結構體來獲取進程相關信息。
2)_EPROCESS 有幾個比較重要的成員:
1> +0x11c VadRoot : Ptr32 Void,該進程VAD樹的根結點。
2> +0x084 UniqueProcessId : Ptr32 Void ,指向PID的指針。(注意是指針,還要取值運算才能得到PID)
3> +0x088 ActiveProcessLinks : _LIST_ENTRY , 進程鏈,我們通過這個獲取獲取其他進程。
4> +0x174 ImageFileName : [16] UChar,指向進程的路徑名稱。
3)我們在驅動中通過 PsGetCurrentProcess(),來獲取當前進程的EPROCESS結構體,然后通過鏈表遍歷其余的EPROCESS,將關鍵信息輸出出來。
二、源代碼:
1 #include <ntddk.h> 2 3 VOID Unload(IN PDRIVER_OBJECT pDriverObject) { 4 DbgPrint("Driver UnLoad!"); 5 } 6 7 //-------------------------------------------------------------// 8 // 在內核中進程遍歷的原理就是先獲取系統進程EPROCESS結構 // 9 // 然后依照其鏈表來獲取其他的進程 // 10 // 依次遍歷出來 // 11 //-------------------------------------------------------------// 12 NTSTATUS process_enum() { 13 PEPROCESS pEprocess = NULL; // 得到系統進程地址 14 PEPROCESS pFirstEprocess = NULL; 15 ULONG ulProcessName = 0; // 字符串指針,指向進程名稱 16 ULONG ulProcessID = 0; // 進程ID 17 18 //----------------------------// 19 // 得到當前系統進程的EPROCESS // 20 //----------------------------// 21 pEprocess = PsGetCurrentProcess(); 22 if (pEprocess == NULL) { 23 DbgPrint("獲取當前系統進程EPROCESS錯誤.."); 24 return STATUS_SUCCESS; 25 } 26 DbgPrint("pEprocess addr is %x0x8\r\n", pEprocess); 27 pFirstEprocess = pEprocess; 28 29 while (pEprocess) { 30 ulProcessName = (ULONG)pEprocess + 0x174; 31 ulProcessID = *(ULONG*)((ULONG)pEprocess + 0x84); 32 DbgPrint("PID=%d,process_name=%s", ulProcessID, ulProcessName); 33 34 //-----------------------------------------------------------------// 35 // 指向下一個進程 // 36 // t = *(ULONG*)((ULONG)pEprocess + 0x88) 獲取下一個進程的該處指針 // 37 // t-0x88 指向下一個 EPROCESS 頭部 // 38 //-----------------------------------------------------------------// 39 pEprocess = (PEPROCESS)(*(ULONG*)((ULONG)pEprocess + 0x88) - 0x88); 40 41 // 判斷標准: 42 if (pEprocess == pFirstEprocess || *(ULONG*)((ULONG)pEprocess + 0x84) <= 0) { 43 DbgPrint("遍歷結束!\r\n"); 44 break; 45 } 46 47 } 48 49 return STATUS_SUCCESS; 50 51 52 } 53 NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING registeryPat) { 54 DbgPrint("Driver Loaded!"); 55 pDriverObject->DriverUnload = Unload; 56 process_enum(); 57 return STATUS_SUCCESS; 58 }
