在运行时检测和拦截链接库依赖项



在UNIX系统上,是否有一种简单的方法来识别一个动态(共享)库是否依赖于其他动态库?

我正在探索系统级api,如C和c++中的dlopen和朋友。我有一个受控的环境,我将调用dlopen并映射特定的函数。这个想法是,人们将能够为应用程序编写本地插件(让我们假设,确保库实际上执行正确的功能,而不是恶意的,这符合作者的最佳利益)。

然而,作为一项安全措施,我希望确保在运行时加载的动态库不链接到任何其他动态库(目的是禁止系统调用,只允许来自本地数学库的函数)-如果有,不要加载它。

我想出的一些(冗长和/或困难的)解决方案:

  • 编写一个编译器shim,用一组非常特定的编译器选项编译插件代码,并注入某种校验和函数,可以用来验证编译器shim是否被使用。
  • 单独分割所有引用我不想使用的函数名的函数调用。
  • 拦截所有带有链接器路径欺骗的系统调用

是否有一种简单的方法来检查动态库的依赖关系?

然而,作为一种安全措施,我想确保在运行时加载的动态库不链接到任何其他动态库

注意,动态库可以导入符号,而无需显式链接到任何其他动态库。例如:

int foo() { return open("/etc/passwd", O_RDONLY); }
gcc -fPIC -shared -o foo.so foo.c -nostdlib

现在foo.so没有任何DT_NEEDED共享库依赖,但仍将open /etc/passwd随意。

(意图是禁止系统调用,只允许来自本地数学库的函数)-如果它允许,则不要加载它。

你的意图有那么多错误,这一点都不好笑。

首先,您不需要链接到任何外部库来直接执行系统调用,它可以在汇编中轻松完成。

此外,插件可以查找和修改动态加载器的数据,一旦它这样做了,它可以让你的主程序做任意的事情。例如,它可以劫持所有主程序对libc.so的调用,并将它们重定向到其他地方。

一旦你在你的进程中运行了不可信的代码,游戏结束

我已经想出了解决方案

他们都没有工作的机会。你花在这上面的时间完全是浪费。

最新更新