我想知道我的系统上的可执行文件使用了哪些库。更具体地说,我想对使用最多的库以及使用它们的二进制文件进行排名。我该怎么做呢?
当前回答
检查程序可执行文件的共享库依赖关系
要找出特定可执行文件所依赖的库,可以使用ldd命令。这个命令调用动态链接器来查找可执行文件的库依赖关系。
>$ldd /path/to/program
注意,不建议使用任何不受信任的第三方可执行文件运行ldd,因为某些版本的ldd可能直接调用可执行文件来识别其库依赖关系,这可能存在安全风险。
相反,更安全的显示未知应用程序二进制程序的库依赖关系的方法是使用以下命令。
$ objdump -p /path/to/program | grep需要
更多信息
其他回答
Readelf -d递归
Redelf -d产生与objdump -p类似的输出,objdump -p在https://stackoverflow.com/a/15520982/895245中提到过
但要注意动态库可能依赖于其他动态库,因此必须递归。
例子:
readelf -d /bin/ls | grep 'NEEDED'
示例ouptut:
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
选择一个,然后重复:
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>/正在运行进程的映射
这对于查找当前正在运行的可执行文件所使用的所有库非常有用。例如:
sudo awk '/\.so/{print $6}' /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)进行了测试。
参见:https://superuser.com/questions/310199/see-currently-loaded-shared-objects-in-linux/1243089
还有一个选项可以读取位于的文件
/proc/<pid>/maps
例如,进程id为2601,则命令为
cat /proc/2601/maps
输出是
7fb37a8f2000-7fb37a8f4000 r-xp 00000000 08:06 4065647 /usr/lib/x86_64-linux-gnu/libproxy/0.4.15/modules/network_networkmanager.so
7fb37a8f4000-7fb37aaf3000 ---p 00002000 08:06 4065647 /usr/lib/x86_64-linux-gnu/libproxy/0.4.15/modules/network_networkmanager.so
7fb37aaf3000-7fb37aaf4000 r--p 00001000 08:06 4065647 /usr/lib/x86_64-linux-gnu/libproxy/0.4.15/modules/network_networkmanager.so
7fb37aaf4000-7fb37aaf5000 rw-p 00002000 08:06 4065647 /usr/lib/x86_64-linux-gnu/libproxy/0.4.15/modules/network_networkmanager.so
7fb37aaf5000-7fb37aafe000 r-xp 00000000 08:06 4065646 /usr/lib/x86_64-linux-gnu/libproxy/0.4.15/modules/config_gnome3.so
7fb37aafe000-7fb37acfd000 ---p 00009000 08:06 4065646 /usr/lib/x86_64-linux-gnu/libproxy/0.4.15/modules/config_gnome3.so
7fb37acfd000-7fb37acfe000 r--p 00008000 08:06 4065646 /usr/lib/x86_64-linux-gnu/libproxy/0.4.15/modules/config_gnome3.so
7fb37acfe000-7fb37acff000 rw-p 00009000 08:06 4065646 /usr/lib/x86_64-linux-gnu/libproxy/0.4.15/modules/config_gnome3.so
7fb37acff000-7fb37ad1d000 r-xp 00000000 08:06 3416761 /usr/lib/x86_64-linux-gnu/libproxy.so.1.0.0
7fb37ad1d000-7fb37af1d000 ---p 0001e000 08:06 3416761 /usr/lib/x86_64-linux-gnu/libproxy.so.1.0.0
7fb37af1d000-7fb37af1e000 r--p 0001e000 08:06 3416761 /usr/lib/x86_64-linux-gnu/libproxy.so.1.0.0
7fb37af1e000-7fb37af1f000 rw-p 0001f000 08:06 3416761 /usr/lib/x86_64-linux-gnu/libproxy.so.1.0.0
7fb37af1f000-7fb37af21000 r-xp 00000000 08:06 4065186 /usr/lib/x86_64-linux-gnu/gio/modules/libgiolibproxy.so
7fb37af21000-7fb37b121000 ---p 00002000 08:06 4065186 /usr/lib/x86_64-linux-gnu/gio/modules/libgiolibproxy.so
7fb37b121000-7fb37b122000 r--p 00002000 08:06 4065186 /usr/lib/x86_64-linux-gnu/gio/modules/libgiolibproxy.so
7fb37b122000-7fb37b123000 rw-p 00003000 08:06 4065186 /usr/lib/x86_64-linux-gnu/gio/modules/libgiolibproxy.so
如果你不关心可执行文件的路径-
ldd `which <executable>` # back quotes, not single quotes
要了解二进制文件使用的库,请使用LDD
ldd path/to/the/tool
您必须编写一个小shell脚本来处理系统范围的故障。
在UNIX系统上,假设二进制(可执行)名称为test。然后我们使用下面的命令列出测试中使用的库
ldd test