我想知道在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?我知道ldd,readelf可以做到这一点,但我需要在加载共享库的可执行文件中使用C/C++编程来做到这一点。
谢谢。
发布于 2019-12-10 09:28:56
加载共享库的可执行文件中的
。
我认为要获取当前进程,读取/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加载以及直接链接的内容。
发布于 2019-12-10 09:29:23
您可以使用proc文件系统通过/proc/<pid>/maps查询共享库。请参考完整的reference for 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进行解析。
发布于 2021-02-22 08:07:36
您可以使用非标准的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.2https://stackoverflow.com/questions/59258867
复制相似问题