如何找出共享对象的哪些函数被程序或其他库使用?

如何找出共享对象的哪些函数被程序或其他库使用? 在这个特定的情况下,我想看看/lib/libgcc1_s.so.1中的哪些函数被其他dynamic库使用。 由于它们是dynamic链接的,因此objdump -d不能parsing函数调用地址。 有没有办法在debugging器中运行程序或静态重新链接? 谢谢,

卢卡

编辑:

nm和readelf不会这样做,我不需要看到哪些符号出现在共享对象中,但是实际上是在链接到它的其他对象中使用的。

Solutions Collecting From Web of "如何找出共享对象的哪些函数被程序或其他库使用?"

只有在图书馆没有被剥夺符号的情况下,nm才会起作用。 但是, nm -D可能会显示一些信息:

 nm -D /lib/libgcc_s.so.1 

但还有另一个工具可以帮助你: readelf

readelf – 显示有关ELF文件的信息。

如果您检查手册页,则选项-sDisplays the entries in symbol table section of the file, if it has one.

 readelf -s /lib/libgcc_s.so.1 

编辑:

那么,在你用nm检测的对象内部没有实现的符号将会在它前面出现一个U标志,但是nm不会告诉你系统上的哪个库实现了这个符号。

所以你正在寻找的可能是lddnm的混合物。 ldd告诉你的应用程序链接到哪个库,nm告诉哪些符号是未定义的( U标志)或是本地实现的( T标志)。

在目标应用程序中列出所有未定义的符号(包含nm)之后,您应该遍历ldd报告的所有库以搜索这些符号(再次使用nm)。 如果你找到了符号,它的前面是T标志,你找到了它。

顺便说一下,我只是写了这个一行为bash来说明我的想法。 它分析一个名为win的应用程序,并试图找到实现所有报告为未定义的符号的库。

 target="win"; for symbol in $(nm -D $target | grep "U " | cut -b12-); do for library in $(ldd $target | cut -d ' ' -f3- | cut -d' ' -f1); do for lib_symbol in $(nm -D $library | grep "T " | cut -b12-); do if [ $symbol == $lib_symbol ]; then echo "Found symbol: $symbol at [$library]"; fi ; done; done; done; 

或者,如果您的终端支持颜色:

 target="win"; for symbol in $(nm -D $target | grep "U " | cut -b12-); do for library in $(ldd $target | cut -d ' ' -f3- | cut -d' ' -f1); do for lib_symbol in $(nm -D $library | grep "T " | cut -b12-); do if [ $symbol == $lib_symbol ]; then echo -e "Found symbol: \e[1;36m$symbol\033[0m at \e[1;34m$library\033[0m"; fi ; done; done; done; 

我相信有人会发现性能的提高。

输出:

 Found symbol: XCreateColormap at [/usr/lib/libX11.so.6] Found symbol: XCreateWindow at [/usr/lib/libX11.so.6] Found symbol: XIfEvent at [/usr/lib/libX11.so.6] Found symbol: XMapWindow at [/usr/lib/libX11.so.6] Found symbol: XOpenDisplay at [/usr/lib/libX11.so.6] Found symbol: __libc_start_main at [/lib/tls/i686/cmov/libc.so.6] Found symbol: __stack_chk_fail at [/lib/tls/i686/cmov/libc.so.6] Found symbol: glClear at [/usr/lib/mesa/libGL.so.1] Found symbol: glClearColor at [/usr/lib/mesa/libGL.so.1] Found symbol: glFlush at [/usr/lib/mesa/libGL.so.1] Found symbol: glXChooseFBConfig at [/usr/lib/mesa/libGL.so.1] Found symbol: glXChooseVisual at [/usr/lib/mesa/libGL.so.1] Found symbol: glXCreateContext at [/usr/lib/mesa/libGL.so.1] Found symbol: glXCreateNewContext at [/usr/lib/mesa/libGL.so.1] Found symbol: glXCreateWindow at [/usr/lib/mesa/libGL.so.1] Found symbol: glXGetVisualFromFBConfig at [/usr/lib/mesa/libGL.so.1] Found symbol: glXMakeContextCurrent at [/usr/lib/mesa/libGL.so.1] Found symbol: glXMakeCurrent at [/usr/lib/mesa/libGL.so.1] Found symbol: glXQueryVersion at [/usr/lib/mesa/libGL.so.1] 

你看过ltrace吗? 它拦截在运行时调用共享库函数,并在发生时打印有关它们的信息。

由于这是一个动态的解决方案,它不会打印任何信息,不会执行您的程序的一部分,而不会执行的库调用。 但是根据您的需求,这可能仍然有帮助。

我没有意识到,即使nm对你似乎打算有限的使用。 而且,(GNU链接器的)预加载可能会使你使用一个据称可以做到的工具之后所做的任何假设失效。 请参阅ld.so手册页 。 任何人都可以使用LD_PRELOAD来替代正常情况下会出现的符号分辨率。

但是,即使没有调试器,也可以使用LD_DEBUG来查看最终使用哪个函数。

也许nm工具可以帮助你,因为它显示了二进制文件中包含的符号名称。
使用ABC就像ABC一样简单:

 nm my_binary 

这可以通过在逆向工程中使用称为静态分析的技术来实现

你需要一个反编译器。 见http://en.wikipedia.org/wiki/Disassembler

IDA PRO是一个很好的反汇编器的女巫回答你的问题。它能够读取ELF文件格式,但不幸的是它不是免费的。