在驱动中实现进程遍历
在驱动中实现进程遍历
一、进程遍历思路:
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 }