这一部分是 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 本质上是在导出表里按名称或序号查找函数地址。复盘时关注:

  1. 目标模块基址。
  2. 导出目录 RVA。
  3. 名称表遍历。
  4. 序号表映射。
  5. 函数地址表取 RVA。
  6. 加模块基址得到 VA。

4、导入表

导入表记录当前 PE 依赖哪些 DLL 和函数。

项 说明
Import Descriptor 每个导入 DLL 一项
Name DLL 名称
OriginalFirstThunk INT,导入名称表
FirstThunk IAT,加载后保存真实函数地址

文件状态下 IAT/INT 可能相似;加载后 IAT 会被修成真实函数地址。

5、名称导入与序号导入

导入方式 特点
名称导入 可读性强,常见
序号导入 体积小,但可读性差

逆向时看到没有函数名,可能是序号导入或符号缺失。

6、重定位表

如果 PE 没有加载到首选 ImageBase,绝对地址需要修正。重定位表告诉加载器哪些位置要加上基址差值。

1
2
delta = ActualBase - ImageBase
修正地址 = 原值 + delta

7、重定位块

重定位表按页组织:

字段 含义
PageRVA 当前页 RVA
BlockSize 当前块总大小
Entries 多个 2 字节重定位项

重定位项高 4 位是类型,低 12 位是页内偏移。

8、检测和防护视角

现象 说明
IAT 指向异常区域 可能被 Hook 或修复异常
导出表移动 可能是保护壳、修改器或特殊样本
重定位缺失 模块可能必须固定基址加载
名称异常 混淆、转发导出、序号导入需要结合上下文判断

9、学习检查清单

检查项 状态
能说出导出三表的映射关系 待复盘
能解释 IAT 和 INT 的区别 待复盘
能说明加载器如何修复导入地址 待复盘
能解释重定位基址差值 待复盘
能遍历重定位块并理解类型/偏移 待复盘