枚举PEB获取进程模块列表

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


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


 

[cpp] view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. typedef PPEB (__stdcall *PFNPsGetProcessPeb)(PEPROCESS pEProcess);  
  2.   
  3. typedef ULONG   PPS_POST_PROCESS_INIT_ROUTINE;    
  4.   
  5. typedef struct _PEB_LDR_DATA {  
  6.     BYTE       Reserved1[8];  
  7.     PVOID      Reserved2[3];  
  8.     LIST_ENTRY InMemoryOrderModuleList;  
  9. } PEB_LDR_DATA, *PPEB_LDR_DATA;  
  10.   
  11. typedef struct _RTL_USER_PROCESS_PARAMETERS {  
  12.     BYTE           Reserved1[16];  
  13.     PVOID          Reserved2[10];  
  14.     UNICODE_STRING ImagePathName;  
  15.     UNICODE_STRING CommandLine;  
  16. } RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;  
  17.   
  18. typedef struct _PEB {  
  19.     BYTE                          Reserved1[2];  
  20.     BYTE                          BeingDebugged;  
  21.     BYTE                          Reserved2[1];  
  22.     PVOID                         Reserved3[2];  
  23.     PPEB_LDR_DATA                 Ldr;  
  24.     PRTL_USER_PROCESS_PARAMETERS  ProcessParameters;  
  25.     BYTE                          Reserved4[104];  
  26.     PVOID                         Reserved5[52];  
  27.     PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;  
  28.     BYTE                          Reserved6[128];  
  29.     PVOID                         Reserved7[1];  
  30.     ULONG                         SessionId;  
  31. } PEB, *PPEB;  
  32.   
  33. typedef struct _LDR_DATA_TABLE_ENTRY    
  34. {    
  35.     LIST_ENTRY InLoadOrderLinks;    
  36.     LIST_ENTRY InMemoryOrderLinks;    
  37.     LIST_ENTRY InInitializationOrderLinks;    
  38.     PVOID DllBase;    
  39.     PVOID EntryPoint;    
  40.     DWORD SizeOfImage;    
  41.     UNICODE_STRING FullDllName;    
  42.     UNICODE_STRING BaseDllName;    
  43.     DWORD Flags;    
  44.     WORD LoadCount;    
  45.     WORD TlsIndex;    
  46.     LIST_ENTRY HashLinks;    
  47.     PVOID SectionPointer;    
  48.     DWORD CheckSum;    
  49.     DWORD TimeDateStamp;    
  50.     PVOID LoadedImports;    
  51.     PVOID EntryPointActivationContext;    
  52.     PVOID PatchInformation;    
  53. }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 ? 在CODE上查看代码片 派生到我的代码片
  1. NTSTATUS GetProcessModules(ULONG ulProcessId)  
  2. {  
  3.     NTSTATUS nStatus;  
  4.     //PEB结构指针  
  5.     PPEB pPEB = NULL;  
  6.   
  7.     //EPROCESS结构指针  
  8.     PEPROCESS  pEProcess = NULL;  
  9.   
  10.     //查找的函数名称  
  11.     UNICODE_STRING uniFunctionName;  
  12.       
  13.     //进程参数信息  
  14.     PRTL_USER_PROCESS_PARAMETERS pParam  = NULL;  
  15.   
  16.     //LDR数据结构  
  17.     PPEB_LDR_DATA pPebLdrData = NULL;    
  18.   
  19.     //LDR链表入口  
  20.     PLDR_DATA_TABLE_ENTRY pLdrDataEntry = NULL;    
  21.   
  22.     //链表头节点、尾节点  
  23.     PLIST_ENTRY pListEntryStart = NULL;  
  24.     PLIST_ENTRY pListEntryEnd = NULL;   
  25.   
  26.     //函数指针  
  27.     PFNPsGetProcessPeb  PsGetProcessPeb = NULL;  
  28.   
  29.     //保存APC状态  
  30.     KAPC_STATE KAPC ={0};  
  31.   
  32.     //是否已经附加到进程  
  33.     BOOLEAN bIsAttached = FALSE;  
  34.   
  35.     //获取进程的EPROCESS结构指针  
  36.     nStatus = PsLookupProcessByProcessId((HANDLE)ulProcessId, &pEProcess);  
  37.     if (!NT_SUCCESS(nStatus))  
  38.     {  
  39.         return STATUS_UNSUCCESSFUL;  
  40.     }  
  41.   
  42.     //查找函数地址  
  43.     RtlInitUnicodeString(&uniFunctionName, L"PsGetProcessPeb");  
  44.     PsGetProcessPeb = (PFNPsGetProcessPeb)MmGetSystemRoutineAddress(&uniFunctionName);  
  45.     if (PsGetProcessPeb == NULL)  
  46.     {  
  47.         KdPrint(("Get PsGetProcessPeb Failed~!\n"));  
  48.         return STATUS_UNSUCCESSFUL;  
  49.     }  
  50.   
  51.     //获取PEB指针  
  52.     pPEB = PsGetProcessPeb(pEProcess);  
  53.     if (pPEB == NULL)  
  54.     {  
  55.         KdPrint(("Get pPEB Failed~!\n"));  
  56.         return STATUS_UNSUCCESSFUL;  
  57.     }  
  58.   
  59.     //附加到进程  
  60.     KeStackAttachProcess(pEProcess, &KAPC);  
  61.   
  62.     bIsAttached = TRUE;  
  63.   
  64.     //指向LDR  
  65.     pPebLdrData = pPEB->Ldr;  
  66.   
  67.     //头节点、尾节点  
  68.     pListEntryStart = pListEntryEnd = pPebLdrData->InMemoryOrderModuleList.Flink;  
  69.   
  70.   
  71.     //开始遍历_LDR_DATA_TABLE_ENTRY  
  72.     do    
  73.     {    
  74.         //通过_LIST_ENTRY的Flink成员获取_LDR_DATA_TABLE_ENTRY结构    
  75.         pLdrDataEntry = (PLDR_DATA_TABLE_ENTRY)CONTAINING_RECORD(pListEntryStart,LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);    
  76.   
  77.         //输出DLL全路径  
  78.         KdPrint(("%wZ \n", &pLdrDataEntry->FullDllName));  
  79.   
  80.         pListEntryStart = pListEntryStart->Flink;    
  81.   
  82.     }while(pListEntryStart != pListEntryEnd);    
  83.   
  84.   
  85.     //Detach进程  
  86.     if (bIsAttached != FALSE)  
  87.     {  
  88.         KeUnstackDetachProcess(&KAPC);  
  89.     }  
  90.   
  91.     //减少引用计数  
  92.     if (pEProcess != NULL)  
  93.     {  
  94.         ObDereferenceObject(pEProcess);  
  95.         pEProcess = NULL;  
  96.     }  
  97.   
  98.     return STATUS_SUCCESS;  
  99. }  
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


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部