通过PEB遍历进程模块(x64/wow4)
时间: 2023-10-29 16:01:38 浏览: 360
PEB(Process Environment Block)是Windows操作系统中的一个重要结构体,它包含了当前进程的环境信息。通过PEB,我们可以获取当前进程的模块信息,包括模块的基地址、模块的名称等。
在x64和wow64下,PEB结构体的定义并没有变化,但是由于x64和wow64的指针长度不同,所以在使用PEB时需要注意指针长度的问题。
以下是通过PEB遍历进程模块的代码示例:
```c++
#include <windows.h>
#include <winternl.h>
#include <iostream>
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef struct _PEB_LDR_DATA {
ULONG Length;
BOOLEAN Initialized;
PVOID SsHandle;
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
} PEB_LDR_DATA, *PPEB_LDR_DATA;
typedef struct _LDR_DATA_TABLE_ENTRY {
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;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
typedef struct _PEB {
BOOLEAN InheritedAddressSpace;
BOOLEAN ReadImageFileExecOptions;
BOOLEAN BeingDebugged;
BOOLEAN Spare;
HANDLE Mutant;
PVOID ImageBaseAddress;
PPEB_LDR_DATA LoaderData;
PVOID ProcessParameters;
PVOID SubSystemData;
PVOID ProcessHeap;
PVOID FastPebLock;
PVOID AtlThunkSListPtr;
PVOID IFEOKey;
PVOID CrossProcessFlags;
PVOID UserSharedInfoPtr;
ULONG SystemReserved;
ULONG AtlThunkSListPtr32;
PVOID ApiSetMap;
ULONG TlsExpansionCounter;
PVOID TlsBitmap;
ULONG TlsBitmapBits[2];
PVOID ReadOnlySharedMemoryBase;
PVOID HotpatchInformation;
PVOID ReadOnlyStaticServerData;
PVOID AnsiCodePageData;
PVOID OemCodePageData;
PVOID UnicodeCaseTableData;
ULONG NumberOfProcessors;
ULONG NtGlobalFlag;
LARGE_INTEGER CriticalSectionTimeout;
ULONG_PTR HeapSegmentReserve;
ULONG_PTR HeapSegmentCommit;
ULONG_PTR HeapDeCommitTotalFreeThreshold;
ULONG_PTR HeapDeCommitFreeBlockThreshold;
ULONG_PTR NumberOfHeaps;
ULONG_PTR MaximumNumberOfHeaps;
PVOID ProcessHeaps;
PVOID GdiSharedHandleTable;
PVOID ProcessStarterHelper;
PVOID GdiDCAttributeList;
PVOID LoaderLock;
ULONG OSMajorVersion;
ULONG OSMinorVersion;
USHORT OSBuildNumber;
USHORT OSCSDVersion;
ULONG OSPlatformId;
ULONG ImageSubsystem;
ULONG ImageSubsystemMajorVersion;
ULONG ImageSubsystemMinorVersion;
ULONG_PTR ImageProcessAffinityMask;
ULONG_PTR GdiHandleBuffer[34];
PVOID PostProcessInitRoutine;
PVOID TlsExpansionBitmap;
ULONG TlsExpansionBitmapBits[32];
ULONG SessionId;
ULARGE_INTEGER AppCompatFlags;
ULARGE_INTEGER AppCompatFlagsUser;
PVOID pShimData;
PVOID AppCompatInfo;
UNICODE_STRING CSDVersion;
PVOID ActivationContextData;
PVOID ProcessAssemblyStorageMap;
PVOID SystemDefaultActivationContextData;
PVOID SystemAssemblyStorageMap;
ULONG_PTR MinimumStackCommit;
} PEB, *PPEB;
void EnumerateProcessModules(HANDLE hProcess)
{
PEB peb;
ZeroMemory(&peb, sizeof(PEB));
// 获取PEB地址
BOOL bRet = ReadProcessMemory(hProcess, &NtCurrentTeb()->ProcessEnvironmentBlock, &peb, sizeof(PEB), NULL);
if (!bRet)
{
std::cout << "ReadProcessMemory failed!" << std::endl;
return;
}
// 遍历模块列表
PPEB_LDR_DATA pLdrData = peb.LoaderData;
if (pLdrData == NULL)
{
std::cout << "LoaderData is NULL!" << std::endl;
return;
}
PLIST_ENTRY pListHead = &pLdrData->InMemoryOrderModuleList;
PLIST_ENTRY pListEntry = pListHead->Flink;
while (pListEntry != pListHead)
{
PLDR_DATA_TABLE_ENTRY pLdrEntry = CONTAINING_RECORD(pListEntry, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
if (pLdrEntry->DllBase != NULL)
{
// 获取模块基地址和名称
wchar_t szModule[MAX_PATH] = { 0 };
bRet = ReadProcessMemory(hProcess, pLdrEntry->FullDllName.Buffer, szModule, pLdrEntry->FullDllName.Length, NULL);
if (bRet)
{
std::wcout << L"Module Base: " << pLdrEntry->DllBase << L", Module Name: " << szModule << std::endl;
}
}
pListEntry = pListEntry->Flink;
}
}
int main(int argc, char* argv[])
{
DWORD dwProcessId = 0;
if (argc > 1)
{
dwProcessId = atoi(argv[1]);
}
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if (hProcess == NULL)
{
std::cout << "OpenProcess failed!" << std::endl;
return 0;
}
EnumerateProcessModules(hProcess);
CloseHandle(hProcess);
return 0;
}
```
需要注意的是,以上代码中使用了一些Windows内部的结构体和函数,如`UNICODE_STRING`、`LIST_ENTRY`、`NtCurrentTeb()`等,需要包含相应的头文件,并且这些结构体和函数都不是官方公开的API,可能会在未来的操作系统版本中发生变化。因此,开发者在使用这些结构体和函数时需要特别注意。
阅读全文