在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
的调用,并将它们重定向到其他地方。
一旦你在你的进程中运行了不可信的代码,游戏结束。
我已经想出了解决方案
他们都没有工作的机会。你花在这上面的时间完全是浪费。