実行可能ファイルとそのライブラリの両方を組み合わせます。

実行可能ファイルとそのライブラリの両方を組み合わせます。

/bin/cat次の共有ライブラリを使用する実行可能ファイルがあるとします。

linux-vdso.so.1
libc.so.6
/lib64/ld-linux-x86-64.so.2

これらのものを何とか一緒に「結合」することは可能ですか(実行可能なアーカイブまたは同様のもの)。

これを実行したいプログラムのコードがないため、-staticフラグを使用してコンパイルすることはできません。

答え1

システムの場所にあるすべてのライブラリを実行可能ファイルのあるサブディレクトリにコピーして使用できます。パヘルフ、実行可能ファイルがシステムのlibディレクトリではなく、その場所でlibの依存関係を見つけるようにします。

たとえば、

相対化ライブラリ:

#!/bin/bash -e
[ -n "$1" ] || set -- a.out
mkdir -p ./lib/ #<copy the libraries here
#use ldd to resolve the libs and use `patchelf --print-needed to filter out
# "magic" libs kernel-interfacing libs such as linux-vdso.so, ld-linux-x86-65.so or libpthread
# which you probably should not relativize anyway
join \
    <(ldd "$1" |awk '{if(substr($3,0,1)=="/") print $1,$3}' |sort) \
    <(patchelf --print-needed "$1" |sort) |cut -d\  -f2 |

#copy the lib selection to ./lib
xargs -d '\n' -I{} cp --copy-contents {} ./lib 
#make the relative lib paths override the system lib path
patchelf --set-rpath "\$ORIGIN/lib" "$1"

LD_LIBRARY_PATH(ハッキングとは異なり、これはsetuid実行可能ファイルでも機能する必要があると思います。)

./libその後、実行可能ファイルと一緒にディレクトリを移動するだけです。

答え2

「加入」の意味によって異なります。最良の方法は、ソースソースコードを静的バイナリに再コンパイルすることです。

ただし、アプリケーションが制御するサブディレクトリ(/usr/share/myapp例:)にすべてのライブラリを含めてから、そのディレクトリをライブラリの検索順序に入れることができます。 1つの方法は(Linuxでは)以下を使用することですLD_LIBRARY_PATH

LD_LIBRARY_PATH=/usr/share/myapp/lib:/usr/local/lib:/usr/lib/i686-linux-gnu:/lib/i686-linux-gnu

Linuxでは、/etc/ld.so.conf同じ操作を実行するようにファイルを変更できます。 Ubuntuは*.confファイルをディレクトリに追加することもできます/etc/ld.so.conf.d

答え3

複数の共有オブジェクトと共有ライブラリELF実行可能ファイルを静的にリンクされたblobに変換することは容易ではありません。

これ実行可能ファイルおっしゃった内容は可能かもしれません。 「実行可能なアーカイブ」とは、実行時にシステム内の他のファイルに依存せずにそれ自体を解凍してプログラムを実行するファイルを意味します。

これは、ほとんどのLinuxディストリビューションにあるシェルスクリプトとユーティリティを使用して非常に簡単に実行できます(ただし、シェルとユーティリティへの依存関係が追加されます)。原則は同じですが、ELF「実行可能アーカイブ」を作成することはもう少し複雑です。プログラムのバージョンが頻繁に実行されることが予想される場合は、次のようにユーザーシステムにそのバージョンを「インストール」するようにスクリプトを変更する必要があります。デビッドそしてジャネブ

シェルスクリプトベースの実行可能アーカイブの使用例

実行に必要なファイルを収集します。catプログラムを使用する例の内容は次のとおりです。

fachas_cat_files/cat
fachas_cat_files/lib/libc.so.6

Base64でエンコードしてtgzファイルを生成します。ディレクトリを設定したら、これを実行cat.b64できます。fachas_cat_files

tar -cz fachas_cat_files | base64 > cat.b64

これは、スクリプトに含めることができるように、印刷可能な文字でtarファイルを表します。

圧縮中のファイルのmd5sumをメモしてください。これをシェルスクリプトで使用して、解凍したファイルが自分のファイルであることを確認できます。

find fachas_cat_files/ -type f -exec md5sum {} \; > cat.md5

以下のようにシェルスクリプトを作成し、名前を新しい「アーカイブ」プログラムとして指定します。

#!/bin/bash

TEMP_DIR=/tmp

# Check Md5sum
md5sum -c --quiet >/dev/null 2>&1 <<EOF 
--- Paste contents of cat.md5 here. ---
EOF

# Untar from base64 encoded tarball.
test $? -eq 0 || base64 -d <<EOF | tar -xz -C ${TEMP_DIR}
--- Paste contents of cat.b64 here. ---
EOF

# Execute the binary.
LD_LIBRARY_PATH=${TEMP_DIR}/fachas_cat_files/lib/ ${TEMP_DIR}/fachas_cat_files/cat $*

# Optionally remove the temporary files, if you do, the whole md5sum set of steps is 
# not necessary.
# rm -fr ${TEMP_DIR}/fachas_cat_files

答え4

実行可能なアーカイブのために変更された「ld-linux」に似たブートローダを作成したい場合は、これが可能であると言いたいと思います。 /proc/xxx/maps ファイルシステムで実行されている動的実行可能ファイルを調べると、実行中の動的実行可能ファイルがプロセスのメモリ空間にマップされたファイルの束にすぎないことがわかります。これらのマップされたファイルは、別々のファイルではなく実行可能なアーカイブの領域にすることができ、まだプロセスに表示されるのと同じデータを持ちます。実行可能なアーカイブの領域をPAGE_SIZEでソートする必要があります。 ld-linuxでファイル(実行ファイルとライブラリ)を見つけてマッピングすることに加えて、他のほとんどの機能は変更されていない可能性があります。

実行可能ファイルがdlopenなどのAPIを使用すると、合併症が発生します。実行可能なアーカイブにも含める必要がある場合は、libdl.soも変更してシステムlibdl.soの代わりにアーカイブに含める必要があります。

実行可能なアーカイブは、ブートストラップがファイルとファイル自体を見つけることができるように、ファイルのリストとそのオフセットを含む「ブートストラップld-linuxの置き換え」(静的バイナリ)のPAGE_SIZE接続でなければなりません。

誰でも参加すれば有用なプロジェクトになると思います。ドッカーコンテナよりはるかに軽いです。

関連情報