それに依存するプログラムを構築した後、共有ライブラリのファイル名を変更するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/2759254

質問

ディレクトリ構造の奥深くにあると予想される共有ライブラリに依存するプログラムがあります。その共有ライブラリをより良い場所に移動したいと思います。 OS Xでは、これはinstall_name_toolで実行できます。 Linuxに相当するものを見つけることができません。

参考のために、 readelf -d myprogram 次の言い換えの出力を吐き出します。

Dynamic section at offset 0x1e9ed4 contains 30 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [this/is/terrible/library.so]
 0x00000001 (NEEDED)                     Shared library: [libGL.so.1]
 0x00000001 (NEEDED)                     Shared library: [libGLU.so.1]
 0x00000001 (NEEDED)                     Shared library: [libstdc++.so.6]
(continues in an uninteresting fashion)

(そしてリクエストに応じて、 ldd myprogram:)

    linux-gate.so.1 =>  (0x0056a000)
    this/is/terrible/library.so => not found
    libGL.so.1 => /usr/lib/mesa/libGL.so.1 (0x0017d000)
    libGLU.so.1 => /usr/lib/libGLU.so.1 (0x00a9c000)
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00710000)
   (etc, etc)

そして、私は「this/is/therrible/library.so」を「共有/library.so」にしたいです。プログラムが「構築された」場所に残されている場合、この/IS/IS/Therrible/Library.soが実際に存在する場合、LDDは予想通りそれを見つけることができます。

私はRPATHについて知っていますが、それは私が探しているものではなく、検索パスをグローバルに変更する必要はありません。

役に立ちましたか?

解決

ht - これは役立つかもしれません。

HTは、実行可能ファイル用のファイルエディター/ビューアー/アナライザーです。目標は、デバッガーの低レベルの機能とIDEの使いやすさを組み合わせることです。最も重要なファイル形式のすべての(六角)編集機能とサポートを実装する予定です。

Zorbathutのソリューションとは大きく違うものを見つけることができませんでしたが、おそらく異なる長さの名前を付けて、バイナリを有効に保つことが可能です。

ゲルフ - これも便利です。

Gelfは、ELFオブジェクトファイルを操作するための一般的なELFクラスに依存しないAPIです。 Gelfは、32ビットおよび64ビットのELF形式のオブジェクトファイルを処理するための単一の一般的なインターフェイスを提供します。

他のヒント

使用できます Patchelf:

patchelf --replace-needed liboriginal.so.1 libreplacement.so.1 my-program

依存関係を削除することもできます。

patchelf --remove-needed libfoo.so.1 my-program

依存関係を追加します:

patchelf --add-needed libfoo.so.1 my-program

または、ライブラリを検索する場所を変更します(rpath):

patchelf --set-rpath /path/to/lib:/other/path my-program

暫定的で恐ろしい、ハッキーなソリューションを投稿します。

ライブラリの依存関係は、.dependsブロックとして知られるELFブロックに保存されます。そのブロックの形式は、識別子/StringPointerペアの大量の配列であり、StringPointerはバイナリのどこかにある標準のCヌル終端文字列を指しています。

これがどこに向かっているのかわかりますよね?

うん、必要な新しいパスが古いパスよりも大きくない限り、バイナリに到達して、単純な文字列置換を行うことができます。バイトを追加または削除しないようにしてください。そうしないと、バイナリ全体が破損します。あなたがそれについてより安全にしたいなら、あなたは実際にあなたが適切な場所を確保するためにエルフ構造を実際に通過することができます - 今、私はただソース文字列が正確に1回表示されることを確認するためにただチェックしています。

Elfにはチェックサムが含まれていますが、どうやら実際にそれを検証するローダーはないので、無視するのは「安全」である - 乱雑ではあるが -

「本当の解決策」は、ELF構造の低レベルの一般化操作を可能にするユーティリティです。私が言うことができるように、そのようなユーティリティは存在しません。いくつかの専門的なケースを除くすべてのもの(主にRPAT)を除いて、私はそのようなユーティリティが書くのがどれほど難しいかを知らないふりをしません。

私はこれに対するより良い解決策を絶対に愛していますが、これまでのところ、これはうまくいくようです。

ld_library_pathを使用して、共有ライブラリの検索パスを変更できます。プログラムが例のように特定の相対パスに依存している場合、そのディレクトリ構造が必要です。言い換えれば、あなたはlibを移動することができます /home/user/dev/project/this/is/terrible/library.so/usr/local/lib/this/is/terrible/library.so しかし、そうではありません /usr/local/lib/library.so

プログラムを再構築できれば、LIBに使用する相対パスを変更できます。

Linuxの共有Libsに関するいくつかの情報があります http://tldp.org/howto/program-library-howto/shared-libraries.html

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top