Wie werden alle gemeinsam genutzten Bibliotheken angezeigt, die von ausführbaren Dateien unter Linux verwendet werden?


225

Ich möchte wissen, welche Bibliotheken von ausführbaren Dateien auf meinem System verwendet werden. Insbesondere möchte ich bewerten, welche Bibliotheken am häufigsten verwendet werden, zusammen mit den Binärdateien, die sie verwenden. Wie kann ich das machen?


Sie werden wahrscheinlich keine genaue Nummer erhalten können, wenn die ausführbaren Dateien verwendet werden dlopen.
jxh

Antworten:


271
  1. Verwenden Sie ldddiese Option, um gemeinsam genutzte Bibliotheken für jede ausführbare Datei aufzulisten.
  2. Bereinigen Sie die Ausgabe
  3. Sortieren, Zählungen berechnen, nach Zählung sortieren

So finden Sie die Antwort für alle ausführbaren Dateien im Verzeichnis "/ 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

Ändern Sie "/ bin" oben in "/", um alle Verzeichnisse zu durchsuchen.

Die Ausgabe (nur für das Verzeichnis / bin) sieht ungefähr so ​​aus:

  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

Bearbeiten - "grep -P" wurde entfernt


2
Dies ist eine großartige Antwort (ich habe sie hochgestimmt), aber können Sie den Befehl "grep -P '\ t. * So'" erklären? Laut man interpretiert dies das Muster als Perl-Regexp, aber meine Version von grep unterstützt es nicht (man gibt an, dass dies ein allgemeines Problem ist). Welcher Teil des regulären Ausdrucks ist perlspezifisch?
Bobby Jack

2
Ich denke, Sie müssen möglicherweise verwendenldd -v
MountainX

56
Beachten Sie, dass ldddie ausführbare Datei tatsächlich mit einer speziellen Umgebungsvariablen ausgeführt wird und der dynamische Linux-Linker dieses Flag erkennt und nur die Bibliotheken ausgibt, anstatt die ausführbare Datei auszuführen. Schauen Sie sich die Quelle an ldd; Auf meinem System ist es ein Bash-Skript. Wenn die ausführbare Datei statisch verknüpft ist und Syscalls verwendet und einen anderen Loader angibt, kann sie beliebige böse Dinge tun. Verwenden lddSie es also nicht für eine ausführbare Datei, der Sie nicht vertrauen.
Barry Kelly

'ldd' funktioniert bei Cross-kompilierten Binärdateien nicht für mich. Die Frage besteht darin, die Bibliotheken zu finden, die von Programmen auf dem aktuellen System verwendet werden (das wären native Programme, wie formuliert). Dies ist eine gute Antwort darauf. Ich dachte jedoch, ich würde erwähnen, dass Sie etwas anderes verwenden müssen, wenn Sie nach den gemeinsam genutzten Bibliotheken für Programme für ein anderes System suchen ('readelf' in einer anderen Antwort erwähnt, hat für mich funktioniert)
Tim Bird

68

Ich hatte kein ldd in meiner ARM-Toolchain, also habe ich objdump verwendet:

$ (CROSS_COMPILE) objdump -p

Zum Beispiel:

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
Dies sollte auch sicher sein, im Gegensatz zu lddnicht vertrauenswürdigen ausführbaren Dateien.
PSkocik

Außerdem werden obbjdump -pzusätzliche Informationen wie RPATHdie angezeigt, die bei der Untersuchung dynamischer Verknüpfungsprobleme mit Ihrer ausführbaren Datei hilfreich sein können.
Sitaktif

+1 für die Methode, die tatsächlich sicher und zuverlässig ist (ich habe irgendwie ein System, in dem musl-gccregelmäßig Binärdateien erstellt werden, sodass beim Aufrufen lddder Binärdatei nur die Binärdatei ausgeführt wird , sodass ich heutzutage regelmäßig daran erinnert werde, wie unsicher sie lddist).
mtraceur


48

Verwenden Sie ldd, um zu erfahren, welche Bibliotheken eine Binärdatei verwendet

ldd path/to/the/tool

Sie müssten ein kleines Shell-Skript schreiben, um zu Ihrer systemweiten Aufschlüsselung zu gelangen.


19

Überprüfen Sie die Abhängigkeiten der gemeinsam genutzten Bibliothek einer ausführbaren Programmdatei

Um herauszufinden, von welchen Bibliotheken eine bestimmte ausführbare Datei abhängt, können Sie den Befehl ldd verwenden. Dieser Befehl ruft den dynamischen Linker auf, um die Bibliotheksabhängigkeiten einer ausführbaren Datei herauszufinden.

> $ ldd / path / to / program

Beachten Sie, dass es NICHT empfohlen wird, ldd mit einer nicht vertrauenswürdigen ausführbaren Datei eines Drittanbieters auszuführen, da einige Versionen von ldd die ausführbare Datei möglicherweise direkt aufrufen, um ihre Bibliotheksabhängigkeiten zu identifizieren, was ein Sicherheitsrisiko darstellen kann.

Stattdessen können Sie Bibliotheksabhängigkeiten einer unbekannten Anwendungsbinärdatei sicherer anzeigen, indem Sie den folgenden Befehl verwenden.

$ objdump -p / path / to / program | grep BENÖTIGT

Für mehr Information


14

readelf -d Rekursion

redelf -derzeugt eine ähnliche Ausgabe, objdump -pdie unter https://stackoverflow.com/a/15520982/895245 erwähnt wurde

Beachten Sie jedoch, dass dynamische Bibliotheken von anderen dynamischen Bibliotheken abhängen können, auf die Sie zurückgreifen müssen.

Beispiel:

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

Beispiel ouptut:

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

Dann:

$ 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

Wählen Sie eine aus und wiederholen Sie:

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

Beispielausgabe:

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]

Und so weiter.

/proc/<pid>/maps zum Ausführen von Prozessen

Dies ist nützlich, um alle Bibliotheken zu finden, die derzeit von ausführbaren Dateien verwendet werden. Z.B:

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

zeigt alle aktuell geladenen dynamischen Abhängigkeiten von 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

Diese Methode zeigt auch Bibliotheken dlopen, die mit diesem minimalen Setup geöffnet und getestet wurden, das mit einem sleep(1000)unter Ubuntu 18.04 gehackten Setup gehackt wurde .

Siehe auch: /superuser/310199/see-currently-loaded-shared-objects-in-linux/1243089


7

Unter OS X standardmäßig gibt es keine ldd, objdumpoder lsof. Versuchen Sie alternativ 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)

In diesem Beispiel which opensslfüllt die Verwendung den vollständig qualifizierten Pfad für die angegebene ausführbare und aktuelle Benutzerumgebung aus.


6

Angenommen, auf einem UNIX-System ist der binäre (ausführbare) Name test. Dann verwenden wir den folgenden Befehl, um die im Test verwendeten Bibliotheken aufzulisten

ldd test

4

Mit lddkönnen Sie die Bibliotheken erhalten, die Tools verwenden. Um die Verwendung von Bibliotheken für eine Reihe von Tools einzustufen, können Sie den folgenden Befehl verwenden.

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

(Hier werden sedalle Zeilen entfernt, die nicht mit einer Registerkarte beginnen, und nur die tatsächlichen Bibliotheken herausgefiltert. Mit erhalten sort | uniq -cSie jede Bibliothek mit einer Zählung, die angibt, wie oft sie aufgetreten ist.)

Möglicherweise möchten Sie sort -gam Ende hinzufügen , um die Bibliotheken in der Reihenfolge ihrer Verwendung abzurufen.

Beachten Sie, dass Sie mit dem obigen Befehl wahrscheinlich Zeilen erhalten, die nicht aus der Bibliothek stammen. Eine der statischen ausführbaren Dateien ("keine dynamische ausführbare Datei") und eine ohne Bibliothek. Letzteres ist das Ergebnis, linux-gate.so.1dass es sich nicht um eine Bibliothek in Ihrem Dateisystem handelt, sondern um eine vom Kernel "bereitgestellte".


2

Eine weitere Option ist das Lesen der Datei unter

/proc/<pid>/maps

Wenn die Prozess-ID beispielsweise 2601 lautet, lautet der Befehl

cat /proc/2601/maps

Und die Ausgabe ist wie

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

auf Ubuntu-Druckpaketen, die sich auf eine ausführbare Datei beziehen

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

0

Ich fand diesen Beitrag sehr hilfreich, da ich Abhängigkeiten von einer von Drittanbietern bereitgestellten Bibliothek untersuchen musste (32- oder 64-Bit-Ausführungspfade).

Ich habe ein rekursives Q & D-Bash-Skript zusammengestellt, das auf dem Vorschlag 'readelf -d' in einer RHEL 6-Distribution basiert.

Es ist sehr einfach und testet jede Abhängigkeit jedes Mal, selbst wenn es zuvor getestet wurde (dh sehr ausführlich). Die Ausgabe ist auch sehr einfach.

#! /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!!

Leiten Sie die Ausgabe in eine Datei um und suchen Sie nach "gefunden" oder "fehlgeschlagen".

Verwenden und modifizieren Sie auf eigenes Risiko, wie Sie möchten.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.