런타임에 어떤 동적 라이브러리 실행 파일이 로드되는지 확인하는 방법은 무엇입니까?

런타임에 어떤 동적 라이브러리 실행 파일이 로드되는지 확인하는 방법은 무엇입니까?

런타임 시 바이너리에 의해 로드된 동적 라이브러리(및 해당 전체 경로) 목록을 찾고 싶습니다. CentOS 6.0을 사용하고 있습니다. 어떻게 해야 하나요?

답변1

ldd다음 명령을 사용하여 이 작업을 수행할 수 있습니다 .

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

예:

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

답변2

readelf -d $executable | grep 'NEEDED'

예를 들어 크로스 컴파일되었거나 신뢰할 수 없는 경우 실행 파일을 실행할 수 없는 경우 다음을 사용할 수 있습니다.

일반적인 상황에서 ldd는 표준 동적 링커(ld.so(8) 참조)를 호출하고 LD_TRACE_LOADED_OBJECTS 환경 변수를 1로 설정합니다. 그러면 링커가 라이브러리 종속성을 표시하게 됩니다. 그러나 어떤 경우에는 일부 버전의 ldd가 프로그램을 직접 실행하여 종속성 정보를 얻으려고 시도할 수도 있습니다. 따라서 신뢰할 수 없는 실행 파일에는 ldd를 사용하면 안 됩니다. 임의의 코드가 실행될 수 있기 때문입니다.

예:

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

그러나 보다 정확한 방법은 ldd검색 경로/캐시를 이해하는 것입니다. ldconfig나는 이것이 갈 길이라고 생각합니다 .

하나를 선택하고 반복하십시오.

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

init1현재 로드된 모든 동적 종속성을 표시(PID )합니다.

/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)우분투 18.04에서 깨졌습니다.

또한보십시오:Linux에서 현재 로드된 공유 객체를 보는 방법은 무엇입니까? |수퍼유저

답변3

ldd 및 lsof는 로드된 라이브러리를 표시합니다.곧장또는주어진 순간. 그들은 다음을 통해 로드된 라이브러리를 고려하지 않습니다.dlopen(또는 폐기됨dlclose). 예를 들어 다음을 사용하면 이를 더 잘 이해할 수 있습니다 strace.

strace -e trace=open myprogram

( dlopen결국 그렇게 불릴 것입니다 open. 물론 64비트 열기에 대해 다른 이름을 가진 시스템이 있을 수도 있지만...).

예:

strace -e trace=open date

이것을 보여주세요:

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

여기에서 ".so" 이름을 찾아 공유 객체를 볼 수 있습니다.

답변4

일괄 쿼리:

  1. 작은 스크립트( useslib)를 생성하여 PATH에 넣습니다(또는 아래 명령에 전체 경로를 지정합니다).

    #! /bin/bash
    ldd $1 | grep -q $2
    exit $?
    
  2. 예를 들어 명령에서 사용하십시오 find.

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

(libgtk-x11-2.0은 gtk2 라이브러리인 것 같습니다)

관련 정보