この質問は古く、他の回答は古いです。「雇用されたロシア人」の回答は非常に有益で有益ですが、ソースコードがある場合にのみ機能します. そうしないと、当時の代替手段は非常にトリッキーでした。幸いなことに、今日では、patchelfを使用して、この問題に対する簡単な解決策があります (彼の返信の 1 つでコメントされているように) 。あなたがしなければならないことは次のとおりです。
$ ./patchelf --set-interpreter /path/to/newglibc/ld-linux.so.2 --set-rpath /path/to/newglibc/ myapp
その後、ファイルを実行するだけです:
$ ./myapp
chroot
ありがたいことに、バイナリを手動で編集する必要はありません。ただし、バイナリ ファイルが変更されるため、パッチを適用する前にバイナリをバックアップすることを忘れないでください。パッチを適用した後、古いパスをインタープリター/rpath に復元することはできません。機能しない場合は、実際に機能するパスが見つかるまでパッチを適用し続ける必要があります...まあ、試行錯誤のプロセスである必要はありません。たとえば、OPの例では、彼が必要GLIBC_2.3
だったので、を使用してそのバージョンを提供するライブラリを簡単に見つけることができますstrings
。
$ strings /lib/i686/libc.so.6 | grep GLIBC_2.3
$ strings /path/to/newglib/libc.so.6 | grep GLIBC_2.3
理論的には、システム libc には必要なバージョンがないため、最初の grep は空になり、2 番目の grep は GLIBC_2.3 を出力する必要があります。これは、バージョンが使用されているためです。したがって、そのパスを使用してバイナリを使用myapp
できることがわかります。patchelf
セグメンテーション違反が発生した場合は、最後にある注をお読みください。
Linuxでバイナリを実行しようとすると、バイナリはリンカー、次にライブラリをロードしようとします。それらはすべてパスおよび/または正しい場所にあるはずです。問題がリンカーにあり、バイナリが探しているパスを知りたい場合は、次のコマンドで見つけることができます。
$ readelf -l myapp | grep interpreter
[Requesting program interpreter: /lib/ld-linux.so.2]
問題がライブラリにある場合、使用されているライブラリを提供するコマンドは次のとおりです。
$ readelf -d myapp | grep Shared
$ ldd myapp
これにより、バイナリに必要なライブラリが一覧表示されますが、OP の場合と同様に既にエラーが発生しているため、問題のあるライブラリはおそらく既にわかっています。
「patchelf」は、これら 2 つの問題に関連して、プログラムを実行しようとしているときに遭遇する可能性のあるさまざまな問題に対して機能します。たとえば、次のようになった場合は、ここでELF file OS ABI invalid
説明するように、新しいローダー (--set-interpreter
コマンドの一部) を設定することで修正される場合があります。別の例は、ここに例示されているように、そこにあり実行可能なファイルを実行したときに取得するという問題です。その特定のケースでは、OP にローダーへのリンクがありませんでしたが、あなたのケースではルート アクセス権がなく、リンクを作成できない可能性があります。新しいインタープリターを設定すると、問題が解決します。No such file or directory
洞察力と解決策を提供してくれたEmployed RussianとMichael Pankovに感謝します!
セグメンテーション違反に関する注意: 複数のライブラリを使用している場合、myapp
それらのほとんどは問題ありませんが、一部は問題ありません。次にpatchelf
、新しいディレクトリに移動すると、セグメンテーション違反が発生します。バイナリを作成するときpatchelf
、いくつかのライブラリが最初は別のパスにあったとしても、いくつかのライブラリのパスを変更します。以下の私の例を見てください。
$ ldd myapp
./myapp: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by ./myapp)
./myapp: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by ./myapp)
linux-vdso.so.1 => (0x00007fffb167c000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f9a9aad2000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f9a9a8ce000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f9a9a6af000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f9a9a3ab000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9a99fe6000)
/lib64/ld-linux-x86-64.so.2 (0x00007f9a9adeb000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f9a99dcf000)
ほとんどのライブラリは含まれて/lib/x86_64-linux-gnu/
いますが、問題のあるライブラリ ( libstdc++.so.6
) は on であることに注意してください/usr/lib/x86_64-linux-gnu
。myapp
を指すようにパッチルフした後/path/to/mylibs
、セグメンテーション違反が発生しました。何らかの理由で、ライブラリはバイナリと完全に互換性がありません。myapp
元のライブラリについて文句を言わなかったので、 から/lib/x86_64-linux-gnu/
にコピーし、そこから/path/to/mylibs2
もコピーしました。それから私はそれを にパッチルフし、現在動作しています。バイナリが異なるライブラリを使用していて、バージョンも異なる場合、状況を修正できないことがあります。:(しかし、可能であれば、ライブラリを混在させることが方法かもしれません。理想的ではありませんが、うまくいくかもしれません。頑張ってください!libstdc++.so.6
/path/to/mylibs
/path/to/mylibs2
myapp