我试图通过研究一些共享对象中的指令来学习汇编语言的一两件事。我遇到了一个构造,其中call
指令在开始后导致1个字节,例如(从hte
输出):
af6fc | e8fcffffff call af6fdh
显然,目标地址必须由适当的函数替换(在本例中我知道strcmp
)。我发现这很奇怪,因为在相同的共享对象的其他部分中,使用strcmp
/ .got
调用相同的 .plt
函数机制消除了重写.text
部分的需要。在后一种情况下,可以通过研究.rel.plt
表和.dynsym
来识别目标函数。但是,如何找到前一个地址重定向到前者的位置?我在任何部分都找不到任何地址af6fc
或af6fd
,至少在hte
无法访问的地址中找不到。
答案 0 :(得分:1)
您没有说明您所在的平台。它似乎是ix86
。
在ix86
上,可以将非-fPIC
编译的代码链接到一个共享库(这会生成一个带有文本重定位的库,这是次优的。)
如果使用objdump -R foo.so
转储动态重定位,您应该会看到对地址0xaf6fd
进行了重定位。动态链接器将在0xaf6fd
更新4个字节,以指向重定位在加载foo.so
后指示的位置。
在同一共享对象的其他部分中,使用.got / .plt机制调用相同的strcmp函数
这些调用来自使用-fPIC
编译(正确)的对象。