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'"명령을 설명 할 수 있습니까? man에 따르면, 이것은 패턴을 perl regexp로 해석하지만 grep의 내 버전은 그것을 지원하지 않습니다 (man은 이것이 일반적인 문제임을 나타냅니다). 정규식의 어떤 비트가 perl에 특정한가요?
Bobby Jack

2
당신이 사용해야 할 수도 있습니다ldd -v
MountainX

58
주의하십시오 ldd실제로 특별한 환경 변수와 실행 파일을 실행하고 리눅스 동적 링커가이 플래그를 인식하고 단지 아니라 실행 파일을 실행하는 것보다 라이브러리를 출력합니다. 소스를보십시오 ldd; 내 시스템에서는 bash 스크립트입니다. 실행 파일이 정적으로 링크되어 있고 syscall을 사용하고 다른 로더를 지정하면 임의의 악의적 인 일을 수행 할 수 있습니다. 따라서 ldd신뢰할 수없는 실행 파일 에는 사용 하지 마십시오.
Barry Kelly

크로스 컴파일 된 바이너리에서는 'ldd'가 작동하지 않습니다. 문제는 현재 시스템에서 프로그램이 사용하는 라이브러리를 찾는 것입니다 (즉, 기본 프로그램이됩니다). 이것은 좋은 대답입니다. 그러나 다른 시스템 (다른 답변에서 언급 한 'readelf')에서 프로그램을위한 공유 라이브러리를 찾는 경우 다른 것을 사용해야한다고 언급했습니다.
Tim Bird

68

ARM 툴체인에 ldd가 없었으므로 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

리눅스에서는 다음을 사용합니다.

lsof -P -T -p Application_PID

ldd실행 파일이 기본아닌 로더를 사용할 때보 다 더 효과적입니다.


mariadb가 LD_PRELOAD에 의해로드되는 tc-malloc을 실제로 사용 하고 있는지 알아내는 데 사용했습니다 . 잘 작동합니다.
cmc

2
나는 주어진 pid에 대해 '.so'를 보여줄 무언가를 찾고있었습니다. 이것이 바로 내가 필요한 것입니다. 감사!
레오 Ufimtsev

48

바이너리가 사용하는 라이브러리를 배우려면 ldd를 사용하십시오.

ldd path/to/the/tool

시스템 전체의 고장에 도달하려면 작은 쉘 스크립트를 작성해야합니다.


19

프로그램 실행 파일의 공유 라이브러리 종속성 확인

특정 실행 파일이 의존하는 라이브러리를 찾으려면 ldd 명령을 사용할 수 있습니다. 이 명령은 동적 링커를 호출하여 실행 파일의 라이브러리 종속성을 찾습니다.

> $ ldd / path / to / 프로그램

일부 버전의 ldd는 실행 파일을 직접 호출하여 라이브러리 종속성을 식별 할 수 있으므로 보안 위험이있을 수 있으므로 신뢰할 수없는 타사 실행 파일과 함께 ldd를 실행하지 않는 것이 좋습니다.

대신 알 수없는 응용 프로그램 바이너리의 라이브러리 종속성을 표시하는보다 안전한 방법은 다음 명령을 사용하는 것입니다.

$ objdump -p / path / to / 프로그램 | grep 필요

더 많은 정보를 위해서


14

readelf -d 재귀

redelf -dhttps://stackoverflow.com/a/15520982/895245objdump -p 에서 언급 된 것과 유사한 출력을 생성합니다 .

그러나 동적 라이브러리는 다른 동적 라이브러리에 의존 할 수 있으므로 반복해야합니다.

예:

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

샘플 ouptut :

 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

이 방법은 또한 Ubuntu 18.04에서 해킹 한 최소 설정으로dlopen 테스트 한 라이브러리를 보여줍니다 .sleep(1000)

참조 : /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 시스템에서 이진 (실행 파일) 이름이 test라고 가정하십시오. 그런 다음 다음 명령을 사용하여 테스트에 사용 된 라이브러리를 나열합니다.

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

실행 파일과 관련된 우분투 인쇄 패키지

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

0

이 게시물은 타사 제공 라이브러리 (32 대 64 비트 실행 경로)의 종속성을 조사하는 데 매우 유용했습니다.

RHEL 6 배포판의 'readelf -d'제안을 기반으로 Q & D 순환 bash 스크립트를 작성했습니다.

그것은 매우 기본적이며 이전에 테스트되었을지라도 매번 모든 의존성을 테스트 할 것입니다 (즉, 매우 장황합니다). 출력도 매우 기본적입니다.

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

출력을 파일로 리디렉션하고 'found'또는 'failed'에 대해 grep

물론 자신이 원하는대로 사용하고 수정하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.