卸载自身的 Linux 共享库
Linux shared library that unloads itself
我的目标是将几个glibc函数挂接到位于特定路径的一组进程中。有多种方法可以做到这一点(gdb,strace等)。但我需要在最早的舞台上自动可靠地制作它,这样我就不会错过任何一个电话。所以我决定采用LD_PRELOAD
方法。而且我需要在没有任何用户干预的情况下自动完成它,因此将LD_PRELOAD
注入环境有点脆弱,可能会被用户覆盖。所以我决定在/etc/ld.so.preload
中指定我的库 - 这很好用。
在我的库 ctor 代码中,我检查我所在的进程是否是我需要的进程并执行必要的钩子,否则它是无操作的,库只是一个自重。
__attribute__((constructor)) void my_lib_ctor()
{
if (is_relevant_process())
{
do_the_wiring();
}
}
该库不导出任何符号,并且默认情况下隐藏了其中的所有内容(-fvisibility=hidden
编译器标志),因此任何进程都对我的库没有任何真正的依赖关系。因此,在注入不相关的过程中,可以安全地卸载。
更新过程需要卸载 - 如果要更新库,则不应将其加载到长时间运行的进程中 - 否则它们将在库替换时崩溃(这是预期的)。感兴趣的流程是短暂的,并且由用户启动,因此对它们的影响可以忽略不计。
问题是 - 我不知道如何安全地卸载它。我在考虑dlclose
,但是从库本身调用它将导致它从回调返回已经卸载的库代码。
如果还有其他方法可以在早期阶段(应用程序main()
执行之前)自动可靠地挂钩 glibc 调用,而无需接触感兴趣的应用程序本身,如果您让我知道它们,我会很高兴(操作系统配置的轻微修改,例如预加载,是可以的)。谢谢!
我想你有一些误解,你所要求的只是没有意义:
在我的库 ctor 代码中,我检查我所在的进程是否是我需要的进程并执行必要的钩子,否则它是无操作的,库只是一个自重。
卸载它的工作,而不是让它无所事事,它更重。
更新过程需要卸载 - 如果要更新库,则不应将其加载到长时间运行的进程中 - 否则它们将在库替换时崩溃(这是预期的)。
仅当您错误地覆盖库文件而不是替换文件时,才会发生这种情况。后者可以通过将临时文件安装到同一目录并以旧文件为目标执行rename
功能(等效于mv
命令)来执行。
如果还有其他方法可以在早期阶段自动可靠地钩住 glibc 调用
您对"可靠"的关注听起来可疑地接近于想要使用此机制以潜在恶意应用程序无法绕过的方式实施策略/访问控制。这在库级别基本上是不可能的。您需要在某种真正的沙箱中运行它们才能实现这一点(例如,通过将文件替换为在适当的沙箱中调用它们的包装脚本)。
- 在为LINUX创建共享库时,如何避免STL的私有/弱副本
- 共享库 (.so) 没有扩展名的 Linux 可执行文件之间的区别?
- Linux 可执行文件通过 dlopen 在emplace_back崩溃打开共享库
- Linux c++.在预加载的共享库中定义的基类的崩溃调用函数
- 如何在 Linux 中构建共享库时使未定义引用的链接器失败
- 在 Linux 上,在 C++ 程序中,如何找到已加载共享库的路径?
- 如何在 Linux 中使用 V8 共享库
- 如果我在 Linux 上更改C++动态共享库,而我的可执行程序在其上使用,会发生什么
- 不同的数学符号绑定与共享库与 dlopen 并直接链接到可执行文件 (Linux)
- Ogre 3D共享库与CMAKE链接时,在Linux上执行二进制时找不到
- 写入 Linux 上的共享内存时出现周期性延迟峰值
- 如何链接到与 Linux 中不同版本的 boost 链接的共享库
- 在 Linux 上打开() 与 O_RDWR |O_CREAT |如果文件位于 Win10 PC 的桑巴共享上,O_EX
- 如何在Linux上热重新加载共享库
- 卸载自身的 Linux 共享库
- 混合调试和发布库:Windows vs Linux,静态与共享
- Linux 共享库链接错误(未定义的符号)
- Linux C++.链接共享对象和主对象
- 共享库 C++ Linux 加载非虚拟函数
- 如何对 Linux 共享库进行签名?