Windows内核驱动EPROCESS遍历进程模块

 时间:2024-10-24 22:58:58

1、包含的头文件#include <ntifs.h>#include <ntstrsafe.h>

2、声明的API函数NTKERNELAPI HANDLE PsGetProcessInheritedFromUniqueProcessId(IN PEPROCESS Process);NTKERNELAPI PPEB_EX PsGetProcessPeb(PEPROCESS Process);NTKERNELAPI NTSTATUS PsLookupProcessByProcessId(HANDLE Id, PEPROCESS *Process);NTKERNELAPI NTSTATUS PsLookupThreadByThreadId(HANDLE Id, PETHREAD *Thread);NTKERNELAPI PEPROCESS IoThreadToProcess(PETHREAD Thread);//NTKERNELAPI VOID NTAPI KeAttachProcess(PEPROCESS Process);//NTKERNELAPI VOID NTAPI KeDetachProcess();//NTKERNELAPI VOID NTAPI KeStackAttachProcess(PEPROCESS Process, PKAPC_STATE ApcState);//NTKERNELAPI VOID NTAPI KeUnstackDetachProcess(PKAPC_STATE ApcState);

3、因为要通过PEPROCESS 来获取进程和模块,所以还要用到几个结构体要,在WinDbg 可看到。这里新建一个头文件,包含了PEB等信息#include "peb.h"如下:#pragma once#include <ntifs.h>typedef struct _PEB_LDR_DATA_EX{ ULONG Length; // +0x00 BOOLEAN Initialized; // +0x04 PVOID SsHandle; // +0x08 LIST_ENTRY InLoadOrderModuleList; // +0x0c LIST_ENTRY InMemoryOrderModuleList; // +0x14 LIST_ENTRY InInitializationOrderModuleList;// +0x1c }PEB_LDR_DATA_EX, *PPEB_LDR_DATA_EX;typedef struct _LDR_DATA_TABLE_ENTRY_EX { LIST_ENTRY InLoadOrderLinks; LIST_ENTRY InMemoryOrderLinks; LIST_ENTRY InInitializationOrderLinks; PVOID DllBase; PVOID EntryPoint; ULONG SizeOfImage; UNICODE_STRING FullDllName; UNICODE_STRING BaseDllName; ULONG Flags; USHORT LoadCount; USHORT TlsIndex; union { LIST_ENTRY HashLinks; struct { PVOID SectionPointer; ULONG CheckSum; }; }; union { ULONG TimeDateStamp; PVOID LoadedImports; }; PVOID EntryPointActivationContext; PVOID PatchInformation; LIST_ENTRY ForwarderLinks; LIST_ENTRY ServiceTagLinks; LIST_ENTRY StaticLinks; PVOID ContextInformation; PVOID OriginalBase; LARGE_INTEGER LoadTime;} LDR_DATA_TABLE_ENTRY_EX, *PLDR_DATA_TABLE_ENTRY_EX;typedef struct _CURDIR { UNICODE_STRING DosPath; PVOID Handle;}CURDIR, *PCURDIR;typedef struct _RTL_DRIVE_LETTER_CURDIR { USHORT Flags; USHORT Length; ULONG TimeStamp; STRING DosPath;}RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR;//进程参数typedef struct _RTL_USER_PROCESS_PARAMETERS{ ULONG MaximumLength; ULONG Length; ULONG Flags; ULONG DebugFlags; PVOID ConsoleHandle; ULONG ConsoleFlags; PVOID StandardInput; PVOID StandardOutput; PVOID StandardError; CURDIR CurrentDirectory; UNICODE_STRING DllPath; UNICODE_STRING ImagePathName; UNICODE_STRING CommandLine; PVOID Environment; ULONG StartingX; ULONG StartingY; ULONG CountX; ULONG CountY; ULONG CountCharsX; ULONG CountCharsY; ULONG FillAttribute; ULONG WindowFlags; ULONG ShowWindowFlags; UNICODE_STRING WindowTitle; UNICODE_STRING DesktopInfo; UNICODE_STRING ShellInfo; UNICODE_STRING RuntimeData; RTL_DRIVE_LETTER_CURDIR CurrentDirectores[32];}RTL_USER_PROCESS_PARAMETERS,*PRTL_USER_PROCESS_PARAMETERS;//进程环境块(因为Windows内核有一个机构PEB,为了不重定义,所以就另起一个名字)typedef struct _PEB_EX { UCHAR InheritedAddressSpace; UCHAR ReadImageFileExecOptions; UCHAR BeingDebugged; UCHAR SpareBool; PVOID Mutant; PVOID ImageBaseAddress; PPEB_LDR_DATA_EX Ldr; PRTL_USER_PROCESS_PARAMETERS ProcessParameters; UCHAR Reserved4[104]; PVOID Reserved5[52]; PVOID PostProcessInitRoutine; PVOID Reserved7; UCHAR Reserved6[128]; ULONG SessionId;} PEB_EX, *PPEB_EX;

4、用于遍历进程函数void EnumProcess(PEPROCESS eprocess){ KAPC_STATE ks; if (!MmIsAddressValid(eprocess)) return; //获取 PEB信息 PPEB_EX peb = PsGetProcessPeb(eprocess); if (!peb) return; //依附进程!!!!!!!!!!!!!! KeStackAttachProcess(eprocess, &ks); __try { if (PsGetProcessId(eprocess)!=0) { //获取 进程参数 PRTL_USER_PROCESS_PARAMETERS rtl_user_process_param = (PRTL_USER_PROCESS_PARAMETERS)peb->ProcessParameters; DbgPrint("CommandLine:%wZ\n", &rtl_user_process_param->CommandLine); DbgPrint("ImagePath=%wZ\n", &rtl_user_process_param->ImagePathName); //DbgPrint("Window Title=%wZ\n", &rtl_user_process_param->WindowTitle); DbgPrint("——————————————————————————————"); } } __except (EXCEPTION_EXECUTE_HANDLER) { //DbgPrint("Can not Process..."); } //取消依附进程 KeUnstackDetachProcess(&ks);}

5、//遍历模块,大体上和遍历进程一样,但也要注意void EnumModules(PEPROCESS eprocess){ KAPC_STATE ks; if (!MmIsAddressValid(eprocess)) return; //获取 PEB信息 PPEB_EX peb = PsGetProcessPeb(eprocess); if (!peb) return; //依附进程!!!!!!!!!!!!!! KeStackAttachProcess(eprocess, &ks); __try { PPEB_LDR_DATA_EX peb_LDR_data = (PPEB_LDR_DATA_EX)peb->Ldr; PLIST_ENTRY list_entry = &peb_LDR_data->InLoadOrderModuleList; //先获取第一个 PLIST_ENTRY currentList = list_entry->Flink; while (currentList!=list_entry) { PLDR_DATA_TABLE_ENTRY_EX ldr_data_table_entry = (PLDR_DATA_TABLE_ENTRY_EX)currentList; DbgPrint("Module Base=%p DllPath=%wZ\n", ldr_data_table_entry->DllBase, &ldr_data_table_entry->FullDllName); //指向下一个 currentList = currentList->Flink; } } __except (EXCEPTION_EXECUTE_HANDLER) { //DbgPrint("Can not Modules..."); } //取消依附进程 KeUnstackDetachProcess(&ks);}

6、//这个函数把上面两个函数整合在一起了VOID EnumProcessModuleInformations(){ //第一个进程环境块 PEPROCESS eprocess=PsGetCurrentProcess(); PEPROCESS eprocess_first = eprocess; while (1) {//获取进程 EnumProcess(eprocess); //下一个进程,我获取的是WinXP的 EPROCESS ! eprocess = (PEPROCESS)(*(ULONG*)((ULONG)eprocess + 0x88) - 0x88); if (eprocess == eprocess_first) { break; } } eprocess= eprocess_first; while (1) {//获取模块 EnumModules(eprocess); //下一个进程 eprocess = (PEPROCESS)(*(ULONG*)((ULONG)eprocess + 0x88) - 0x88); if (eprocess == eprocess_first) { break; } } }

7、//卸载函数很简单VOID unload(PDRIVER_OBJECT p){ DbgPrint("UnloadDriver...");}

8、//驱动入口函数 NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver_Obj, PUNICODE_STRING pRegisterPath){ DbgPrint("DriverEntry..."); pDriver_Obj->DriverUnload = unload; DbgPrint("DriverName:%wZ RegisterPath:%wZ \n ", &pDriver_Obj->DriverName, pRegisterPath);//这里调用 EnumProcessModuleInformations(); return STATUS_SUCCESS;}

9、最后,基本上OK了,附上一张测试图:

Windows内核驱动EPROCESS遍历进程模块
  • Hyper-V安装Windows Server 2008 R2 x64企业版
  • win10更新错误最简单解决办法
  • 易语言如何创建EDB数据库
  • 手把手教你制作绿色软件
  • IntelliJ IDEA如何设置悬浮提示
  • 热门搜索
    热爱祖国手抄报内容 儿童手抄报春节 廉洁修身手抄报 百善孝为先手抄报内容 法制在我身边手抄报 清明节英语手抄报内容 法制安全手抄报图片 建党95周年手抄报 保护环境手抄报素材 水是生命之源手抄报