共有ライブラリを使用するCプログラムがあるとします。
共有ライブラリを変更して再構築すると、そのライブラリを使用するすべてのプログラムは、次回実行されると自動的にその変更を受け取ります。静的ライブラリーの場合、変更はプログラムが新しいバージョンのライブラリーに再コンパイルされた後にのみ表示されます。
一部の共有ライブラリ関数のコードを変更したり(メソッドシグネチャを変更せずに)、新しい関数を追加するなど、関数のアドレスが変更されます。
共有ライブラリを使用するプログラムは、再コンパイルや再リンクなしでどのようにこれらの機能を再検索できますか?住所が変更された場合。
答え1
.so
すべてのライブラリはエクスポートされた関数と場所のリストを保持しているからです。
したがって、広く言うと、プログラムが共有ライブラリから関数を取得しようとすると、多段階プロセスが発生します。つまり、エクスポートされた名前のリストを読み、関数名を探し、そのアドレスを取得し、その.so
アドレスにあるファイルを読み取ります。
これらの住所を直接見つけるには、こちらをご覧ください。https://en.wikipedia.org/wiki/Executable_and_Linkable_Format
答え2
共有ライブラリのヘッダには、関数の名前とアドレスを含むテーブルがあります。したがって、メインプログラムが関数を呼び出そうとすると、テーブルを検索してそのアドレスにジャンプします(必要に応じて適切なパラメータを使用してください)。
答え3
既存の回答に追加:実行可能ファイルは動的ローダーを使用して共有ライブラリの.soファイルを見つけ、初期化機能を実行し、次の表を取得します。シンボル(例:関数名/壊れた署名)には関数アドレスが含まれています。その後、共有ライブラリの関数を使用するたびに、リンカステップで使用される関数ポインタの値が変更されます。
したがって、秘密は、プログラムがこれらの関数を使用するために固定アドレスを使用しないことです。まだ定義されていないアドレスを持つ関数ポインタのリストがあり、動的リンカはライブラリ自体の関数の実際のアドレスを次の場所に入力します。実行時間。