通過PEB遍歷當前進程中的模塊(C語言實現)
0x00 相關說明:
Windows應用層如果要遍歷當前進程所加載的模塊可以使用WIN32API通過進程快照來實現
通過PEB來遍歷進程模塊沒有WIN32API的使用痕跡,在某些場合更加好用
其中32位應用程序的 PEB 的地址可以通過 fs:[0x30]獲取,fs:[0]為TEB結構的地址
0x01 相關數據結構:
下面的數據結構可以在windbg中使用命令查看(使用 dt <數據結構名稱>)
typedef struct _TEB { //fs:[0]
NT_TIB Tib;
PVOID EnvironmentPointer;CLIENT_ID Cid;
PVOID ActiveRpcInfo;
PVOID ThreadLocalStoragePointer;
PPEB Peb;
//......
} TEB, * PTEB;
typedef struct _PEB { //fs:[0x30]
BYTE InheritedAddressSpace;
BYTE ReadImageFileExecOptions;
BYTE BeingDebugged;BYTE BitField;
PVOID Mutant;
PVOID ImageBaseAddress;
PPEB_LDR_DATA Ldr;
//......
} PEB, * PPEB;
typedef struct _PEB_LDR_DATA {
UINT Length;
BYTE 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 InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
//......
} _LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, * PUNICODE_STRING;
typedef struct _CLIENT_ID {
PVOID UniqueProcess;
PVOID UniqueThread;
} CLIENT_ID, * PCLIENT_ID;
0x02 實現原理:
結構索引流程如下:
其中各個_LDR_DATA_TABLE_ENTRY結構的關系如下:(以3個模塊為例)
其中 InLoadOrderLinks、InMemoryOrderLinks、InInitializationOrderLinks 均為:LIST_ENTRY
0x03 代碼實現:
代碼實現如下:(記得自行添加前面介紹的相關結構定義):
int main(int argc, char* argv[])
{
PPEB pPEB = (PPEB)__readfsdword(0x30);
PPEB_LDR_DATA pLdr = pPEB->Ldr;DWORD dwFixOffset=0;
PLDR_DATA_TABLE_ENTRY pBase, pNext;printf("Enum InLoadOrderModuleList:\r\n");
dwFixOffset = 0;
pBase = (PLDR_DATA_TABLE_ENTRY)((DWORD)(pLdr->InLoadOrderModuleList.Flink) - dwFixOffset);
pNext = pBase;
do {
wprintf_s(L"%s\r\n", pNext->FullDllName.Buffer);
pNext = (PLDR_DATA_TABLE_ENTRY)((DWORD)(pNext->InLoadOrderLinks.Flink) - dwFixOffset);
} while (pBase != pNext);
printf("Enum InLoadOrderModuleList End!\r\n\r\n");printf("Enum InMemoryOrderModuleList:\r\n");
dwFixOffset = (DWORD) & (pBase->InMemoryOrderLinks) - (DWORD)pBase;
pBase = (PLDR_DATA_TABLE_ENTRY)((DWORD)(pLdr->InMemoryOrderModuleList.Flink) - dwFixOffset);
pNext = pBase;
do {
wprintf_s(L"%s\r\n", pNext->FullDllName.Buffer);
pNext = (PLDR_DATA_TABLE_ENTRY)((DWORD)(pNext->InMemoryOrderLinks.Flink) - dwFixOffset);
} while (pBase != pNext);
printf("Enum InMemoryOrderModuleList End!\r\n\r\n");printf("Enum InInitializationOrderModuleList:\r\n");
dwFixOffset = (DWORD) & (pBase->InInitializationOrderLinks) - (DWORD)pBase;
pBase = (PLDR_DATA_TABLE_ENTRY)((DWORD)(pLdr->InInitializationOrderModuleList.Flink) - dwFixOffset);
pNext = pBase;
do {
wprintf_s(L"%s\r\n", pNext->FullDllName.Buffer);
pNext = (PLDR_DATA_TABLE_ENTRY)((DWORD)(pNext->InInitializationOrderLinks.Flink) - dwFixOffset);
} while (pBase != pNext);
printf("Enum InInitializationOrderModuleList End!\r\n\r\n");
system("pause");
return 0;
}
代碼執行結果:
通過PEB遍歷當前進程中的模塊(C語言實現)