PE文件-DataDirectory解剖
已知OptionalHeader的最后一个字段是DataDirectory,DataDirectory是一个结构体数组
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
// // Directory format. // typedef struct _IMAGE_DATA_DIRECTORY { DWORD VirtualAddress; //占4个字节 DWORD Size; //占4个字节 } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
数组一共16个元素,每个元素的组成是一个结构体_IMAGE_DATA_DIRECTORY,该结构体一共2个字段,分别是VirtualAddress和Size,VirtualAddress即虚拟地址,此处指的是相对虚拟地址,即RVA,Size即该条目(即数组元素代表的东西)的大小。
虽然每个元素都是一个由VirtualAddress字段和Size字段组成的结构体,但是每个元素都表示不同的东西,如下:
// Directory Entries #define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory #define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory #define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory #define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory #define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory #define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table #define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory // IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // (X86 usage) #define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7 // Architecture Specific Data #define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // RVA of GP #define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory #define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory #define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Bound Import Directory in headers #define IMAGE_DIRECTORY_ENTRY_IAT 12 // Import Address Table #define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 // Delay Load Import Descriptors #define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 // COM Runtime descriptor
第1个元素。Export Table,导出表
root@entry0:~# xxd -s $((0xe8+4+2+2+4+4+4+2+2+2+1+1+4+4+4+4+4+4+4+4+4+2+2+2+2+2+2+4+4+4+4+2+2+4+4+4+4+4+4)) -l 8 test.exe 00000160: 0000 0000 0000 0000 ........ root@entry0:~#
前4个字节是VirtualAddress,内容是0,后4个字节是Size,内容也是0,说明没有导出表。
第2个元素。Import Table,导入表
root@entry0:~# xxd -s $((0xe8+4+2+2+4+4+4+2+2+2+1+1+4+4+4+4+4+4+4+4+4+2+2+2+2+2+2+4+4+4+4+2+2+4+4+4+4+4+4+8)) -l 8 test.exe 00000168: 6cc7 0000 7800 0000 l...x... root@entry0:~#
VirtualAddress是0xc76c,Size是0x78,即导入表的RVA是0xc76c,导入表大小是0x78
第3个元素。Resource Table,资源表
root@entry0:~# xxd -s $((0xe8+4+2+2+4+4+4+2+2+2+1+1+4+4+4+4+4+4+4+4+4+2+2+2+2+2+2+4+4+4+4+2+2+4+4+4+4+4+4+8+8)) -l 8 test.exe 00000170: 0050 0100 c807 0000 .P...... root@entry0:~#
VirtualAddress是0x015000,Size是0x7c8,即资源表的RVA是0x15000,资源表大小是0x7c8
第4个元素。Exception Table,异常表
root@entry0:~# xxd -s $((0xe8+4+2+2+4+4+4+2+2+2+1+1+4+4+4+4+4+4+4+4+4+2+2+2+2+2+2+4+4+4+4+2+2+4+4+4+4+4+4+8+8+8)) -l 8 test.exe 00000178: 0000 0000 0000 0000 ........ root@entry0:~#
VirtualAddress和Size都是0,说明没有异常表
第5个元素。Certificate Table,证书表
root@entry0:~# xxd -s $((0xe8+4+2+2+4+4+4+2+2+2+1+1+4+4+4+4+4+4+4+4+4+2+2+2+2+2+2+4+4+4+4+2+2+4+4+4+4+4+4+8+8+8+8)) -l 8 test.exe 00000180: 0000 0000 0000 0000 ........ root@entry0:~#
VirtualAddress和Size都是0,说明没有证书表
第6个元素。Base Relocation Table,基础重定位表
root@entry0:~# xxd -s $((0xe8+4+2+2+4+4+4+2+2+2+1+1+4+4+4+4+4+4+4+4+4+2+2+2+2+2+2+4+4+4+4+2+2+4+4+4+4+4+4+8+8+8+8+8)) -l 8 test.exe 00000188: 0000 0000 0000 0000 ........ root@entry0:~#
VirtualAddress和Size都是0,说明没有基础重定位表
第7个元素。Debug,调试数据表
root@entry0:~# xxd -s $((0xe8+4+2+2+4+4+4+2+2+2+1+1+4+4+4+4+4+4+4+4+4+2+2+2+2+2+2+4+4+4+4+2+2+4+4+4+4+4+4+8+8+8+8+8+8)) -l 8 test.exe 00000190: e0c1 0000 1c00 0000 ........ root@entry0:~#
VirtualAddress是0xc1e0,Size是0x1c,调试数据表的RVA是0xc1e0,大小是0x1c
第8个元素。版权信息表,64位的文件该字段是保留字段,都为0
root@entry0:~# xxd -s $((0xe8+4+2+2+4+4+4+2+2+2+1+1+4+4+4+4+4+4+4+4+4+2+2+2+2+2+2+4+4+4+4+2+2+4+4+4+4+4+4+8+8+8+8+8+8+8)) -l 8 test.exe 00000198: 0000 0000 0000 0000 ........ root@entry0:~#
VirtualAddress和Size都是0,说明没有版权信息表
第9个元素。Global Ptr,要存储在全局指针寄存器中的值的RVA。此结构的大小成员必须设置为零
root@entry0:~# xxd -s $((0xe8+4+2+2+4+4+4+2+2+2+1+1+4+4+4+4+4+4+4+4+4+2+2+2+2+2+2+4+4+4+4+2+2+4+4+4+4+4+4+8+8+8+8+8+8+8+8)) -l 8 test.exe 000001a0: 0000 0000 0000 0000 ........ root@entry0:~#
的确都是0
第10个元素。TLS Table。线程本地存储表
root@entry0:~# xxd -s $((0xe8+4+2+2+4+4+4+2+2+2+1+1+4+4+4+4+4+4+4+4+4+2+2+2+2+2+2+4+4+4+4+2+2+4+4+4+4+4+4+8+8+8+8+8+8+8+8+8)) -l 8 test.exe 000001a8: 0000 0000 0000 0000 ........ root@entry0:~#
VirtualAddress和Size都是0,说明没有线程本地存储表
第11个元素。Load Config Table,载入配置表
root@entry0:~# xxd -s $((0xe8+4+2+2+4+4+4+2+2+2+1+1+4+4+4+4+4+4+4+4+4+2+2+2+2+2+2+4+4+4+4+2+2+4+4+4+4+4+4+8+8+8+8+8+8+8+8+8+8)) -l 8 test.exe 000001b0: 0000 0000 0000 0000 ........ root@entry0:~#
VirtualAddress和Size都是0,说明没有载入配置表
第12个元素。Bound Import,绑定的导入表
root@entry0:~# xxd -s $((0xe8+4+2+2+4+4+4+2+2+2+1+1+4+4+4+4+4+4+4+4+4+2+2+2+2+2+2+4+4+4+4+2+2+4+4+4+4+4+4+8+8+8+8+8+8+8+8+8+8+8)) -l 8 test.exe 000001b8: 0000 0000 0000 0000 ........ root@entry0:~#
VirtualAddress和Size都是0,说明没有绑定的导入表
第13个元素。IAT,导入地址表
root@entry0:~# xxd -s $((0xe8+4+2+2+4+4+4+2+2+2+1+1+4+4+4+4+4+4+4+4+4+2+2+2+2+2+2+4+4+4+4+2+2+4+4+4+4+4+4+8+8+8+8+8+8+8+8+8+8+8+8)) -l 8 test.exe 000001c0: 00c0 0000 e001 0000 ........ root@entry0:~#
VirtualAddress是0xc000,Size是0x1e0,导入地址表RVA是0xc000,大小是0x1e0
第14个元素。Delay Import Descriptor,延迟导入描述符
root@entry0:~# xxd -s $((0xe8+4+2+2+4+4+4+2+2+2+1+1+4+4+4+4+4+4+4+4+4+2+2+2+2+2+2+4+4+4+4+2+2+4+4+4+4+4+4+8+8+8+8+8+8+8+8+8+8+8+8+8)) -l 8 test.exe 000001c8: 0000 0000 0000 0000 ........ root@entry0:~#
VirtualAddress和Size都是0,说明没有延迟导入描述符
第15个元素。CLR Runtime Header,CLR运行时头部
root@entry0:~# xxd -s $((0xe8+4+2+2+4+4+4+2+2+2+1+1+4+4+4+4+4+4+4+4+4+2+2+2+2+2+2+4+4+4+4+2+2+4+4+4+4+4+4+8+8+8+8+8+8+8+8+8+8+8+8+8+8)) -l 8 test.exe 000001d0: 0000 0000 0000 0000 ........ root@entry0:~#
VirtualAddress和Size都是0,说明CLR运行时头部
第16个元素。保留字段,都是0
root@entry0:~# xxd -s $((0xe8+4+2+2+4+4+4+2+2+2+1+1+4+4+4+4+4+4+4+4+4+2+2+2+2+2+2+4+4+4+4+2+2+4+4+4+4+4+4+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8)) -l 8 test.exe 000001d8: 0000 0000 0000 0000 ........ root@entry0:~#