Linux 获取运行服务在Ubuntu中使用的所有共享库的列表

Linux 获取运行服务在Ubuntu中使用的所有共享库的列表,linux,ubuntu,shared-libraries,Linux,Ubuntu,Shared Libraries,我为上述问题找到的一些解决方案是:(让我们以一个正在运行的服务为例,比如说/usr/sbin/acpid,并假设流程的pid是1234) ldd/usr/sbin/acpid输出: linux vdso.so.1=>(0x00007ffe5eb7a000) libc.so.6=>/lib/x86_64-linux-gnu/libc.so.6(0x00007fa0b1a48000) /lib64/ld-linux-x86-64.so.2(0x000055a297a76000) sudo objd

我为上述问题找到的一些解决方案是:(让我们以一个正在运行的服务为例,比如说
/usr/sbin/acpid
,并假设流程的pid是1234)

  • ldd/usr/sbin/acpid
    输出:

    linux vdso.so.1=>(0x00007ffe5eb7a000)
    libc.so.6=>/lib/x86_64-linux-gnu/libc.so.6(0x00007fa0b1a48000)
    /lib64/ld-linux-x86-64.so.2(0x000055a297a76000)

  • sudo objdump-p/usr/sbin/acpid |需要grep
    输出:

    需要libc.so

  • sudo pmap 1234
    输出: 1234:/usr/sbin/acpid
    0000000000 400000 44K r-x——acpid
    0000000000 60A000 4K r---acpid
    0000000000 60B000 4K rw---acpid
    0000000000 60C000 4K rw---[anon]
    000000000 20CE000 132000 rw---[anon]
    00007f0ac06c7000 1788K r-x--libc-2.23.所以
    00007f0ac0886000 2048K-----libc-2.23.所以
    00007f0ac0a86000 16K r----libc-2.23.所以
    00007f0ac0a8a000 8K rw--libc-2.23.所以
    00007f0ac0a8c000 16K rw---[anon]
    00007f0ac0a90000 152K r-x--ld-2.23.所以
    00007F0AC0CAA0000 12K rw---[anon]
    00007f0ac0cb3000 8K rw---[anon]
    00007f0ac0cb5000 4K r----ld-2.23.所以
    00007f0ac0cb6000 4K rw---ld-2.23.so
    00007f0ac0cb7000 4K rw---[anon]
    00007FFCACBDA000132K rw---[堆叠]
    00007ffcacbfb000 8K r---[anon]
    00007ffcacbfd000 8K r-x--[anon]
    ffffffffff600000 4K r-x--[anon]
    总计4400K

  • readelf-d/usr/sbin/acpid |需要grep
    输出: 0x0000000000000001(需要)共享库:[libc.so.6]

  • 在这个过程中,我还了解了什么是共享库,以及在Linux中如何在更广泛的层面上处理它们

    下面是我需要帮助的事情:

  • 如果我们查看上面每个解决方案的输出,libc.so.6出现在解决方案1、2和4的输出中,但不出现在解决方案3中。此外,上述解决方案1的输出报告了inux vdso.so.1和/lib64/ld-linux-x86-64.so.2,其他解决方案都没有报告这两个版本。那么这些解决方案中的哪一个应该被视为准确的解决方案呢
  • 据我所知,共享库在运行时由加载程序加载到内存中。此外,根据需要,流程可以在需要时加载更多的共享库。我在这里是对还是错?在正确的情况下,任何给定进程使用的共享库都可以是动态的。因此,如果我真的需要知道某个进程正在使用的共享库,我是否需要一直轮询该进程来解决这个问题?(我确信有更好/优雅的解决方案)
  • 解决方案1,即ldd方法,是我想要避免的,因为它具有内在的安全风险(取决于所使用的ldd版本),即启动可执行文件本身以确定其共享库

    那么,找出一个进程使用的共享库的最佳方法是什么?

    < P>我会考虑<代码> LSOF-P<代码>:

    例如:

    lsof -p 552|grep '.so'
    cron    552 root  mem    REG    8,17           153905860 /lib/x86_64-linux-gnu/libnss_files-2.19.so (path dev=248,120)
    cron    552 root  mem    REG    8,17           153905748 /lib/x86_64-linux-gnu/libnss_nis-2.19.so (path dev=248,120)
    cron    552 root  mem    REG    8,17           153905744 /lib/x86_64-linux-gnu/libnsl-2.19.so (path dev=248,120)
    cron    552 root  mem    REG    8,17           153905743 /lib/x86_64-linux-gnu/libnss_compat-2.19.so (path dev=248,120)
    cron    552 root  mem    REG    8,17           153897718 /lib/x86_64-linux-gnu/libpcre.so.3.13.1 (path dev=248,120)
    cron    552 root  mem    REG    8,17           153905740 /lib/x86_64-linux-gnu/libdl-2.19.so (path dev=248,120)
    cron    552 root  mem    REG    8,17           153897705 /lib/x86_64-linux-gnu/libaudit.so.1.0.0 (path dev=248,120)
    cron    552 root  mem    REG    8,17           153905753 /lib/x86_64-linux-gnu/libc-2.19.so (path dev=248,120)
    cron    552 root  mem    REG    8,17           153897811 /lib/x86_64-linux-gnu/libselinux.so.1 (path dev=248,120)
    cron    552 root  mem    REG    8,17           153897716 /lib/x86_64-linux-gnu/libpam.so.0.83.1 (path dev=248,120)
    cron    552 root  mem    REG    8,17           153905746 /lib/x86_64-linux-gnu/ld-2.19.so (path dev=248,120)
    ...
    
    附言:
    是的,“2。根据我的理解,共享库被加载到内存中……是正确的。

    < P>我会考虑<代码> LSOF-P<代码>:

    例如:

    lsof -p 552|grep '.so'
    cron    552 root  mem    REG    8,17           153905860 /lib/x86_64-linux-gnu/libnss_files-2.19.so (path dev=248,120)
    cron    552 root  mem    REG    8,17           153905748 /lib/x86_64-linux-gnu/libnss_nis-2.19.so (path dev=248,120)
    cron    552 root  mem    REG    8,17           153905744 /lib/x86_64-linux-gnu/libnsl-2.19.so (path dev=248,120)
    cron    552 root  mem    REG    8,17           153905743 /lib/x86_64-linux-gnu/libnss_compat-2.19.so (path dev=248,120)
    cron    552 root  mem    REG    8,17           153897718 /lib/x86_64-linux-gnu/libpcre.so.3.13.1 (path dev=248,120)
    cron    552 root  mem    REG    8,17           153905740 /lib/x86_64-linux-gnu/libdl-2.19.so (path dev=248,120)
    cron    552 root  mem    REG    8,17           153897705 /lib/x86_64-linux-gnu/libaudit.so.1.0.0 (path dev=248,120)
    cron    552 root  mem    REG    8,17           153905753 /lib/x86_64-linux-gnu/libc-2.19.so (path dev=248,120)
    cron    552 root  mem    REG    8,17           153897811 /lib/x86_64-linux-gnu/libselinux.so.1 (path dev=248,120)
    cron    552 root  mem    REG    8,17           153897716 /lib/x86_64-linux-gnu/libpam.so.0.83.1 (path dev=248,120)
    cron    552 root  mem    REG    8,17           153905746 /lib/x86_64-linux-gnu/ld-2.19.so (path dev=248,120)
    ...
    
    附言: 是的,“2.根据我的理解,共享库被加载到内存中…”是正确的

    libc.so.6出现在解决方案1、2和4的输出中,但不出现在解决方案3中

    libc.so.6
    是指向
    libc-2.23.so的符号链接,因此它存在,尽管形式不同

    和/lib64/ld-linux-x86-64.so.2,其他解决方案都没有报告

    同上,它是ld-2.23。所以

    此外,上面解决方案1的输出报告了inux vdso.so.1

    这是一个虚拟共享库,它不存在,但由内核模拟以提高某些库函数的性能。我想是3号

    ffffffffff600000 4K r-x-- [ anon ]
    
    但它没有注释

    以下哪种解决方案应被视为准确的解决方案

    2和4是等效的。它们不如1和3,因为它们只报告应用程序的直接依赖项(而不是其依赖项的传递依赖项)。此外,1不如3,因为它不会报告动态加载的lib(通过
    dlopen

    此外,一个进程可以根据需要加载更多的共享库 需要的时候。我在这里是对还是错

    是的,这是用来实现插件的

    所以,如果我真的需要了解共享库 被进程使用时,是否需要轮询该进程 一直在想这个? (我确信有更好/优雅的解决方案)

    不,没有更简单的解决办法。您可以检查应用程序是否调用了
    dlopen
    (通过扫描readelf--dyn syms-W)的输出-如果不这样做,您很可能很好(一些真正聪明的应用程序可能会通过
    mmap
    等加载libs本身,但这种情况非常罕见,可以忽略)

    如果应用程序确实调用了
    dlopen
    ,那么最好使用解决方案3。这显然是不完整的,因为应用程序可能随时加载新的lib,这取决于它的算法(通常无法静态地计算出来,因为这相当于解决暂停问题)

    查找潜在的
    dlopen
    -ed lib的一个近似解决方案是扫描应用程序中的所有字符串(通过在其上运行
    strings
    ),并提取看起来像库名称的所有内容。当然,这不会捕获动态生成库名称的情况(例如,从某个配置文件读取)

    解决方案1,ldd方法,是我想要的 由于其固有的安全风险而避免 (取决于所使用的ldd版本)的 s