参考:
https://zhuanlan.zhihu.com/p/47075612
https://docs.microsoft.com/zh-cn/windows/win32/debug/pe-format
<加密与解密 第4版>
<Windows PE 权威指南>
PE 基础
概念
PE文件是windows系统中遵循PE结构的文件,比如以.exe .dll为后缀名的文件以及系统驱动文件sys。
具体PE文件类型:
可执行系列:EXE,SCR;
驱动程序系列:SYS,VXD;
库系列:DLL,OCX,CPL,DRV;
对象文件系列:OBJ;
装载PE文件
https://blog.csdn.net/benny5609/article/details/1788067
装载一PE文件的主要步骤:
- 当PE文件被执行,PE装载器检查 DOS MZ header 里的 PE header 偏移量。如果找到,则跳转到 PE header。
- PE装载器检查 PE header 的有效性。如果有效,就跳转到PE header的尾部。
- 紧跟 PE header 的是节表。PE装载器读取其中的节信息,并采用文件映射方法将这些节映射到内存,同时付上节表里指定的节属性。
- PE文件映射入内存后,PE装载器将处理PE文件中类似 import table(引入表)逻辑部分
PE组成
PE文件大体分为两部分:
头 (包括下图中的DOS头,PE文件头,块表 Section Table)
主体 ( 块Section)。
Section又被翻译为节 故有节表 节体叫法.
PE文件头结构
PE文件头结构
PE头 IMAGE_NT_HEADERS
扩展PE头/可选头(IMAGE_OPTIONAL_HEADER32)
数据目录项 (IMAGE_DATA_DIRECTORY)
组成:
- 导出表、
- 导入表、
- 资源表、
- 异常处理表、
- 安全表、(Certificate Table)
- 重定位表、
- 调试表、
- 版权、
- 指针目录、
- TLS、
- 载入配置、
- 绑定输入目录、
- 导入地址表、
- 延迟载入、
- COM信息。
PE文件地址与VA(virtualAddress)之间的转换。
虚拟内存
文件偏移地址(File Offset Address) :文件相对于文件开头的偏移
装载基址(Image Base) :PE装入内存时的基地址,EXE在内存中的基地址是0x00400000,DLL的基地址是0x10000000,这些位置可以通过修改编译选项更改
虚拟内存地址 (Virtual Address, VA) :PE文件中的指令被装入内存后的地址,在Windows系统中,PE文件被系统加载器映射到内存中。每个程序都有自己的虚拟空间,这个虚拟空间的内存地址称为虚拟地址(Virtual Address,VA)。
相对虚拟地址(Relative Virtual Address,RVA) :相对虚拟地址是内存地址相对于映射基地址偏移量
虚拟内存地址、装载基址、相对虚拟地址之间的关系:
VA= Image base+ RVA
节偏移
节偏移 :PE文件中的数据按照磁盘数据标准存放,以0x200字节为基本单位进行组织,当PE文件装载到内存时,将按照内存数据标准存放,以0x1000字节为基本单位,所以文件偏移地址和相对虚拟内存会有细微的差别,这种差别称为节偏移
SectionAlignment : 内存当中的块对齐数,一般为0x1000。
FileAlignment :磁盘当中块对齐数,一般为0x200。
文件偏移地址、虚拟内存地址、装载基址、相对虚拟地址和节偏移之间的关系:
文件偏移地址 = 虚拟内存地址(VA)- 装载基址(ImageBase)- 节偏移
= RVA –节偏移
入口点(OEP)
入口点(Original Entry Point) : 首先明确一个概念就是OEP是一个RVA,然后使用OEP +Imagebase ==入口点的VA,通常情况下,OEP指向的不是main函数。
PE 文件磁盘与内存映像
PE文件不是作为单一内存映射文件,被载人内存是很重要的。Windows加载器(又称PE装载器)遍历PE文件并决定文件的哪一部分被映射,这种映射方式是将文件较高的偏移位置映射到较高的内存地址中。磁盘文件一旦被载入内存,磁盘上的数据结构布局和内存中的数据结构布局就是一致的。
当PE文件通过Windows加载器载人内存后,PE在内存中的版本称为模块(Module)。
映射文件的起始地址称为模块句柄(hModule),可以通过模块句柄访问内存中的其他数据结构。这个初始内存地址也称为基地址(ImageBase)。