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

lul*_*omo 23 c linux shared-libraries elf objdump

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

卢卡

编辑:

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

kar*_*lip 41

nm仅在库未被删除其符号时才起作用.但是,nm -D可以告诉你一些信息:

nm -D /lib/libgcc_s.so.1
Run Code Online (Sandbox Code Playgroud)

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

readelf - 显示有关ELF文件的信息.

如果你查看手册页,选项-s:Displays the entries in symbol table section of the file, if it has one.

readelf -s /lib/libgcc_s.so.1
Run Code Online (Sandbox Code Playgroud)

编辑:

好吧,在你用nm检查的对象中没有实现的符号会出现在它前面的U标志,但是nm不会告诉你系统上哪个库实现了那个符号.

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

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

顺便说一句,我只是用bash写这个单行来说明我的想法.它分析名为win的应用程序,并尝试查找实现报告为undefined的所有符号的库.

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;
Run Code Online (Sandbox Code Playgroud)

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

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;
Run Code Online (Sandbox Code Playgroud)

我相信有人会发现性能提升.

输出:

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]
Run Code Online (Sandbox Code Playgroud)

  • 请参阅https://gist.github.com/toojays/dffd9b806692a10649c1fcd146ee7866,以便更快地实施,遵循大致相似的方法. (2认同)

Jay*_*rod 5

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

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


jop*_*rat 0

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

nm my_binary
Run Code Online (Sandbox Code Playgroud)