Tim*_*sch 7 c linux shared-libraries ld-preload
我很熟悉使用dlopen()先前调用来检查共享库是否已加载到进程中dlopen()而不会触发加载(如果不存在),如下所示:
void* lib = dlopen(lib_name, RTLD_NOLOAD);
if (lib != NULL) {
...
}
Run Code Online (Sandbox Code Playgroud)
我最近尝试应用相同的模式来确定是否已使用LD_PRELOAD将少数共享库中的一个加载到进程空间中.然而在所有的情况下,上述呼吁dlopen()的回报NULL.
所以基本上,如果我使用这个命令行启动进程
LD_PRELOAD=libawesome.so ./mycoolprocess
Run Code Online (Sandbox Code Playgroud)
然后在mycoolprocess.c中的代码中运行以下检查
void* has_awesome = dlopen("libawesome.so", RTLD_NOLOAD);
if (has_awesome != NULL) {
printf("libawesome is available\n");
}
Run Code Online (Sandbox Code Playgroud)
无论是否使用LD_PRELOAD加载了共享库,对dlopen()always 的调用都会返回NULL.根据Andrew Henle在下面的评论,我也尝试dlopen使用其中一个重新加载的共享对象的绝对路径进行调用,但dlopen在这种情况下,尽管共享对象已预加载,仍会返回NULL.
所以我的问题是双重的:
分别是“否”和“是”。
dlopen()和 LD_PRELOAD 技巧,虽然它们都处理共享库,但以根本不同的方式操作。
LD_PRELOAD 环境变量由动态链接器/加载器 (ld-linux.so) 处理,并影响可执行二进制文件本身中重定位记录的解析。简而言之,在代码中调用动态库中定义的函数的每一点,链接器(在构建时)都会插入一个占位符作为要跳转到的内存地址。在运行时,这些占位符会被基于加载到内存中的共享库的真实地址替换,它们本身在可执行文件中命名,但如果使用 LD_PRELOAD 则可能会被覆盖。
因此,一旦可执行文件加载到内存中并且所有这些占位符都已填充真实地址,就没有简单(或可移植)的方法来告诉什么来自哪里。然而...
您可以检查正在运行的进程的内存映射。在 Linux 上,这意味着通过 /proc/<pid>/maps 进行解析。文件内容相当不言自明,因此只需随机选择一个并查看即可。
不知道如何在其他系统上执行此操作,但我相信大多数现代 unixen 都有某种 /proc 文件系统。
| 归档时间: |
|
| 查看次数: |
2580 次 |
| 最近记录: |