3.5 数据结构字段详解
3.5.1 PE头IMAGE_NT_HEADER的字段
1.IMAGE_NT_HEADER.Signature
+0000h,双字。PE文件标识,被定义为00004550h。也就是“P”“E”加上两个0,这也是PE这个称呼的由来。如果更改其中任何一个字节,操作系统就无法把该文件识别为正确的PE文件。通过修改这个字段,会导致PE文件在32位系统中加载失败,但由于这个文件的其他部分(特别是DOS头)还没有被破坏,系统还是可以识别出其为DOS系统下的可执行程序,并通过调用纯DOS环境来运行DOS Stub中的程序代码。
如果你确认操纵系统中的某个PE文件携带病毒,并且开机后会被加载进内存运行,最简单的处理办法是通过WindowsPE盘启动系统。在系统中找到病毒文件,使用记事本简单地修改其中任何一个字符,保存文件,重新开机后即可防止病毒文件被加载。
2.IMAGE_NT_HEADER.FileHeader
+0004h,结构。该结构指向IMAGE_FILE_HEADER,由于PE扩展自通用COFF规范,所以,该字段在官方文档中被称为标准COFF头。
3.IMAGE_NT_HEADER.OptionalHeader
+0018h,结构。该结构指向IMAGE_OPTIONAL_HEADER32。Windows操作系统可执行文件的大部分特性均在这个结构里呈现。因为符合COLL规范的”.obj”目标文件中该部分并不存在,所以该部分被称为OptionalHeader(可选的头部信息,简称 可选头),它是操作系统映象文件所独有的头部信息。
可选头又分为两部分,前10个字段原属于COFF,用来加载和运行一个可执行文件;后21个字段则是通过连接器加载的。他们作为PE扩展部分,用于描述可执行文件的一些信息,供PE加载器加载使用。
3.5.2 标准PE头IMAGE_FILE_HEADER的字段
4.IMAGE_FILE_HEADER.Machine
+0004h,单字。用来指定PE文件运行的平台。由于Windows最初设计为可以运行在Intel、Sun、Dec、IBM等多种硬件平台上,或者能模拟这些平台的软件环境中,而不同的硬件平台其指令的机器码不相同,因此为不同平台编译的EXE文件是无法通用的。假设将运行在Intel 386机器上的PE文件该字段设置为01f0h,既指定平台为IBM POWER PC(小尾方式),则系统会有下图所示提示:
5.IMAGE_FILE_HEADER.NumberOfSections
+0006h,单字。文件中存在的节的总数(XP中可以有0个节),数值不能小于1,也不能超过96。如果将该值设置为0,则系统装载时会提示不是有效的Win32程序。如果想在PE中增加或删除节,必须改变此处的值。
另外,这个值既不能比实际内存中多,也不能少,否则装载时会发生错误。
6.IMAGE_FILE_HEADER.TimeDateStamp
+0008h,双字。编译器创建此文件时的时间戳。低32位存放的值是自1970年1月1日00:00时开始到创建时间为止的总秒数。
该数值可以所以修改而不会影响程序的运行。所以,有的连接器在这里填入固定的值,有的则随意写入任何值,这对用户创建的文件并没有实际的意义。另外,这个时间与操作系统文件属性里看到的三个时间(创建时间、修改时间、访问时间)也没有任何联系。
7.IMAGE_FILE_HEADER.PointerToSymbolTable
+0010h,双字。COFF符号表的文件偏移。如果不存在COFF符号表,此值为0。对于映象文件来说,此值为0,因为微软已经不赞成在PE中使用COFF调试信息了。
8.IMAGE_FILE_HEADER.NumberOfSymbols
+0010h,双字。符号表中元素数目。对于映象文件来说,此值为0,主要用于调试。
9.IMAGE_FILE_HEADER.SizeOfOptionalHeader
+0014h,单字。指定结构IMAGE_OPTIONAL_HEADER32的长度,默认情况下这个值等于00e0h;如果是64位PE文件,该结构的默认大小为00F0h。
用户可以自己定义这个值的大小,不过需要注意两点:
1)改完之后,需要自行将文件中IMAGE_OPTIONAL_HEADER32