Windows逆向工程提升之IMAGE_BASE_RELOCATION
- 公开视频 -> 链接点击跳转公开课程
- 博客首页 -> 链接点击跳转博客主页
目录
重定位的概念与作用
什么是重定位?
为什么需要重定位?
IMAGE_RELOCATION 结构详解
结构定义
字段解析
重定位类型(Relocation Type)
重定位表的工作流程
加载器处理步骤
示例计算
图解示例
重定位表结构解析
绝对地址数据引用
重定位的概念与作用
什么是重定位?
- 定义:当 PE 文件(如 DLL 或 EXE)无法加载到预设的基地址(ImageBase)时,需调整代码和数据中的绝对地址,确保程序正确运行。
- 核心机制:通过 重定位表(Relocation Table) 记录需要修正的地址偏移。
- 应用场景:
- ASLR(地址空间布局随机化):现代操作系统随机化基址以增强安全性。
- DLL 冲突:多个模块可能竞争同一基地址。
- 动态加载:通过 LoadLibrary 加载到非默认地址。
为什么需要重定位?
- 基址冲突:若两个 DLL 的 ImageBase 相同,后加载的需调整地址。
- 内存灵活性:允许程序在任意内存位置运行。
- 安全需求:ASLR 依赖重定位表实现基址随机化。
IMAGE_RELOCATION 结构详解
结构定义
重定位表由多个 重定位块(Block) 组成,每个块对应一个内存页(4KB),结构定义为 IMAGE_BASE_RELOCATION:
typedef struct _IMAGE_BASE_RELOCATION {DWORD VirtualAddress; // 块的起始 RVA(内存页基址)DWORD SizeOfBlock; // 块总大小(包括本结构和后续条目)// 后续为 WORD 类型的条目(TypeOffset)
} IMAGE_BASE_RELOCATION, *PIMAGE_BASE_RELOCATION;
字段解析
字段名 | 描述 |
VirtualAddress | 当前块的起始 RVA,所有条目偏移均相对于此地址。 |
SizeOfBlock | 块总大小(字节),包含结构头和后续条目。 |
TypeOffset | 每个条目为 2 字节(WORD): - 高 4 位:重定位类型(如 IMAGE_REL_BASED_HIGHLOW) - 低 12 位:相对于 VirtualAddress 的偏移值。 |
重定位类型(Relocation Type)
类型值 | 宏定义 | 说明 |
0 | IMAGE_REL_BASED_ABSOLUTE | 无操作,用于填充对齐。 |
3 | IMAGE_REL_BASED_HIGHLOW | 修正 32 位地址(低地址 + 高地址调整)。 |
9 | IMAGE_REL_BASED_DIR64 | 修正 64 位地址(用于 64 位 PE 文件)。 |
重定位表的工作流程
加载器处理步骤
- 尝试加载到 ImageBase:若成功,无需重定位。
- 计算 Delta 值:
- Delta = ActualBase - ImageBase。
- 遍历重定位块:
- 对每个条目中的偏移地址加上 Delta。
- 修正地址:
- 修改代码或数据中的绝对地址。
示例计算
- 原始地址:0x00401000(基于 ImageBase=0x00400000)。
- 实际基址:0x00500000(Delta=0x00100000)。
- 修正后地址:0x00401000 + 0x00100000 = 0x00501000。