Sistemimdeki yürütülebilir dosyalar tarafından hangi kütüphanelerin kullanıldığını bilmek istiyorum. Daha spesifik olarak, en çok hangi kütüphanelerin kullanıldığını ve bunları kullanan ikili dosyaları sıralamak istiyorum. Bunu nasıl yapabilirim?
Sistemimdeki yürütülebilir dosyalar tarafından hangi kütüphanelerin kullanıldığını bilmek istiyorum. Daha spesifik olarak, en çok hangi kütüphanelerin kullanıldığını ve bunları kullanan ikili dosyaları sıralamak istiyorum. Bunu nasıl yapabilirim?
Yanıtlar:
ldd
Her yürütülebilir dosya için paylaşılan kitaplıkları listelemek için kullanın ."/ Bin" dizinindeki tüm yürütülebilir dosyaların yanıtını bulmak için:
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
Tüm dizinleri aramak için yukarıdaki "/ bin" i "/" olarak değiştirin.
Çıktı (sadece / bin dizini için) şöyle görünecektir:
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
Düzenle - "grep -P" kaldırıldı
ldd -v
ldd
aslında özel bir ortam değişkeni ile yürütülebilir çalışır ve Linux dinamik bağlayıcı bu bayrağı tanır ve sadece yerine çalıştırılabilir çalışan daha kütüphaneleri çıkarır. Şu kaynağa bakın ldd
; benim sistemimde, bu bir bash betiği. Yürütülebilir dosya statik olarak bağlıysa ve syscalls kullanıyorsa ve farklı bir yükleyici belirtirse, keyfi kötü şeyler yapabilir. Bu yüzden ldd
güvenmediğiniz bir yürütülebilir dosyada kullanmayın .
ARM araç zincirimde ldd yoktu, bu yüzden objdump kullandım:
$ (CROSS_COMPILE) objdump -p
Örneğin:
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
ldd
güvenilmez çalıştırılabilir dosyalarda kullanılmaması gerektiği gibi güvenli olmalıdır.
obbjdump -p
gibi ek bilgileri de gösterir RPATH
.
musl-gcc
düzenli olarak ikili ürettiği bir sistem var ki ldd
, ikili çağrıyı sadece ikili yürütür , bu yüzden bugünlerde düzenli olarak ne kadar güvensiz ldd
olduğunu hatırlatıyorum ).
Linux'ta şunu kullanıyorum:
lsof -P -T -p Application_PID
Bu ldd
, yürütülebilir dosya varsayılan olmayan bir yükleyici kullandığından daha iyi çalışır
Yürütülebilir bir programın paylaşılan kitaplık bağımlılıklarını denetleme
Belirli bir yürütülebilir dosyanın hangi kitaplıklara bağlı olduğunu bulmak için ldd komutunu kullanabilirsiniz. Bu komut, bir yürütülebilir dosyanın kitaplık bağımlılıklarını bulmak için dinamik bağlayıcıyı çağırır.
> $ ldd / path / to / program
Ldd'nin güvenilir olmayan herhangi bir üçüncü taraf yürütülebilir dosya ile çalıştırılmasının ÖNERİLMEDİĞİNDİR, çünkü bazı ldd sürümleri, güvenlik riski olabilecek kitaplık bağımlılıklarını tanımlamak için yürütülebilir dosyayı doğrudan çağırabilir.
Bunun yerine, bilinmeyen bir uygulama ikili dosyasının kitaplık bağımlılıklarını göstermenin daha güvenli bir yolu aşağıdaki komutu kullanmaktır.
$ objdump -p / yol / program / | grep GEREKİR
readelf -d
yineleme
redelf -d
benzer çıktı üretir objdump -p
: https://stackoverflow.com/a/15520982/895245
Ancak dinamik kütüphanelerin, dinlenmesi gereken diğer dinamik kütüphanelere bağlı olabileceğine dikkat edin.
Misal:
readelf -d /bin/ls | grep 'NEEDED'
Örnek çıkış:
0x0000000000000001 (NEEDED) Shared library: [libselinux.so.1]
0x0000000000000001 (NEEDED) Shared library: [libacl.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
Sonra:
$ 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
Birini seçin ve tekrarlayın:
readelf -d /lib/x86_64-linux-gnu/libselinux.so.1 | grep 'NEEDED'
Örnek çıktı:
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]
Ve bunun gibi.
/proc/<pid>/maps
çalışan işlemler için
Bu, şu anda çalıştırılabilir dosyalar çalıştırılarak kullanılan tüm kütüphaneleri bulmak için yararlıdır. Örneğin:
sudo awk '/\.so/{print $6}' /proc/1/maps | sort -u
şu anda yüklü olan init
(PID 1
) dinamik bağımlılıklarını gösterir :
/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
Bu yöntem aynı zamanda Ubuntu 18.04'te hacklenmiş bu asgari kurulumladlopen
test edilen kütüphaneleri gösterir .sleep(1000)
Ayrıca bakınız: /superuser/310199/see-currently-loaded-shared-objects-in-linux/1243089
Varsayılan olarak OS X'te orada hayır ldd
, objdump
ya lsof
. Alternatif olarak otool -L
şunları deneyin :
$ 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)
Bu örnekte, which openssl
verilen yürütülebilir ve geçerli kullanıcı ortamı için tam yoldaki dolguların kullanılması .
UNIX sisteminde, ikili (yürütülebilir) adın test olduğunu varsayalım. Sonra testte kullanılan kütüphaneleri listelemek için aşağıdaki komutu kullanırız:
ldd test
İle ldd
araçların kullandığı kütüphaneleri alabilirsiniz. Bir araç kümesi için kitaplık kullanımını sıralamak için aşağıdaki komut gibi bir şey kullanabilirsiniz.
ldd /bin/* /usr/bin/* ... | sed -e '/^[^\t]/ d; s/^\t\(.* => \)\?\([^ ]*\) (.*/\2/g' | sort | uniq -c
(Burada sed
bir sekme ile başlamayan tüm satırları çıkarır ve yalnızca gerçek kütüphaneleri filtreler.sort | uniq -c
Her kütüphaneyi, kaç kez meydana geldiğini gösteren bir sayıyla alırsınız.)
Eklemek isteyebilirsiniz sort -g
Sonunda kütüphaneleri kullanım sırasına göre almak .
Yukarıdaki komutla muhtemelen iki kitaplık olmayan satır elde edeceğinizi unutmayın. Statik yürütülebilir dosyalardan biri ("dinamik yürütülebilir değil") ve biri kütüphane olmadan. İkincisi, linux-gate.so.1
dosya sisteminizdeki bir kütüphane değil, çekirdek tarafından "sağlanan" bir kütüphanedir.
Bir seçenek daha şu adresteki dosyayı okuyabilir:
/proc/<pid>/maps
Örneğin, işlem kimliği 2601'dir, sonra komut
cat /proc/2601/maps
Ve çıktı şöyle
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
yürütülebilir ile ilgili ubuntu baskı paketleri üzerinde
ldd executable_name|awk '{print $3}'|xargs dpkg -S |awk -F ":" '{print $1}'
Bir üçüncü taraf tarafından sağlanan kitaplık (32 vs 64 bit yürütme yolları) bağımlılıkları araştırmak için gerekli olarak bu yazı çok yararlı buldum.
RHEL 6 dağıtımındaki 'readelf -d' önerisine dayanan bir Soru-Cevap yinelenen bash betiği oluşturdum.
Çok basittir ve daha önce test edilmiş olsa bile (yani çok ayrıntılı) her bağımlılığı her seferinde test edecektir. Çıktı da çok basit.
#! /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!!
çıktıyı bir dosyaya yönlendirin ve 'bulundu' veya 'başarısız' için grep
İstediğiniz gibi kendi sorumluluğunuzdadır kullanın ve değiştirin.
dlopen
.