PE文件格式的概要:
DOS MZ header |
DOS stub |
PE header |
Section table |
Section 1 |
Section 2 |
Section ... |
Section n |
所有 PE文件(甚至32位的 DLLs) 必须以一个简单的 DOS MZ header 开始。
PE header 是PE相关结构IMAGE_NT_HEADERS的简称。在执行时,PE装载器将从 DOS MZ header 中找到 PE header 的起始偏移量。因而跳过了 DOS stub 直接定位到真正的文件头 PE header。
PE文件的真正内容划分成块,称之为sections(节)。每节是一块拥有共同属性的数据,节的划分是基于各组数据的共同属性:,而不是逻辑概念。也就是说节名称仅仅是个区别不同节的符号而已,类似"data", "code"的命名只为了便于识别,惟有节的属性设置决定了节的特性和功能,当PE装载器映射节内容时,它会检查相关节属性并置对应内存块为指定属性。
section table(节表),类似与磁盘中的根目录,节表里有一个结构数组,有多少个节,就有多少个数据成员。每一个成员详细地说明每一个节的对应的属性、文件偏移量、虚拟偏移量等。
装载一PE文件的主要步骤:
- 当PE文件被执行,PE装载器检查 DOS MZ header 里的 PE header 偏移量。如果找到,则跳转到 PE header。
- PE装载器检查 PE header 的有效性。如果有效,就跳转到PE header的尾部。
- 紧跟 PE header 的是节表。PE装载器读取其中的节信息,并采用文件映射方法将这些节映射到内存,同时付上节表里指定的节属性。
- PE文件映射入内存后,PE装载器将处理PE文件中类似 import table(引入表)逻辑部分。