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

4

有没有一种工具,可以读取头文件并打印Linux可执行文件运行所需的动态库的名称?

我需要它来了解我刚从源代码构建的二进制文件中是否存在一些奇怪的依赖项(即非常规依赖项),或者它基本上是静态链接的。我认为这比阅读makefiles更容易...


可能是在Linux上显示可执行文件使用的所有库的重复问题。 - Ciro Santilli OurBigBook.com
2个回答

8

readelf -d $executable | grep 'NEEDED'

如果你无法运行该可执行文件,例如它是交叉编译的,或者你不信任它,可以使用此命令:

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

示例:

readelf -d /bin/ls | grep 'NEEDED'

样例输出:

 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 用于运行中的进程

这对于查找当前正在运行的可执行文件所使用的所有库非常有用。例如:

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)
另请参阅:

6

/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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接