PE文件详解(八)

本文转载自小甲鱼PE文件详解系列教程原文传送门
当应用程序需要调用DLL中的函数时,会由系统将DLL中的函数映射到程序的虚拟内存中,dll中本身没有自己的栈,它是借用的应用程序的栈,这样当dll中出现类似于mov eax, [1000000]这样直接寻址的代码时,由于事先并不知道它会被映射到应用程序中的哪个位置,并且可能这个内存地址已经被使用,所以当调用dll中的函数时,系统会进行一个基址重定位的操作。系统是根据dll中的基址重定位表中的信息决定如何进行基址重定位,哪些位置的指令需要进行基址重定位。
所以这次主要说明基址重定位表。
这个重定位表位于数据目录表的第六项。这个表的主要结构如下:

IMAGE_BASE_RELOCATION STRUC

    VirtualAddress      DWORD        ?  ; 重定位数据开始的RVA 地址
    SizeOfBlock         DWORD        ?  ; 重定位块得长度
    TypeOffset          WORD         ?  ; 重定项位数组

IMAGE_BASE_RELOCATION  ENDS

VirtualAddress 是 Base Relocation Table 的位置它是一个 RVA 值
SizeOfBlock 是 Base Relocation Table 的大小;
这个结构的示意图如下:
这里写图片描述
TypeOffset 是一个数组,数组每项大小为两个字节(16位),它由高 4位和低 12位组成,高 4位代表重定位类型,低 12位是重定位地址。高4位一般是3,表示这个地址是一个32位的地址,它与 VirtualAddress 相加即是指向PE 映像中需要修改的那个地址的位置,注意这里不是定位到对应代码的位置
接下来进行手工的方式找到需要重定位的代码位置:
打开一个dll文件,发现它的基址重定位表所在RVA = 0x00004000
通过计算得到它是在.relo ,对应文件的偏移为0x800,查看这个位置的值为:
这里写图片描述
VirtualAddress = 0x1000,
SizeOfBlock = 0x18
通过它的大小,得知需要重定位的位置主要有(0x18 - 8) / 2 = 8,最后一个以0结尾,所以实际上总共有7处需要重定位
这8个位置分别为:0x028, 0x02e, 0x003e 0x04b, 0x051, 0x61, 0x6c
这里写图片描述
后面的以此类推,可以发现这些需要重定位的位置,存储的都是一些立即寻址的地址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值