4

この質問の 2 番目の回答でわかるように、セクションの名前を使用して、プログラム内からプログラムの特定のセクションへのポインターを取得するのは非常に簡単です。を使用libelfすると、プログラム自体のファイルを開き、その中のすべてのセクション (構造体で表されるElf64_Shdr) をループし、セクション名が必要なものと一致したときに停止し、構造体のsh_addr要素に格納されているポインターを使用しますElf64_Shdr。この場合、必要なポインターは ELF 実行可能ファイルで定義されているため、取得するのは非常に簡単です。

しかし、動的ライブラリを使用するプログラムがあり、その動的ライブラリのセクションへのポインターを取得する必要があるとします。セクションのアドレスは実行時に定義されるため、動的ライブラリのセクションへのポインターを取得するにはどうすればよいでしょうか?

ところで、動的ライブラリとメイン プログラム自体の両方に、それぞれに同じ名前のセクションがあります (これは、ポインターを取得する必要があるセクションです)。したがって、この場合、同じ名前のこれら 2 つのセクションがメモリに隣接して格納される可能性があるため、(最初の段落で説明したように) メイン ファイルのセクションへのポインターを取得し、オフセットを追加するだけで済みます。動的ライブラリ セクションに到達するには?

4

2 に答える 2

5

プログラム内からプログラムの特定のセクションへのポインタを取得するのは非常に簡単です

必ずしも。セクション テーブルは実行時には実際には必要なく、完全に取り除くことができます (セクションではなくセグメントのみが重要です)。

セクションのアドレスは実行時に定義されるため、動的ライブラリのセクションへのポインターを取得するにはどうすればよいでしょうか?

ライブラリは、メインの実行可能ファイルとまったく違いはありません。主な違いは、ライブラリは通常アドレスでリンクされ0(メインの実行可能ファイルはそうではありません)、ランタイム ローダーによって他の一定のオフセットに再配置されることです。

そのオフセットがわかったら、それをセクションの開始 (libelf から、readelf -S foo.soまたは libelf から見つけることができます) に追加するだけで、ほら: セクションのランタイム アドレスが得られます。

では、特定の共有ライブラリの再配置を見つけるにはどうすればよいでしょうか?

洗練されていない解決策 (Nick によって既に提案されています) は parse/proc/self/mapsです。

より良い解決策は、 (glibc-specific) を使用することdl_iterate_phdrです。ドキュメンテーションはこちら。を使用したいと思うでしょうdlpi_addr

于 2012-11-14T05:49:31.370 に答える