【问题标题】:So most of the binary is composed of reloc table?那么大部分二进制是由reloc表组成的吗?
【发布时间】:2011-05-14 14:12:13
【问题描述】:

我刚刚使用objdump -x ... 来检查 PE 文件的各个部分。

大约有 90,000 行 reloc 条目:

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

大多数PE文件的大部分空间都是由上面的reloc条目组成的吗?

这些条目是做什么用的?

更新

谁能解释一下重定位条目是如何像上面那样工作的?

【问题讨论】:

  • @Ignacio Vazquez-Abrams,你能详细说明一下吗?
  • 虽然有些恶意软件样本完全由重定位项组成(即没有明确的代码或数据,而是将重定位序列重复应用于同一内存位置以形成最终值),代码+数据超过重定位次数的可能性要大得多。这个想法是,任何引用内存中绝对地址的值都必须具有相应的重定位项,以防图像无法加载到其请求的地址。

标签: portable-executable relocation


【解决方案1】:

当内存中存在基础冲突时,需要重新定位。如果动态链接库想要将其代码段加载到某个内存空间,但当它已经被另一个模块占用时,则必须将其加载到不同的位置。但是,通过将其加载到不同的地址空间中,它会弄乱库引用的所有绝对引用。例如,假设可执行文件有一个名为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 的值来反映这个变化。

关于您关于由.reloc 表组成的PE 的多数空间的问题,答案是视情况而定。如果您的程序频繁访问全局变量和常量,它将有一个巨大的重定位表,因为加载器必须更新的地方太多了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-12
    • 1970-01-01
    • 2018-05-26
    • 2012-05-15
    • 2015-07-01
    • 2014-02-03
    • 1970-01-01
    • 2016-03-02
    相关资源
    最近更新 更多