通过PEB->LDR_DATA结构获取模块基址
2017-12-18 20:01
337 查看
peb的0xc处是ldr结构地址
0x0C: PPEB_LDR_data ldr;
PEB_LDR_Data结构体:
typedef struct _PEB_LDR_DATA
{
ULONG Length; // +0x00
BOOLEAN Initialized; // +0x04
PVOID SsHandle; // +0x08
LIST_ENTRY InLoadOrderModuleList; // +0x0c
LIST_ENTRY InMemoryOrderModuleList; // +0x14
LIST_ENTRY InInitializationOrderModuleList;// +0x1c
} PEB_LDR_DATA,*PPEB_LDR_DATA; // +0x24
LIST_ENTRY结构:
typedef struct _LIST_ENTRY {
struct _LIST_ENTRY *Flink;
struct _LIST_ENTRY *Blink;
} LIST_ENTRY, *PLIST_ENTRY, *RESTRICTED_POINTER PRLIST_ENTRY;
_LDR_DATA_TABLE_ENTRY:
lkd> dt -b _LDR_DATA_TABLE_ENTRY
nt!_LDR_DATA_TABLE_ENTRY
+0x000 InLoadOrderLinks : _LIST_ENTRY
+0x000 Flink : Ptr32
+0x004 Blink : Ptr32
+0x008 InMemoryOrderLinks : _LIST_ENTRY
+0x000 Flink : Ptr32
+0x004 Blink : Ptr32
+0x010 InInitializationOrderLinks : _LIST_ENTRY
+0x000 Flink : Ptr32
+0x004 Blink : Ptr32
+0x018 DllBase : Ptr32
+0x01c EntryPoint : Ptr32
+0x020 SizeOfImage : Uint4B
+0x024 FullDllName : _UNICODE_STRING
+0x000 Length : Uint2B
+0x002 MaximumLength : Uint2B
+0x004 Buffer : Ptr32 //+0x28
+0x02c BaseDllName : _UNICODE_STRING
+0x000 Length : Uint2B
+0x002 MaximumLength : Uint2B
+0x004 Buffer : Ptr32
+0x034 Flags : Uint4B
+0x038 LoadCount : Uint2B
+0x03a TlsIndex : Uint2B
+0x03c HashLinks : _LIST_ENTRY
+0x000 Flink : Ptr32
+0x004 Blink : Ptr32
+0x03c SectionPointer : Ptr32
+0x040 CheckSum : Uint4B
+0x044 TimeDateStamp : Uint4B
+0x044 LoadedImports : Ptr32
+0x048 EntryPointActivationContext : Ptr32
+0x04c PatchInformation : Ptr32
ULONG_STRING:
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
这几个结构体即是pdr链的几个重要结构体。
通过fs:[0x30]来获取PEB地址,再通过PEB+0xC来获取Ldr地址,再通过Ldr的InLoadOrderLinks和InMeoryOrderLinks和InInitializationOrderLinks三个不同的访问模块顺序的双向链表来访问List_Data_Table_Entry来获取模块的基址和名字。
![](https://img-blog.csdn.net/20171218200603713?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYTg5MzU3NDMwMQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
汇编来访问DLL地址:
以InLoadOrderLinks顺序的Dllbase
mov eax,fs:[0x30] //访问TEB
mov eax,[eax+0xC] //访问Ldr
mov eax,[eax+0xC] //访问InLoadOrderLinks顺序的表,同理0x14和0x1c
mov ebx,[eax+0x18] //访问以InLoadOrderLinks顺序的Dllbase
mov edx,[eax+0x28] //0x24是fullname,由于是UNICODE_STRING结构,所以这个+0x4才是字符串地址
以InMemoryOrderLinks顺序的Dllbase
mov eax,fs:[0x30]
mov eax,[eax+0xC]
mov eax,[eax+0x14]
mov ebx,[eax+0x10]
mov edx,[eax+0x20]
以InInitializationOrderLinks顺序的Dllbase
mov eax,fs:[0x30]
mov eax,[eax+0xC]
mov eax,[eax+0x1c]
mov ebx,[eax+0x8]
mov edx,[eax+0x14]
mov eax,[eax] /循环链表
C语言实现循环打印LDR链表以及DllBase:
void *PEB = NULL,
*Ldr = NULL,
*Flink = NULL,
*p = NULL,
*BaseAddress = NULL,
*FullDllName = NULL;
__asm
{
mov eax,fs:[0x30]
mov PEB,eax
}
Ldr = (PVOID)*((PDWORD)((DWORD)PEB + 0xC));
Flink = (PVOID)*((PDWORD)((DWORD)Ldr + 0x14));
p = Flink;
do
{
BaseAddress = (PVOID)*((PDWORD)((DWORD)p + 0x10));
FullDllName = (PVOID)*((PDWORD)((DWORD)p + 0x20));
wprintf(L"FullDllName is %s\n",FullDllName);
printf("BaseAddress is %x\n",BaseAddress);
p = (PVOID)*((PDWORD)p); //p的前四字节为Flink,后四字节为Blink
} while (Flink != (PVOID)*((PDWORD)p));
0x0C: PPEB_LDR_data ldr;
PEB_LDR_Data结构体:
typedef struct _PEB_LDR_DATA
{
ULONG Length; // +0x00
BOOLEAN Initialized; // +0x04
PVOID SsHandle; // +0x08
LIST_ENTRY InLoadOrderModuleList; // +0x0c
LIST_ENTRY InMemoryOrderModuleList; // +0x14
LIST_ENTRY InInitializationOrderModuleList;// +0x1c
} PEB_LDR_DATA,*PPEB_LDR_DATA; // +0x24
LIST_ENTRY结构:
typedef struct _LIST_ENTRY {
struct _LIST_ENTRY *Flink;
struct _LIST_ENTRY *Blink;
} LIST_ENTRY, *PLIST_ENTRY, *RESTRICTED_POINTER PRLIST_ENTRY;
_LDR_DATA_TABLE_ENTRY:
lkd> dt -b _LDR_DATA_TABLE_ENTRY
nt!_LDR_DATA_TABLE_ENTRY
+0x000 InLoadOrderLinks : _LIST_ENTRY
+0x000 Flink : Ptr32
+0x004 Blink : Ptr32
+0x008 InMemoryOrderLinks : _LIST_ENTRY
+0x000 Flink : Ptr32
+0x004 Blink : Ptr32
+0x010 InInitializationOrderLinks : _LIST_ENTRY
+0x000 Flink : Ptr32
+0x004 Blink : Ptr32
+0x018 DllBase : Ptr32
+0x01c EntryPoint : Ptr32
+0x020 SizeOfImage : Uint4B
+0x024 FullDllName : _UNICODE_STRING
+0x000 Length : Uint2B
+0x002 MaximumLength : Uint2B
+0x004 Buffer : Ptr32 //+0x28
+0x02c BaseDllName : _UNICODE_STRING
+0x000 Length : Uint2B
+0x002 MaximumLength : Uint2B
+0x004 Buffer : Ptr32
+0x034 Flags : Uint4B
+0x038 LoadCount : Uint2B
+0x03a TlsIndex : Uint2B
+0x03c HashLinks : _LIST_ENTRY
+0x000 Flink : Ptr32
+0x004 Blink : Ptr32
+0x03c SectionPointer : Ptr32
+0x040 CheckSum : Uint4B
+0x044 TimeDateStamp : Uint4B
+0x044 LoadedImports : Ptr32
+0x048 EntryPointActivationContext : Ptr32
+0x04c PatchInformation : Ptr32
ULONG_STRING:
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
这几个结构体即是pdr链的几个重要结构体。
通过fs:[0x30]来获取PEB地址,再通过PEB+0xC来获取Ldr地址,再通过Ldr的InLoadOrderLinks和InMeoryOrderLinks和InInitializationOrderLinks三个不同的访问模块顺序的双向链表来访问List_Data_Table_Entry来获取模块的基址和名字。
汇编来访问DLL地址:
以InLoadOrderLinks顺序的Dllbase
mov eax,fs:[0x30] //访问TEB
mov eax,[eax+0xC] //访问Ldr
mov eax,[eax+0xC] //访问InLoadOrderLinks顺序的表,同理0x14和0x1c
mov ebx,[eax+0x18] //访问以InLoadOrderLinks顺序的Dllbase
mov edx,[eax+0x28] //0x24是fullname,由于是UNICODE_STRING结构,所以这个+0x4才是字符串地址
以InMemoryOrderLinks顺序的Dllbase
mov eax,fs:[0x30]
mov eax,[eax+0xC]
mov eax,[eax+0x14]
mov ebx,[eax+0x10]
mov edx,[eax+0x20]
以InInitializationOrderLinks顺序的Dllbase
mov eax,fs:[0x30]
mov eax,[eax+0xC]
mov eax,[eax+0x1c]
mov ebx,[eax+0x8]
mov edx,[eax+0x14]
mov eax,[eax] /循环链表
C语言实现循环打印LDR链表以及DllBase:
void *PEB = NULL,
*Ldr = NULL,
*Flink = NULL,
*p = NULL,
*BaseAddress = NULL,
*FullDllName = NULL;
__asm
{
mov eax,fs:[0x30]
mov PEB,eax
}
Ldr = (PVOID)*((PDWORD)((DWORD)PEB + 0xC));
Flink = (PVOID)*((PDWORD)((DWORD)Ldr + 0x14));
p = Flink;
do
{
BaseAddress = (PVOID)*((PDWORD)((DWORD)p + 0x10));
FullDllName = (PVOID)*((PDWORD)((DWORD)p + 0x20));
wprintf(L"FullDllName is %s\n",FullDllName);
printf("BaseAddress is %x\n",BaseAddress);
p = (PVOID)*((PDWORD)p); //p的前四字节为Flink,后四字节为Blink
} while (Flink != (PVOID)*((PDWORD)p));
相关文章推荐
- DriverObject->DriverSection结构体LDR_DATA_TABLE_ENTRY中的结构
- 通过PEB获取模块基址
- 通过PEB的Ldr枚举进程内所有已加载的模块
- 通过PEB的Ldr枚举进程内所有已加载的模块
- Android获取Manifest中<meta-data>元素的值
- Android获取Manifest中<meta-data>元素的值
- Android获取Manifest中<meta-data>元素的值
- PEB及PEB_LDR_DATA结构
- Android 获取 AndroidManifest.xml 中 <meta-data> 元素的值
- 搜索PEB结构获取Kernel32.dll基址
- 通过miscdevice获得驱动私有数据结构体时file->private_data为空的解决方法
- Android获取Manifest中<meta-data>元素的值
- 第2讲:搜索PEB结构获取kernel32.dll的基址暴力搜索内存空间获得 Api 的线性地址
- 通过读写PEB.Ldr实现模块枚举和模块隐藏(脱链)
- 通过PEB的Ldr枚举进程内所有已加载的模块
- Android获取Manifest中<meta-data>元素的值
- Android获取Manifest中<meta-data>元素的值
- 通过反射获取泛型<T>的class
- list.get(i)-List和list.get(i).get("key")->Map结构 获取值的区别
- 通过PEB结构遍历进程模块