一、PE 文件加载完整流程(10步核心)
- 创建进程内核对象
系统通过CreateProcess创建进程对象,分配PID、句柄、内存空间。 - 创建主线程对象
分配主线程栈、线程环境块TEB,挂起等待加载完成。 - 读取并校验DOS头、NT头
检查MZ、PE签名,判断是否有效32/64位PE。 - 解析区段表,映射内存
按Section对齐内存,将代码、数据、资源分别映射到虚拟地址。 - 修复基址重定位(Relocation)
首选基址被占用时,根据.reloc表修正绝对地址。 - 遍历导入表IAT,加载依赖DLL
递归加载所有依赖DLL,解析函数地址,填入IAT。 - 执行DLL入口函数 DllMain
按加载顺序依次调用DLL_PROCESS_ATTACH。 - 初始化TLS(线程本地存储)
执行TLS回调,早于EP执行,逆向常用来反调试。 - 设置入口点EP(AddressOfEntryPoint)
定位程序真正开始执行的代码位置。 - 唤醒主线程,从EP开始执行
进程启动完成,跑用户代码。
二、逆向必懂关键结构(一句话)
- PEB:进程环境块,保存加载模块、IAT、LDR链表。
- LDR:管理已加载模块链表(InLoad/InMem/InInit)。
- IAT:导入函数地址表,调用系统函数全靠它。
- Relocation:基址被占时修正绝对地址。
- TLS:早于入口执行,常用于反调试。
三、总结
PE加载就是:校验头部→映射内存→重定位→填IAT→跑DllMain→执行TLS→从EP启动。