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

相關文章
相關標籤/搜索