重定位表

首先我们要知道PE文件在映射进内存的时候有一个默认基址保存在可选头的ImageBase中

所以每次在映射进内存的时候都会在这个地址进行映射,都是所有的dll的默认基址都是一样的,如果一个dll的默认基址已经被其他dll占据了怎么办。只能映射到别的地方。从而ImageBase中的值就没有了参考价值。

程序中有许多常量值是按照基址为ImageBase编写的,

Offset        HEX          Assembly
10001000      55           push ebp
10001001      8BEC         mov ebp,esp
10001003      6AFE         push 0xFFFFFFFF
10001005      68 10220010  push 0x10002210

我们可以看到10001005处push的值是一个VA常量,都是如果映射到内存的基址变了,这个VA常量也必须改变才可以。这时候就需要用我们的重定位表。

我们先来看重定位表的结构

typedef struct _IMAGE_BASE_RELOCATION
{
    DWORD VirtualAddress;
    DWORD SizeOfBlock;
    WORD TypeOffset[1];
}IMAGE_BASE_RELOCATION;

重定位表由IMAGE_BASE_RELOCATION的数组构成。

每个数组记录了当前4KB页面中需要重定向的地址。如何定位到这些值呢?

VirtualAddress:需要重定位的数据的RVA,这个值需要加上后面的TypeOffset的低12位才是需要重定位数据的RVA

需要重定位的数据位置 = 真实加载基址 + VirtualAddress + TypeOffset低12位
重定位后地址 = (真实加载基址-默认加载基址) + 需要进行重定位的地址

 原本的常量是根据默认加载基址计算的,现在基址换成了真实加载基址,我们只需要将原本的数据加上基址的偏移就可以替换成真实有效的地址了。

注意:
1.应用场合:
凡是涉及到直接寻址的指令都需要进行基址重定位处理;
2.EXE文件不存在重定位表:对于EXE文件来说,每个文件总是使用独立的虚拟地址空间,所以EXE总是能够按照这个地址装入,这意味着EXE 文件不再需要重定位信息。

DLL文件需要重定位表:对于DLL文件来说,由于多个DLL文件全部使用宿主EXE文件的地址空间,不能保证装入地址没有被其他DLL使用, 所以DLL文件必须包含重定位表。
3.同一系统的kernel32.dll、user32.dll等会被加载到自身固有的IB,所以系统的DLL实际上并不会发生重定位问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值