Linux'ta yürütülebilir dosyalar tarafından kullanılan tüm paylaşılan kütüphaneler nasıl gösterilir?


225

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?


Yürütülebilir dosyalar kullanırsa, kesin bir sayı alamazsınız dlopen.
jxh

Yanıtlar:


271
  1. lddHer yürütülebilir dosya için paylaşılan kitaplıkları listelemek için kullanın .
  2. Çıktıyı temizleme
  3. Sıralama, hesaplama sayısı, sayıma göre sıralama

"/ 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ı


2
Bu harika bir cevap (ben oy verdim) ama "grep -P '\ t. * So'" komutunu açıklayabilir misiniz? İnsana göre bu, kalıbı perl regexp olarak yorumlar, ancak grep versiyonum bunu desteklemiyor (insan bunun genel bir sorun olduğunu gösteriyor). Normal ifadenin hangi kısmı perl'e özgüdür?
Bobby Jack

2
Sanırım kullanmanız gerekebilirldd -v
MountainX

58
Unutmayın lddaslı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 lddgüvenmediğiniz bir yürütülebilir dosyada kullanmayın .
Barry Kelly

'ldd' çapraz derlenmiş ikili dosyalarda benim için çalışmıyor. Buradaki soru, mevcut sistemdeki programlar tarafından kullanılan (yerel programlar olarak ifade edilen kütüphaneleri) bulmaktır. Bunun için iyi bir cevap. Ancak, farklı bir sistem için programlar için paylaşılan kütüphaneleri ararken başka bir şey kullanmanız gerektiğini belirtmiştim (başka bir cevapta bahsedilen 'kendim', benim için çalıştı)
Tim Bird

68

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

2
Bu da lddgüvenilmez çalıştırılabilir dosyalarda kullanılmaması gerektiği gibi güvenli olmalıdır.
PSkocik

Ayrıca, çalıştırılabilir programınızla dinamik bağlantı sorunlarını araştırırken yardımcı olabilecek, obbjdump -pgibi ek bilgileri de gösterir RPATH.
sitaktif

Aslında güvenli ve güvenilir bir yöntem için +1 (Bir şekilde musl-gccdü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 lddolduğunu hatırlatıyorum ).
mtraceur


48

bir binary hangi kütüphaneleri kullanır öğrenmek için ldd kullanın

ldd path/to/the/tool

Sistem genelindeki çöküşünüze ulaşmak için küçük bir kabuk komut dosyası yazmanız gerekir.


19

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

daha fazla bilgi için


14

readelf -d yineleme

redelf -dbenzer çı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


8

Varsayılan olarak OS X'te orada hayır ldd, objdumpya 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 opensslverilen yürütülebilir ve geçerli kullanıcı ortamı için tam yoldaki dolguların kullanılması .


6

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

4

İle lddaraç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 sedbir 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 -gSonunda 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.1dosya sisteminizdeki bir kütüphane değil, çekirdek tarafından "sağlanan" bir kütüphanedir.


2

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

2

yürütülebilir ile ilgili ubuntu baskı paketleri üzerinde

ldd executable_name|awk '{print $3}'|xargs dpkg -S |awk -F  ":"  '{print $1}'

0

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.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.