Je veux découvrir la liste des bibliothèques dynamiques qu'un binaire charge lors de l'exécution (avec leurs chemins d'accès complets). J'utilise CentOS 6.0. Comment faire ça?
Vous pouvez le faire avec la commande ldd
:
NAME
ldd - print shared library dependencies
SYNOPSIS
ldd [OPTION]... FILE...
DESCRIPTION
ldd prints the shared libraries required by each program or shared
library specified on the command line.
....
Exemple:
$ ldd /bin/ls
linux-vdso.so.1 => (0x00007fff87ffe000)
libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007ff0510c1000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007ff050eb9000)
libacl.so.1 => /lib/x86_64-linux-gnu/libacl.so.1 (0x00007ff050cb0000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff0508f0000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007ff0506ec000)
/lib64/ld-linux-x86-64.so.2 (0x00007ff0512f7000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007ff0504ce000)
libattr.so.1 => /lib/x86_64-linux-gnu/libattr.so.1 (0x00007ff0502c9000)
readelf -d $executable | grep 'NEEDED'
Peut être utilisé si vous ne pouvez pas exécuter l'exécutable, par ex. si elle a été compilée de manière croisée, ou si vous n'y faites pas confiance:
Dans le cas habituel, ldd appelle l'éditeur de liens dynamique standard (voir ld.so (8)) avec la variable d'environnement LD_TRACE_LOADED_OBJECTS définie sur 1, ce qui entraîne l'éditeur de liens pour afficher les dépendances de bibliothèque. Cependant, sachez que dans certaines circonstances, certaines versions de ldd peuvent tenter d'obtenir les informations de dépendance en exécutant directement le programme. Par conséquent, vous ne devez jamais utiliser ldd sur un exécutable non approuvé, car cela peut entraîner l'exécution de code arbitraire.
Exemple:
readelf -d /bin/ls | grep 'NEEDED'
Exemple de sortie:
0x0000000000000001 (NEEDED) Shared library: [libselinux.so.1]
0x0000000000000001 (NEEDED) Shared library: [libacl.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
Notez que les bibliothèques peuvent dépendre d'autres bibliothèques, vous devez donc maintenant trouver les dépendances.
Une approche naïve qui fonctionne souvent est:
$ 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
mais la méthode la plus précise consiste à comprendre le chemin de recherche/cache ldd
. Je pense que ldconfig
est la voie à suivre.
Choisissez-en un et répétez:
readelf -d /lib/x86_64-linux-gnu/libselinux.so.1 | grep 'NEEDED'
Exemple de sortie:
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]
Etc.
Voir également:
/proc/<pid>/maps
Pour l'exécution des processus
Mentionné par Basile , ceci est utile pour trouver toutes les bibliothèques actuellement utilisées par les exécutables. Par exemple.:
Sudo awk '/\.so/{print $6}' /proc/1/maps | sort -u
affiche toutes les dépendances dynamiques actuellement chargées de 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
Cette méthode montre également les bibliothèques ouvertes avec dlopen
, testées avec cette configuration minimale piratées avec une sleep(1000)
sur Ubuntu 18.04.
Voir aussi: Comment voir les objets partagés actuellement chargés dans Linux? | Super User
ldd et lsof montrent les bibliothèques chargées soit directement soit à un moment donné . Ils ne tiennent pas compte des bibliothèques chargées via dlopen
(ou supprimées par dlclose
). Vous pouvez obtenir une meilleure image de cela en utilisant strace
, par exemple,
strace -e trace=open myprogram
(puisque dlopen
appelle finalement open
- bien que vous puissiez bien sûr avoir un système utilisant des noms différents pour les ouvertures 64 bits ...).
Exemple:
strace -e trace=open date
me montre ceci:
open("/etc/ld.so.cache", O_RDONLY) = 3
open("/lib/x86_64-linux-gnu/librt.so.1", O_RDONLY) = 3
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY) = 3
open("/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY) = 3
open("/usr/lib/locale/locale-archive", O_RDONLY) = 3
open("/etc/localtime", O_RDONLY) = 3
Wed Apr 12 04:56:32 EDT 2017
à partir de laquelle on pourrait grep les noms ".so" pour juste voir les objets partagés.
lsof peut également vous montrer quelles bibliothèques sont utilisées pour un processus particulier.
c'est à dire.
$ pidof nginx
6920 6919
$ lsof -p 6919|grep mem
nginx 6919 root mem REG 0,64 65960 43 /lib64/libnss_files-2.12.so
nginx 6919 root mem REG 0,64 19536 36 /lib64/libdl-2.12.so
nginx 6919 root mem REG 0,64 10312 1875 /lib64/libfreebl3.so
nginx 6919 root mem REG 0,64 1923352 38 /lib64/libc-2.12.so
nginx 6919 root mem REG 0,64 88600 1034 /lib64/libz.so.1.2.3
nginx 6919 root mem REG 0,64 1967392 1927 /usr/lib64/libcrypto.so.1.0.1e
nginx 6919 root mem REG 0,64 183080 1898 /lib64/libpcre.so.0.0.1
nginx 6919 root mem REG 0,64 40400 1217 /lib64/libcrypt-2.12.so
nginx 6919 root mem REG 0,64 142688 77 /lib64/libpthread-2.12.so
nginx 6919 root mem REG 0,64 154664 31 /lib64/ld-2.12.so
créer un petit script (useslib
) et le mettre dans le PATH (ou spécifier un chemin complet dans la commande ci-dessous)
#! /bin/bash
ldd $1 | grep -q $2
exit $?
Utilisez-le dans une commande find
, par exemple:
find /usr/bin/ -executable -type f -exec useslib {} libgtk-x11-2.0 \; -print
(libgtk-x11-2.0 semble être la lib gtk2)
Pour un processus du pid 1234, vous pouvez également lire le /proc/1234/maps
pseudo-fichier (textuel) (lire proc (5) ...) ou utiliser pmap (1)
Cela donne espace d'adressage virtuel de ce processus, d'où les fichiers (y compris les bibliothèques partagées, même dlopen (3) - ed one) qui sont mappés en mémoire
(bien sûr, utilisez ps aux
ou pgrep (1) pour trouver les processus exécutant un programme donné)
Il est possible d'utiliser pmap
.
Par exemple, démarrez un processus: $ watch date
Obtenez pid: $ ps -ef | grep watch
Afficher la carte mémoire: $ pmap <pid>
Afficher avec le chemin complet: $ pmap <pid> -p
$ pmap 72770
72770: watch date
00005613a32c9000 20K r-x-- watch
00005613a34cd000 4K r---- watch
00005613a34ce000 4K rw--- watch
00005613a4f6a000 264K rw--- [ anon ]
00007f2f3a7d5000 204616K r---- locale-archive
00007f2f46fa7000 1748K r-x-- libc-2.27.so
00007f2f4715c000 2048K ----- libc-2.27.so
00007f2f4735c000 16K r---- libc-2.27.so
00007f2f47360000 8K rw--- libc-2.27.so
00007f2f47362000 16K rw--- [ anon ]
00007f2f47366000 12K r-x-- libdl-2.27.so
00007f2f47369000 2044K ----- libdl-2.27.so
00007f2f47568000 4K r---- libdl-2.27.so
00007f2f47569000 4K rw--- libdl-2.27.so
00007f2f4756a000 160K r-x-- libtinfo.so.6.1
00007f2f47592000 2048K ----- libtinfo.so.6.1
00007f2f47792000 16K r---- libtinfo.so.6.1
00007f2f47796000 4K rw--- libtinfo.so.6.1
00007f2f47797000 232K r-x-- libncursesw.so.6.1
00007f2f477d1000 2048K ----- libncursesw.so.6.1
00007f2f479d1000 4K r---- libncursesw.so.6.1
00007f2f479d2000 4K rw--- libncursesw.so.6.1
00007f2f479d3000 148K r-x-- ld-2.27.so
00007f2f47bdb000 20K rw--- [ anon ]
00007f2f47bf1000 28K r--s- gconv-modules.cache
00007f2f47bf8000 4K r---- ld-2.27.so
00007f2f47bf9000 4K rw--- ld-2.27.so
00007f2f47bfa000 4K rw--- [ anon ]
00007ffd39404000 136K rw--- [ stack ]
00007ffd3959b000 12K r---- [ anon ]
00007ffd3959e000 8K r-x-- [ anon ]
ffffffffff600000 4K r-x-- [ anon ]
total 215692K
$ pmap 72770 -p
72770: watch date
00005613a32c9000 20K r-x-- /usr/bin/watch
00005613a34cd000 4K r---- /usr/bin/watch
00005613a34ce000 4K rw--- /usr/bin/watch
00005613a4f6a000 264K rw--- [ anon ]
00007f2f3a7d5000 204616K r---- /usr/lib/locale/locale-archive
00007f2f46fa7000 1748K r-x-- /usr/lib64/libc-2.27.so
00007f2f4715c000 2048K ----- /usr/lib64/libc-2.27.so
00007f2f4735c000 16K r---- /usr/lib64/libc-2.27.so
00007f2f47360000 8K rw--- /usr/lib64/libc-2.27.so
00007f2f47362000 16K rw--- [ anon ]
00007f2f47366000 12K r-x-- /usr/lib64/libdl-2.27.so
00007f2f47369000 2044K ----- /usr/lib64/libdl-2.27.so
00007f2f47568000 4K r---- /usr/lib64/libdl-2.27.so
00007f2f47569000 4K rw--- /usr/lib64/libdl-2.27.so
00007f2f4756a000 160K r-x-- /usr/lib64/libtinfo.so.6.1
00007f2f47592000 2048K ----- /usr/lib64/libtinfo.so.6.1
00007f2f47792000 16K r---- /usr/lib64/libtinfo.so.6.1
00007f2f47796000 4K rw--- /usr/lib64/libtinfo.so.6.1
00007f2f47797000 232K r-x-- /usr/lib64/libncursesw.so.6.1
00007f2f477d1000 2048K ----- /usr/lib64/libncursesw.so.6.1
00007f2f479d1000 4K r---- /usr/lib64/libncursesw.so.6.1
00007f2f479d2000 4K rw--- /usr/lib64/libncursesw.so.6.1
00007f2f479d3000 148K r-x-- /usr/lib64/ld-2.27.so
00007f2f47bdb000 20K rw--- [ anon ]
00007f2f47bf1000 28K r--s- /usr/lib64/gconv/gconv-modules.cache
00007f2f47bf8000 4K r---- /usr/lib64/ld-2.27.so
00007f2f47bf9000 4K rw--- /usr/lib64/ld-2.27.so
00007f2f47bfa000 4K rw--- [ anon ]
00007ffd39404000 136K rw--- [ stack ]
00007ffd3959b000 12K r---- [ anon ]
00007ffd3959e000 8K r-x-- [ anon ]
ffffffffff600000 4K r-x-- [ anon ]
total 215692K