Wie finde ich heraus, ob die ausführbaren Dateien der dynamischen Bibliotheken beim Ausführen geladen werden?

63

Ich möchte die Liste der dynamischen Bibliotheken herausfinden, die eine Binärdatei lädt, wenn sie ausgeführt wird (mit ihren vollständigen Pfaden). Ich benutze CentOS 6.0. Wie macht man das?

Ciro Santilli ist ein Schauspieler
quelle

Antworten:

61

Sie können dies mit dem lddBefehl tun :

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.
....

Beispiel:

$ 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)
cuonglm
quelle
1
Irgendeine Vorstellung davon, was ein MacOS-Äquivalent dazu wäre? Nein, lldauf Darwin, so scheint es, und ich kann es auch nicht über Homebrew finden.
mz2
7
Auf macOS:otool -L <path-to-binary>
Richard Viney
Beachten Sie, dass dies die Binärdatei ausführen kann. Wenn die Binärdatei nicht vertrauenswürdig ist, ist es möglicherweise besser, sie nicht zu verwenden ldd. Siehe Manpage .
Paul Rooney
45

readelf -d $executable | grep 'NEEDED'

Kann verwendet werden, wenn Sie die ausführbare Datei nicht ausführen können, z. B. wenn sie crosscompiliert wurde oder wenn Sie ihr nicht vertrauen:

Im Normalfall ruft ldd den dynamischen Standardlinker (siehe ld.so (8)) mit der Umgebungsvariablen LD_TRACE_LOADED_OBJECTS auf 1 auf, wodurch der Linker die Bibliotheksabhängigkeiten anzeigt. Beachten Sie jedoch, dass einige Versionen von ldd unter Umständen versuchen, die Abhängigkeitsinformationen durch direktes Ausführen des Programms abzurufen. Sie sollten daher niemals ldd für eine nicht vertrauenswürdige ausführbare Datei verwenden, da dies zur Ausführung von beliebigem Code führen kann.

Beispiel:

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

Beispiel Ausgabe:

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

Beachten Sie, dass Bibliotheken von anderen Bibliotheken abhängen können. Daher müssen Sie jetzt die Abhängigkeiten ermitteln.

Ein naiver Ansatz, der oft funktioniert, ist:

$ 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

Die genauere Methode ist jedoch, den lddSuchpfad / Cache zu verstehen . Ich denke, das ldconfigist der richtige Weg.

Wähle einen aus und wiederhole:

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.

Siehe auch:

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

Dies wird von Basile erwähnt und ist nützlich, um alle Bibliotheken zu finden, die derzeit zum Ausführen 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) an:

/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 dlopen, die mit diesem minimalen Setup geöffnet wurden , das mit sleep(1000)Ubuntu 18.04 gehackt wurde .

Siehe auch: Wie werden die aktuell geladenen freigegebenen Objekte in Linux angezeigt? | Super User

Ciro Santilli ist ein Schauspieler
quelle
1
Das Schöne an der readelf-Methode ist, dass sie auch auf Cross-Binaries (z. B. armhf auf amd64) funktioniert
Ghostrider,
13

ldd und lsof zeigen die Bibliotheken an, die entweder direkt oder zu einem bestimmten Zeitpunkt geladen wurden . Sie berücksichtigen nicht die Bibliotheken, die über geladen dlopen(oder von verworfendlclose ) wurden. Sie können sich ein besseres Bild davon machen, indem Sie stracez.

strace -e trace=open myprogram

(da dlopenletztendlich Anrufe open- obwohl man natürlich ein System haben kann, das unterschiedliche Namen für 64-Bit-Öffnungen verwendet ...).

Beispiel:

strace -e trace=open date

zeigt mir das:

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

von dem aus man die ".so" -Namen abrufen kann, um nur gemeinsam genutzte Objekte zu sehen.

Thomas Dickey
quelle
3
Eine Verbesserung:strace -e trace=open,openat myprogram
Cyker
Schöne Methode. /proc/<pid>/mapszeigt auch dlopenlibs btw: unix.stackexchange.com/questions/120015/… Die ltrace -S Ausgabe ist sogar noch cooler, da sowohl Systemaufrufe als auch Bibliotheksaufrufe wie folgt angezeigt werdendlopen : unix.stackexchange.com/questions/226524/…
Ciro Santilli 新疆 改造 改造 法轮功 法轮功 法轮功事件
7

lsof kann Ihnen auch zeigen, welche Bibliotheken für einen bestimmten Prozess verwendet werden.

dh

$ 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
Gongora
quelle
2

Für einen Prozess von pid 1234 können Sie auch die /proc/1234/maps(textuelle) Pseudodatei lesen (read proc (5) ...) oder pmap (1) verwenden.

Dies gibt den virtuellen Adressraum dieses Prozesses an, daher die Dateien (einschließlich der gemeinsam genutzten Bibliotheken, sogar die mit dlopen (3) bezeichneten ), die dem Speicher zugeordnet sind

(Verwenden Sie ps auxoder pgrep (1) , um die Prozesse zu finden, auf denen ein bestimmtes Programm ausgeführt wird.)

Basile Starynkevitch
quelle
1

Für Massenabfragen:

  1. Erstellen Sie ein kleines Skript ( useslib) und fügen Sie es in den Pfad ein (oder geben Sie einen vollständigen Pfad im folgenden Befehl an).

    #! /bin/bash
    ldd $1 | grep -q $2
    exit $?
    
  2. Verwenden Sie es in einem findBefehl, zum Beispiel:

    find /usr/bin/ -executable -type f -exec useslib {} libgtk-x11-2.0 \; -print
    

(libgtk-x11-2.0 scheint die gtk2-lib zu sein)

Magnet
quelle
0

Es ist möglich zu verwenden pmap.

Starten Sie zum Beispiel einen Prozess: $ watch date

Erhalten Sie pid: $ ps -ef | grep watch

Speicherkarte anzeigen: $ pmap <pid>

Zeige mit vollem Pfad: $ 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
Lane Ouyang
quelle