我想找出运行时二进制加载的动态库列表(及其完整路径)。我正在使用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)


评论


任何关于macOS等同于此的想法吗?它不会在达尔文上出现lld,也无法通过自制程序找到它。

– mz2
16-10-23在14:05



在macOS上:otool -L <二进制路径>

–理查德·维尼(Richard Viney)
17 Mar 17 '17 at 22:23

请注意,这可能会执行二进制文件。因此,如果二进制文件不受信任,最好不使用ldd。请参见手册页。

–保罗·鲁尼
19年8月19日在2:57

要遵循@PaulRooney的评论:特别是,手册页建议使用objdump -p / path / to / program |如果您不信任可执行文件,则需要grep来替代ldd。

–乔什·戴斯蒙德(Josh Desmond)
20-4-4在21:56

我使用此代码片段找到了部门,然后将其复制到我的监狱... ldd $ {jail} / bin / * | egrep -o'\ [^ \] * / lib \ [^ \] * \ [。\] \ [0-9 \]'| xargs -I {} -P1 sudo cp -v {} $ {jail} {}

–理查德
20年4月14日在23:20

#2 楼

readelf -d $executable | grep 'NEEDED'

如果您无法运行可执行文件,例如是交叉编译还是不信任它:


通常情况下,ldd使用LD_TRACE_LOADED_OBJECTS调用标准动态链接器(请参阅ld.so(8))。环境变量设置为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]


等等。

另请参见:


确定Linux二进制文件的直接共享对象依赖性? |堆栈溢出
如何在C ++中找到ELF Binary所需的动态库? |堆栈溢出
如何知道ELF需要哪些动态库? |堆栈溢出

/proc/<pid>/maps用于运行进程

提到Basile,这对于查找当前正在运行的可执行文件正在使用的所有库很有用。例如:

sudo awk '/\.so/{print }' /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打开的库,并通过在Ubuntu 18.04上用sleep(1000)修改过的最小设置对其进行了测试。

另请参阅:如何查看Linux中当前加载的共享库? |超级用户

评论


关于readelf方法的一个好地方是它也适用于跨二进制文件(例如:amd64上的armhf)

– Ghostrider
19年8月20日在2:21

+1用于深入了解elf二进制文件本身,而不是依赖链接程序或其他工具。

– Alireza Mohamadi
20-2-27在16:58

#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”名称以查看共享的对象。

评论


一个改进:strace -e trace = open,openat myprogram

– Cyker
18年6月26日在18:04

不错的方法。 / proc / / maps还显示dlopen libs btw:unix.stackexchange.com/questions/120015/…ltrace -S输出甚至更酷,因为它既显示syscall也显示库调用,例如dlopen:unix.stackexchange.com/questions / 226524 /…

– Ciro Santilli郝海东冠状病六四事件法轮功
18/09/13在21:27

#4 楼

lsof还可以向您显示用于某个特定进程的库。



$ pidof nginx
6920 6919

$ lsof -p 6919|grep mem
nginx   6919 root  mem    REG               0,64    65960     43 /lib64/libnss_files-2.12.so
nginx   6919 root  mem    REG               0,64    19536     36 /lib64/libdl-2.12.so
nginx   6919 root  mem    REG               0,64    10312   1875 /lib64/libfreebl3.so
nginx   6919 root  mem    REG               0,64  1923352     38 /lib64/libc-2.12.so
nginx   6919 root  mem    REG               0,64    88600   1034 /lib64/libz.so.1.2.3
nginx   6919 root  mem    REG               0,64  1967392   1927 /usr/lib64/libcrypto.so.1.0.1e
nginx   6919 root  mem    REG               0,64   183080   1898 /lib64/libpcre.so.0.0.1
nginx   6919 root  mem    REG               0,64    40400   1217 /lib64/libcrypt-2.12.so
nginx   6919 root  mem    REG               0,64   142688     77 /lib64/libpthread-2.12.so
nginx   6919 root  mem    REG               0,64   154664     31 /lib64/ld-2.12.so


#5 楼

对于批量查询:



创建一个小脚本(useslib)并放入PATH(或在下面的命令中指定完整路径)

#! /bin/bash
ldd  | grep -q 
exit $?



find命令中使用,例如:

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



(libgtk-x11- 2.0似乎是gtk2 lib)

#6 楼

对于pid 1234的处理,您还可以读取/proc/1234/maps(文本)伪文件(读取proc(5)...)或使用pmap(1)

,这提供了虚拟地址空间该进程,因此,这些文件(包括共享库,甚至是dlopen(3)-ed)都被映射为内存

(当然,请使用ps aux或pgrep(1)查找运行某些给定的进程程序)

#7 楼

可以使用pmap

例如,启动一个进程:$ watch date

获取pid:$ ps -ef | grep watch

显示内存映射:$ pmap <pid>

显示完整路径:$ pmap <pid> -p

 $ pmap 72770
72770:   watch date
00005613a32c9000     20K r-x-- watch
00005613a34cd000      4K r---- watch
00005613a34ce000      4K rw--- watch
00005613a4f6a000    264K rw---   [ anon ]
00007f2f3a7d5000 204616K r---- locale-archive
00007f2f46fa7000   1748K r-x-- libc-2.27.so
00007f2f4715c000   2048K ----- libc-2.27.so
00007f2f4735c000     16K r---- libc-2.27.so
00007f2f47360000      8K rw--- libc-2.27.so
00007f2f47362000     16K rw---   [ anon ]
00007f2f47366000     12K r-x-- libdl-2.27.so
00007f2f47369000   2044K ----- libdl-2.27.so
00007f2f47568000      4K r---- libdl-2.27.so
00007f2f47569000      4K rw--- libdl-2.27.so
00007f2f4756a000    160K r-x-- libtinfo.so.6.1
00007f2f47592000   2048K ----- libtinfo.so.6.1
00007f2f47792000     16K r---- libtinfo.so.6.1
00007f2f47796000      4K rw--- libtinfo.so.6.1
00007f2f47797000    232K r-x-- libncursesw.so.6.1
00007f2f477d1000   2048K ----- libncursesw.so.6.1
00007f2f479d1000      4K r---- libncursesw.so.6.1
00007f2f479d2000      4K rw--- libncursesw.so.6.1
00007f2f479d3000    148K r-x-- ld-2.27.so
00007f2f47bdb000     20K rw---   [ anon ]
00007f2f47bf1000     28K r--s- gconv-modules.cache
00007f2f47bf8000      4K r---- ld-2.27.so
00007f2f47bf9000      4K rw--- ld-2.27.so
00007f2f47bfa000      4K rw---   [ anon ]
00007ffd39404000    136K rw---   [ stack ]
00007ffd3959b000     12K r----   [ anon ]
00007ffd3959e000      8K r-x--   [ anon ]
ffffffffff600000      4K r-x--   [ anon ]
 total           215692K
 


 $ pmap 72770 -p
72770:   watch date
00005613a32c9000     20K r-x-- /usr/bin/watch
00005613a34cd000      4K r---- /usr/bin/watch
00005613a34ce000      4K rw--- /usr/bin/watch
00005613a4f6a000    264K rw---   [ anon ]
00007f2f3a7d5000 204616K r---- /usr/lib/locale/locale-archive
00007f2f46fa7000   1748K r-x-- /usr/lib64/libc-2.27.so
00007f2f4715c000   2048K ----- /usr/lib64/libc-2.27.so
00007f2f4735c000     16K r---- /usr/lib64/libc-2.27.so
00007f2f47360000      8K rw--- /usr/lib64/libc-2.27.so
00007f2f47362000     16K rw---   [ anon ]
00007f2f47366000     12K r-x-- /usr/lib64/libdl-2.27.so
00007f2f47369000   2044K ----- /usr/lib64/libdl-2.27.so
00007f2f47568000      4K r---- /usr/lib64/libdl-2.27.so
00007f2f47569000      4K rw--- /usr/lib64/libdl-2.27.so
00007f2f4756a000    160K r-x-- /usr/lib64/libtinfo.so.6.1
00007f2f47592000   2048K ----- /usr/lib64/libtinfo.so.6.1
00007f2f47792000     16K r---- /usr/lib64/libtinfo.so.6.1
00007f2f47796000      4K rw--- /usr/lib64/libtinfo.so.6.1
00007f2f47797000    232K r-x-- /usr/lib64/libncursesw.so.6.1
00007f2f477d1000   2048K ----- /usr/lib64/libncursesw.so.6.1
00007f2f479d1000      4K r---- /usr/lib64/libncursesw.so.6.1
00007f2f479d2000      4K rw--- /usr/lib64/libncursesw.so.6.1
00007f2f479d3000    148K r-x-- /usr/lib64/ld-2.27.so
00007f2f47bdb000     20K rw---   [ anon ]
00007f2f47bf1000     28K r--s- /usr/lib64/gconv/gconv-modules.cache
00007f2f47bf8000      4K r---- /usr/lib64/ld-2.27.so
00007f2f47bf9000      4K rw--- /usr/lib64/ld-2.27.so
00007f2f47bfa000      4K rw---   [ anon ]
00007ffd39404000    136K rw---   [ stack ]
00007ffd3959b000     12K r----   [ anon ]
00007ffd3959e000      8K r-x--   [ anon ]
ffffffffff600000      4K r-x--   [ anon ]
 total           215692K
 


#8 楼

我不知道ldconfig(8)的-p选项的普及程度如何,但是如果您想避免ldd的任何安全问题,则使用readelf(1)建议和ldconfig的-p的以下sh / awk脚本可能会有所帮助(1),还可以看到动态库的路径。 (注意:这并不会像以前那样进行包含的传递性关闭,因此您只能看到a.out直接调用的库。)

#!/usr/bin/env bash

needs=`readelf -d  | \
  awk '=="(NEEDED)" {
      gsub("[][]", "", ); 
      hits[]=
  }
  END {
      for (i in hits) {
          printf(sprintf("%s ", i))
      }
  }'`

ldconfig -p | \
    awk -vneeds="$needs" \
       'BEGIN{
          split(needs,aneeds)
        }

        { 
          if (!arr[]) 
            arr[] = $NF
        }

        END { 
          for (i in aneeds) { 
            need = aneeds[i]; 
            if (arr[need]) {
              print need "\t" arr[need]
            } else {
               print "unfulfilled:", need
            }
          }
       }'


例如:

{1001} ./foo.sh a.out
libc.so.6   /usr/lib/libc.so.6
libX11.so.6 /usr/lib/libX11.so.6
libgdk-3.so.0   /usr/lib/libgdk-3.so.0
libgcr-base-3.so.1  /usr/lib/libgcr-base-3.so.1
libjavascriptcoregtk-4.0.so.18  /usr/local/lib/libjavascriptcoregtk-4.0.so.18
libatk-1.0.so.0 /usr/lib/libatk-1.0.so.0
libharfbuzz.so.0    /usr/lib/libharfbuzz.so.0
libsoup-2.4.so.1    /usr/lib/libsoup-2.4.so.1
libgdk_pixbuf-2.0.so.0  /usr/lib/libgdk_pixbuf-2.0.so.0
libgck-1.so.0   /usr/lib/libgck-1.so.0
libgthread-2.0.so.0 /usr/lib/libgthread-2.0.so.0
libgcr-ui-3.so.1    /usr/lib/libgcr-ui-3.so.1
libglib-2.0.so.0    /usr/lib/libglib-2.0.so.0
libgobject-2.0.so.0 /usr/lib/libgobject-2.0.so.0
libcairo-gobject.so.2   /usr/lib/libcairo-gobject.so.2
libpango-1.0.so.0   /usr/lib/libpango-1.0.so.0
libz.so.1   /usr/lib/libz.so.1
libgio-2.0.so.0 /usr/lib/libgio-2.0.so.0
libpangocairo-1.0.so.0  /usr/lib/libpangocairo-1.0.so.0
libp11-kit.so.0 /usr/lib/libp11-kit.so.0
libcairo.so.2   /usr/lib/libcairo.so.2
libgtk-3.so.0   /usr/lib/libgtk-3.so.0
libwebkit2gtk-4.0.so.37 /usr/local/lib/libwebkit2gtk-4.0.so.37