这里只列出需要重点记忆的,完整的需要用到再去查阅,加粗的就是非常重要的
基础概念
- 基地址ImageBase:PE文件载入内存后,内存中的版本称为模块(Module),起始地址称为模块句柄(hModule)也成基地址(ImageBase)
- 虚拟地址VA:PE被装入内存后,每个程序都有自己的虚拟空间,虚拟空间的内存地址称为虚拟地址(VA)
- 相对虚拟地址RVA:是PE文件载入地址的偏移位置(偏移量)
- 公式:虚拟地址VA=基地址ImageBase+相对虚拟地址RVA
|DOS头|作用
|–|--
WORD e_magic| “MZ标记” 用于判断是否为可执行文件,值为0x5A4D
DWORD e_lfanew|PE头相对于文件的偏移,用于定位PE文件,在文件开始偏移3CH处
标准PE头 | 作用 |
---|---|
WORD Machine | 程序运行的CPU型号:0x0 任何处理器/0x14C 386及后续处理器 |
WORD NumberOfSections | 文件中存在的节的总数,如果要新增节或者合并节 就要修改这个值 |
DWORD TimeDateStamp | 时间戳:文件的创建时间(和操作系统的创建时间无关),编译器填写的 |
WORD SizeOfOptionalHeader | 可选PE头的大小,32位PE文件默认E0h 64位PE文件默认为F0h 大小可以自定义* |
WORD Characteristics | 每个位含义不同,根据每个位的0或者1共同组合一个16进制数 |
可选PE头 | 作用 |
---|---|
WORD **Magic | **说明文件类型:10B 32位下的PE文件 20B 64位下的PE文件 |
DWORD SizeOfCode | 所有代码节的和,必须是FileAlignment的整数倍 编译器填的 |
DWORD SizeOfInitializedData | 已初始化数据大小的和,必须是FileAlignment的整数倍 编译器填的 |
DWORD SizeOfUninitializedData | 未初始化数据大小的和,必须是FileAlignment的整数倍 编译器填的 |
DWORD AddressOfEntryPoint | 程序入口 |
DWORD BaseOfCode | 代码开始的基址 |
DWORD BaseOfData | 数据开始的基址 |
DWORD ImageBase | 内存镜像基址 |
DWORD SectionAlignment* | 内存对齐,一般为1000h |
DWORD FileAlignment | 文件对齐,以前老编译器为200H,现在一般为1000H |
DWORD SizeOfImage | 内存中整个PE文件的映射的尺寸,可以比实际的值大,但必须是SectionAlignment的整数倍 |
DWORD SizeOfHeaders | 所有头+节表按照文件对齐后的大小,否则加载会出错 |
DWORD CheckSum | 校验和,看程序是否被修改过 |
DWORD SizeOfStackReserve | 初始化时保留的栈大小 |
DWORD SizeOfStackCommit | 实际提交的栈大小 |
DWORD SizeOfHeapReserve | 初始化保留的堆大小 |
DWORD SizeOfHeapCommit | 实际提交的堆大小 |
DWORD NumberOfRvaAndSizes | 目录项数目,现在一般是16,包括导入表,导出表,重定向表加在一起的数目 |