PE文件格式详解(三)――DOS Header & PE Header

上一节中我们对PE文件的各个部分的作用有了一个总体的认识,从这节起我们会对PE文件的每个部分作更进一步的解释,当然别忘记了上一节中我提出的两个问题。

1.DOS MZ header 和 DOS Stub:

        所有 PE文件(甚至32位的 DLLs) 必须以一个简单的 DOS MZ header 开始。我们通常对此结构没有太大兴趣。有了它,一旦程序在DOS下执行,DOS就能识别出这是有效的执行体,然后运行紧随 MZ header 之后的 DOS stub。DOS stub实际上是个有效的 EXE,在不支持 PE文件格式的操作系统中,它将简单显示一个错误提示,类似于字符串 "This program requires Windows" 或者程序员可根据自己的意图实现完整的 DOS代码。通常我们也不对 DOS stub 太感兴趣: 因为大多数情况下它是由汇编器/编译器自动生成。通常,它简单调用中断21h服务9来显示字符串"This program cannot run in DOS mode"。在Window95下运行32位程序的时候这个部分并不会被加载器映射的线性地址空间,当Win32 加载器把一个PE 文件映像到内存,内存映像文件(memory mapped file)的第一个字节对应到DOS Stub 的第一个字节。WINNT.H 为DOS stub 表头DOS MZ header定义了一个结构,第一个域 e_magic ,被称为魔术数字,它被用于表示一个MS-DOS兼容的文件类型,其作用类似于PE header中的Signature域,所有MS-DOS兼容的可执行文件都将这个值设为0x5A4D,表示ASCII字符MZ。MS-DOS头部之所以有的时候被称为MZ头部,就是这个缘故。还有许多其它的域对于MS-DOS操作系统来说都有用,但是对于Windows NT来说,这个结构中只有一个有用的域——最后一个域 e_lfnew ,PE头部就是由它定位的。循此我们将非常容易找到PE头部,它是一个相对偏移值(或说是RVA),指向真正的PE头部(PE header)。为了获得指针,你必须为RVA 加上image 的基地址:

   pNTHeader = dosHeader + dosHeader->e_lfanew;

有了这个指向PE Header的指针我们就可以取得很多有用的信息了,既然我们研究的是PE文件格式,因此PE Header才是我们研究的重点。总之,DOS MZ header和 DOS Stub之间的关系相当于PE header和 EXE或者DLL之间的关系。

    2.PE Header:

         PE header 是PE相关结构 IMAGE_NT_HEADERS 的简称,其中包含了许多PE装载器用到的重要域。当我们更加深入研究PE文件格式后,将对这些重要域耳目能详。执行体在支持PE文件结构的操作系统中执行时,PE装载器将从 DOS MZ header 中找到 PE header 的起始偏移量。因而跳过了 DOS stub 直接定位到真正的文件头 PE header。PE头部整个是个IMAGE_NT_HEADERS 结构,定义于WINNT.H。这个结构正是Windows 95 的module database(“模块”的概念在第一节中说过了,操作系统就是利用这个结构感知“模块”的存在、获得“模块”的信息等;这个结构我会在以后的“模块”学习当中提及)。每一个被载入的EXE 或DLL 都以一个IMAGE_NT_HEADERS 结构表现出来。此结构有一个DWORD 和两个子结构:

DWORD Signature;

IMAGE_FILE_HEADER FileHeader;

IMAGE_OPTIONAL_HEADER OptionalHeader;

(1) 对于PE格式的文件Signature 字段内容应该是ASCII 的PE/0/0。

(2) IMAGE_FILE_HEADER FileHeader:

Field name

Meanings

Machine

该文件运行所要求的CPU。对于Intel平台,该值是IMAGE_FILE_MACHINE_I386 (14Ch)。我们尝试了LUEVELSMEYER的pe.txt声明的14Dh和14Eh,但Windows不能正确执行。看起来,除了禁止程序执行之外,本域对我们来说用处不大。

NumberOfSections

文件的节数目。如果我们要在文件中增加或删除一个节,就需要修改这个值。

TimeDateStamp

文件创建日期和时间。我们不感兴趣。

PointerToSymbolTable

用于调试。

NumberOfSymbols

用于调试。

SizeOfOptionalHeader

指示紧随本结构之后的 OptionalHeader 结构大小,必须为有效值。

Characteristics

关于文件信息的标记,比如文件是exe还是dll。

      IMAGE_FILE_HEADER结构比较简单,也比较容易理解,在此不做过多的解释;简言之,只有三个域对我们有一些用: Machine, NumberOfSections 和 Characteristics。通常不会改变 Machine 和Characteristics 的值,但如果要遍历节表就得使用 NumberOfSections。

(3)   比较复杂也更有趣的是第三个东东即:IMAGE_OPTIONAL_HEADER,现在我们学习 IMAGE_NT_HEADERS 中的最后成员optional header 结构,它包含了PE文件的逻辑分布信息。该结构共有31个域,一些是很关键,另一些不太常用。这里只介绍那些真正有用的域。

Field

Meanings

AddressOfEntryPoint

PE装载器准备运行的PE文件的第一个指令的RVA。若您要改变整个执行的流程,可以将该值指定到新的RVA,这样新RVA处的指令首先被执行。

ImageBase

PE文件的优先装载地址。比如,如果该值是400000h,PE装载器将尝试把文件装到虚拟地址空间的400000h处。字眼"优先"表示若该地址区域已被其他模块占用,那PE装载器会选用其他空闲地址。

SectionAlignment

内存中节对齐的粒度。例如,如果该值是4096 (1000h),那么每节的起始地址必须是4096的倍数。若第一节从401000h开始且大小是10个字节,则下一节必定从402000h开始,即使401000h和402000h之间还有很多空间没被使用。

FileAlignment

文件中节对齐的粒度。例如,如果该值是(200h),,那么每节的起始地址必须是512的倍数。若第一节从文件偏移量200h开始且大小是10个字节,则下一节必定位于偏移量400h: 即使偏移量512和1024之间还有很多空间没被使用/定义。

MajorSubsystemVersion
MinorSubsystemVersion

win32子系统版本。若PE文件是专门为Win32设计的,该子系统版本必定是4.0否则对话框不会有3维立体感。

SizeOfImage

内存中整个PE映像体的尺寸。它是所有头和节经过节对齐处理后的大小。

SizeOfHeaders

所有头+节表的大小,也就等于文件尺寸减去文件中所有节的尺寸。可以以此值作为PE文件第一节的文件偏移量。

Subsystem

NT用来识别PE文件属于哪个子系统。 对于大多数Win32程序,只有两类值: Windows GUI 和 Windows CUI (控制台)。

SizeOfStackReserve

线程初始堆栈的保留大小。

SizeOfStackCommit

一开始即被提交(committed)给线程初始堆栈的内存数量。

SizeOfHeapReserve

保留给最初的process heap 的虚拟内存数量。

SizeOfHeapCommit

一开始即被提交(committed)给process heap 的内存数量。

DataDirectory

IMAGE_DATA_DIRECTORY 结构数组。每个结构给出一个重要数据结构的RVA,比如引入地址表等。

上面表格里最难理解的也是很重要的一个域是最后一个,即:DataDirectory;它是一个结构数组,它一共包含16个元素即共含16个结构;每一个结构对应于一个section(注意这里的section是按照第一节中按作用进行划分的section,不是最终生成的PE文件中包含的节),结构中的两个域分别描述了该section的 RVA 和 SIZE; 这样一来加载器就能够通过这个数组迅速在image 中找到特定的section,后面讲到的导入表,引出表都要用到这个数组中相应的元素,到时候还会有进一步的解释。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值