PE文件结构
PE文件格式详解

PE文件格式详解(一)基础知识什么是PE文件格式:我们知道所有文件都是一些连续(当然实际存储在磁盘上的时候不一定是连续的)的数据组织起来的,不同类型的文件肯定组织形式也各不相同;PE文件格式便是一种文件组织形式,它是32位Window系统中的可执行文件EXE以及动态连接库文件DLL的组织形式。
为什么我们双击一个EXE文件之后它就会被Window运行,而我们双击一个DOC文件就会被Word打开并显示其中的内容;这说明文件中肯定除了存在那些文件的主体内容(比如EXE文件中的代码,数据等,DOC 文件中的文件内容等)之外还存在其他一些重要的信息。
这些信息是给文件的使用者看的,比如说EXE文件的使用者就是Window,而DOC文件的使用者就是Word。
Window可以根据这些信息知道把文件加载到地址空间的那个位置,知道从哪个地址开始执行;加载到内存后如何修正一些指令中的地址等等。
那么PE文件中的这些重要信息都是由谁加入的呢?是由编译器和连接器完成的,针对不同的编译器和连接器通常会提供不同的选项让我们在编译和联结生成PE文件的时候对其中的那些Window需要的信息进行设定;当然也可以按照默认的方式编译连接生成Window中默认的信息。
例如:WindowNT默认的程序加载基址是0x40000;你可以在用VC连接生成EXE文件的时候使用选项更改这个地址值。
在不同的操作系统中可执行文件的格式是不同的,比如在Linux上就有一种流行的ELF格式;当然它是由在Linux上的编译器和连接器生成的,所以编译器、连接器是针对不同的CPU架构和不同的操作系统而涉及出来的。
在嵌入式领域中我们经常提到交叉编译器一词,它的作用就是在一种平台下编译出能在另一个平台下运行的程序;例如,我们可以使用交叉编译器在跑Linux的X86机器上编译出能在Arm上运行的程序。
程序是如何运行起来的:一个程序从编写出来到运行一共需要那些工具,他们都对程序作了些什么呢?里面都涉及哪些知识需要学习呢?先说工具:编辑器-》编译器-》连接器-》加载器;首先我们使用编辑器编辑源文件;然后使用编译器编译程目标文件OBJ,这里面涉及到编译原理的知识;连接器把OBJ文件和其他一些库文件和资源文件连接起来生成EXE文件,这里面涉及到不同的连接器的知识,连接器根据OS的需要生成EXE文件保存着磁盘上;当我们运行EXE文件的时候有Window的加载器负责把EXE文件加载到线性地址空间,加载的时候便是根据上一节中说到的PE文件格式中的哪些重要信息。
逆向分析实验2PE文件结构分析

实验二PE文件结构分析一. 实验目的1.了解PE文件的输入表结构;2.手工解析PE文件的输入表;3.编程实现PE文件输入表的解析。
二. 实验内容1.第一步:手动解析输入表结构(1)使用工具箱中的工具e verything,寻找当前系统中任意一个e xe文件,文件名称是: actmovie.exe(2)使用LordPE“PE编辑器”打开exe文件,确定输入表的RVA,截图如下(图1):(3)点击PE编辑器右侧的“位置计算器”,得到文件偏移值,截图如下(图2):(4)使用16进制编辑工具,跳转到相应的输入文件偏移地址,输入表是每个IID对应一个DLL,根据IID大小,这里取20字节的数据进行分析,将输入表第一个IID结构的数据与IID结构体的成员一一对应,具体如下所示:IMAGE_IMPORT_DESCRIPTOR {OriginalFirstThunk = 000013C0TimeDateStamp = FFFFFFFFForwarderChain = FFFFFFFFName = 000014C0FirstThunk = 0000100C}(5)关注OriginalFirstThunk和Name两个成员,其中Name是一个RVA,用步骤(3)的方法得到其文件偏移值为 000008C0 ,在16进制编辑工具转到这个偏移地址,可见输入表的第一个D LL名为 msvcrt.dll ,截图如下(图3):(6)分析一下OriginalFirstThunk,它指向一个类型为IMAGE_THUNK_DATA的数组,上面已经分析出了它的值为000013C0 ,这是一个RVA,用步骤(3)的方法得到文件偏移地址 00007C0 。
在16进制编辑工具转到这个偏移地址,其中前面4个字节的数据为 63 5F 00 C8 ,截图如下(图4):(7)可以看出,这是以序号(填“以名字”或“以序号”)的方式输入函数;用与步骤(3)相同的方式在16进制编辑工具中对应IMAGE_IMPORT_BY_NAME结构的数据,可以看到函数的输入序号为 20 ,函数名为 cexit ,截图如下(图5):(8)验证:使用L ordPE单击“目录表”界面中输入表右侧的“…按钮”,打开输入表对话框,可以验证获取的DLL名和函数名是否正确。
PE文件格式

WORD e_crlc; // Relocations
WORD e_cparhdr; // Size of header in paragraphs
么正确的开始地址是0x401560。如果可执行程序调入0x100000处,则开始地址为0x101560。
因为PE文件的每一个段不必按同样的边界对齐方式调入,因此RVA地址的计算变得比较复
杂。例如,在文件中每一个段往往按512个字节的方式对齐,而在内存中可能以4096字节的方
式对齐。这方面的介绍可见下面的“SectionAlignment”、“FileAlignment”。举个例子,
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
WORD e_magic; // Magic number
WORD e_cblp; // Bytes on last page of file
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
三、文件头(File Header)
通过DOS头,你可以找到一个叫做IMAGE_FILE_HEADER的结构,如下;下面我分别介绍一
下。
typedef struct _IMAGE_FILE_HEADER {
中只有大约100个字节的代码,只输出一个诸如“this program needs windows NT ”之类的
信息。
你可以通过一个叫做IMAGE_DOS_HEADER的结构来识别一个合法的DOS头。这个结构的头两
个字节一定是“MZ”(#define IMAGE_DOS_SIGNATURE "MZ")。怎么才能找到PE开始的标志呢
PE文件头简析及输入表、输出表的分析

PE文件头简析及输入表、输出表的分析2008年01月13日星期日 22:50PE文件头简析及输入表、输出表的分析前两天由于做个免杀,需要对输入表做些改变,所以又重新看了pe文件的结构尤其是输入表及输出表的一些细节方面,做个笔记,方便自己以后翻看,也给大家提个方便,呵呵!1、PE文件格式文件尾___________________________________________________________________Code View调试信息 |COFF 符号表 | 调试信息COFF 行号 |------------------------------------------------------------------.reloc |.edata | 块(Section) .data |.text |---------------------------------------------------------------------------------------------------IMAGE_SECTION_HEADER |IMAGE_SECTION_HEADER | 块表(Section Table)IMAGE_SECTION_HEADER |IMAGE_SECTION_HEADER | //对应.text块---------------------------------------------------------------------------------------------------------数据目录表 | //包含在可选映像头中,包含输出\入表信息 IMAGE_OPTIONAL_HEADER32 | 可选映像头IMAGE_FILE_HEADER | 文件映像头"PE",0,0 | pe文件标识(pe文件头包含三个部分)---------------------------------------------------------------------------------------------------------DOS stub |DOS 'MZ' HEADER | 该字段中的e_lfanew字段指向pe头 ---------------------------------------------------------------------------------------------------------文件头说明:01、输入表、输出表的位置:在pe头中可选映像头字段中数据目录表字段中,相对于pe文件标识处的偏移分别为:+80h、+78h;(其中pe文件标识的位置在DOS 'MZ' HEADER字段中的e_lfanew指出,该字段相对于文件开始的偏移为+3Ch,4个字节);02、在用例子说明时用c32asm打开,其中的偏移均为文件在磁盘上存储的物理偏移,而查看的值均为给出的各个地址的RVA,转化方法入下:查到的RVA值-VOffset(可由lordpe查看)+ROffset 得到的就是可以c32asm中的偏移2、上面对pe文件格式做了简要介绍,下面主要分析输入表和输出表:输入表篇:概念不做介绍,位置上面已经给出,呵呵输入表的结构:输入表是以一个IMAGE_IMPORT_DESCRIPTOR(IID)数组开始,一个程序要调用几个dll就会有几个IID项,即每个IID对应于一个dllIID结构:IMAGE_IMPORT_DESCRIPTOR structunion{DWORD Characteristics ; ;00hDWORD OriginalFirstThunk; // 注释1};TimeDateStamp DWORD ;04h // 时间标志,可以忽略;ForwarderChain DWORD ;08h // 正向链接索引,一般为0,当程序引用一个dll中的api,而这个api又引用其它dll中的api时用;Name DWORD ;0Ch //DLL名字的指针,以00结尾的ASCII字符的RVA地址;FirstThunk DWORD ;10h // 注释2IMAGE_IMPORT_DESCRIPTOR ends注释 1:该值为一个 IMAGE_THUNK_DATA数组的RVA,其中的每个指针都指向IMAGE_IMPORT_BY_NAME结构。
深入剖析PE文件

深入剖析PE文件PE文件是Win32的原生文件格式.每一个Win32可执行文件都遵循PE文件格式.对PE文件格式的了解可以加深你对Win32系统的深入理解.一、基本结构。
上图便是PE文件的基本结构。
(注意:DOS MZ Header和部分PE header的大小是不变的;DOS stub部分的大小是可变的。
)一个PE文件至少需要两个Section,一个是存放代码,一个存放数据。
NT上的PE文件基本上有9个预定义的Section。
分别是:.text, .bss, .rdata, .data, .rsrc, .edata, .idata, .pdata, 和.debug。
一些PE文件中只需要其中的一部分Section.以下是通常的分类:l 执行代码Section , 通常命名为:.text (MS) or CODE (Borland)l 数据Section, 通常命名为:.data, .rdata, 或.bss(MS) 或DATA(Borland).资源Section, 通常命名为:.edatal 输入数据Section, 通常命名为:.idatal 调试信息Section,通常命名为:.debug这些只是命名方式,便于识别。
通常与系统并无直接关系。
通常,一个PE文件在磁盘上的映像跟内存中的基本一致。
但并不是完全的拷贝。
Windows加载器会决定加载哪些部分,哪些部分不需要加载。
而且由于磁盘对齐与内存对齐的不一致,加载到内存的PE文件与磁盘上的PE文件各个部分的分布都会有差异。
当一个PE文件被加载到内存后,便是我们常说的模块(Module),其起始地址就是所谓的HModule.二、DOS头结构。
所有的PE文件都是以一个64字节的DOS头开始。
这个DOS头只是为了兼容早期的DOS操作系统。
这里不做详细讲解。
只需要了解一下其中几个有用的数据。
1. e_magic:DOS头的标识,为4Dh和5Ah。
分别为字母MZ。
PE文件结构详解

PE文件结构详解1 摘要Windows NT 3.1引入了一种名为PE文件格式的新可执行文件格式。
PE文件格式的规范包含在了MSDN的CD中(Specs and Strategy, Specifications, Windows NT File Format Specifications),但是它非常之晦涩。
然而这一的文档并未提供足够的信息,所以开发者们无法很好地弄懂PE格式。
本文旨在解决这一问题,它会对整个的PE文件格式作一个十分彻底的解释,另外,本文中还带有对所有必需结构的描述以及示范如何使用这些信息的源码示例。
为了获得PE文件中所包含的重要信息,我编写了一个名为PEFILE.DLL的动态链接库,本文中所有出现的源码示例亦均摘自于此。
这个DLL和它的源代码都作为PEFile示例程序的一部分包含在了CD中(译注:示例程序请在MSDN中寻找,本站恕不提供),你可以在你自己的应用程序中使用这个DLL;同样,你亦可以依你所愿地使用并构建它的源码。
在本文末尾,你会找到PEFILE.DLL的函数导出列表和一个如何使用它们的说明。
我觉得你会发现这些函数会让你从容应付PE文件格式的。
2 介绍Windows操作系统家族最近增加的Windows NT为开发环境和应用程序本身带来了很大的改变,这之中一个最为重大的当属PE文件格式了。
新的PE文件格式主要来自于UNIX操作系统所通用的COFF规范,同时为了保证与旧版本MS-DOS及Windows操作系统的兼容,PE文件格式也保留了MS-DOS中那熟悉的MZ头部。
在本文之中,PE文件格式是以自顶而下的顺序解释的。
在你从头开始研究文件内容的过程之中,本文会详细讨论PE文件的每一个组成部分。
很多解决PE文件格式的工作和直接观看数据有关。
例如,要弄懂导入地址名称表是如何构成的,我就得同时查看.idata段头部、导入映像数据目录、可选头部以及当前的.idata段实体,而EXEVIEW.EXE就是查看这些信息的最佳示例。
PE文件结构解析

PE⽂件结构解析说明:本⽂件中各种⽂件头格式截图基本都来⾃看雪的《加密与解密》;本⽂相当《加密与解密》的阅读笔记。
1.PE⽂件总体结构PE⽂件框架结构,就是exe⽂件的排版结构。
也就是说我们以⼗六进制打开⼀个.exe⽂件,开头的那些内容就是DOS头内容,下来是PE头内容,依次类推。
如果能认识到这样的内含,那么“exe开头的内容是不是就直接是我们编写的代码”(不是,开头是DOS头内容)以及“我们编写的代码被编排到了exe⽂件的哪⾥”(在.text段,.text具体地址由其相应的IMAGE_SECTION_HRADER指出)此类的问题答案就显⽽易见了。
exe⽂件从磁盘加载到内存,各部份的先后顺序是保持不变的,但由于磁盘(⼀般200H)和内存(⼀般1000H)区块的对齐⼤⼩不⼀样,所以同⼀内容在磁盘和在内存中的地址是不⼀样的。
换⾔之你在磁盘上看到⼀段内容⼀内容要到在内存中找到它--假设它是能映射到内容的部份--那么要做相应的地址转换。
(⽐如你在Ultraedit 中看到某⼏个字节⽽想在OllyDbg中找到这⼏个字节那么需要进⾏地址转换)另外要注意,PE⽂件中存放的地址值都是内存中的地址,这些地址在OllyDbg中不需要转换到其指定的位置就能找到其指向的内容;这要根据这个地址找到内容在Ultraedit的地址,需要将此RVA址转换成⽂件偏移地址。
还要注意DOS头/PE头/块表,映射到内存时属同⼀区块⽽且是第⼀区块,所以此三者上的RVA和⽂件偏移地址是相等的。
2.DOS头部2.1MS-DOS头部(IMAGE_DOS_HEADER)最后的e_lfanew即是PE⽂件的RVA地址我们在前边已经提过,对于DOS头/PE头/区块表三部分RVA和⽂件偏移地址是相等的,所以上边在⼗六进制⽂本编缉器中,直接转向e_lfanew指向的000000B0可以正好找到PE头。
2.2DOS stubDOS stub是当操作系统不⽀持PE⽂件时执⾏的部分,⼀般由编译器⾃⼰⽣成内容是输出“This program cannot be run in MS-DOS mode”等提⽰。
PE文件结构

节表的数据
第一个结构
最后一个结构
对齐填充数据
偏移转换计算 一
入口RVA:00261001
内存块大小
内存块起始 文件块大小
文件块起始
起始位置 块起始
结束位置 块起始 + 块长度
各个节的范围
• • • • • • • • • • • 节名 Code DATA BSS .idata .tls .rdata .reloc .rsrc .aspack .adata 起始地址 - 终了地址 00001000 - 00140000 00140000 - 00145000 00145000 - 0014B000 0014B000 - 0014E000 0014E000 - 0014F000 0014F000 - 00150000 00150000 - 00165000 00165000 - 00261000 00261000 - 00264000 00264000 - 00265000
文件头数据信息
节数目:0Ah
可选头定义
• • • • • • • • • • • • • • IMAGE_OPTIONAL_HEADER32 STRUCT SizeOfCode DWORD ? ;001ch 所有含代码的节的总大小 SizeOfInitializedData DWORD ? ;0020h 所有含已初始化数据的节的总大小 SizeOfUninitializedData DWORD ? ;0024h 所有含未初始化数据的节的大小 AddressOfEntryPoint DWORD ? ;0028h 程序执行入口RVA BaseOfCode DWORD ? ;002ch 代码的节的起始RVA BaseOfData DWORD ? ;0030h 数据的节的起始RVA ImageBase DWORD ? ;0034h PE文件的装载地址 SectionAlignment DWORD ? ;0038h 内存中的节的对齐粒度 FileAlignment DWORD ? ;003ch 文件中的节的对齐粒度 SizeOfImage DWORD ? ;0050h 内存中整个PE映像尺寸 SizeOfHeaders DWORD ? ;0054h 所有头+节表的大小 DataDirectory IMAGE_DATA_DIRECTORY 16 dup(<>) ;0078h IMAGE_OPTIONAL_HEADER32 ENDS
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
文件偏移和RVA的关系
节数据n 文件 偏移 节数据n …… 节数据1 节表 PE头 DOS块 …… 节数据1 节表 PE头 DOS块 offset 0 相对虚拟地址 Relative Virtual Address RVA
磁盘文件中 映射 内存中
IMAGE_DATA_DIRECTORY
• • • • IMAGE_DATA_DIRECTORY STRUCT VirtualAddress DWORD Size DWORD IMAGE_DATA_DIRECTORY ENDS
找到导入表、导出表
四、PE结构简单应用
• 粗略分辨dll/exe、
– 文件头中的Characteristics字段 – 位于PE头16h偏移处 – 该字段占用2个字节,16个bit位 – 该字段定义是按照bit位来定义的
Characteristics字段
数据位 • • • • • • • • • • • • • • • • 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 代表的含义 ;文件中不存在重定位信息 ;文件是可执行的 ;不存在行信息 ;不存在符号信息 ;被舍弃,值为“0” ;应用程序可以处理大于2GB的地址空间 ;保留,留以后扩展 ;小尾方式 ;只在32位平台上运行 ;不包含调试信息 ;不能从可移动盘(如软盘、光盘)运行 ;不能从网络运行 ;系统文件(如驱动程序),不能直接运行 ;这是一个 DLL 文件 ;文件不能在多处理器上计算机上运行 ;大尾方式
导入表
• • • • • • • • • • IMAGE_IMPORT_DESCRIPTOR STRUCT union Characteristics DWORD OriginalFirstThunk DWORD ends TimeDateStamp DWORD ForwarderChain DWORD Name1 DWORD FirstThunk DWORD IMAGE_IMPORT_DESCRIPTOR ENDS ? ? ;指向被调函数名的指针数组的指针 ? ? ? ? ;时间日期记录,无实际意义,可忽略 ;正向连接索引 ;指向被调用dll的名字指针数组的指针 ;指向被调函数地址的指针数组的指针
;DOS代码的初始化堆栈段 ;DOS代码的初始化堆栈指针
;DOS代码的入口IP ;DOS代码的入口CS
;指向PE文件的头部
DOS头结构图示
DOS头,40h e_lfanew
显示数据
实际数据
00 01 00 00
00 00 01 00
DOS块图示
选中的数据为dos块
PE头组成
• PE头的三个构成部分
;导出表 ;导入表 ;资源 ;重定位表 ;调试信息 ;版权信息 ;导入函数地址表
可选头数据
入口点
导入表
导出表
节表
• • • • • • • • • • • • • • • IMAGE_SECTION_HEADER STRUCT Name1 db IMAGE_SIZEOF_SHORT_NAME union Misc PhysicalAddress dd VirtualSize dd ends VirtualAddress dd SizeOfRawData dd PointerToRawData dd PointerToRelocations dd PointerToLinenumbers dd NumberOfRelocations dw NumberOfLinenumbers dw Characteristics dd IMAGE_SECTION_HEADER ENDS 8dup(?) ? ? ? ? ? ? ? ? ? ? ;8个字节的节表名称,如“.text/code” ; 物理地址 ;节区的真实长度 (内存中) ;节区的RVA地址 ; 物理长度,在文件中对齐后的尺寸 ;节基于文件的偏移量,在文件中的偏移 ;重定位的偏移,在OBJ文件中使用 ;行号表的偏移(供调试用) ;重定位项数目,在OBJ文件中使用 ;行号表中行号的数量 ;节在内存中的属性特征:可读,可写,可执行等等。
示例分析
获取的属性值为818E 转化成二进制数据:1000000110001110 找到有效位:15 、8 、7 、3 、2 、1 分析有效位的含义 1 文件是可执行的 2 不存在行信息 3 不存在符号信息 7 小尾方式 8 只在32位平台上运行 15 大尾方式
文件头数据信息
节数目:0Ah
可选头定义
• • • • • • • • • • • • • • IMAGE_OPTIONAL_HEADER32 STRUCT SizeOfCode DWORD ? ;001ch 所有含代码的节的总大小 SizeOfInitializedData DWORD ? ;0020h 所有含已初始化数据的节的总大小 SizeOfUninitializedData DWORD ? ;0024h 所有含未初始化数据的节的大小 AddressOfEntryPoint DWORD ? ;0028h 程序执行入口RVA BaseOfCode DWORD ? ;002ch 代码的节的起始RVA BaseOfData DWORD ? ;0030h 数据的节的起始RVA ImageBase DWORD ? ;0034h PE文件的装载地址 SectionAlignment DWORD ? ;0038h 内存中的节的对齐粒度 FileAlignment DWORD ? ;003ch 文件中的节的对齐粒度 SizeOfImage DWORD ? ;0050h 内存中整个PE映像尺寸 SizeOfHeaders DWORD ? ;0054h 所有头+节表的大小 DataDirectory IMAGE_DATA_DIRECTORY 16 dup(<>) ;0078h IMAGE_OPTIONAL_HEADER32 ENDS
导出表
• • • • • • • • • • • • • IMAGE_EXPORT_DIRECTORY STRUCT Characteristics DWORD ? ;未使用,总是为0 TimeDateStamp DWORD ? ;文件的产生时刻 MajorVersion WORD ? ;未使用,总是为0 MinorVersion WORD ? ;未使用,总是为0 nName DWORD ? ;指向文件名的RVA nBase DWORD ? ;导出函数的起始序号 NumberOfFunctions DWORD ? ;导出函数的总数 NumberOfNames DWORD ? ;以名称导出的函数总数 AddressOfFunctions DWORD ? ;指向导出函数地址表的RVA AddressOfNames DWORD ? ;指向函数名地址表的RVA AddressOfNameOrdinals DWORD ? ;指向函数名序号表的RVA IMAGE_EXPORT_DIRECTORY ENDS
– DOS头
• 指向DOS可执行程序部分 • 指向PE结构部分
– DOS块
• DOS的可执行程序部分
DOS头结构定义
• • • • • • • • • • • • • • • • • • • • • IMAGE_DOS_HEADER STRUCT e_magic WORD ? e_cblp WORD ? e_cp WORD ? e_crlc WORD ? e_cparhdr WORD ? e_minalloc WORD ? e_maxalloc WORD ? e_ss WORD ? e_sp WORD ? e_csum WORD ? e_ip WORD ? e_cs WORD ? e_lfarlc WORD ? e_ovno WORD ? e_res WORD 4 dup(?) e_oemid WORD ? e_oeminfo WORD ? e_res2 WORD 10 dup(?) e_lfanew DWORD ? IMAGE_DOS_HEADER ENDS ;DOS可执行文件标记,固定为“MZ”
PE结构图示
二、PE结构的学习价值
• • • • 逆向分析需要其支持 是加密、解密的基础 有助于程序的编写 加深对windows系统的认识
三、PE结构分析
• PE结构主要数据块
– DOS部分 – PE头 – 节表 – 节数据
三、PE结构分析
• PE结构总览
DOS部分
• DOS部分由如下两部分构成
节表的数据
第一个结构
最后一个结构
对齐填充数据
偏移转换计算 一
入口RVA:00261001
内存块大小
内存块起始 文件块大小
文件块起始
起始位置 块起始
结束位置 块起始 + 块长度
各个节的范围
• • • • • • • • • • • 节名 Code DATA BSS .idata .tls .rdata .reloc .rsrc .aspack .adata 起始地址 - 终了地址 00001000 - 00140000 00140000 - 00145000 00145000 - 0014B000 0014B000 - 0014E000 0014E000 - 0014F000 0014F000 - 00150000 00150000 - 00165000 00165000 - 00261000 00261000 - 00264000 00264000 - 00265000
? ?
;数据的起始RVA ;数据块的长度大小
• • • • • • •
0 1 2 5 6 7 12
IMAGE_DIRECTORY_ENTRY_EXPORT IMAGE_DIRECTORY_ENTRY_IMPORT IMAGE_DIRECTORY_ENTRY_RESOURCE IMAGE_DIRECTORY_ENTRY_BASERELOC IMAGE_DIRECTORY_ENTRY_DEBUG IMAGE_DIRECTORY_ENTRY_ARCHITECTURE IMAGE_DIRECTORY_ENTRY_IAT