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;
}
标签:遍历,pLdrDataEntry,LIST,re,TABLE,ENTRY,DATA,PEB
From: https://www.cnblogs.com/Mz1-rc/p/17923224.html