Bagaimana mengetahui beban dinamis yang dapat dieksekusi pustaka saat dijalankan?

64

Saya ingin mengetahui daftar perpustakaan dinamis yang dimuat biner saat dijalankan (Dengan jalur lengkapnya). Saya menggunakan CentOS 6.0. Bagaimana cara melakukannya?

Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
sumber

Jawaban:

61

Anda dapat melakukan ini dengan lddperintah:

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

Contoh:

$ 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
sumber
1
Adakah yang kira-kira setara dengan makOS ini? Tidak lldpada darwin, tampaknya, saya juga tidak dapat menemukannya melalui homebrew.
mz2
7
Di MacOS:otool -L <path-to-binary>
Richard Viney
perlu diketahui bahwa ini dapat menjalankan biner. Jadi, jika biner tidak dipercaya, mungkin lebih baik tidak digunakan ldd. Lihat halaman manual .
Paul Rooney
46

readelf -d $executable | grep 'NEEDED'

Dapat digunakan jika Anda tidak dapat menjalankan executable, misalnya jika itu dikompilasi silang, atau jika Anda tidak mempercayainya:

Dalam kasus biasa, ldd memanggil tautan dinamis standar (lihat ld.so (8)) dengan variabel lingkungan LD_TRACE_LOADED_OBJECTS diatur ke 1, yang menyebabkan tautan tersebut menampilkan dependensi perpustakaan. Perlu diketahui, bagaimanapun, bahwa dalam beberapa keadaan, beberapa versi ldd dapat mencoba untuk mendapatkan informasi ketergantungan dengan secara langsung menjalankan program. Dengan demikian, Anda tidak boleh menggunakan ldd pada executable yang tidak dipercaya, karena ini dapat mengakibatkan eksekusi kode arbitrer.

Contoh:

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

Contoh ouptut:

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

Perhatikan bahwa pustaka dapat bergantung pada pustaka lain, jadi sekarang Anda perlu menemukan dependensinya.

Pendekatan naif yang sering berhasil adalah:

$ 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

tetapi metode yang lebih tepat adalah memahami lddjalur pencarian / cache. Saya pikir ldconfigadalah cara untuk pergi.

Pilih satu, dan ulangi:

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

Output sampel:

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]

Dan seterusnya.

Lihat juga:

/proc/<pid>/maps untuk menjalankan proses

Disebutkan oleh Basile , ini berguna untuk menemukan semua perpustakaan yang saat ini digunakan oleh menjalankan executable. Misalnya:

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

menunjukkan semua dependensi dinamis init(PID 1) yang saat ini dimuat :

/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

Metode ini juga menunjukkan perpustakaan dibuka dengan dlopen, diuji dengan pengaturan minimal ini diretas dengan sleep(1000)Ubuntu 18.04.

Lihat juga: Bagaimana cara melihat objek bersama yang saat ini dimuat di Linux? | Pengguna Super

Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
sumber
1
Bagian yang bagus tentang metode readelf adalah ia bekerja pada cross-binari (mis: armhf pada amd64) juga
Ghostrider
13

ldd dan lsof menunjukkan perpustakaan dimuat baik secara langsung atau pada saat tertentu . Mereka tidak memperhitungkan pustaka yang dimuat melalui dlopen(atau dibuang olehdlclose ). Anda bisa mendapatkan gambaran yang lebih baik tentang penggunaan ini strace, misalnya,

strace -e trace=open myprogram

(Karena dlopenpada akhirnya panggilan open- meskipun Anda tentu saja dapat memiliki sistem menggunakan nama yang berbeda untuk membuka 64-bit ...).

Contoh:

strace -e trace=open date

tunjukkan ini:

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

dari mana orang dapat menangkap nama ".so" untuk hanya melihat objek yang dibagikan.

Thomas Dickey
sumber
3
Suatu peningkatan:strace -e trace=open,openat myprogram
Cyker
Metode yang bagus. /proc/<pid>/mapsjuga menunjukkan dlopenlibs btw: unix.stackexchange.com/questions/120015/... ltrace -S output lebih dingin karena menampilkan panggilan syscalls dan perpustakaan seperti dlopen: unix.stackexchange.com/questions/226524/…
Ciro Santilli 新疆 改造 中心 法轮功 六四事件
7

lsof juga dapat menunjukkan kepada Anda perpustakaan mana yang sedang digunakan untuk satu proses tertentu.

yaitu

$ 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
sumber
2

Untuk proses pid 1234, Anda juga bisa membaca /proc/1234/mapsfile pseudo (tekstual) (baca proc (5) ...) atau menggunakan pmap (1)

Ini memberikan ruang alamat virtual dari proses itu, maka file-file (termasuk perpustakaan bersama, bahkan dlopen (3) -ed satu) yang dipetakan memori

(tentu saja, gunakan ps auxatau pgrep (1) untuk menemukan proses menjalankan beberapa program yang diberikan)

Basile Starynkevitch
sumber
1

Untuk kueri massal:

  1. buat skrip kecil ( useslib) dan masukkan ke dalam PATH (orspecify path lengkap pada perintah di bawah)

    #! /bin/bash
    ldd $1 | grep -q $2
    exit $?
    
  2. Gunakan itu dalam findperintah, misalnya:

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

(libgtk-x11-2.0 tampaknya menjadi lib gtk2)

xenoid
sumber
0

Itu mungkin digunakan pmap.

Sebagai contoh, mulailah proses: $ watch date

Dapatkan pid: $ ps -ef | grep watch

Tampilkan peta memori: $ pmap <pid>

Tampilkan dengan jalur lengkap: $ 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
sumber