我的目标是将多个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调用,而又不会碰到感兴趣的应用程序本身,我会很高兴的如果您让我知道它们(对OS配置进行一些修改,例如预加载,就可以)。谢谢!
答案 0 :(得分:1)
我认为您有一些误解,而您要的只是没有道理:
在我的库ctor代码中,我检查我所处的进程是否是我需要的并进行必要的挂接,否则,它是空操作,库只是一个负担。
以及卸载它的工作,而不是仅仅让它无所事事,而是更多。
更新过程需要卸载-如果要更新库,则不应将其加载到长时间运行的进程中-否则它们将在替换库时崩溃(这是预期的)。
仅当您错误地覆盖库文件而不是替换文件时,才会发生这种情况。可以通过将临时文件安装到同一目录并以旧文件为目标来执行rename
函数(相当于mv
命令)来执行后者。
如果还有其他方法可以在早期阶段自动可靠地挂接glibc调用
您对“可靠”的关注听起来像是要使用此机制来强加策略/访问控制,而这种方式可能会使恶意应用程序无法解决。在库级别,这根本上不可能。您需要在某种真实的沙箱中运行它们以实现此目的(例如,通过在适当的沙箱中调用它们的包装脚本替换文件)。