在Linux上使用C/C++执行程序时列出共享库

3

我希望知道在Linux上执行C/C++程序时加载了哪些动态库。

例如,

int main()
{
    ...
    list = GetAllSharedLibraryFilePaths();
}

列表应包含:libm.so.6,librt.so.1,... 或路径:/lib/x86_64-linux-gnu/libm.so.6,/lib/x86_64-linux-gnu/librt.so.1...

是否有任何API可以返回所有共享库文件路径? 我知道lddreadelf可以做到这一点,但我需要在加载共享库的可执行文件中使用C/C++编程来完成。

谢谢。


你说的“我需要在加载共享库的可执行文件中使用C/C++编程来完成这个任务”是什么意思?如果你只需要让调用程序能够访问它,你可以尝试使用system("ldd")命令并解析输出结果。 - undefined
3个回答

1

您可以使用非标准 dl_iterate_phdr(3) 函数来遍历已加载的共享对象列表。

#define _GNU_SOURCE
#include <link.h>
#include <stdio.h>

int print(struct dl_phdr_info *info, size_t size, void *data) {
  printf("%s\n", info->dlpi_name);
  return 0;
}

int main() {
  dl_iterate_phdr(print, NULL);
  return 0;
}

$ gcc test.c -o test
$ ./test

linux-vdso.so.1
/lib/x86_64-linux-gnu/libc.so.6
/lib64/ld-linux-x86-64.so.2

0
在加载共享库的可执行文件中。
我相信要获取当前进程,在Linux上读取/proc/self/maps文件是最简单的方法,然后查找所有映射到进程内存中的唯一.so文件,例如最后一列。
55e8485f5000-55e8485fd000 r-xp 00000000 fd:01 654093                     /bin/cat
55e8487fc000-55e8487fd000 r--p 00007000 fd:01 654093                     /bin/cat
55e8487fd000-55e8487fe000 rw-p 00008000 fd:01 654093                     /bin/cat
55e84a238000-55e84a259000 rw-p 00000000 00:00 0                          [heap]
7f403d604000-7f403d8e2000 r--p 00000000 fd:01 920600                     /usr/lib/locale/locale-archive
7f403d8e2000-7f403dac9000 r-xp 00000000 fd:01 1439402                    /lib/x86_64-linux-gnu/libc-2.27.so
7f403dac9000-7f403dcc9000 ---p 001e7000 fd:01 1439402                    /lib/x86_64-linux-gnu/libc-2.27.so
...

所以你可以看到其中一个加载的库是 /lib/x86_64-linux-gnu/libc-2.27.so。它应该包括通过 dlopen 加载的任何内容,以及直接链接的内容。


0

你可以使用proc文件系统来查询共享库,使用/proc/<pid>/maps。请查阅proc的完整参考文档,其中显示了一些示例输出供您解析:

address           perms offset  dev   inode       pathname
...
35b1800000-35b1820000 r-xp 00000000 08:02 135522  /usr/lib64/ld-2.15.so
35b1a1f000-35b1a20000 r--p 0001f000 08:02 135522  /usr/lib64/ld-2.15.so
35b1a20000-35b1a21000 rw-p 00020000 08:02 135522  /usr/lib64/ld-2.15.so
35b1a21000-35b1a22000 rw-p 00000000 00:00 0
35b1c00000-35b1dac000 r-xp 00000000 08:02 135870  /usr/lib64/libc-2.15.so
35b1dac000-35b1fac000 ---p 001ac000 08:02 135870  /usr/lib64/libc-2.15.so
35b1fac000-35b1fb0000 r--p 001ac000 08:02 135870  /usr/lib64/libc-2.15.so
35b1fb0000-35b1fb2000 rw-p 001b0000 08:02 135870  /usr/lib64/libc-2.15.so

通过获取第6列中的唯一路径名集合,您可以获得给定进程中加载的所有实际共享库。

请注意,这只会给出在调用时处于活动状态的共享库,并且如果您在启动时调用此函数,将会获取到由加载器使用ELF中的NEEDED条目解析的共享库。如果工具使用dyld,则需要再次检查列表。

请注意,如果您出于安全目的进行此操作,共享库在您检查此列表时已经被加载,因此任何潜在的恶意行为可能已经发生并被掩盖。如果您想出于安全原因检查共享库,您需要解析ELF的NEEDED条目,然后使用环境中的PATH进行解析。


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