re | 通过PEB遍历进程模块

发布时间 2023-12-23 16:01:20作者: Mz1

re | 通过PEB遍历进程模块

最近在设计实验,重新写一些代码存一下:
使用vc6编译通过。
比较好的参考文章:https://www.cnblogs.com/bokernb/p/6404795.html

#include <stdio.h>
#include <windows.h>
/*
typedef struct _LIST_ENTRY {
   struct _LIST_ENTRY *Flink;
   struct _LIST_ENTRY *Blink;
} LIST_ENTRY, *PLIST_ENTRY, *RESTRICTED_POINTER PRLIST_ENTRY;
*/

typedef struct _UNICODE_STRING {
  USHORT Length;
  USHORT MaximumLength;
  PWSTR  Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

typedef struct _LDR_DATA_TABLE_ENTRY
{
    LIST_ENTRY InLoadOrderLinks;                  // 3个双向链表
    LIST_ENTRY InMemoryOrderLinks;
    LIST_ENTRY InInitializationOrderLinks;
    PVOID      DllBase;
    PVOID      EntryPoint;
    UINT    SizeOfImage;               // 这里32位的就是UINT 64位是UINT64
    UNICODE_STRING FullDllName;
    UNICODE_STRING BaseDllName;     // 查找这个
	//...
}LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;

void shellcode(){
	// 准备字符串备用
	wchar_t wsKernel32Dll[] = L"kernel32.dll";
	char sUser32Dll[] = "USER32.dll";
	char sGetProcAddr[] = "GetProcAddress";
	char sLoadLibraryA[] = "LoadLibraryA";
	char sMessageBoxA[] = "MessageBoxA";

	// 通过fs:[0x30]查找PEB 找到3个链表 找到K32.dll
	/*
	_PEB_LDR_DATA
	[0] Length
	[4] Initialized
	[8] SsHandle
	[c] InLoadOrderModuleList : _LIST_ENTRY
	[14] InMemoryOrderModuleList : _LIST_ENTRY
	[1c] InInitializationOrderModuleList : _LIST_ENTRY
	...

	*/
	DWORD pBeg = 0;
	DWORD pPLD = 0;
	PLIST_ENTRY pInLoadOrderModuleList = 0;
	__asm{
		pushad
		mov eax, fs:[0x30]        ; PEB
		mov eax, [eax+0x0c]       ; PEB->Ldr
		add eax, 0x0c             ; _PEB_LDR_DATA->InLoadOrderModuleList
		lea ebx, dword ptr [pInLoadOrderModuleList] ; 获取InLoadOrderModuleList的地址保存在变量中
		mov [ebx], eax;
		popad
	}
	printf("InLoadOrderModuleList: %p %p \n",pInLoadOrderModuleList->Flink, pInLoadOrderModuleList->Blink);
	// 拿到第一个LDR_DATA_TABLE_ENTRY节点的地址
	PLDR_DATA_TABLE_ENTRY pFirstLdrDataEntry = (PLDR_DATA_TABLE_ENTRY)pInLoadOrderModuleList->Flink;
	// 循环遍历所有的模块
	PLDR_DATA_TABLE_ENTRY pLdrDataEntry = pFirstLdrDataEntry;
	while(1){
		printf("[%p] %p %p \n", pLdrDataEntry, pLdrDataEntry->InLoadOrderLinks.Flink, pLdrDataEntry->InLoadOrderLinks.Blink);
		printf("    [%S(%p)] %S \n", pLdrDataEntry->BaseDllName.Buffer, pLdrDataEntry->DllBase, pLdrDataEntry->FullDllName.Buffer);
		if (pLdrDataEntry->InLoadOrderLinks.Flink == (PLIST_ENTRY)pFirstLdrDataEntry){
			break;
		}
		// 判断是不是kernel32.dll
		if(wcsicmp(pLdrDataEntry->BaseDllName.Buffer, wsKernel32Dll) == 0){
			printf("~~~~~~ find it! ~~~~~~~\n");
		}
		pLdrDataEntry = (PLDR_DATA_TABLE_ENTRY)pLdrDataEntry->InLoadOrderLinks.Flink;
	}


	// 通过导出表查找LoadLibrary


}

int main(){
	shellcode();

	return 0;
}