Wie zeige ich alle gemeinsam genutzten Bibliotheken an, die von ausführbaren Dateien unter Linux verwendet werden?
-
09-06-2019 - |
Frage
Ich möchte wissen, welche Bibliotheken von ausführbaren Dateien auf meinem System verwendet werden.Genauer gesagt möchte ich eine Rangfolge erstellen, welche Bibliotheken am häufigsten verwendet werden, zusammen mit den Binärdateien, die sie verwenden.Wie kann ich das machen?
Lösung
- Verwenden
ldd
um gemeinsam genutzte Bibliotheken für jede ausführbare Datei aufzulisten. - Bereinigen Sie die Ausgabe
- 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 /bin-Verzeichnis) sieht in etwa 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“ entfernt
Andere Tipps
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
Um zu erfahren, welche Bibliotheken eine Binärdatei verwendet, verwenden Sie ldd
ldd path/to/the/tool
Sie müssten ein kleines Shell-Skript schreiben, um zu Ihrer systemweiten Aufschlüsselung zu gelangen.
Unter Linux verwende ich:
lsof -P -T -p Application_PID
Das funktioniert besser als ldd
wenn die ausführbare Datei a verwendet Nicht standardmäßiger Loader
Überprüfen Sie die Abhängigkeiten einer 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 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.
Eine sicherere Möglichkeit, Bibliotheksabhängigkeiten einer unbekannten Anwendungsbinärdatei anzuzeigen, besteht stattdessen in der Verwendung des folgenden Befehls.
$ objdump -p /Pfad/zum/Programm | grep GEBRAUCHT
readelf -d
Rekursion
redelf -d
erzeugt eine ähnliche Ausgabe wie objdump -p
was erwähnt wurde unter: https://stackoverflow.com/a/15520982/895245
Beachten Sie jedoch, dass dynamische Bibliotheken von anderen dynamischen Bibliotheken abhängen können, sodass Sie eine Rekursion durchführen müssen.
Beispiel:
readelf -d /bin/ls | grep 'NEEDED'
Beispielausgabe:
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
für laufende Prozesse
Dies ist nützlich, um alle Bibliotheken zu finden, die derzeit von der Ausführung ausführbarer Dateien verwendet werden.Z.B.:
sudo awk '/\.so/{print $6}' /proc/1/maps | sort -u
zeigt alle aktuell geladenen dynamischen Abhängigkeiten von an 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 an, die mit geöffnet wurden dlopen
, getestet mit dieses minimale Setup gehackt mit einem sleep(1000)
auf Ubuntu 18.04.
Siehe auch: https://superuser.com/questions/310199/see-currently-loaded-shared-objects-in-linux/1243089
Nehmen wir auf einem UNIX-System an, dass der Name der Binärdatei (ausführbare Datei) test ist.Dann verwenden wir den folgenden Befehl, um die im Test verwendeten Bibliotheken aufzulisten
ldd test
Unter OS X gibt es standardmäßig keine ldd
, objdump
oder lsof
.Versuchen Sie es 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 wird verwendet which openssl
füllt den vollständig qualifizierten Pfad für die angegebene ausführbare Datei und die aktuelle Benutzerumgebung aus.
Mit ldd
Sie können die Bibliotheken erhalten, die die Tools verwenden.Um die Nutzung von Bibliotheken für eine Reihe von Tools zu bewerten, können Sie etwa den folgenden Befehl verwenden.
ldd /bin/* /usr/bin/* ... | sed -e '/^[^\t]/ d; s/^\t\(.* => \)\?\([^ ]*\) (.*/\2/g' | sort | uniq -c
(Hier sed
Entfernt alle Zeilen, die nicht mit einem Tabulator beginnen, und filtert nur die tatsächlichen Bibliotheken heraus.Mit sort | uniq -c
Sie erhalten für jede Bibliothek eine Zählung, die angibt, wie oft sie aufgetreten ist.)
Vielleicht möchten Sie hinzufügen sort -g
am Ende, um die Bibliotheken in der Reihenfolge ihrer Verwendung zu erhalten.
Beachten Sie, dass Sie mit dem obigen Befehl wahrscheinlich zwei Nicht-Bibliothekszeilen erhalten.Eine statische ausführbare Datei („keine dynamische ausführbare Datei“) und eine ohne Bibliothek.Letzteres ist das Ergebnis von linux-gate.so.1
Dabei handelt es sich nicht um eine Bibliothek in Ihrem Dateisystem, sondern um eine, die vom Kernel „bereitgestellt“ wird.
Unter Ubuntu Drucken von Paketen, die sich auf eine ausführbare Datei beziehen
ldd ausführbarer_Name|awk '{print $3}'|xargs dpkg -S |awk -F ":" '{print $1}'
Eine weitere Option besteht darin, einfach die Datei zu lesen, die sich unter befindet
/proc/<pid>/maps
Wenn zum Beispiel die Prozess-ID 2601 ist, lautet der Befehl auch
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
Ich fand diesen Beitrag sehr hilfreich, da ich Abhängigkeiten von einer von einem Drittanbieter bereitgestellten Bibliothek untersuchen musste (32- oder 64-Bit-Ausführungspfad(e)).
Ich habe ein rekursives Q&D-Bash-Skript basierend auf dem Vorschlag „readelf -d“ für eine RHEL 6-Distribution zusammengestellt.
Es ist sehr einfach und testet jedes Mal jede Abhängigkeit, auch wenn sie möglicherweise schon einmal getestet wurde (d. h. sehr ausführlich).Die Ausgabe ist ebenfalls 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“.
Nutzen und modifizieren Sie, natürlich auf eigenes Risiko, nach Ihren Wünschen.