2011-05-14 108 views
2

我刚刚使用objdump -x ...来检查PE文件的各个部分。那么大部分的二进制文件都是由reloc表组成的?

还有约90,000线RELOC条目:

reloc 92 offset bc0 [524bc0] HIGHLOW 
reloc 93 offset bc4 [524bc4] HIGHLOW 
    .... 

是否持有诚然,大多数PE文件的大部分空间是由像上面的RELOC项?

这些条目是什么?

UPDATE

任何人都可以解释搬迁项目如何运作像上面?

+0

搬迁。不完全是。 – 2011-05-14 14:27:43

+0

@Ignacio Vazquez-Abrams,你能详细说明一下吗? – 2011-05-14 14:32:04

+0

虽然有恶意软件样本完全由*组成的重定位项目组成(即没有显式代码或数据,而是将重定位序列反复应用到同一内存位置以形成最终值),但代码+数据超过重定位的数量。这个想法是,任何引用内存中绝对地址的值都必须有一个相应的重定位项,以防图像无法加载到其请求的地址。 – 2017-04-28 18:28:58

回答

10

当存储器中存在基本冲突时需要重定位。如果动态链接库希望将其代码段加载到某个内存空间中,但是当它已经被另一个模块占用时,它必须加载到另一个地方。但是,通过将其加载到不同的地址空间中,它会混淆库引用的所有绝对引用。例如,假设可执行文件具有名为int dummy;的全局变量,并且该变量位于0x602315中。每当这个变量被访问/写入,该程序执行以下的操作码(假定代码位于0x524BBE,相同你提到的条目):

0x524BBE: MOV EAX, DWORD PTR DS:[0x602315];//move dummy to eax register to do stuff

如果库在不同的装空间0x602315不会指向该变量,因为地址空间0x602315已被其他模块占用。因此,要解决此问题,您必须告诉PE加载器将位移(|new base address-expected base address|)添加/减去此值(0x602315)。为此,每个PE都包含一个称为重定位表的表,并且此表包含代码中引用此变量的所有偏移量。

所以,让我们说,而不是0x524000(预期的基准偏移量),该库被加载在0x700000。那么,PE装载器将做的是查找条目在表中的位移(0x700000-0x524000 = 0x1DC000)添加到偏移(0x602315),使得您的加载代码看起来就像这样:

0x700BBE: MOV EAX, DWORD PTR DS:[0x7DE315];//move dummy to eax register to do stuff

这将运行良好,因为它指向变量dummy的正确位置。

回到你的问题,objdump的输出显示了这个表的每个条目。 92可能意味着条目的索引,BC0是您访问变量的代码的相对地址,[524BC0]将是相对地址+预期基准偏移量的结果。而HIGHLOW只是一种重新定位(这基本上是为将来的使用保留的),目前只有一种重定位(HIGHLOW)被使用,所以你不必担心其他类型)。当加载器读取此条目时,它将更改0x524BC0的值以反映此更改。

关于你对PE的多数空间构成的问题.reloc表,答案是它取决于。如果你的程序频繁地访问全局变量和常量,它将会有一个巨大的重定位表,因为这些地方的加载器必须更新。

相关问题