这一部分是 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 的区别 待复盘
能说明加载器如何修复导入地址 待复盘
能解释重定位基址差值 待复盘
能遍历重定位块并理解类型/偏移 待复盘