Як показати всі спільні бібліотеки, якими користуються виконувані файли в Linux?


225

Я хотів би знати, які бібліотеки використовуються виконуваними файлами в моїй системі. Більш конкретно, я хотів би оцінити, які бібліотеки використовуються найбільше, а також двійкові файли, які ними користуються. Як я можу це зробити?


Ймовірно, ви не зможете отримати точну кількість, якщо використовуються виконувані файли dlopen.
jxh

Відповіді:


271
  1. Використовуйте lddдля переліку спільних бібліотек для кожного виконуваного файлу.
  2. Очистіть вихід
  3. Сортування, обчислення підрахунків, сортування за підрахунком

Щоб знайти відповідь на всі виконувані файли в каталозі "/ bin":

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

Змініть "/ bin" вище на "/", щоб шукати всі каталоги.

Вихід (лише для каталогу / bin) буде виглядати приблизно так:

  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

Редагувати - Видалено "grep -P"


2
Це чудова відповідь (я це вже проголосував), але чи можете ви пояснити команду "grep -P" \ t. * So ""? За словами людини, це трактує зразок як пергель-регепс, але моя версія grep не підтримує його (людина вказує, що це загальне питання). Який біт regexp специфічний для perl?
Боббі Джек

2
Я думаю, вам може знадобитися використанняldd -v
MountainX

58
Майте на увазі, що lddнасправді працює виконуваний файл зі спеціальною змінною середовища, а динамічний лінкер Linux розпізнає цей прапор і просто виводить бібліотеки, а не працює виконуваним файлом. Подивіться на джерело ldd; у моїй системі це сценарій bash. Якщо виконуваний файл є статично пов'язаним і використовує системні дзвінки та вказує інший завантажувач, він може робити довільні злі речі. Тому не використовуйте lddу виконаному файлі, якому ви не довіряєте.
Баррі Келлі

'ldd' не працює для мене на схрещених бінарних файлах. Питання полягає у пошуку бібліотек, які використовуються програмами в поточній системі (це були б натурні програми, як фразові). Це гарна відповідь на це. Однак я подумав зазначити, що вам потрібно скористатися чимось іншим, якщо шукати спільні бібліотеки для програм для іншої системи ("readelf", згаданий в іншій відповіді, працював на мене)
Tim Bird,

68

У мене не було ldd на моєму ланцюжку інструментів ARM, тому я використовував objdump:

$ (CROSS_COMPILE) objdump -p

Наприклад:

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
Це також повинно бути безпечним, на відміну від того, lddщо не слід використовувати у ненадійних виконуваних файлах.
PSkocik

Крім того, obbjdump -pвідображається додаткова інформація на зразок RPATH, яка може бути корисною при дослідженні динамічних зв'язків проблем із вашим виконуваним файлом.
sitaktif

+1 для методу, який насправді є безпечним і надійним (я якось отримав систему, в якій musl-gccрегулярно виробляє двійкові файли, так що виклик lddна бінарний файл просто виконує двійкові файли , тому сьогодні мені регулярно нагадують про те, наскільки це небезпечно ldd).
mtraceur

54

У Linux я використовую:

lsof -P -T -p Application_PID

Це працює краще, ніж lddколи виконуваний файл використовує завантажувач за замовчуванням


Використовуйте це, щоб дізнатися, чи mariadb насправді використовує tc-malloc , який завантажується LD_PRELOAD. Чудово працює.
cmc

2
Я шукав щось, що могло б показати мені ".so" для певного подруги. Це саме те, що мені було потрібно. Дякую!
Лев Уфімцев

48

щоб дізнатися, якими бібліотеками користується бінарний файл, використовуйте ldd

ldd path/to/the/tool

Вам доведеться написати невеликий скрипт оболонки, щоб дійти до вашої загальної системи.


19

Перевірте залежність спільної бібліотеки виконуваної програми

Щоб дізнатися, від яких бібліотек залежить певний виконуваний файл, ви можете скористатися командою ldd. Ця команда викликає динамічний лінкер, щоб з'ясувати залежність виконуваної бібліотеки.

> $ ldd / шлях / до / програми

Зауважте, що НЕ рекомендується запускати ldd з будь-яким не довіреним стороннім виконуваним файлом, оскільки деякі версії ldd можуть безпосередньо викликати виконуваний файл для виявлення його залежностей від бібліотеки, що може становити загрозу безпеці.

Натомість більш безпечним способом відображення залежностей бібліотеки від невідомої бінарної програми є використання наступної команди.

$ objdump -p / шлях / до / програми | grep ПОТРІБНА

для отримання додаткової інформації


14

readelf -d рекурсія

redelf -dстворює аналогічний вихід, про objdump -pякий згадувалося на веб- сайті: https://stackoverflow.com/a/15520982/895245

Але майте на увазі, що динамічні бібліотеки можуть залежати від інших динамічних бібліотек, і вам доведеться повторювати.

Приклад:

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

Вибірка зразка:

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

Тоді:

$ 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

Виберіть один і повторіть:

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

Вибірка зразка:

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]

І так далі.

/proc/<pid>/maps для запуску процесів

Це корисно для пошуку всіх бібліотек, які зараз використовуються для запуску виконуваних файлів. Наприклад:

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

показує всі завантажені в даний час динамічні залежності 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

Цей метод також показує бібліотеки, відкриті dlopen, перевірені цією мінімальною установкою, підключеною до sleep(1000)Ubuntu 18.04.

Дивіться також: /superuser/310199/see-currently-loaded-shared-objects-in-linux/1243089


7

У OS X за замовчуванням немає ldd, objdumpабо lsof. В якості альтернативи спробуйте otool -L:

$ 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)

У цьому прикладі, використовуючи which opensslзаповнення повністю кваліфікованого шляху для даного виконуваного та поточного середовища користувача.


6

Припустимо, в системі UNIX тест бінарного (виконується) імені є тестовим. Тоді ми використовуємо наступну команду для переліку бібліотек, які використовуються в тесті є

ldd test

4

З lddвами можна отримати бібліотеки, якими користуються інструменти. Для ранжирування використання бібліотек для набору інструментів ви можете використовувати щось на зразок наступної команди.

ldd /bin/* /usr/bin/* ... | sed -e '/^[^\t]/ d; s/^\t\(.* => \)\?\([^ ]*\) (.*/\2/g' | sort | uniq -c

(Тут sedзнімаються всі рядки, які не починаються з вкладки, і фільтруються лише фактичні бібліотеки. З sort | uniq -cкожної бібліотеки ви отримуєте підрахунок, який вказує кількість разів, коли вона відбулася.)

Ви можете додати sort -gв кінці, щоб отримати бібліотеки в порядку використання.

Зверніть увагу, що ви, ймовірно, отримуєте рядки двох небібліотечних рядків із вищевказаною командою. Один зі статичних виконуваних файлів ("не динамічний виконуваний файл") і один без бібліотеки. Останнє є результатом, linux-gate.so.1який не є бібліотекою у вашій файловій системі, а такою, яку "постачає" ядро.


2

Ще одним варіантом може бути лише читання файлу, розміщеного на

/proc/<pid>/maps

Наприклад, id процесу 2601, тоді команда є

cat /proc/2601/maps

І вихід схожий

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

на пакунки друку ubuntu, пов'язані з виконуваним файлом

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

0

Мені ця публікація виявилася дуже корисною, оскільки мені потрібно було дослідити залежності від бібліотеки, що постачається сторонніми сторонами (32 проти 64 бітових шляхів виконання).

Я зібрав Q&D повторюваний скрипт bash на основі пропозиції 'readelf -d' для дистрибутива RHEL 6.

Це дуже просто і буде перевіряти кожну залежність кожен раз, навіть якщо вона могла бути випробувана раніше (тобто дуже багатослівна). Вихід також є дуже базовим.

#! /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!!

перенаправити вихід у файл та grep для 'знайдено' або 'не вдалося'

Використовуйте та змінюйте, на власний ризик, звичайно, як хочете.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.