Linux ELF补丁、绑定问题

Linux ELF补丁、绑定问题,linux,gcc,binding,g++,elf,Linux,Gcc,Binding,G++,Elf,目前我正在尝试修补ELF可执行对象文件 我正在使用原始的hello world应用程序测试我的实用程序。修补后,一切似乎都很好,但在执行时,应用程序会出错 修补时,我还插入了一个新的共享对象依赖项。为了理解哪里出了问题,我同时设法将共享对象链接到我的测试应用程序中。这样我就可以收到格式良好的g++生成的结果,我可以将其与我的算法结果进行比较(或多或少) 我遇到的问题是,在执行过程中,我修改的hello world应用程序无法调用std::cout例程,因为std::ostream::sentry

目前我正在尝试修补ELF可执行对象文件

我正在使用原始的hello world应用程序测试我的实用程序。修补后,一切似乎都很好,但在执行时,应用程序会出错

修补时,我还插入了一个新的共享对象依赖项。为了理解哪里出了问题,我同时设法将共享对象链接到我的测试应用程序中。这样我就可以收到格式良好的
g++
生成的结果,我可以将其与我的算法结果进行比较(或多或少)

我遇到的问题是,在执行过程中,我修改的hello world应用程序无法调用
std::cout
例程,因为
std::ostream::sentry::sentry(std::ostream&)
ctor失败;我设法用
gdb
深入研究了这个问题。在调试并与格式良好的结果进行比较时,我设法找出了问题所在。似乎符号
std::cout
/
\u ZSt4cout
重定位绑定有点误用。尽管这两个结果在
.dynamic
部分中具有完全相同的
DT\u NEEDED
条目(顺序也相同),尽管它们在
.dynsym
部分中都具有
std::cout
的导入符号条目,并相应地修改了
.gnu.version
.gnu.hash
内容,-尽管如此,
std::ios_base::Init::Init()
函数在解析
std::cout
对象时,对这两个结果的操作不同。对于格式良好的结果-在hello world应用程序的
.bss
部分的正确条目上,而对于my algo结果-在
libstdc++
共享库的
部分的
std::cout
条目上(由
readelf
util验证)

最后,但并非最不重要的一点是,当使用
LD_DEBUG=bindings
选项执行时,我收到以下格式良好的结果输出(添加
std::cin
/
\u ZSt3cin
,以作对比):

而对于algo修改结果:

...
     10027: binding file /usr/lib/x86_64-linux-gnu/libstdc++.so.6 [0] to /usr/lib/x86_64-linux-gnu/libstdc++.so.6 [0]: normal symbol `_ZSt4cout' [GLIBCXX_3.4]
     10027: binding file /home/user/Documents/Test/libmyexternal.so [0] to /usr/lib/x86_64-linux-gnu/libstdc++.so.6 [0]: normal symbol `_ZSt4cout' [GLIBCXX_3.4]
     10027: binding file ./hello_world_algotest  [0] to /usr/lib/x86_64-linux-gnu/libstdc++.so.6 [0]: normal symbol `_ZSt4cout' [GLIBCXX_3.4]
...
     10027: binding file /usr/lib/x86_64-linux-gnu/libstdc++.so.6 [0] to /usr/lib/x86_64-linux-gnu/libstdc++.so.6 [0]: normal symbol `_ZSt3cin' [GLIBCXX_3.4]
     10027: binding file ./hello_world_algotest [0] to /usr/lib/x86_64-linux-gnu/libstdc++.so.6 [0]: normal symbol `_ZSt3cin' [GLIBCXX_3.4]
...
我如何解决这个问题,或者这种行为的原因是什么?
glibc
libstdc++
如何处理这种情况,以及algo-modified应用程序的
std::cout
条目如何在库中变得“不可见”(尽管
readelf
objdump
nm
utils表明一切都是正确的)


当然,glibc和libstdc++
版本和hello world应用程序都是在相同的
g++
版本下编译的
.bss
节正确驻留,所有节和段都设置了正确的标志。

glibc
源代码中挖掘,使用
gdb
(丢失了几天),我找到了
\u dl\u lookup\u symbol\u x
do\u lookup\u x
函数,这些函数在
dl lookup.c
中定义;传递的参数告诉我(格式良好的结果和algo派生的结果之间)的区别在于散列。嗯,我忘了GNU哈希表被错误地修改了。添加导入函数后,您必须更改GNU哈希表索引(幸运的是,您不必重建整个哈希表,只需更新索引;不要忘记,在添加导入函数时,您仍然必须更改.dynsym和GNU版本表的内容)(关于整个GNU哈希概念的一个非常酷的解释可以在这里看到:)。顺便说一句,我发现并修复了一个过时的.bss节号错误(发生在节重建过程中)。

使用
gdb
glibc
源代码中挖掘(损失了几天),我访问了
dl\u lookup\u symbol\u x
do\u lookup\u x
函数,这些函数在
dl lookup.c
中定义;传递的参数向我显示了差异(格式良好的结果和算法导出的结果之间)我忘了GNU哈希表被错误地修改了。一旦添加了导入函数,就必须更改GNU哈希表索引(幸运的是,您不必重建整个哈希表,只需更新索引;不要忘记,在添加导入函数时,您仍然需要更改.dynsym和GNU版本的表内容)(这里可以看到对整个GNU哈希概念的一个非常酷的解释:)。顺便说一句,我发现并修复了一个带有过时的.bss节号的错误(由于节重建而发生)

...
     10027: binding file /usr/lib/x86_64-linux-gnu/libstdc++.so.6 [0] to /usr/lib/x86_64-linux-gnu/libstdc++.so.6 [0]: normal symbol `_ZSt4cout' [GLIBCXX_3.4]
     10027: binding file /home/user/Documents/Test/libmyexternal.so [0] to /usr/lib/x86_64-linux-gnu/libstdc++.so.6 [0]: normal symbol `_ZSt4cout' [GLIBCXX_3.4]
     10027: binding file ./hello_world_algotest  [0] to /usr/lib/x86_64-linux-gnu/libstdc++.so.6 [0]: normal symbol `_ZSt4cout' [GLIBCXX_3.4]
...
     10027: binding file /usr/lib/x86_64-linux-gnu/libstdc++.so.6 [0] to /usr/lib/x86_64-linux-gnu/libstdc++.so.6 [0]: normal symbol `_ZSt3cin' [GLIBCXX_3.4]
     10027: binding file ./hello_world_algotest [0] to /usr/lib/x86_64-linux-gnu/libstdc++.so.6 [0]: normal symbol `_ZSt3cin' [GLIBCXX_3.4]
...