如何在我的二进制文件中找到哪个共享库导出了哪个导入的符号?

How to find which shared library exported which imported symbol in my binary?

我正在尝试查找导入了外部符号的共享库。目前我可以通过使用 nm 或许多替代方法(例如使用 radare2)来获取所有导入的符号。我还可以使用 ldd 获取二进制文件所依赖的库。但是,我在这一点上陷入困​​境,因为我找不到一种有效的方法来获取我的二进制文件中的哪个外部符号依赖于哪个共享库。因此,例如,我如何才能找到以有效方式导出名为 foo 或 printf 或其他任何函数的共享库?我举个例子:

        Output of nm -D myfile    
             w __cxa_finalize
             U foo
             w __gmon_start__
             w _ITM_deregisterTMCloneTable
             w _ITM_registerTMCloneTable
             U __libc_start_main
             U printf
             U puts

         Output of ldd
                linux-vdso.so.1 (0x00007ffd30904000)
libfoo.so => /home/user/Desktop/dynamic_link_example/libfoo.so (0x00007f1b08aaf000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1b088a1000)
/lib64/ld-linux-x86-64.so.2 (0x00007f1b08abb000)

So, for example how can I find the shared library which exports the function named foo or printf or anything in an efficient way?

您可以 运行 您的程序 env LD_DEBUG=bindings ./a.out。这会产生很多输出,你可以 grep for foo and printf.

请注意,“我的二进制文件中的哪个外部符号取决于哪个共享库”的答案是“首先定义该符号的库”。

所以如果 今天 你的二进制文件 foo 依赖于 lifoo.so 并且 printf 依赖于 libc.so.6,没有什么能阻止你来自 运行 一个不同的 libfoo.so 明天,并且 libfoo.so 的不同版本可能定义不同的符号。如果 libfoo.so 的新版本定义了 printf,那将导致您对符号 printf 的问题的答案从 libc.so.6 更改为 libfoo.so.