How do I find out which functions of a shared object are used by a program or an other library?

后端 未结 5 1738
清歌不尽
清歌不尽 2021-01-30 11:37

How do I find out which functions of a shared object are used by a program or an other library? In this specific case, I would like to see which functions in /lib/libgcc1_s.so.1

相关标签:
5条回答
  • 2021-01-30 11:53

    nm will only work if the library wasn't stripped of its symbols. However, nm -D could show you some info:

    nm -D /lib/libgcc_s.so.1
    

    But there's another tool which can help you: readelf

    readelf - Displays information about ELF files.

    And if you check the man pages, option -s: Displays the entries in symbol table section of the file, if it has one.

    readelf -s /lib/libgcc_s.so.1
    

    EDIT:

    Well, symbols that are not implemented inside the object you are inspecting with nm will appear with a U flag in front of it, but nm won't tell you which library on your system implements that symbol.

    So what you are looking for can probably be achieved with a mixture of ldd and nm. ldd tells which libraries your application is linked with, and nm tells which symbols are undefined (U flag) or implemented locally (T flag).

    After listing all the undefined symbols (with nm) on the target application, you should iterate through all libraries reported by ldd in search of those symbols (using nm again). If you find the symbol and it's preceded by the T flag, you found it.

    By the way, I just wrote this one-liner for bash to illustrate my idea. It analyses an application named win and tries to find the libraries that implement all the symbols reported as 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;
    

    Or, if your terminal supports colors:

    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;
    

    I'm sure someone will find a performance improvement.

    Outputs:

    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]
    
    0 讨论(0)
  • 2021-01-30 11:53

    Maybe the nm tool can help you since it displays the symbols' names contained in a binary file.
    It is as simple as ABC to use:

    nm my_binary
    
    0 讨论(0)
  • 2021-01-30 12:07

    This can be achieved using technique called static analysis in Reverse Engineering

    You need a Disassembler for this. See http://en.wikipedia.org/wiki/Disassembler

    IDA PRO is a good disassembler witch answers your question.It is capable of reading ELF file format but unfortunately it is not free.

    0 讨论(0)
  • 2021-01-30 12:12

    I'm not aware of one, even nm is of limited use for what you seem to intend. Also, preloading (of the GNU linker) could invalidate any assumptions you make after using a tool that purportedly could do that. See the ld.so man page. LD_PRELOAD can be used by anyone to override the resolution of symbols as it would occur under normal circumstances.

    However, even without a debugger you can use LD_DEBUG to see which function ultimately is being used.

    0 讨论(0)
  • 2021-01-30 12:14

    Have you looked at ltrace? It intercepts calls to shared library functions at runtime and prints information about them as they occur.

    Since this is a dynamic solution, it wouldn't print any information for a library call made in part of your program that never gets executed. But it might still be helpful depending on your needs.

    0 讨论(0)
提交回复
热议问题