枚举PEB获取进程模块列表
枚举进程模块的方法有很多种,常见的有枚举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;//指向LDRpPebLdrData = pPEB->Ldr;//头节点、尾节点pListEntryStart = pListEntryEnd = pPebLdrData->InMemoryOrderModuleList.Flink;//开始遍历_LDR_DATA_TABLE_ENTRYdo { //通过_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
转载于:https://www.cnblogs.com/kuangke/p/5761429.html
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
