作者:Jolina | 来源:互联网 | 2023-09-07 17:28
我想知道在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 ++编程来做到这一点。
谢谢。
在加载共享库的可执行文件中。
我相信要获取当前进程,读取/proc/self/maps
文件是在Linux上获取此信息的最简单方法,并且查找最后映射到进程内存的所有唯一.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
加载的内容以及直接链接的内容。
,
您可以使用proc文件系统通过/proc//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
在第六列中使用唯一的路径名集,将为您提供给定进程中加载的所有实际共享库。
请注意,这只会为您提供在调用时在进程中处于活动状态的共享库,如果您在启动时调用它,则将获得由加载程序使用{{1 }}在ELF中的条目。如果该工具使用NEEDED
,则需要再次检查列表。
请注意,如果出于安全目的执行此操作,则在您检查此列表时将已加载共享库,因此任何潜在的有害操作都可能已经发生并被掩盖。如果出于安全原因要检查共享库,则需要解析ELF dyld
条目,然后从环境中使用NEEDED
进行解析。
,
您可以使用非标准的 dl_iterate_phdr(3)
函数来遍历加载的共享对象列表。
#define _GNU_SOURCE
#include
#include
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