我有一个在Linux下运行的程序。如果系统上存在特定的库,则程序会崩溃,但如果该库不存在,则程序可以正常运行。 (它似乎只在第一次运行时查找该库,但并不关心是否找不到它。如果该库在后续运行期间存在,则程序似乎会忽略它。)
我想限制程序在运行时可以使用的库。我怎样才能实现这个目标?
限制和可能性:
- 我无法修改程序。
- 我无法升级或更改系统上的现有库。
- 我可以将程序包装在 shell 脚本中或从我自己的程序中调用它。
编辑:它是 Firefox 的修改衍生品,未公开提供。事实上,正如 Faheem Mitha 怀疑的那样,它似乎在用户配置文件中创建了一些东西。我现在不确定它是什么。
答案1
您可以在 a 中运行该程序chroot
,这将强制加载程序仅使用您已复制到受限环境中的库。
进一步阅读:
- 更改根目录(拱)
- UNIX chroot() 操作的最佳实践
- chroot(Debian)
- 基本 Chroot(乌班图)
- 3.13 配置和使用 Chroot Jails(甲骨文Linux)
答案2
鉴于程序会记住运行之间是否使用该库,它必须将此信息存储在配置文件中的某个位置。作为由法希姆·米萨建议最好的办法是找到该配置文件并在运行程序之前创建它。
运行程序strace
应该告诉你它加载了哪些文件:
strace -o myprogram.strace -e open,access myprogram
如果您确实需要改变程序的工作方式,那么这种情况需要LD_PRELOAD
。您需要找到程序进行的库调用(不是系统调用!)来确定是否加载文件。该ltrace
命令可能会有所帮助。例如,如果程序调用dlopen
,则dlopen
在程序尝试打开该特定库时重写该函数以返回错误。警告:未经测试的代码。
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
int dlopen(const char *filename, int flags) {
int (*original_dlopen)(const char *, int) = dlsym(RTLD_NEXT, "dlopen");
if (!strcmp(filename, PATH_TO_HIDE)) {
return NULL;
}
return original_fopen(path, mode);
}
编译用
gcc -DPATH_TO_HIDE='"libfoo.so"' -O -Wall -fPIC -shared -o hide_libfoo.so hide_library.c -dl
运行程序如下:
LD_PRELOAD=./hide_libfoo.so ./myprogram