25

ディレクトリ構造の奥深くにある共有ライブラリに依存するプログラムがあります。その共有ライブラリをより良い場所に移動したいと思います。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/terrible/library.so」を「shared/library.so」に訂正したいと思います。プログラムが、相対パス this/is/terrible/library.so が実際に存在する「構築された」場所に残っている場合、予想どおり、ldd はそれを見つけることができることに注意してください。

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

4

4 に答える 4

11

暫定的で恐ろしい、ハッキーな解決策を投稿します。

ライブラリの依存関係は、.depends ブロックと呼ばれる ELF ブロックに格納されます。そのブロックの形式は、識別子/文字列ポインタのペアの大きな配列であり、文字列ポインタは、バイナリのどこかにある標準の C ヌル終了文字列を指しています。

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

はい、必要な新しいパスが古いパスよりも大きくない限り、バイナリに直接アクセスして単純な文字列置換を行うことができます。バイトを追加または削除しないようにしてください。そうしないと、バイナリ全体が破損します。より安全にしたい場合は、実際に ELF 構造をトラバースして、正しい場所にいることを確認できます。現在、ソース文字列が 1 回だけ表示されることを確認しています。

ELFにはチェックサムが含まれていますが、実際にそれを検証するローダーがないようです。そのため、無視しても「安全」です-面倒ではありますが.

「本当の解決策」は、ELF 構造の低レベルの一般化された操作を可能にするユーティリティです。私が知る限り、そのようなユーティリティは存在しません。いくつかの特殊なケース (主に RPATH) を除いて、そのようなユーティリティを作成するのがどれほど難しいかを知っているふりはしません。

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

于 2010-05-03T17:52:06.247 に答える
6

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

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

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

gelf-これも便利かもしれません。

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

于 2010-05-03T19:26:40.543 に答える
-3

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

プログラムを再構築できる場合は、ライブラリに使用する相対パスを変更できます。

Linux の共有ライブラリに関する詳細情報は、http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.htmlにあります。

于 2010-05-03T17:36:21.147 に答える