Voglio scoprire l'elenco delle librerie dinamiche che un binario carica quando viene eseguito (con i loro percorsi completi). Sto usando CentOS 6.0. Come fare questo?
Voglio scoprire l'elenco delle librerie dinamiche che un binario carica quando viene eseguito (con i loro percorsi completi). Sto usando CentOS 6.0. Come fare questo?
Risposte:
Puoi farlo con il ldd
comando:
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.
....
Esempio:
$ 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)
otool -L <path-to-binary>
ldd
. Vedi la pagina man .
readelf -d $executable | grep 'NEEDED'
Può essere utilizzato se non è possibile eseguire l'eseguibile, ad esempio se è stato compilato in modo incrociato o se non ci si fida:
Nel solito caso, ldd invoca il linker dinamico standard (vedi ld.so (8)) con la variabile d'ambiente LD_TRACE_LOADED_OBJECTS impostata su 1, che fa sì che il linker visualizzi le dipendenze della libreria. Tenere presente, tuttavia, che in alcune circostanze, alcune versioni di ldd potrebbero tentare di ottenere le informazioni sulla dipendenza eseguendo direttamente il programma. Pertanto, non dovresti mai utilizzare ldd su un eseguibile non attendibile, poiché ciò potrebbe comportare l'esecuzione di codice arbitrario.
Esempio:
readelf -d /bin/ls | grep 'NEEDED'
Uscita campione:
0x0000000000000001 (NEEDED) Shared library: [libselinux.so.1]
0x0000000000000001 (NEEDED) Shared library: [libacl.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
Nota che le librerie possono dipendere da altre librerie, quindi ora devi trovare le dipendenze.
Un approccio ingenuo che spesso funziona è:
$ 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
ma il metodo più preciso è comprendere il ldd
percorso / cache di ricerca. Penso che ldconfig
sia la strada da percorrere.
Scegline uno e ripeti:
readelf -d /lib/x86_64-linux-gnu/libselinux.so.1 | grep 'NEEDED'
Uscita campione:
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]
E così via.
Guarda anche:
/proc/<pid>/maps
per i processi in esecuzione
Menzionato da Basile , questo è utile per trovare tutte le librerie attualmente in uso eseguendo eseguibili. Per esempio:
sudo awk '/\.so/{print $6}' /proc/1/maps | sort -u
mostra tutte le dipendenze dinamiche attualmente caricate di 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
Questo metodo mostra anche le librerie aperte con dlopen
, testate con questa configurazione minima hackerata con un sleep(1000)
su Ubuntu 18.04.
Vedi anche: Come vedere gli oggetti condivisi attualmente caricati su Linux? | Super utente
ldd e lsof mostrano le librerie caricate direttamente o in un dato momento . Non tengono conto delle librerie caricate tramite dlopen
(o scartate dadlclose
). Puoi ottenere un'immagine migliore di questo usando strace
, ad esempio,
strace -e trace=open myprogram
(poiché alla dlopen
fine chiama open
- anche se ovviamente potresti avere un sistema che usa nomi diversi per le aperture a 64 bit ...).
Esempio:
strace -e trace=open date
mi mostra questo:
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
da cui si potrebbe grep i nomi ".so" per vedere solo oggetti condivisi.
strace -e trace=open,openat myprogram
/proc/<pid>/maps
mostra anche dlopen
libs tra btw: unix.stackexchange.com/questions/120015/… l' ltrace -S
output è ancora più interessante in quanto mostra sia syscalls che chiamate di libreria come dlopen
: unix.stackexchange.com/questions/226524/…
lsof può anche mostrarti quali librerie vengono utilizzate per un particolare processo.
vale a 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
Per un processo di pid 1234, puoi anche leggere lo /proc/1234/maps
pseudo-file (testuale) (leggi proc (5) ...) o usare pmap (1)
Ciò fornisce lo spazio di indirizzi virtuale di quel processo, quindi i file (comprese le librerie condivise, anche dlopen (3) -ed uno) che sono mappati in memoria
(ovviamente, usa ps aux
o pgrep (1) per trovare i processi che eseguono un determinato programma)
crea un piccolo script ( useslib
) e inseriscilo nel PERCORSO (oppure specifica un percorso completo nel comando seguente)
#! /bin/bash
ldd $1 | grep -q $2
exit $?
Usalo in un find
comando, ad esempio:
find /usr/bin/ -executable -type f -exec useslib {} libgtk-x11-2.0 \; -print
(libgtk-x11-2.0 sembra essere la lib gtk2)
È possibile l'uso pmap
.
Ad esempio, avviare un processo: $ watch date
Ottieni pid: $ ps -ef | grep watch
Mostra mappa di memoria: $ pmap <pid>
Mostra con percorso completo: $ 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
lld
su darwin, sembra, né posso trovarlo tramite homebrew.