我发现上述问题的一些解决方案是:(让我们举一个正在运行的服务的例子,比如说/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 NEEDED
输出:
需要libc.so.6
1234:/ usr / sbin / acpid
0000000000400000 44K r-x-- acpid
000000000060a000 4K r ---- acpid
000000000060b000 4K rw --- acpid
000000000060c000 4K rw --- [anon]
00000000020ce000 132K rw --- [anon]
00007f0ac06c7000 1788K r-x-- libc-2.23.so
00007f0ac0886000 2048K ----- libc-2.23.so
00007f0ac0a86000 16K r ---- libc-2.23.so
00007f0ac0a8a000 8K rw --- libc-2.23.so
00007f0ac0a8c000 16K rw --- [anon]
00007f0ac0a90000 152K r-x-- ld-2.23.so
00007f0ac0caa000 12K rw --- [anon]
00007f0ac0cb3000 8K rw --- [anon]
00007f0ac0cb5000 4K r ---- ld-2.23.so
00007f0ac0cb6000 4K rw --- ld-2.23.so
00007f0ac0cb7000 4K rw --- [anon]
00007ffcacbda000 132K rw --- [堆栈]
00007ffcacbfb000 8K r ---- [anon]
00007ffcacbfd000 8K r-x-- [anon]
ffffffffff600000 4K r-x-- [anon]
总计4400K
0x0000000000000001(NEEDED)共享库:[libc.so.6]
同样在这个过程中,我了解了共享库的确切内容以及它们在Linux中如何在广泛的层面上进行处理。
现在我需要帮助的是:
那么找出流程使用的共享库的最佳方法是什么?
答案 0 :(得分: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.so
。
上面的解决方案1的输出也报告了inux-vdso.so.1
这是一个虚拟共享库,它不存在但是由内核模拟以提高某些库函数的性能。我猜3有它在
ffffffffff600000 4K r-x-- [ anon ]
但它没有注释。
哪些解决方案应该被认为是准确的。
2和4是等价的。它们不如1和3,因为它们仅报告应用程序的直接依赖关系(不是它的依赖项的传递依赖关系)。此外,1不如3,因为它不会报告动态加载的库(通过dlopen
)。
是的,那用来实现例如插件。此外,根据需要,进程可以加载任何更多的共享库 什么时候需要。我在这里是对还是错?
所以,如果我真的需要知道共享库 由一个进程使用,我是否需要轮询该进程 所有的时间来弄清楚这一点? (我确定有更好/更优雅的解决方案)
不,没有更简单的解决方案。您可以检查应用是否调用dlopen
(通过扫描readelf --dyn-syms -W
的输出) - 如果不是,那么大多数 可能很好(某些确实如此)聪明的应用程序可能会通过mmap
等自己加载库本,但这种情况非常罕见,可以忽略不计。)
如果app 调用dlopen
而不是你能做的最好的事情就是使用解决方案3.这显然是不完整的,因为app可能随时加载新的lib,具体取决于它的算法(并且通常没有办法静态地弄明白,因为这相当于解决停止问题。)
找到潜在 dlopen
- lib的一个近似解决方案是扫描应用程序中的所有字符串(通过在其上运行strings
)并提取看起来像的所有内容图书馆名称。当然,这不会捕获动态生成库名称的情况(例如,从某个配置文件中读取)。
解决方案1,ldd方法,是我想要的 避免因为它具有固有的安全风险 (取决于所使用的ldd的版本) 启动一个可执行文件来找出它的共享库。
我不认为可执行文件已启动,即没有应用程序或libs代码运行。
那么找出共享库的最佳方法是什么呢? 一个过程使用?
我没有。 3(其中有许多等效变体,例如其他帖子中建议的扫描/proc/PID/maps
或lsof
)。根据您对dlopen
的倾向程度,您还可以扫描字符串以查找可能已加载的库,但恕我直言,这在大多数情况下都是过度杀伤。
答案 1 :(得分:0)
我考虑lsof -p <pid>
:
https://linux.die.net/man/8/lsof
例如:
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)
...
PS: 是的,&#34; 2。根据我的理解,共享库被加载到内存中......&#34;是对的。