我找到的上述问题的一些解决方案是:(让我们举一个正在运行的服务的例子,比如 /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
- sudo pmap 1234
输出:
1234:/ usr / sbin / acpid 0000000000400000 44K rx-- acpid 000000000060a000 4K r ---- acpid 000000000060b000 4K rw --- acpid 000000000060c000 4K rw --- [anon] 00000000020ce000 132K rw --- [anon] 00007f0ac06c7000 1788K rx-- 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 rx-- 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 --- [stack] 00007ffcacbfb000 8K r ---- [anon] 00007ffcacbfd000 8K rx-- [anon] ffffffffff600000 4K rx-- [anon]总计4400K
- readelf -d /usr/sbin/acpid | grep NEEDED
输出:
0x0000000000000001(NEEDED)共享库:[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的版本)启动可执行文件本身以找出它的共享库 .
那么,找出流程使用的共享库的最佳方法是什么?
2 回答
libc.so.6
是libc-2.23.so
的符号链接,因此它存在,虽然形式不同 .同上,这是
ld-2.23.so
.这是一个虚拟共享库,它不存在但是由内核模拟以提高某些库函数的性能 . 我猜3有它
但它没有注释 .
2和4是等价的 . 它们不如1和3,因为它们只报告应用程序的直接依赖性(不是它的传递依赖性报告动态加载的库(通过
dlopen
) .是的,那用来实现例如插件 .
不,没有更简单的解决方案 . 您可以检查应用程序是否调用
dlopen
(通过扫描readelf --dyn-syms -W
的输出) - 如果不是,您很可能很好(一些非常聪明的应用程序可能会通过mmap
等自己加载库,但这种情况非常罕见,可以忽略) .如果app确实调用了
dlopen
而不是你能做的最好的事情就是使用解决方案3.这显然是不完整的,因为app可能随时加载新的libs,具体取决于它's algorithm (and there' s通常无法静态计算,因为它相当于解决停止问题) .找到可能的
dlopen
-ed库的一个近似解决方案是扫描所有字符串应用程序(通过运行strings
)并提取看起来像库名称的所有内容 . 当然,这不会捕获动态生成库名的情况(例如,从某个配置文件中读取) .我不认为可执行文件已启动,即没有运行app或libs代码 .
我没有 . 3(其具有许多等效变体,例如其他帖子中建议的扫描
/proc/PID/maps
或lsof
) . 根据您对dlopen
的倾向程度,您还可以扫描字符串以查找可能已加载的库,但恕我直言,这在大多数情况下都是过度杀伤 .我考虑
lsof -p <pid>
:https://linux.die.net/man/8/lsof
例如:
PS:是的,“2 . 根据我的理解,共享库被加载到内存中......”是正确的 .