25

共有オブジェクトのどの関数がプログラムまたは他のライブラリで使用されているかを調べるにはどうすればよいですか? この特定のケースでは、/lib/libgcc1_s.so.1 内のどの関数が他の動的ライブラリによって使用されているかを確認したいと思います。それらは動的にリンクされているため、objdump -d は関数呼び出しアドレスを解決しません。プログラムをデバッガーで実行したり、静的に再リンクしたりする方法はありますか? ありがとう、

ルカ

編集:

nm と readelf は役に立ちません。共有オブジェクトに存在するシンボルを確認する必要はありませんが、実際にリンクしている他のオブジェクトでどのシンボルが使用されているかを確認する必要はありません。

4

5 に答える 5

44

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]
于 2011-02-24T17:27:23.060 に答える
5

ltraceを見ましたか?実行時に共有ライブラリ関数の呼び出しをインターセプトし、それらに関する情報を出力します。

これは動的なソリューションであるため、実行されないプログラムの一部で行われたライブラリ呼び出しに関する情報は出力されません。ただし、ニーズによっては、それでも役立つ場合があります。

于 2011-02-24T20:47:52.437 に答える
1

私はそれを知りません、nmあなたが意図しているように見えるもののために限られた用途でさえあります。また、(GNUリンカーの)プリロードは、それを実行できるとされるツールを使用した後に行った仮定を無効にする可能性があります。ld.soのマニュアルページを参照してください。LD_PRELOAD通常の状況で発生するように、シンボルの解像度をオーバーライドするために誰でも使用できます。

ただし、デバッガーがなくても、LD_DEBUG最終的にどの関数が使用されているかを確認するために使用できます。

于 2011-02-24T17:22:49.530 に答える
0

nmバイナリファイルに含まれているシンボルの名前を表示するので、ツールが役立つかもしれません。
ABCと同じくらい簡単に使用できます。

nm my_binary
于 2011-02-24T17:21:32.550 に答える
0

これは、リバース エンジニアリングの静的解析と呼ばれる手法を使用して実現できます。

これには逆アセンブラが必要です。http://en.wikipedia.org/wiki/Disassemblyrを参照

IDA PRO は、あなたの質問に答える優れた逆アセンブラーです。ELF ファイル形式を読み取ることができますが、残念ながら無料ではありません。

于 2012-03-19T17:37:16.213 に答える