PE详解之IMAGE_OPTIONAL_HEADER32 结构定义即各个属性的作用(PE详解03)
- 格式:doc
- 大小:64.00 KB
- 文档页数:6
PE⽂件解析-PE头解析-1-⽂件头,PE头PE⽂件解析-PE头解析PE头⼜叫NT头,是PE⽂件真正的头部,DOS头只是⽤来为了兼容以前的DOS系统。
PE头位于DOS Stub后⾯,以PE00作为起始标记类似于DOS头的MZDOS StubDOS Stub就是DOS头结束到PE头的开始中间的区域,基本上是垃圾区域没啥⽤,但是加壳的时候可以⽤到。
NT/PE头typedef struct _IMAGE_NT_HEADERS {DWORD Signature;//PE标志,就是PE00IMAGE_FILE_HEADER FileHeader;//⽂件头,是另⼀个⽂件的结构体IMAGE_OPTIONAL_HEADER32 OptionalHeader;//可选PE头,也叫扩展头} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;⽂件头typedef struct _IMAGE_FILE_HEADER {WORD Machine;//程序允许的CPU型号,如果为0表⽰能在任何CPU上运⾏,如果是0x14c表⽰的是386以及后续的型号WORD NumberOfSections;//⽂件中存在的区段的数量DWORD TimeDateStamp;//时间戳DWORD PointerToSymbolTable;DWORD NumberOfSymbols;WORD SizeOfOptionalHeader;//可选PE头的⼤⼩32位默认是E0,64位默认是F0WORD Characteristics;//⽂件属性,每个位有不同的含义,} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;代码解析。
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文件是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。
文件格式详解原作者:MSDN摘要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文件格式的。
介绍Windows操作系统家族最近增加的Windows NT为开发环境和应用程序本身带来了很大的改变,这之中一个最为重大的当属PE文件格式了。
新的PE文件格式主要来自于UNIX操作系统所通用的COFF规范,同时为了保证与旧版本MS-DOS及Windows操作系统的兼容,PE文件格式也保留了MS-DOS中那熟悉的MZ头部。
在本文之中,PE文件格式是以自顶而下的顺序解释的。
在你从头开始研究文件内容的过程之中,本文会详细讨论PE文件的每一个组成部分。
许多单独的文件成分定义都来自于Microsoft Win32 SDK开发包中的WINNT.H文件,在这个文件中你会发现用来描述文件头部和数据目录等各种成分的结构类型定义。
但是,在WINNT.H中缺少对PE文件结构足够的定义,在这种情况下,我定义了自己的结构来存取文件数据。
pe32基本结构摘要:1.PE32的基本概念2.PE32的结构组成3.PE32的重要部分及其功能4.PE32的应用领域5.总结正文:PE32(Portable Executable 32-bit)是一种可移植的可执行文件格式,广泛应用于Windows操作系统中。
它主要由两部分组成:头部(Header)和节(Section)。
本文将详细介绍PE32的基本结构,以便读者更好地理解和应用这一重要技术。
一、PE32的基本概念PE32是一种32位的可执行文件格式,它起源于微软为取代NE格式而开发的一种新的executable 文件格式。
与NE格式相比,PE32格式具有更好的可移植性和更强大的功能。
二、PE32的结构组成PE32文件的结构主要由以下几个部分组成:1.魔数(Magic Number):位于PE32文件的开头,用于标识该文件是一个PE32格式的可执行文件。
2.机器代码(Machine Code ):用于表示程序的指令,由计算机硬件直接执行。
3.代码签名(Code Signature):用于验证代码的完整性和来源,确保程序不被恶意篡改。
4.导入库(Import Library):用于链接程序依赖的外部库。
5.导出符号(Export Symbol):用于向其他程序提供本程序的接口。
6.资源(Resource):包括程序需要的图形、音频、文本等资源。
7.调试信息(Debug Information):用于调试程序的详细信息。
8.入口点(Entry Point):程序开始执行的地址。
三、PE32的重要部分及其功能1.魔数:它是PE32文件的一个关键组成部分,用于识别文件格式。
不同的魔数对应不同的文件类型,如PE32、PE32+等。
2.导入库和导出符号:这两个部分用于实现程序的模块化。
导入库表示程序依赖的外部库,导出符号表示程序向其他程序提供的接口。
3.资源:这些资源包括程序运行所需的图形、音频、文本等数据。
pe文件框架结构PE文件是指Windows操作系统平台下的可执行文件,它是一种二进制程序文件,在Windows操作系统中扮演着非常重要的角色。
因此,了解PE文件的框架结构对于了解Windows操作系统的关键机制和安全性方面有很大的帮助。
本文将分步骤阐述PE文件框架结构。
一、DOS头DOS头是PE文件结构的开始部分,用于在早期版本的Windows操作系统上运行应用程序。
DOS头包含了一些用于MS-DOS的信息和可执行程序的信息,比如可执行程序的起始地址和执行入口点。
二、PE文件头PE文件头是指非常关键的PE文件头部区域,包含了PE文件的组织结构信息和代码在内存中的布局信息。
PE文件头由四部分组成,分别是文件标识头(Signature),文件头部(File Header),可选头部(Optional Header),数据目录(Data Directory)。
三、节表在PE文件头部区域中,还有一块重要的信息是节表。
节表用于存储PE 文件中的区段信息,包括代码段、数据段、资源段和导出等信息。
在代码段、数据段和资源段中,存储着PE文件的程序和数据,节表为了对各个节进行可控制的访问,便于程序的控制和调试。
四、数据目录PE文件头部区域中还包含了一个数据目录,在32位PE中,数据目录通常有16个数据目录,用于存储PE文件中的各种信息,如导入表、导出表、资源表、重定位表等等。
五、代码段代码段是PE文件的主要部分,它包含了PE文件的执行代码和程序逻辑,是PE文件的核心内容。
代码段的格式主要是二进制代码,对程序的执行有很大的影响。
六、数据段数据段主要用来存放程序中要用到的各种数据,包括全局变量、局部变量和常量等。
数据段会经常开辟空间以存储函数中的局部变量和运行时生成的各种实例对象。
综上,PE文件是Windows操作系统平台下的可执行文件,其框架结构主要由DOS头、PE文件头、节表、数据目录、代码段和数据段组成。
了解PE文件的结构以及各个部分之间的关联是非常重要的,既有助于我们更好的理解操作系统机制,又有助于我们在软件开发和安全领域中进行有效的分析和优化。
dll文件32位64位检测工具以及Windows文件夹SysWow64的坑作者:缘生梦发布日期:2014-03-10 20:33:04我来说两句(0)2Tag标签:dll文件32位64位检测工具以及Windows文件夹SysWow64的坑 自从操作系统升级到64位以后,就要不断的需要面对32位、64位的问题。
相信有很多人并不是很清楚32位程序与64位程序的区别,以及Program Files (x86),Program Files的区别。
同时,对于程序的dll文件应该放到System32文件夹,还是SysWow64,大部分人做的决定是,32位程序放到System32,64位程序放到SysWow64。
是不是这样呢,那么今天就由我身边发生的一个案例来详细的说明一下。
dll文件不匹配导致数据库无法启动前段时间,数据库做了一些功能上的改进,于是用VS2010编译检出了一个版本,供测试部测试。
测试部拿到数据库后,通过批处理将数据库程序,注册为服务。
虽然执行的是批处理,实际上注册服务的过程,是通过运行数据库程序,并给其传入命令行参数来完成的,详情请看这篇文章玩转Windows服务系列——Debug、Release版本的注册和卸载,及其原理。
通过批处理运行程序后,出现如下问题:出现这种问题,测试部不淡定了,叫我去看。
我又试着运行了一下程序,依然出现这个问题。
“可是在我的机器上运行的挺好的啊”,这是我说的第一句话,相信很多人看了这句话就会心的笑了。
有问题就是有问题,既然我的机器上可以正常运行,那么测试机为什么不行呢,首先要查找原因。
数据库是用VS2010编译的,那么在其他机器上运行,就需要运行的操作系统中以及安装了VS2010的运行时,否则就会因为缺少程序运行所必须的dll文件而无法正常运行。
我想应该是这个原因,但又一想,如果没有装运行时的话,会提示缺少msvcr100.dll、msvcp100.dll等文件,上图中的问题显然不是缺少dll问题。
1 基本概念下表描述了贯穿于本文中的一些概念:图1 解释了Microsoft PE可执行文件格式:PE文件总体上分为“头”和“节”。
“头”是“节”的描述、简化、说明,“节”是“头”的具体化。
3 文件头PE文件的头分为DOS头、NT头、节头。
注意,这是本人的分法,在此之前并没有这种分法。
这样分法会更加合理,更易理解。
因为这三个部分正好构成SizeOfHeaders所指的范围,所以将它们合为“头”。
这里的3个头与别的文章的头的定义会有所区别。
节头紧跟在NT头后面。
3.1 DOS头(PE文件签名的偏移地址就是大小)用记事本打开任何一个镜像文件,其头2个字节必为字符串“MZ”,这是Mark Zbikowski的姓名缩写,他是最初的MS-DOS设计者之一。
然后是一些在MS-DOS下的一些参数,这些参数是在MS-DOS下运行该程序时要用到的。
在这些参数的末尾也就是文件的偏移0x3C(第60字节)处是是一个4字节的PE文件签名的偏移地址。
该地址有一个专用名称叫做“E_lfanew”。
这个签名是“PE00”(字母“P”和“E”后跟着两个空字节)。
紧跟着E_lfanew 的是一个MS-DOS程序。
那是一个运行于MS-DOS下的合法应用程序。
当可执行文件(一般指exe、com文件)运行于MS-DOS下时,这个程序显示“This program cannot be run in DOS mode(此程序不能在DOS模式下运行)”这条消息。
用户也可以自己更改该程序,有些还原软件就是这么干的。
同时,有些程序既能运行于DOS又能运行于Windows下就是这个原因。
Notepad.exe整个DOS头大小为224个字节,大部分不能在DOS下运行的Win32文件都是这个值。
MS-DOS程序是可有可无的,如果你想使文件大小尽可能的小可以省掉MS-DOS程序,同时把前面的参数都清0。
3.2 NT头(244或260个字节)紧跟着PE文件签名之后,是NT头。
PE⽂件学习笔记(⼀):DOS头与PE头解析在Windows下所谓PE⽂件即Portable Executable,意为可移植的可执⾏的⽂件。
常见的.EXE、.DLL、.OCX、.SYS、.COM都是PE⽂件。
PE⽂件有⼀个共同特点:前两个字节为4D 5A(MZ)。
如果⼀个⽂件前两个字节不是4D 5A则其肯定不是可执⾏⽂件。
⽐如⽤16进制⽂本编辑器打开⼀个“.xls”⽂件其前两个字节为:0XD0 0XCF;打开⼀个“.pdf”其前两个字节为:0X25 0X50。
PE⽂件结构:DOS头+PE头+节表+.data/.rdata/.text。
⽽今天我们就来具体了解⼀下PE⽂件的DOS头和PE头的结构成员与部分成员的作⽤。
注意:⼀个exe⽂件本⾝是⼀个PE⽂件,但是由于包含dll库,所以⼀个exe⽂件也是许多PE⽂件组成的(包含多个dll)⼀个PE⽂件。
1、DOS头:共40H(64字节)DOS头中声明⽤的寄存器(我们可以看到e_ss、e_sp、e_ip、e_cs还是16位的寄存器),所以在32位/64为系统中⽤到的只有两个成员了(第⼀个和最后⼀个):①e_magic:判断⼀个⽂件是不是PE⽂件;②e_lfanew:相对于⽂件⾸的偏移量,⽤于找到PE头;具体结构如下(前⾯的⼗六进制数表⽰该成员相对于结构的偏移量,WORD2字节变量、DWORD4字节变量)://注释掉的不需要重点分析struct _IMAGE_DOS_HEADER{0X00 WORD e_magic; //※Magic DOS signature MZ(4Dh 5Ah):MZ标记:⽤于标记是否是可执⾏⽂件//0X02 WORD e_cblp; //Bytes on last page of file//0X04 WORD e_cp; //Pages in file//0X06 WORD e_crlc; //Relocations//0X08 WORD e_cparhdr; //Size of header in paragraphs//0X0A WORD e_minalloc; //Minimun extra paragraphs needs//0X0C WORD e_maxalloc; //Maximun extra paragraphs needs//0X0E WORD e_ss; //intial(relative)SS value//0X10 WORD e_sp; //intial SP value//0X12 WORD e_csum; //Checksum//0X14 WORD e_ip; //intial IP value//0X16 WORD e_cs; //intial(relative)CS value//0X18 WORD e_lfarlc; //File Address of relocation table//0X1A WORD e_ovno; //Overlay number//0x1C WORD e_res[4]; //Reserved words//0x24 WORD e_oemid; //OEM identifier(for e_oeminfo)//0x26 WORD e_oeminfo; //OEM information;e_oemid specific//0x28 WORD e_res2[10]; //Reserved words0x3C DWORD e_lfanew; //※Offset to start of PE header:定位PE⽂件,PE头相对于⽂件的偏移量};我们查看下⾯所⽰unins000.exe⽂件的结构信息:64字节(共4⾏)的DOS头,第⼀个成员2个字节是可执⾏⽂件的标志信息;最后⼀个成员4字节是PE头的偏移地址为00000100H,我们可以根据00000100H来获取PE头的地址。
IMAGE_OPTIONAL_HEADER 结构,正如名字的意思,这是一个可选映像头,是一个可选的结构,但是呢,实际上上节课我们讲解的IMAGE_FILE_HEADER 结构远远不足以来定义PE 文件的属性。
因此,这些属性在IMAGE_OPTIONAL_HEADER 结构中进行定义。
因此这两个结构联合起来,才是一个完整的“PE文件结构”。
那么我们接着就应该顺理成章地来谈谈IMAGE_OPTIONAL_HEADER32 结构的定义:(啥?结构不会,先看看小甲鱼童鞋的《零基础入门学习C语言》关于结构方面的章节吧~)typedef struct _IMAGE_OPTIONAL_HEADER{//// Standard fields.//+18h WORD Magic; // 标志字, ROM 映像(0107h),普通可执行文件(010Bh)+1Ah BYTE MajorLinkerVersion; // 链接程序的主版本号+1Bh BYTE MinorLinkerVersion; // 链接程序的次版本号+1Ch DWORD SizeOfCode; // 所有含代码的节的总大小+20h DWORD SizeOfInitializedData; // 所有含已初始化数据的节的总大小+24h DWORD SizeOfUninitializedData; // 所有含未初始化数据的节的大小+28h DWORD AddressOfEntryPoint; // 程序执行入口RVA+2Ch DWORD BaseOfCode; // 代码的区块的起始RVA+30h DWORD BaseOfData; // 数据的区块的起始RVA //// NT additional fields. 以下是属于NT结构增加的领域。
//+34h DWORD ImageBase; // 程序的首选装载地址+38h DWORD SectionAlignment; // 内存中的区块的对齐大小+3Ch DWORD FileAlignment; // 文件中的区块的对齐大小+40h WORD MajorOperatingSystemVersion; // 要求操作系统最低版本号的主版本号+42h WORD MinorOperatingSystemVersion; // 要求操作系统最低版本号的副版本号+44h WORD MajorImageVersion; // 可运行于操作系统的主版本号+46h WORD MinorImageVersion; // 可运行于操作系统的次版本号+48h WORD MajorSubsystemVersion; // 要求最低子系统版本的主版本号+4Ah WORD MinorSubsystemVersion; // 要求最低子系统版本的次版本号+4Ch DWORD Win32VersionValue; // 莫须有字段,不被病毒利用的话一般为0+50h DWORD SizeOfImage; // 映像装入内存后的总尺寸+54h DWORD SizeOfHeaders; // 所有头+ 区块表的尺寸大小+58h DWORD CheckSum; // 映像的校检和+5Ch WORD Subsystem; // 可执行文件期望的子系统+5Eh WORD DllCharacteristics; // DllMain()函数何时被调用,默认为0+60h DWORD SizeOfStackReserve; // 初始化时的栈大小+64h DWORD SizeOfStackCommit; // 初始化时实际提交的栈大小+68h DWORD SizeOfHeapReserve; // 初始化时保留的堆大小+6Ch DWORD SizeOfHeapCommit; // 初始化时实际提交的堆大小+70h DWORD LoaderFlags; // 与调试有关,默认为0+74h DWORD NumberOfRvaAndSizes; // 下边数据目录的项数,这个字段自Windows NT 发布以来// 一直是16+78h IMAGE_DATA_DIRECTORYDataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];// 数据目录表} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;事实上,这个结构中的大部分字段都不重要,大家可以从注释中理解它们的含义,小甲鱼将比较重要的字段在下边跟大家详细讲解。
另外,这玩意千万不要去背啊,我们要把绝大多数的时间拿来改变,而不是记住。
不用做笔记,把这篇文章转载到您的博客就行(最好注明:小甲鱼是帅哥)吼吼^_^●AddressOfEntryPoint字段指出文件被执行时的入口地址,这是一个RVA地址(RVA的含义在下一节中详细介绍)。
如果在一个可执行文件上附加了一段代码并想让这段代码首先被执行,那么只需要将这个入口地址指向附加的代码就可以了。
●ImageBase字段指出文件的优先装入地址。
也就是说当文件被执行时,如果可能的话,Windows优先将文件装入到由ImageBase字段指定的地址中,只有指定的地址已经被**模块使用时,文件才被装入到**地址中。
链接器产生可执行文件的时候对应这个地址来生成机器码,所以当文件被装入这个地址时不需要进行重定位操作,装入的速度最快,如果文件被装载到**地址的话,将不得不进行重定位操作,这样就要慢一点。
对于EXE文件来说,由于每个文件总是使用独立的虚拟地址空间,优先装入地址不可能被**模块占据,所以EXE总是能够按照这个地址装入,这也意味着EXE文件不再需要重定位信息。
对于DLL文件来说,由于多个DLL文件全部使用宿主EXE文件的地址空间,不能保证优先装入地址没有被**的DLL使用,所以DLL文件中必须包含重定位信息以防万一。
因此,在前面介绍的IMAGE_FILE_HEADER 结构的Characteristics 字段中,DLL 文件对应的IMAGE_FILE_RELOCS_STRIPPED 位总是为0,而EXE文件的这个标志位总是为1。
在链接的时候,可以通过对link.exe指定/base:address选项来自定义优先装入地址,如果不指定这个选项的话,一般EXE文件的默认优先装入地址被定为00400000h,而DLL文件的默认优先装入地址被定为10000000h。
●SectionAlignment 字段和FileAlignment字段SectionAlignment字段指定了节被装入内存后的对齐单位。
也就是说,每个节被装入的地址必定是本字段指定数值的整数倍。
而FileAlignment字段指定了节存储在磁盘文件中时的对齐单位。
●Subsystem字段指定使用界面的子系统,它的取值如表17.3所示。
这个字段决定了系统如何为程序建立初始的界面,链接时的/subsystem:**选项指定的就是这个字段的值,在前面章节的编程中我们早已知道:如果将子系统指定为Windows CUI,那么系统会自动为程序建立一个控制台窗口,而指定为Windows GUI的话,窗口必须由程序自己建立。
界面子系统的取值和含义取Windows.inc中的预定义值含义值0IMAGE_SUBSYSTEM_UNKNOWN未知的子系统1IMAGE_SUBSYSTEM_NATIVE不需要子系统(如驱动程序)2IMAGE_SUBSYSTEM_WINDOWS_GUI Windows图形界面3IMAGE_SUBSYSTEM_WINDOWS_CUI Windows控制台界面5IMAGE_SUBSYSTEM_OS2_CUI OS2控制台界面7IMAGE_SUBSYSTEM_POSIX_CUI POSIX控制台界面8IMAGE_SUBSYSTEM_NATIVE_WINDOWS不需要子系统9IMAGE_SUBSYSTEM_WINDOWS_CE_GUIWindows CE图形界面●DataDirectory字段这个字段可以说是最重要的字段之一,它由16个相同的IMAGE_DATA_DIRECTORY结构组成,虽然PE文件中的数据是按照装入内存后的页属性归类而被放在不同的节中的,但是这些处于各个节中的数据按照用途可以被分为导出表、导入表、资源、重定位表等数据块,这16个IMAGE_DATA_DIRECTORY结构就是用来定义多种不同用途的数据块的(如表17.4所示)。
IMAGE_DATA_DIRECTORY结构的定义很简单,它仅仅指出了某种数据块的位置和长度。
IMAGE_DATA_DIRECTORY STRUCTVirtualAddress DWORD ? ;数据的起始RVAisize DWORD ? ;数据块的长度IMAGE_DATA_DIRECTORY ENDS数据目录列表的含义索引索引值在Windows.inc中的预定义值对应的数据块0IMAGE_DIRECTORY_ENTRY_EXPORT导出表1IMAGE_DIRECTORY_ENTRY_IMPORT导入表2IMAGE_DIRECTORY_ENTRY_RESOURCE资源3IMAGE_DIRECTORY_ENTRY_EXCEPTION异常(具体资料不详)4IMAGE_DIRECTORY_ENTRY_SECURITY安全(具体资料不详)5IMAGE_DIRECTORY_ENTRY_BASERELOC重定位表6IMAGE_DIRECTORY_ENTRY_DEBUG调试信息7IMAGE_DIRECTORY_ENTRY_ARCHITECTURE版权信息8IMAGE_DIRECTORY_ENTRY_GLOBALPTR具体资料不详9IMAGE_DIRECTORY_ENTRY_TLS Thread Local Storage10IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG具体资料不详11IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT具体资料不详12IMAGE_DIRECTORY_ENTRY_IAT导入函数地址表13IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT具体资料不详14IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR具体资料不详15未使用在PE文件中寻找特定的数据时就是从这些IMAGE_DATA_DIRECTORY结构开始的,比如要存取资源,那么必须从第3个IMAGE_DATA_DIRECTORY结构(索引为2)中得到资源数据块的大小和位置;同理,如果要查看PE文件导入了哪些DLL文件的哪些API函数,那就必须首先从第2个IMAGE_DATA_DIRECTORY结构得到导入表的位置和大小。