共有オブジェクトのどの関数がプログラムまたは他のライブラリによって使用されているかを確認するにはどうすればよいですか?この特定のケースでは、/ lib /libgcc1_s.so.1のどの関数が他のダイナミックライブラリによって使用されているかを確認したいと思います。それらは動的にリンクされているため、objdump-dは関数呼び出しアドレスを解決しません。デバッガーでプログラムを実行したり、静的に再リンクしたりする以外の方法はありますか?ありがとう、
ルカ
編集:
nmとreadelfは機能しません。共有オブジェクトに存在するシンボルを確認する必要はありませんが、実際には、共有オブジェクトにリンクしている他のオブジェクトで使用されています。
nmは、ライブラリからシンボルが削除されていない場合にのみ機能します。しかしながら、 nm -D
いくつかの情報を表示できます:
nm -D /lib/libgcc_s.so.1
しかし、あなたを助けることができる別のツールがあります: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
編集:
さて、nmで検査しているオブジェクト内に実装されていないシンボルは、その前に[〜#〜] u [〜#〜]フラグが付いて表示されますが、nmは通知しませんシステム上のどのライブラリがそのシンボルを実装しているか。
したがって、探しているものは、おそらくlddとnmの混合で達成できます。 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と同じくらい簡単です:
nm my_binary
これは、リバースエンジニアリングで静的分析と呼ばれる手法を使用して実現できます。
これには逆アセンブラが必要です。 http://en.wikipedia.org/wiki/Disassembler を参照してください
IDA PROは、あなたの質問に答える優れた逆アセンブラウィッチです。ELFファイル形式を読み取ることができますが、残念ながら無料ではありません。