驱动之路_链表枚举进程
其实每个进程都有一个EPROCESS 结构的对象
可以通过windbg的命令查看:
dt_eprocess 0x11111 查看结构体
dt_LIST_ENTRY 0x2222 查看链表
#define INITCODE code_seg("INIT") //定义区段,代码运行一次后就释放该函数占用的内存空间 #define PAGECODE code_seg("PAGE") //可以用于虚拟内存 #include <ntddk.h> //这里是C语言的头文件 #include "stdafx.h" typedef enum WIN_VER_DETAIL { WINDOWS_VERSION_NONE, // 0 WINDOWS_VERSION_2K, WINDOWS_VERSION_XP, WINDOWS_VERSION_2K3, WINDOWS_VERSION_2K3_SP1_SP2, WINDOWS_VERSION_VISTA_2008, WINDOWS_VERSION_7_7600_UP, WINDOWS_VERSION_7_7000 } WIN_VER_DETAIL; WIN_VER_DETAIL WinVersion; EXTERN_C NTSTATUS PsLookupProcessByProcessId(IN ULONG ulProcId, OUT PEPROCESS * pEProcess); WIN_VER_DETAIL GetWindowsVersion() { RTL_OSVERSIONINFOEXW osverinfo; if (WinVersion) return WinVersion; memset(&osverinfo,0,sizeof(RTL_OSVERSIONINFOEXW)); osverinfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW); if (RtlGetVersion((RTL_OSVERSIONINFOW*)&osverinfo) != STATUS_SUCCESS){ return WINDOWS_VERSION_NONE; } // KdPrint(("[xxxxxxxx] OSVersion NT %d.%d:%d sp%d.%d\n", // osverinfo.dwMajorVersion, osverinfo.dwMinorVersion, osverinfo.dwBuildNumber, // osverinfo.wServicePackMajor, osverinfo.wServicePackMinor)); if (osverinfo.dwMajorVersion == 5 && osverinfo.dwMinorVersion == 0){ WinVersion = WINDOWS_VERSION_2K; } else if (osverinfo.dwMajorVersion == 5 && osverinfo.dwMinorVersion == 1){ WinVersion = WINDOWS_VERSION_XP; } else if (osverinfo.dwMajorVersion == 5 && osverinfo.dwMinorVersion == 2){ if (osverinfo.wServicePackMajor==0){ WinVersion = WINDOWS_VERSION_2K3; } else{ WinVersion = WINDOWS_VERSION_2K3_SP1_SP2; } } else if (osverinfo.dwMajorVersion == 6 && osverinfo.dwMinorVersion == 0){ WinVersion = WINDOWS_VERSION_2K3_SP1_SP2; } else if (osverinfo.dwMajorVersion == 6 && osverinfo.dwMinorVersion == 1 && osverinfo.dwBuildNumber == 7000){ WinVersion = WINDOWS_VERSION_7_7000; } else if (osverinfo.dwMajorVersion == 6 && osverinfo.dwMinorVersion == 1 && osverinfo.dwBuildNumber >= 7600){ WinVersion = WINDOWS_VERSION_7_7600_UP; } return WinVersion; } #pragma PAGECODE /*指的代码运行后 就从内存释放掉*/ VOID DDK_UnLoad(IN PDRIVER_OBJECT pDriverObject) { KdPrint(("驱动成功被卸载...")); } VOID EnumProcess() { //先获取PID=4的进程对象 ULONG_PTR offset_eprocess_flink;//ULONG_PTR=无符号整形,如果在win7 64位下,那么他就是64位,如果是32位那么他就是32位 WIN_VER_DETAIL WinVer; NTSTATUS status = STATUS_UNSUCCESSFUL; PEPROCESS eprocess_process_object; PLIST_ENTRY listentry_process_list; PLIST_ENTRY first_process_list;//记录第一个 ULONG_PTR count=0; //我们要在这里初始化一下偏移量 //EPROCESS 增加新的成员 WinVer = GetWindowsVersion(); switch(WinVer) { case WINDOWS_VERSION_XP: offset_eprocess_flink = 0x88; break; case WINDOWS_VERSION_7_7600_UP: case WINDOWS_VERSION_7_7000: offset_eprocess_flink = 0xb8; break; case WINDOWS_VERSION_VISTA_2008: offset_eprocess_flink = 0x0a0; break; case WINDOWS_VERSION_2K3_SP1_SP2: offset_eprocess_flink = 0x98; break; case WINDOWS_VERSION_2K3: offset_eprocess_flink = 0x088; break; } //做一个简单的效验 if (!offset_eprocess_flink){ return; } status = PsLookupProcessByProcessId((ULONG)4, &eprocess_process_object); if (NT_SUCCESS(status)) { //ObDereferenceObject来减少引用计数 ObDereferenceObject(eprocess_process_object); //相加得到ActiveProcessLinks listentry_process_list = (PLIST_ENTRY)((ULONG_PTR)eprocess_process_object + offset_eprocess_flink); //listentry_process_list这个是第一个进程ID为4的链表 first_process_list = listentry_process_list;//把进程为4的进程链表地址给first do { //(ULONG_PTR)listentry_process_list 这里如果是指针的话,要通过ULONG_PTR强制转换 DbgPrint("%X",(ULONG_PTR)listentry_process_list - offset_eprocess_flink);//打印出自己的EPROCESS 内存地址 listentry_process_list = listentry_process_list->Flink;//赋值下一个进程链表 } while (listentry_process_list != first_process_list);//如果赋值到最后一个就退出链表 } } NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,PUNICODE_STRING pString)//驱动入口函数 { KdPrint(("驱动被加载!!!"));//调试的时候可以用这个函数调试 pDriverObject->DriverUnload=DDK_UnLoad;//设置卸载驱动函数 EnumProcess(); return (NTSTATUS)1; }

浙公网安备 33010602011771号