您的位置:首页 > 其它

枚举PEB获取进程模块列表

2016-08-11 16:18 417 查看
枚举进程模块的方法有很多种,常见的有枚举PEB和内存搜索法,今天,先来看看实现起来最简单的枚举PEB实现获取进程模块列表。

首先,惯例是各种繁琐的结构体定义。需要包含 ntifs.h 和 WinDef.h, 此处不再列出,各位看官根据情况自行添加。

[cpp] view plain copy

print?





typedef PPEB (__stdcall *PFNPsGetProcessPeb)(PEPROCESS pEProcess);

typedef ULONG PPS_POST_PROCESS_INIT_ROUTINE;

typedef struct _PEB_LDR_DATA {

BYTE Reserved1[8];

PVOID Reserved2[3];

LIST_ENTRY InMemoryOrderModuleList;

} PEB_LDR_DATA, *PPEB_LDR_DATA;

typedef struct _RTL_USER_PROCESS_PARAMETERS {

BYTE Reserved1[16];

PVOID Reserved2[10];

UNICODE_STRING ImagePathName;

UNICODE_STRING CommandLine;

} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;

typedef struct _PEB {

BYTE Reserved1[2];

BYTE BeingDebugged;

BYTE Reserved2[1];

PVOID Reserved3[2];

PPEB_LDR_DATA Ldr;

PRTL_USER_PROCESS_PARAMETERS ProcessParameters;

BYTE Reserved4[104];

PVOID Reserved5[52];

PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;

BYTE Reserved6[128];

PVOID Reserved7[1];

ULONG SessionId;

} PEB, *PPEB;

typedef struct _LDR_DATA_TABLE_ENTRY

{

LIST_ENTRY InLoadOrderLinks;

LIST_ENTRY InMemoryOrderLinks;

LIST_ENTRY InInitializationOrderLinks;

PVOID DllBase;

PVOID EntryPoint;

DWORD SizeOfImage;

UNICODE_STRING FullDllName;

UNICODE_STRING BaseDllName;

DWORD Flags;

WORD LoadCount;

WORD TlsIndex;

LIST_ENTRY HashLinks;

PVOID SectionPointer;

DWORD CheckSum;

DWORD TimeDateStamp;

PVOID LoadedImports;

PVOID EntryPointActivationContext;

PVOID PatchInformation;

}LDR_DATA_TABLE_ENTRY,*PLDR_DATA_TABLE_ENTRY;





typedef PPEB (__stdcall *PFNPsGetProcessPeb)(PEPROCESS pEProcess);

typedef ULONG   PPS_POST_PROCESS_INIT_ROUTINE;

typedef struct _PEB_LDR_DATA {
BYTE       Reserved1[8];
PVOID      Reserved2[3];
LIST_ENTRY InMemoryOrderModuleList;
} PEB_LDR_DATA, *PPEB_LDR_DATA;

typedef struct _RTL_USER_PROCESS_PARAMETERS {
BYTE           Reserved1[16];
PVOID          Reserved2[10];
UNICODE_STRING ImagePathName;
UNICODE_STRING CommandLine;
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;

typedef struct _PEB {
BYTE                          Reserved1[2];
BYTE                          BeingDebugged;
BYTE                          Reserved2[1];
PVOID                         Reserved3[2];
PPEB_LDR_DATA                 Ldr;
PRTL_USER_PROCESS_PARAMETERS  ProcessParameters;
BYTE                          Reserved4[104];
PVOID                         Reserved5[52];
PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
BYTE                          Reserved6[128];
PVOID                         Reserved7[1];
ULONG                         SessionId;
} PEB, *PPEB;

typedef struct _LDR_DATA_TABLE_ENTRY
{
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
PVOID DllBase;
PVOID EntryPoint;
DWORD SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
DWORD Flags;
WORD LoadCount;
WORD TlsIndex;
LIST_ENTRY HashLinks;
PVOID SectionPointer;
DWORD CheckSum;
DWORD TimeDateStamp;
PVOID LoadedImports;
PVOID EntryPointActivationContext;
PVOID PatchInformation;
}LDR_DATA_TABLE_ENTRY,*PLDR_DATA_TABLE_ENTRY;


下面进入真正的实现代码:

[cpp] view plain copy

print?





NTSTATUS GetProcessModules(ULONG ulProcessId)

{

NTSTATUS nStatus;

//PEB结构指针

PPEB pPEB = NULL;

//EPROCESS结构指针

PEPROCESS pEProcess = NULL;

//查找的函数名称

UNICODE_STRING uniFunctionName;

//进程参数信息

PRTL_USER_PROCESS_PARAMETERS pParam = NULL;

//LDR数据结构

PPEB_LDR_DATA pPebLdrData = NULL;

//LDR链表入口

PLDR_DATA_TABLE_ENTRY pLdrDataEntry = NULL;

//链表头节点、尾节点

PLIST_ENTRY pListEntryStart = NULL;

PLIST_ENTRY pListEntryEnd = NULL;

//函数指针

PFNPsGetProcessPeb PsGetProcessPeb = NULL;

//保存APC状态

KAPC_STATE KAPC ={0};

//是否已经附加到进程

BOOLEAN bIsAttached = FALSE;

//获取进程的EPROCESS结构指针

nStatus = PsLookupProcessByProcessId((HANDLE)ulProcessId, &pEProcess);

if (!NT_SUCCESS(nStatus))

{

return STATUS_UNSUCCESSFUL;

}

//查找函数地址

RtlInitUnicodeString(&uniFunctionName, L"PsGetProcessPeb");

PsGetProcessPeb = (PFNPsGetProcessPeb)MmGetSystemRoutineAddress(&uniFunctionName);

if (PsGetProcessPeb == NULL)

{

KdPrint(("Get PsGetProcessPeb Failed~!\n"));

return STATUS_UNSUCCESSFUL;

}

//获取PEB指针

pPEB = PsGetProcessPeb(pEProcess);

if (pPEB == NULL)

{

KdPrint(("Get pPEB Failed~!\n"));

return STATUS_UNSUCCESSFUL;

}

//附加到进程

KeStackAttachProcess(pEProcess, &KAPC);

bIsAttached = TRUE;

//指向LDR

pPebLdrData = pPEB->Ldr;

//头节点、尾节点

pListEntryStart = pListEntryEnd = pPebLdrData->InMemoryOrderModuleList.Flink;

//开始遍历_LDR_DATA_TABLE_ENTRY

do

{

//通过_LIST_ENTRY的Flink成员获取_LDR_DATA_TABLE_ENTRY结构

pLdrDataEntry = (PLDR_DATA_TABLE_ENTRY)CONTAINING_RECORD(pListEntryStart,LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);

//输出DLL全路径

KdPrint(("%wZ \n", &pLdrDataEntry->FullDllName));

pListEntryStart = pListEntryStart->Flink;

}while(pListEntryStart != pListEntryEnd);

//Detach进程

if (bIsAttached != FALSE)

{

KeUnstackDetachProcess(&KAPC);

}

//减少引用计数

if (pEProcess != NULL)

{

ObDereferenceObject(pEProcess);

pEProcess = NULL;

}

return STATUS_SUCCESS;

}





NTSTATUS GetProcessModules(ULONG ulProcessId)
{
NTSTATUS nStatus;
//PEB结构指针
PPEB pPEB = NULL;

//EPROCESS结构指针
PEPROCESS  pEProcess = NULL;

//查找的函数名称
UNICODE_STRING uniFunctionName;

//进程参数信息
PRTL_USER_PROCESS_PARAMETERS pParam  = NULL;

//LDR数据结构
PPEB_LDR_DATA pPebLdrData = NULL;

//LDR链表入口
PLDR_DATA_TABLE_ENTRY pLdrDataEntry = NULL;

//链表头节点、尾节点
PLIST_ENTRY pListEntryStart = NULL;
PLIST_ENTRY pListEntryEnd = NULL;

//函数指针
PFNPsGetProcessPeb  PsGetProcessPeb = NULL;

//保存APC状态
KAPC_STATE KAPC ={0};

//是否已经附加到进程
BOOLEAN bIsAttached = FALSE;

//获取进程的EPROCESS结构指针
nStatus = PsLookupProcessByProcessId((HANDLE)ulProcessId, &pEProcess);
if (!NT_SUCCESS(nStatus))
{
return STATUS_UNSUCCESSFUL;
}

//查找函数地址
RtlInitUnicodeString(&uniFunctionName, L"PsGetProcessPeb");
PsGetProcessPeb = (PFNPsGetProcessPeb)MmGetSystemRoutineAddress(&uniFunctionName);
if (PsGetProcessPeb == NULL)
{
KdPrint(("Get PsGetProcessPeb Failed~!\n"));
return STATUS_UNSUCCESSFUL;
}

//获取PEB指针
pPEB = PsGetProcessPeb(pEProcess);
if (pPEB == NULL)
{
KdPrint(("Get pPEB Failed~!\n"));
return STATUS_UNSUCCESSFUL;
}

//附加到进程
KeStackAttachProcess(pEProcess, &KAPC);

bIsAttached = TRUE;

//指向LDR
pPebLdrData = pPEB->Ldr;

//头节点、尾节点
pListEntryStart = pListEntryEnd = pPebLdrData->InMemoryOrderModuleList.Flink;

//开始遍历_LDR_DATA_TABLE_ENTRY
do
{
//通过_LIST_ENTRY的Flink成员获取_LDR_DATA_TABLE_ENTRY结构
pLdrDataEntry = (PLDR_DATA_TABLE_ENTRY)CONTAINING_RECORD(pListEntryStart,LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);

//输出DLL全路径
KdPrint(("%wZ \n", &pLdrDataEntry->FullDllName));

pListEntryStart = pListEntryStart->Flink;

}while(pListEntryStart != pListEntryEnd);

//Detach进程
if (bIsAttached != FALSE)
{
KeUnstackDetachProcess(&KAPC);
}

//减少引用计数
if (pEProcess != NULL)
{
ObDereferenceObject(pEProcess);
pEProcess = NULL;
}

return STATUS_SUCCESS;
}


下面是运行截图:



本帖为原创,转帖请说明出处,谢谢合作。

本帖地址:http://blog.csdn.net/sonsie007/article/details/22622177

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: