0218、Windows 逆向提升:导出表、导入表与重定位
这一部分是 PE 数据目录里最常用的三块:导出表、导入表、重定位表。导出表回答“我提供什么函数”,导入表回答“我依赖什么函数”,重定位回答“加载地址变了,哪些地方要修正”。
1、内容范围
| 小节 | 内容 | 复盘点 |
|---|---|---|
| 05.6 - 07.0 | 导出表 | DLL 导出、导出地址表、名称表、序号表、GetProcAddress |
| 07.1 - 07.7 | 导入表 | IAT/INT、导入名称、序号导入、导入地址修复 |
| 07.8 - 08.6 | 重定位 | 基址差值、重定位块、重定位项、模拟修复 |
2、导出表
导出表让别的模块能通过名称或序号找到 DLL 中的函数。
| 结构 | 作用 |
|---|---|
| Export Directory | 导出表总入口 |
| AddressOfFunctions | 函数地址表 |
| AddressOfNames | 函数名称表 |
| AddressOfNameOrdinals | 名称对应序号表 |
三表联动是导出表复盘重点:名称 -> 序号 -> 函数 RVA。
3、GetProcAddress 原理
GetProcAddress 本质上是在导出表里按名称或序号查找函数地址。复盘时关注:
- 目标模块基址。
- 导出目录 RVA。
- 名称表遍历。
- 序号表映射。
- 函数地址表取 RVA。
- 加模块基址得到 VA。
4、导入表
导入表记录当前 PE 依赖哪些 DLL 和函数。
| 项 | 说明 |
|---|---|
| Import Descriptor | 每个导入 DLL 一项 |
| Name | DLL 名称 |
| OriginalFirstThunk | INT,导入名称表 |
| FirstThunk | IAT,加载后保存真实函数地址 |
文件状态下 IAT/INT 可能相似;加载后 IAT 会被修成真实函数地址。
5、名称导入与序号导入
| 导入方式 | 特点 |
|---|---|
| 名称导入 | 可读性强,常见 |
| 序号导入 | 体积小,但可读性差 |
逆向时看到没有函数名,可能是序号导入或符号缺失。
6、重定位表
如果 PE 没有加载到首选 ImageBase,绝对地址需要修正。重定位表告诉加载器哪些位置要加上基址差值。
1 | delta = ActualBase - ImageBase |
7、重定位块
重定位表按页组织:
| 字段 | 含义 |
|---|---|
| PageRVA | 当前页 RVA |
| BlockSize | 当前块总大小 |
| Entries | 多个 2 字节重定位项 |
重定位项高 4 位是类型,低 12 位是页内偏移。
8、检测和防护视角
| 现象 | 说明 |
|---|---|
| IAT 指向异常区域 | 可能被 Hook 或修复异常 |
| 导出表移动 | 可能是保护壳、修改器或特殊样本 |
| 重定位缺失 | 模块可能必须固定基址加载 |
| 名称异常 | 混淆、转发导出、序号导入需要结合上下文判断 |
9、学习检查清单
| 检查项 | 状态 |
|---|---|
| 能说出导出三表的映射关系 | 待复盘 |
| 能解释 IAT 和 INT 的区别 | 待复盘 |
| 能说明加载器如何修复导入地址 | 待复盘 |
| 能解释重定位基址差值 | 待复盘 |
| 能遍历重定位块并理解类型/偏移 | 待复盘 |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Ruiqy~!






