【2021.01.15】重定位表

重定位表是PE文件结构的一部分,用于解决不同DLL中相同全局变量地址冲突的问题。当多个DLL加载时,由于加载顺序可能导致地址冲突,重定位表通过记录和修改这些冲突的地址,确保每个DLL的全局变量能在正确的位置被访问。重定位表由多个重定位块组成,每个块负责修复4KB物理页内的地址。表的结束由8个连续的00字节标记。每个重定位项使用12位表示在4KB页内的偏移,高4位用于辅助判断是否需要重定位。
摘要由CSDN通过智能技术生成

什么是重定位表?为什么要有重定位表?

  1. 如上图 A.DLL 和 B.DLL 中某个或多个的全局变量编译时可能是相同的内存地址。
  2. 如果 A.DLL 先行加载,其中的某个全局变量抢占到了 0x00410000 这个内存地址。
  3. B.DLL 因为后加载的原因,是从 0x00420000 处开始展开。此时,B.DLL 中如果有全局变量的地址也是 0x00410000 这个内存地址,就会出问题。
  4. 因为在调用 B.DLL 中某个全局变量的时候,如 0x00410000 地址的变量,但因为 B.DLL 是从 0x00420000处开始展开的,所以就无法调用。
  5. 那么这个时候就需要有一张表,记录并修改冲突的项目,例如把 B.DLL 中的 0x00410000 改为 0x00420000,那么就能正常使用了。

重定位表的位置

PE结构图:IMAGE_OPTIONAL_HEADER->DataDirectory 中的 IMAGE_DIRECTORY_ENTRY_BASERELOC 成员,就是重定位表。

typedef struct _IMAGE_BASE_RELOCATION {
    DWORD   VirtualAddress;
    DWORD   SizeOfBlock;        //以字节为单位,它有多大代表一个重定位块有多大
} IMAGE_BASE_RELOCATION;
typedef IMAGE_BASE_RELOCATION UNALIGNED * PIMAGE_BASE_RELOCATION;

什么是重定位块?

一个PE文件中需要修正的地方是有很多的,需要分成很多块来记录。

根据什么来设计为一块一块的?

  1. 内存以 4KB 为单位,也就是在物理内存上,每个内存的大小划分是 4KB,4KB为一个物理页,重定位表也是如此设计。
  2. 一个物理页创建一张重定位表,每张重定位表只负责修复当前物理页上的相关内容,与其他物理页不影响。

如何确定重定位表结束?

直到出现连续 8 个为 00 的字节,代表当前进程重定位表结束。

  • 每个物理页(4KB)重定位表中的地址,在4KB中的偏移需要多少个二进制位才能找到偏移?2的12次方 = 4KB
  • 物理页只有 4KB,如果想找到物理页中的任何一个地址,只需要 12 个二进制位就够了,但是占用了 16 个位。
  • 也就是说,虽然重定位表中真正要修正的数据每个是 2 字节(16 个二进制位),但是真正使用到的只有 16 个二进制位中的 12 个二进制位。
  • 16 个二进制位的高 4 位挪作他用(图中标红的部分),当操作系统真正要修复某个位置的时候,先判断高 4 位。
  • 只有当高 4 位的值等于 3 的时候,才意味着 VirtualAddress + 低12位 才是真正要修复的位置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值