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

包含的头文件函数

#include <ntifs.h>测试

#include <ntstrsafe.h>orm

声明的API函数blog

NTKERNELAPI HANDLE PsGetProcessInheritedFromUniqueProcessId(IN PEPROCESS Process);进程

NTKERNELAPI  PPEB_EX  PsGetProcessPeb(PEPROCESS Process);it

NTKERNELAPI NTSTATUS PsLookupProcessByProcessId(HANDLE Id, PEPROCESS *Process);io

NTKERNELAPI NTSTATUS PsLookupThreadByThreadId(HANDLE Id, PETHREAD *Thread);table

NTKERNELAPI PEPROCESS IoThreadToProcess(PETHREAD Thread);form

//NTKERNELAPI VOID NTAPI KeAttachProcess(PEPROCESS Process);List

//NTKERNELAPI VOID NTAPI KeDetachProcess();

//NTKERNELAPI VOID NTAPI KeStackAttachProcess(PEPROCESS Process, PKAPC_STATE ApcState);

//NTKERNELAPI VOID NTAPI KeUnstackDetachProcess(PKAPC_STATE ApcState);

由于要经过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;

用于遍历进程函数

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);

}

//遍历模块,大致上和遍历进程同样,但也要注意

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);

}

//这个函数把上面两个函数整合在一块儿了

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遍历进程模块 END

相关文章
相关标签/搜索