首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >链路结构LDR PEB

链路结构LDR PEB
EN

Stack Overflow用户
提问于 2015-07-20 09:26:35
回答 2查看 2.5K关注 0票数 2

我需要通过PEB访问kernel32.dll的地址,当我试图通过一个双链接列表访问_LDR_DATA_TABLE_ENTRY结构时,情况变得复杂起来,这个列表给了我_PEB_LDR_DATA结构,这些列表如下:

代码语言:javascript
复制
+0x00c InLoadOrderModuleList : _LIST_ENTRY
+0x014 InMemoryOrderModuleList : _LIST_ENTRY
+0x01c InInitializationOrderModuleList : _LIST_ENTRY

例如,InMemoryOrderModuleListy selected LDR_DATA_TABLE_ENTRY需要访问结构,这必须通过Flink显示实现,其结构如下:

代码语言:javascript
复制
0:000> dt ntdll!_LIST_ENTRY
   +0x000 Flink            : Ptr32 _LIST_ENTRY
   +0x004 Blink            : Ptr32 _LIST_ENTRY

简而言之,不知道select列表是否会InMemoryOrderModuleList,并直接指向第一个输入LDR_DATA_TABLE_ENTRY,因为这个列表是“LIST_ENTRY类型”Flink成员,其偏移量为0并指向该表。

这是我试图理解的获得kernel32地址的代码:

代码语言:javascript
复制
xor ebx, ebx            //clear ebx
mov ebx, fs:[ 0x30 ]    //get a pointer to the PEB
mov ebx, [ ebx + 0x0C ] //get PEB->Ldr
mov ebx, [ ebx + 0x14 ] //get PEB->Ldr.InMemoryOrderModuleList.Flink(1st entry) **here**       
mov ebx, [ ebx ]        //get the next entry(2nd entry)
mov ebx, [ ebx ]        //get the next entry(3rd entry)
mov ebx, [ ebx + 0x10 ] //get the 3rd entries base address(kernel32.dll)

如行中所示,“这里”是给我带来困惑的原因,因为移动的0x14只会选择InMemoryOrderModuleList列表的类型,但正如您在第一局的评论中所看到的那样,使用Flink练习的方式。

我正在等待您的确认,谢谢您的提前!

EN

回答 2

Stack Overflow用户

发布于 2015-07-20 10:47:35

假设PEB在1000小时。

这里列出了PEB的第一批成员,以及它们在内存中的地址。

代码语言:javascript
复制
typedef struct _PEB {
  /* 1000h + 000h = 1000h */    BYTE Reserved1[2];
  /* 1000h + 002h = 1002h */    BYTE BeingDebugged;
  /* 1000h + 003h = 1003h */    BYTE Reserved2[1];
  /* 1000h + 004h = 1004h */    PVOID Reserved3[2];
  /* 1000h + 00ch = 100ch */    PPEB_LDR_DATA Ldr;
  ...
} PEB, *PPEB;

Ldr成员是指针,假设它指向2000 H,即PEB_LDR_DATA位于2000 H。

现在,PEB_LDR_DATA有了这个结构(在正式文档中省略了许多成员)。

代码语言:javascript
复制
typedef struct _PEB_LDR_DATA {
  /* 2000h + 000h = 2000h */ BYTE       Reserved1[8];
  /* 2000h + 008h = 2008h */ PVOID      Reserved2[3];
  /* 2000h + 014h = 2014h */ LIST_ENTRY InMemoryOrderModuleList;
} PEB_LDR_DATA, *PPEB_LDR_DATA;

如您所见,成员InMemoryOrderModuleList 不是指针,因此LIST_ENTRY的所有成员都嵌入到PEB_LDR_DATA结构中。

这意味着在InMemoryOrderModuleList的地址上有LIST_ENTRY的第一个成员,该成员是Flink,位于204。

代码语言:javascript
复制
Here the expanded structure

typedef struct _PEB_LDR_DATA {
  /* 2000h + 000h = 2000h */ BYTE       Reserved1[8];
  /* 2000h + 008h = 2008h */ PVOID      Reserved2[3];
  /* 2000h + 014h = 2014h */ LIST_ENTRY InMemoryOrderModuleList;
       /* 2000h + 014h = 2014h */ LIST_ENTRY* InMemoryOrderModuleList.Flink
       /* 2000h + 018h = 2018h */ LIST_ENTRY* InMemoryOrderModuleList.Blink
} PEB_LDR_DATA, *PPEB_LDR_DATA;

Note表示,现在的FlinkBlink成员是指针。

现在假设InMemoryOrderModuleList.Flink指向3000h。

在3000 h有一个LIST_ENTRY结构,这是第一个条目。

假设这个结构Flink成员指向4000 h,这是第二个条目。

还假设最后一个结构Flink成员指向5000 h,这是第三个条目。

现在,除了PEB_LDR_DATA中的列表头之外,每个LIST_ENTRY实际上都是一个LDR_DATA_TABLE_ENTRY,这是可能的,因为后者具有与前者兼容的内存布局。

因此,您到达感兴趣项时,您可以访问LDR_DATA_TABLE_ENTRY结构的成员。

因为第三个条目位于5000小时,并且LDR_DATA_TABLE_ENTRY有这样的布局

代码语言:javascript
复制
typedef struct _LDR_DATA_TABLE_ENTRY {
    /* 5000h + 000h = 5000h */  PVOID Reserved1[2];
    /* 5000h + 008h = 5008h */  LIST_ENTRY InMemoryOrderLinks;
    /* 5000h + 010h = 5010h */  PVOID Reserved2[2];
    /* 5000h + 018h = 5018h */  PVOID DllBase;
    ...
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;

一幅描绘局势的丑陋图画

检查程序集代码

代码语言:javascript
复制
xor ebx, ebx            //An useless instruction
mov ebx, fs:[ 0x30 ]    //get a pointer to the PEB
;EBX is now  1000h

mov ebx, [ ebx + 0x0C ] //get PEB->Ldr
;This read from 100ch and EBX gets 2000h

mov ebx, [ ebx + 0x14 ] //get PEB->Ldr.InMemoryOrderModuleList.Flink(1st entry)
;This read from 2014h and EBX gets 3000h   

mov ebx, [ ebx ]        //get the next entry(2nd entry)
;This read from 3000h and EBX gets 4000h  

mov ebx, [ ebx ]        //get the next entry(3rd entry)
;This read from 4000h and EBX gets 5000h  

mov ebx, [ ebx + 0x10 ] //get the 3rd entries base address(kernel32.dll)
;This read from 5010h, it seems that this DOES NOT read the correct member! 
;Should be at offset 18h
票数 3
EN

Stack Overflow用户

发布于 2015-07-20 11:27:38

这是因为InMemoryOrderModuleList列表是LIST_ENTRY类型,它的第一个成员是Flink,其位移是0x00

代码语言:javascript
复制
0:000> dt ntdll!_LIST_ENTRY
   **+0x000** Flink            : Ptr32 _LIST_ENTRY
   +0x004 Blink            : Ptr32 _LIST_ENTRY

nMemoryOrderModuleList是一个双链表,其第一个成员是Flink,其位移为0x00。这意味着,如果我选择列表,InMemoryOrderModuleList将直接指向InMemoryOrderModuleList成员_LDR_DATA_TABLE_ENTRY表?而不是_LDR_DATA_TABLE_ENTRY表的开头?

如果我不太懂英语,我很抱歉,对不起

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31512952

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档