如何知道ELF需要哪些动态库?

时间:2009-07-23 15:37:15

标签: header elf dll

是否有任何读取标题的工具会打印Linux可执行文件运行所需的动态库名称?

我需要知道在我刚刚从源代码构建的二进制文件(它是GDB的Python分支)中是否存在一些奇怪的依赖项(即不是非常标准的),或者它主要是静态链接的。我认为这比阅读makefile更容易......

2 个答案:

答案 0 :(得分:4)

/usr/bin/ldd是你的朋友。用法:

ldd /bin/ls

示例输出:

linux-vdso.so.1 =>  (0x00007ffd14f79000)
libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f2d875fc000)
libacl.so.1 => /lib/x86_64-linux-gnu/libacl.so.1 (0x00007f2d873f4000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2d8702f000)
libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f2d86df1000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f2d86bed000)
/lib64/ld-linux-x86-64.so.2 (0x00007f2d8781f000)
libattr.so.1 => /lib/x86_64-linux-gnu/libattr.so.1 (0x00007f2d869e8000)

答案 1 :(得分:2)

<强> readelf -d $executable | grep 'NEEDED'

如果您无法运行可执行文件,则可以使用,例如如果它是交叉编译的,或者你不相信它:

  

在通常情况下,ldd调用标准动态链接器(请参阅ld.so(8)),并将LD_TRACE_LOADED_OBJECTS环境变量设置为1,这会导致链接器显示库          依赖。但是请注意,在某些情况下,某些版本的ldd可能会尝试通过直接执行程序来获取依赖关系信息。因此,你应该          永远不要在不受信任的可执行文件上使用ldd,因为这可能导致执行任意代码。

示例:

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>/maps用于运行流程

这对于通过运行可执行文件查找当前正在使用的所有库非常有用。 E.g:

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打开的库,使用this minimal setup进行测试,并在Ubuntu 18.04上使用sleep(1000)进行了测试。

另见:

相关问题