Linuxで実行可能ファイルによって使用されるすべての共有ライブラリを表示する方法は?


225

私のシステムの実行可能ファイルで使用されているライブラリを知りたいのですが。具体的には、どのライブラリが最もよく使用されるか、およびそれらを使用するバイナリをランク付けしたいと思います。これどうやってするの?


実行可能ファイルがを使用してdlopenいる場合は、正確な数を取得できない可能性があります。
jxh 2018

回答:


271
  1. ldd各実行可能ファイルの共有ライブラリをリストするために使用します。
  2. 出力をクリーンアップする
  3. ソート、カウントの計算、カウントによるソート

「/ bin」ディレクトリにあるすべての実行可能ファイルの答えを見つけるには、次のようにします。

find /bin -type f -perm /a+x -exec ldd {} \; \
| grep so \
| sed -e '/^[^\t]/ d' \
| sed -e 's/\t//' \
| sed -e 's/.*=..//' \
| sed -e 's/ (0.*)//' \
| sort \
| uniq -c \
| sort -n

上記の「/ bin」を「/」に変更して、すべてのディレクトリを検索します。

出力(/ binディレクトリのみ)は次のようになります。

  1 /lib64/libexpat.so.0
  1 /lib64/libgcc_s.so.1
  1 /lib64/libnsl.so.1
  1 /lib64/libpcre.so.0
  1 /lib64/libproc-3.2.7.so
  1 /usr/lib64/libbeecrypt.so.6
  1 /usr/lib64/libbz2.so.1
  1 /usr/lib64/libelf.so.1
  1 /usr/lib64/libpopt.so.0
  1 /usr/lib64/librpm-4.4.so
  1 /usr/lib64/librpmdb-4.4.so
  1 /usr/lib64/librpmio-4.4.so
  1 /usr/lib64/libsqlite3.so.0
  1 /usr/lib64/libstdc++.so.6
  1 /usr/lib64/libz.so.1
  2 /lib64/libasound.so.2
  2 /lib64/libblkid.so.1
  2 /lib64/libdevmapper.so.1.02
  2 /lib64/libpam_misc.so.0
  2 /lib64/libpam.so.0
  2 /lib64/libuuid.so.1
  3 /lib64/libaudit.so.0
  3 /lib64/libcrypt.so.1
  3 /lib64/libdbus-1.so.3
  4 /lib64/libresolv.so.2
  4 /lib64/libtermcap.so.2
  5 /lib64/libacl.so.1
  5 /lib64/libattr.so.1
  5 /lib64/libcap.so.1
  6 /lib64/librt.so.1
  7 /lib64/libm.so.6
  9 /lib64/libpthread.so.0
 13 /lib64/libselinux.so.1
 13 /lib64/libsepol.so.1
 22 /lib64/libdl.so.2
 83 /lib64/ld-linux-x86-64.so.2
 83 /lib64/libc.so.6

編集-「grep -P」を削除


2
これは素晴らしい答えです(私はそれを賛成しました)が、「grep -P '\ t。* so'」コマンドについて説明できますか?男性によると、これはパターンをperl正規表現として解釈しますが、私のバージョンのgrepではサポートしていません(男性はこれが一般的な問題であることを示しています)。正規表現のどの部分がperl固有ですか?
ボビージャック

2
私はあなたが使う必要があるかもしれないと思いますldd -v
MountainX

58
lddは、特別な環境変数を使用して実行可能ファイルを実際に実行し、Linuxダイナミックリンカーはこのフラグを認識し、実行可能ファイルを実行するのではなく、ライブラリを出力することに注意してください。ソースを見てくださいldd。私のシステムでは、bashスクリプトです。実行可能ファイルが静的にリンクされており、syscallsを使用し、別のローダーを指定している場合、任意の悪質なことが行われる可能性があります。したがってldd、信頼できない実行可能ファイルでは使用しないでください。
バリーケリー

「ldd」は、クロスコンパイルされたバイナリでは機能しません。問題は、現在のシステムのプログラムで使用されているライブラリーを検索することです(これは、ネイティブプログラムです)。これはそのための良い答えです。ただし、別のシステムのプログラム用の共有ライブラリを探す場合は、別のものを使用する必要があることを私は言及したいと思いました(別の回答で言及された「readelf」、私のために働いた)
Tim Bird

68

ARMツールチェーンにlddがないため、objdumpを使用しました。

$(CROSS_COMPILE)objdump -p

例えば:

objdump -p /usr/bin/python:

Dynamic Section:
  NEEDED               libpthread.so.0
  NEEDED               libdl.so.2
  NEEDED               libutil.so.1
  NEEDED               libssl.so.1.0.0
  NEEDED               libcrypto.so.1.0.0
  NEEDED               libz.so.1
  NEEDED               libm.so.6
  NEEDED               libc.so.6
  INIT                 0x0000000000416a98
  FINI                 0x000000000053c058
  GNU_HASH             0x0000000000400298
  STRTAB               0x000000000040c858
  SYMTAB               0x0000000000402aa8
  STRSZ                0x0000000000006cdb
  SYMENT               0x0000000000000018
  DEBUG                0x0000000000000000
  PLTGOT               0x0000000000832fe8
  PLTRELSZ             0x0000000000002688
  PLTREL               0x0000000000000007
  JMPREL               0x0000000000414410
  RELA                 0x0000000000414398
  RELASZ               0x0000000000000078
  RELAENT              0x0000000000000018
  VERNEED              0x0000000000414258
  VERNEEDNUM           0x0000000000000008
  VERSYM               0x0000000000413534

2
ldd信頼できない実行可能ファイルでは使用しないでください。これも安全です。
PSkocik

また、のobbjdump -pような追加情報を表示RPATHします。これは、実行可能ファイルの動的リンクの問題を調査するときに役立つ場合があります。
シタクティフ2018年

実際には、安全で信頼性のある方法のための+1は、(私は何とかシステム持ってmusl-gcc定期的に呼び出すようなバイナリを生成しlddたバイナリにするだけでバイナリを実行ので、今日、私は定期的に安全ではないが、どれだけのことを思い出しています、lddですが)。
mtraceur

54

Linuxでは次を使用します:

lsof -P -T -p Application_PID

これlddは、実行可能ファイルがデフォルト以外のローダーを使用する場合よりもうまく機能します


これを使用して、mariadbが実際に LD_PRELOADによってロードされるtc-mallocを使用しているかどうかを確認しました。よく働く。
cmc 2013

2
与えられたpidに対して '.so'を示すものを探していました。これはまさに私が必要としたものです。ありがとう!
レオUfimtsev 2017

48

バイナリが使用するライブラリを知るには、lddを使用します

ldd path/to/the/tool

システム全体の内訳を取得するには、小さなシェルスクリプトを記述する必要があります。


19

プログラム実行可能ファイルの共有ライブラリの依存関係を確認する

特定の実行可能ファイルがどのライブラリに依存しているかを調べるには、lddコマンドを使用できます。このコマンドは、動的リンカーを呼び出して、実行可能ファイルのライブラリの依存関係を見つけます。

> $ ldd / path / to / program

lddのバージョンによっては、実行可能ファイルを直接呼び出してライブラリの依存関係を特定する可能性があるため、信頼できないサードパーティの実行可能ファイルでlddを実行することはお勧めできません。

代わりに、不明なアプリケーションバイナリのライブラリの依存関係を表示するより安全な方法は、次のコマンドを使用することです。

$ objdump -p / path / to / program | 必要なgrep

詳しくは


14

readelf -d 再帰

redelf -dhttps://stackoverflow.com/a/15520982/895245でobjdump -p言及されているのと同様の出力を生成します

ただし、再帰する必要があるため、動的ライブラリは他の動的ライブラリに依存する可能性があることに注意してください。

例:

readelf -d /bin/ls | grep 'NEEDED'

サンプル出力:

 0x0000000000000001 (NEEDED)             Shared library: [libselinux.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libacl.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]

次に:

$ locate libselinux.so.1
/lib/i386-linux-gnu/libselinux.so.1
/lib/x86_64-linux-gnu/libselinux.so.1
/mnt/debootstrap/lib/x86_64-linux-gnu/libselinux.so.1

1つ選択して、繰り返します。

readelf -d /lib/x86_64-linux-gnu/libselinux.so.1 | grep 'NEEDED'

出力例:

0x0000000000000001 (NEEDED)             Shared library: [libpcre.so.3]
0x0000000000000001 (NEEDED)             Shared library: [libdl.so.2]
0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
0x0000000000000001 (NEEDED)             Shared library: [ld-linux-x86-64.so.2]

等々。

/proc/<pid>/maps 実行中のプロセス

これは、実行可能ファイルを実行することによって現在使用されているすべてのライブラリを見つけるのに役立ちます。例えば:

sudo awk '/\.so/{print $6}' /proc/1/maps | sort -u

現在読み込まれているinit(PID 1)の動的依存関係をすべて表示します。

/lib/x86_64-linux-gnu/ld-2.23.so
/lib/x86_64-linux-gnu/libapparmor.so.1.4.0
/lib/x86_64-linux-gnu/libaudit.so.1.0.0
/lib/x86_64-linux-gnu/libblkid.so.1.1.0
/lib/x86_64-linux-gnu/libc-2.23.so
/lib/x86_64-linux-gnu/libcap.so.2.24
/lib/x86_64-linux-gnu/libdl-2.23.so
/lib/x86_64-linux-gnu/libkmod.so.2.3.0
/lib/x86_64-linux-gnu/libmount.so.1.1.0
/lib/x86_64-linux-gnu/libpam.so.0.83.1
/lib/x86_64-linux-gnu/libpcre.so.3.13.2
/lib/x86_64-linux-gnu/libpthread-2.23.so
/lib/x86_64-linux-gnu/librt-2.23.so
/lib/x86_64-linux-gnu/libseccomp.so.2.2.3
/lib/x86_64-linux-gnu/libselinux.so.1
/lib/x86_64-linux-gnu/libuuid.so.1.3.0

このメソッドは、Ubuntu 18.04 のでハッキングされたこの最小限のセットアップdlopenでテストされ、で開かれたライブラリも表示します。sleep(1000)

参照:https : //superuser.com/questions/310199/see-currently-loaded-shared-objects-in-linux/1243089


7

OS Xでは、デフォルトではlddobjdumpまたははありませんlsof。別の方法として、次を試してくださいotool -L

$ otool -L `which openssl`
/usr/bin/openssl:
    /usr/lib/libcrypto.0.9.8.dylib (compatibility version 0.9.8, current version 0.9.8)
    /usr/lib/libssl.0.9.8.dylib (compatibility version 0.9.8, current version 0.9.8)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0)

この例でwhich opensslは、指定された実行可能ファイルと現在のユーザー環境の完全修飾パスに入力を使用しています。


6

UNIXシステムで、バイナリ(実行可能)名がtestであるとします。次に、次のコマンドを使用して、テストで使用されるライブラリをリストします。

ldd test

4

ではldd、あなたのツールが使用するライブラリを入手することができます。ツールセットのライブラリの使用状況をランク付けするには、次のようなコマンドを使用できます。

ldd /bin/* /usr/bin/* ... | sed -e '/^[^\t]/ d; s/^\t\(.* => \)\?\([^ ]*\) (.*/\2/g' | sort | uniq -c

(ここでsedは、タブで始まらないすべての行が取り除かれ、実際のライブラリーのみがフィルターで除外されます。これによりsort | uniq -c、各ライブラリーには、発生した回数を示すカウントが表示されます。

sort -g使用順にライブラリを取得するには、最後に追加することをお勧めします。

上記のコマンドを使用すると、おそらく2行の非ライブラリ行が表示されることに注意してください。静的実行可能ファイルの1つ(「動的実行可能ファイルではない」)と、ライブラリのないもの。後者は、linux-gate.so.1ファイルシステム内のライブラリではなく、カーネルによって「提供された」ライブラリの結果です。


2

もう1つのオプションは、次の場所にあるファイルを読み取るだけです。

/proc/<pid>/maps

たとえば、プロセスIDが2601の場合、コマンドは

cat /proc/2601/maps

そして出力は

7fb37a8f2000-7fb37a8f4000 r-xp 00000000 08:06 4065647                    /usr/lib/x86_64-linux-gnu/libproxy/0.4.15/modules/network_networkmanager.so
7fb37a8f4000-7fb37aaf3000 ---p 00002000 08:06 4065647                    /usr/lib/x86_64-linux-gnu/libproxy/0.4.15/modules/network_networkmanager.so
7fb37aaf3000-7fb37aaf4000 r--p 00001000 08:06 4065647                    /usr/lib/x86_64-linux-gnu/libproxy/0.4.15/modules/network_networkmanager.so
7fb37aaf4000-7fb37aaf5000 rw-p 00002000 08:06 4065647                    /usr/lib/x86_64-linux-gnu/libproxy/0.4.15/modules/network_networkmanager.so
7fb37aaf5000-7fb37aafe000 r-xp 00000000 08:06 4065646                    /usr/lib/x86_64-linux-gnu/libproxy/0.4.15/modules/config_gnome3.so
7fb37aafe000-7fb37acfd000 ---p 00009000 08:06 4065646                    /usr/lib/x86_64-linux-gnu/libproxy/0.4.15/modules/config_gnome3.so
7fb37acfd000-7fb37acfe000 r--p 00008000 08:06 4065646                    /usr/lib/x86_64-linux-gnu/libproxy/0.4.15/modules/config_gnome3.so
7fb37acfe000-7fb37acff000 rw-p 00009000 08:06 4065646                    /usr/lib/x86_64-linux-gnu/libproxy/0.4.15/modules/config_gnome3.so
7fb37acff000-7fb37ad1d000 r-xp 00000000 08:06 3416761                    /usr/lib/x86_64-linux-gnu/libproxy.so.1.0.0
7fb37ad1d000-7fb37af1d000 ---p 0001e000 08:06 3416761                    /usr/lib/x86_64-linux-gnu/libproxy.so.1.0.0
7fb37af1d000-7fb37af1e000 r--p 0001e000 08:06 3416761                    /usr/lib/x86_64-linux-gnu/libproxy.so.1.0.0
7fb37af1e000-7fb37af1f000 rw-p 0001f000 08:06 3416761                    /usr/lib/x86_64-linux-gnu/libproxy.so.1.0.0
7fb37af1f000-7fb37af21000 r-xp 00000000 08:06 4065186                    /usr/lib/x86_64-linux-gnu/gio/modules/libgiolibproxy.so
7fb37af21000-7fb37b121000 ---p 00002000 08:06 4065186                    /usr/lib/x86_64-linux-gnu/gio/modules/libgiolibproxy.so
7fb37b121000-7fb37b122000 r--p 00002000 08:06 4065186                    /usr/lib/x86_64-linux-gnu/gio/modules/libgiolibproxy.so
7fb37b122000-7fb37b123000 rw-p 00003000 08:06 4065186                    /usr/lib/x86_64-linux-gnu/gio/modules/libgiolibproxy.so

2

実行可能ファイルに関連するubuntu印刷パッケージ

ldd executable_name|awk '{print $3}'|xargs dpkg -S |awk -F  ":"  '{print $1}'

0

サードパーティが提供するライブラリ(32ビットと64ビットの実行パス)の依存関係を調査する必要があるため、この投稿は非常に役立ちました。

RHEL 6ディストリビューションでの「readelf -d」の提案に基づいて、Q&D再帰bashスクリプトをまとめました。

これは非常に基本的で、以前にテストされていたとしても(つまり、非常に冗長であっても)毎回すべての依存関係をテストします。出力も非常に基本的です。

#! /bin/bash

recurse ()
# Param 1 is the nuumber of spaces that the output will be prepended with
# Param 2 full path to library
{
#Use 'readelf -d' to find dependencies
dependencies=$(readelf -d ${2} | grep NEEDED | awk '{ print $5 }' | tr -d '[]')
for d in $dependencies; do
   echo "${1}${d}"
   nm=${d##*/}
   #libstdc++ hack for the '+'-s
   nm1=${nm//"+"/"\+"}
   # /lib /lib64 /usr/lib and /usr/lib are searched
   children=$(locate ${d} | grep -E "(^/(lib|lib64|usr/lib|usr/lib64)/${nm1})")
   rc=$?
   #at least locate... didn't fail
   if [ ${rc} == "0" ] ; then
      #we have at least one dependency
      if [ ${#children[@]} -gt 0 ]; then
         #check the dependeny's dependencies
         for c in $children; do
          recurse "  ${1}" ${c}
         done
      else
         echo "${1}no children found"
      fi
   else
      echo "${1}locate failed for ${d}"
   fi
done
}
# Q&D -- recurse needs 2 params could/should be supplied from cmdline
recurse "" !!full path to library you want to investigate!!

出力をファイルにリダイレクトし、 'found'または 'failed'のgrep

もちろん、ご自身の責任において、ご希望どおりに使用および変更してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.