云题海 - 专业文章范例文档资料分享平台

当前位置:首页 > PE文件

PE文件

  • 62 次阅读
  • 3 次下载
  • 2025/6/16 7:53:42

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,后面讲到的导入表,引出表都要用到这个数组中相应的元素,到时候还会有进一步的解释。

PE文件格式详解(四)――Section Table(节表)

到本节为止,我们已经学了许多关于 DOS header 和 PE header 的知识。接下来就该轮到 section table(节表)了。节表其实就是紧挨着 PE header 的一结构数组,它的作用我们在前面已经说过了。该数组成员的数目由 file header (IMAGE_FILE_HEADER) 结构中 NumberOfSections 域的域值来决定。节表结构又命名为 IMAGE_SECTION_HEADER。我们把它的主要成员列表如下: Field Meanings Name1

事实上本域的名称是\,只是\已被MASM用作关键字,所以我们只能用\代替。这儿的节名长不超过8字节。记住节名仅仅是个标记而已,我们选择任何名字甚至空着也行,注意这里不用null结束。命名不是一个ASCIIZ字符串,所以不用null结尾。 VirtualAddress

本节的RVA(相对虚拟地址)。PE装载器将节映射至内存时会读取本值,因此如果域值是1000h,而PE文件装在地址400000h处,那么本节就被载到401000h。 SizeOfRawData

经过文件对齐处理后节尺寸,PE装载器提取本域值了解需映射入内存的节字节数。(译者注: 假设一个文件的文件对齐尺寸是0x200,如果前面的 VirtualSize域指示本节长度是0x388字节,则本域值为0x400,表示本节是0x400字节长)。 PointerToRawData

这是节基于文件的偏移量,PE装载器通过本域值找到节数据在文件中的位置。 Characteristics

包含标记以指示节属性,比如节是否含有可执行代码、初始化数据、未初始数据,是否可写、可读等。

好的,现在PE文件的前半部分结构我们已经了解的差不多了,下面就让我们模拟一下加载器加载PE文件的过程吧: 加载器加载PE文件的主要步骤:

1. 当PE文件被执行,PE装载器检查 DOS MZ header 里的 PE header 偏

移量。如果找到,则跳转到 PE header。

2. PE装载器检查 PE header 的有效性。如果有效,就跳转到PE header

的尾部。 3. 紧跟 PE header 的是节表。PE装载器读取其中的节信息,并采用文件

映射方法将这些节映射到内存,同时付上节表里指定的节属性。 4. PE文件映射入内存后,PE装载器将处理PE文件中类似 import table

(引入表)逻辑部分。 加载器检查PE文件有效性步骤总结如下:

1. 首先检验文件头部第一个字的值是否等于 IMAGE_DOS_SIGNATURE,是

则 DOS MZ header 有效。

2. 一旦证明文件的 DOS header 有效后,就可用e_lfanew来定位 PE

header 了。

3. 比较 PE header 的第一个字的值是否等于 IMAGE_NT_HEADER。如果前

后两个值都匹配,那我们就认为该文件是一个有效的PE文件。 现在我们已知晓 IMAGE_SECTION_HEADER 结构,再来模拟一下 PE装载器的工作吧:

1. 读取 IMAGE_FILE_HEADER 的 NumberOfSections域,知道文件的节数

目。

2. SizeOfHeaders 域值作为节表的文件偏移量,并以此定位节表。 3. 遍历整个结构数组检查各成员值。

4. 对于每个结构,我们读取PointerToRawData域值并定位到该文件偏移

量。然后再读取SizeOfRawData域值来决定映射内存的字节数。将

VirtualAddress域值加上ImageBase域值等于节起始的虚拟地址。然后就准备把节映射进内存,并根据Characteristics域值设置属性。 5. 遍历整个数组,直至所有节都已处理完毕。 遍历节表的步骤:

1. PE文件有效性校验。

2. 定位到 PE header 的起始地址。

3. 从 file header 的 NumberOfSections域获取节数。

4. 通过两种方法定位节表: ImageBase+SizeOfHeaders 或者 PE header

的起始地址+ PE header结构大小。 (节表紧随 PE header)。如果不是使用文件映射的方法,可以用SetFilePointer 直接将文件指针定位到节表。节表的文件偏移量存放在 SizeOfHeaders域里。(SizeOfHeaders 是 IMAGE_OPTIONAL_HEADER 的结构成员) 5. 处理每个 IMAGE_SECTION_HEADER 结构。

好的,到此为止我们已经清楚了加载器加载PE文件的大部分过程,但是别忘了我们的问题,现在问题还没有解决,要解决这个问题就好弄清楚后面两节:Import Table和Export Table,这两节是最重要的当然也是最复杂的。

PE文件格式详解(五)――Improt Table(引入表)

这节即将学习的Import Table和下节的Export Table关系密切,两者联合起来就可以解决我们开始提出的问题。在说明Import Table和Export Table的作用之前先让我们明白编译器是如何处理我们调用外部库函数的。在PE 文件中,当你调用另一模块中的函数(例如USER32.DLL 中的GetMessage),编译器制造出来的CALL 指令并不会把控制权直接传给DLL 中的函数,而是传给一个JMP DWORD PTR [XXXXXXXX] 指令,后者也位于.text 中。JMP 指令跳到一个地址去,此地址储存在.idata 的一个DWORD之中。这个DWORD 内含该函数的真正地址(函数进入点),如图1 所示

那么,这样做有什么好处呢?试想一下,如果CALL指令后面跟的直接就是DLL中的函数地址,那么加载器就需要修补每一个调用DLL 的指令。而现在PE 载入器需要做的,就只是把DLL 函数的真实地址放到.idata 的那个DWORD 之中,根本就没有程序代码需要修补。嗯,现在比较清除了,加载器首先要知道所加载的程序调用了哪些DLL的哪些函数,然后找出这些函数的地址,把他们添入到.idata 的那些DWORD 之中。那么加载器如何知道所加载的程序调用了哪些DLL的哪些函数,这就是Import Table的作用;加载器又是如何找出这些函数的地址呢,这又是Export Table的作用。现在两者的作用都很清除了,剩下的关键问题就是PE加载其如何利用这两个东东来完成上面的任务,完成了这个任务也就解决了我们开始提出的问题。这节我们先讨论前半部分,也就是加载器如何利用Import Table找出所加载的程序调用了哪些DLL的哪些函数。

搜索更多关于: PE文件 的文档
  • 收藏
  • 违规举报
  • 版权认领
下载文档10.00 元 加入VIP免费下载
推荐下载
本文作者:...

共分享92篇相关文档

文档简介:

ImageBase PE文件的优先装载地址。比如,如果该值是400000h,PE装载器将尝试把文件装到虚拟地址空间的400000h处。字眼\优先\表示若该地址区域已被其他模块占用,那PE装载器会选用其他空闲地址。 SectionAlignment 内存中节对齐的粒度。例如,如果该值是4096 (1000h),那么每节的起始地址必须是4096的倍数。若第一节从401000h开始且大小是10个字节,则下一节必定从402000h开始,即使401000h和402000h之间还有很多空间没被使用。 FileAlignment 文件中节对齐的粒度。例如,如果该值是(200h),,那么每节的起始地址必须是512的倍数。若第一节从文件偏移量200h开始且大小是10个字节,则下一节必定位于偏移量400h: 即使偏移量512和1024之间还有很多空间没被使用/定

× 游客快捷下载通道(下载后可以自由复制和排版)
单篇付费下载
限时特价:10 元/份 原价:20元
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信:fanwen365 QQ:370150219
Copyright © 云题海 All Rights Reserved. 苏ICP备16052595号-3 网站地图 客服QQ:370150219 邮箱:370150219@qq.com