union all动态表_[PE](5)数据目录表

一、数据目录表的说明

由16个IMAGE_DATA_DIRECTORY结构线性排列而成,用于定义PE中的16种不同类别的数据所在的位置和大小

 具体的16个数据目录表前面已经说过了,这里再介绍一下:

数组编号英文描述中文描述
0Export table address and size导出表地址和大小
1Import table address and size导入表地址和大小
2Resource table address and size资源表地址和大小
3Exception table address and size异常表地址和大小
4Certificate table address and size属性证书数据地址和大小
5Base relocation table address and size基地址重定位表地址和大小
6Debugging infomation starting address and size调试信息地址和大小
7Architecture-specific data预留为0
8Global pointer register relative virtual address指向全局指针寄存器的值
9Thread local storage(TLS) table address and size线程局部存储地址和大小
10Load configuration table address and size加载配置表地址和大小
11Bound import table address and size绑定导入表地址和大小
12Import address table address and size导入函数地址表地址和大小
13Delay import descriptor address and size延迟导入表地址和大小
14CLR Runtime Header address and sizeCLR运行时头部数据地址和大小
15Reserved系统保留

[0]导出数据所在的节通常被命名为.edata,包含了一些可被其他exe程序访问的符号的相关信息,比较重要的就是导出函数和资源等。

[1]导入数据所在的节通常被命名为.idata,包含了PE映像中所有导入的符号。导入信息在dll和exe中几乎都存在

[2]资源数据所在的节通常被命名为.rsrc,该节是一个多层的二叉排序树,该树的节点指向PE中各种类型的资源,如图标、对话框、菜单等。树的深度可达231

[3]异常数据表所在的节通常命名为.pdata,该节是由用于一长串处理的函数表项组成的数组。

[4]属性证书数据的作用类似于PE文件的校验和或者MD5,通过这种属性证书方式可以验证一个PE文件是否被非法修改过。为PE文件添加属性证书表可以使该PE与属性证书相关联。(如果想防止PE文件被修改,比如说修改跳转的字节码,绕过验证等,是否可以考虑这种方法)

[5]基址重定位信息所处的节通常被命名为.reloc,表中包含了映像中所有需要重定位的内容。被划分为很多块,每一块表示一个4KB页面范围内的基址重定位信息。

[6]调试数据所处的节通常被命名为.debug,它指向IMAGE_DEBUG_DIRECTORY结构数组。其中的每个元素都描述了PE中的一些调试信息。

调试目录可能被加载到虚拟内存中,而大部分情况下是被丢弃的

[7]预留,必须为0

[8]Global Ptr数据描述的是被存储在全局指针寄存器中的一个值

[9]线程本地存储所在的节,通常命名为.tls,本地线程存储TLS是windows支持的一种特殊存储类别,其中的数据对象不是栈变量,而是对应于运行相应代码的单个线程。

当创建线程时,PE加载器通过将线程环境块(TEB)的地址放入FS寄存器来传递线程的TLS数组地址,距TEB开头0x2C(这个地址很重要,特别是在内核调试的时候)的位置处有一个指针指向TLS数组。线程本地存储技术是特定于Intel x86平台的

[10]加载配置信息用于包含保留的SEH技术。该技术基于x86的32位系统,它提供了一个安全的结构化异常处理程序列表,操作系统在进行异常处理的时候要用到这些异常处理程序

[11]绑定导入数据的存在主要是为了优化导入信息,提高PE的加载效率。当PE文件加载到内存时,加载器会先检查导入表,然后把需要加载的DLL载入到地址空间中。

还有一个比较重要的工作是根据导入信息的描述使用动态链接库里输入函数的实际地址去替换IAT表的内容,这个步骤会花去一部分时间。

如果能够知道函数的地址,就可以直接把数组中的元素替换成地址,这种方法称为绑定。

[12]IAT是导入地址表的英文缩写。准确来说,它是导入表的一部分,这个双字数组里定义了所有导入表的VA,程序可以直接通过跳转指令跳转到VA处执行。

[13]延迟导入表也和动态链接库调用有关,这种数据的存在是为了给“应用程序知道首次调用某个DLL中的函数或数据时才加载这个DLL(也就是延迟加载)”这种行为提供了一种统一的访问机制

[14]CLR(Common Language Runtime,公共语言运行时)数据所处的节通常被命名为.cormeta,该信息是.NET框架的一个重要责成部分,所有基于.NET框架开发的程序,其初始化部分都是通过访问这部分定义而实现的。

PE加载时将通过该结构加载托管代码机制(.NET中代码执行的方式,代码由虚拟机托管执行)需要的所有动态链接库文件,并完成与CLR有关的一些其他操作

[15]系统预留,未定义

二、数据目录项IMAGE_DATA_DIRECTORY的字段

typedef struct _IMAGE_DATA_DIRECTORY {    DWORD   VirtualAddress;       //数据的起始RVA    DWORD   Size;                 //数据块的大小(长度)      } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

1、IMAGE_DATA_DIRECTORY.VirtualAddress

这个字段记录了特定类型数据的起始RVA,针对不同的数据结构,该字段包含的数据含义并不一样,有的数据甚至还不是RVA(如属性证书数据中该字段的值表示的是FOA)

2、IMAGE_DATA_DIRECTORY.Size

记录了特定类型的数据块的长度

三、节表项IMAGE_SECTION_HEADER的字段

节表中的内容就是PE文件中大部分数据的所在,包括代码,数据,字符串等信息都在这部分

#define IMAGE_SIZEOF_SHORT_NAME              8typedef struct _IMAGE_SECTION_HEADER {    BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];          //8个字节节命,这个值在上面有定义    union {                                                    DWORD   PhysicalAddress;                           DWORD   VirtualSize;                    //节区的尺寸    } Misc;                                             DWORD   VirtualAddress;                         //节区的RVA地址    DWORD   SizeOfRawData;                          //在文件中对齐后的尺寸    DWORD   PointerToRawData;                       //在文件中的偏移    DWORD   PointerToRelocations;                   //在OBJ文件中用到    DWORD   PointerToLinenumbers;                   //行号表的位置(供调试使用)    WORD    NumberOfRelocations;                    //在OBJ文件中用到    WORD    NumberOfLinenumbers;                    //行号表中行号的数量    DWORD   Characteristics;                        //节的属性 } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

1、IMAGE_SECTION_HEADER.Name

该字段一共8个字节,一般情况下是一个以"\0"结尾的ASCII码字符串来标识节的名称,内容可以自行定义

该名称并不遵循Ansi字符串必须以"\0"结尾的规律,如果不以"\0"结尾,系统依然会认为它是一个字符串,但是会以8字节长度进行截断

2、IMAGE_SECTION_HEADER.Misc

该字段是一个union型的数据,这是节的数据在没有对齐前的真实尺寸,不过很多PE文件里该值并不准确

3、IMAGE_SECTION_HEADER.VirtualAddress

节区的RVA地址

4、IMAGE_SECTION_HEADER.SizeOfRawData

节在文件对齐后的尺寸

5、IMAGE_SECTION_HEADER.PointerToRawData

节区起始数据在文件中的偏移

6、IMAGE_SECTION_HEADER.PointerToRelocations

在".obj"文件中使用, 指向重定位表的指针

7、IMAGE_SECTION_HEADER.PointerToLinenumbers

行号表的位置(供调试用)

8、IMAGE_SECTION_HEADER.NumberOfRelocations

重定位表的个数(在OBJ文件中使用)

9、IMAGE_SECTION_HEADER.NumberOfLinenumbers

行号表中行号的数量

10、IMAGE_SECTION_HEADER.Characteristics

节的属性,这是一个四字节的字段,这个字段很重要,不同的数据位代表了不同的属性,这些数据位的组合描述了内存中一个节所拥有的访问属性

01fd153672afe1e589edb3778c7e9574.png

代码节的属性一般为0x60000020,二进制如下所示

d2bbf7f75d2ef8de4a2c3e1a3555e61b.png

也就是数据位的第5位、第29位、第30位的值为1,对照上面的表,就能够知道0x60000020代表的意思就是可执行,可读和节中包含代码。

数据节的属性一般为0xC0000040,二进制如下:

acef1e2c4cceb0a92252755a7c52ffb0.png

第6位、第30位和第31位的值为1,也就是0xC0000040代表可读,可写和节中包含已初始化数据

常量节(.const段)的属性为0x40000040,也就是可读和包含已初始化数据

资源节的属性和常量节的属性一般是相同的

当PE文件被压缩工具压缩以后,节属性就不一定是这些值了。包含代码的节往往被同时设置成具有可执行,可读和可写属性(正常是没有可写属性的),因为解压部分需要将解压后的代码回写到代码段中。

PE文件理论方面就介绍到这里,后面会从实际应用的角度去加深对PE文件结构的理解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值