1. 程式人生 > >通過PEB遍歷當前進程中的模塊(C語言實現)

通過PEB遍歷當前進程中的模塊(C語言實現)

turn 名稱 應用程序 res info and title 當前 mod

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語言實現)