PE结构
先贴一张结构图
PE 文件执行时 PE 装载器的操作流程
- 检查 DOS 头中 PE 头偏移,跳转至 PE 头位置.[E 文件被执行后,PE 装载器首先启动定位操作 —— 读取 DOS 头(DOS header)中记录的 PE 头(PE header)偏移量,确认该偏移位置后,直接跳转到 PE 头所在的内存地址,为后续验证 PE 头做准备。]
- 验证 PE 头有效性,跳转至 PE 头尾部[跳转至 PE 头后,PE 装载器进入验证环节:检查当前 PE 头的格式与标识是否符合规范(即判断 PE 头是否有效)。若验证通过,装载器会进一步跳转到 PE 头的尾部 —— 因 PE 头尾部与节表(Section Table)直接衔接,此跳转可快速衔接后续节表处理流程。]
- 读取节表信息,通过文件映射机制映射节段并设属性[PE 头尾部紧跟节表,装载器在完成 PE 头验证后,立即读取节表中的节段信息(如节段大小、位置等);随后采用文件映射机制处理节段:Windows 不会一开始就将整个 PE 文件读入物理内存,仅由装载器建立虚拟地址与 PE 文件的映射关系,仅当需要执行某内存页指令或访问某页数据时,才将对应页面从磁盘提交到物理内存(该机制确保文件装入速度不受文件大小显著影响);同时,装载器会根据节表中指定的规则,为映射到内存的节段设置对应的读写属性(如只读、可写、可执行等)。]
- 处理 PE 文件中的逻辑部分[待所有节段成功映射入内存后,PE 装载器进入后续逻辑处理阶段:针对 PE 文件中需动态关联的逻辑部分(典型如输入表 import table,用于关联外部函数与资源),继续执行解析、关联等操作,确保 PE 文件能正常调用外部资源,为最终执行指令奠定基础。]
分析一个程序
DOS头分成header和DOS存根。
如图2,e_lfanew指向PE头的位置。
例题
有两处被改动了
WZ –> MZ 90 –>80再用IDA打开。
发现可以正常打开了
1 | # 已知的 data 数组(37字节) |
1 | flag{Y0u_kn0w_what_1s_PE_File_F0rmat} |