首页 > 解决方案 > 防止函数插入链接到执行插入的库的库中

问题描述

好吧,我找不到适合我的问题标题的简短短语,但这就是我的意思:

我有一个库,其中插入了一些系统调用,例如open(2). 我使用这种方法进行设置。我添加它以DYLD_INSERT_LIBRARIES实现我的目标。

包含插入代码的库是a.dylib.

我需要链接一个库b.dyliba.dylib因为它包含一些a.dylib需要的功能。

问题是也a.dylib插入b.dylib了我不想要的功能。

我不是链接专家。有什么方法可以防止这种行为,发生这种情况的原因是什么?

更新:

这是如何b.dylib构建的:

clang -dynamiclib -fPIC -Wextra -Wall -pedantic -Wl,-single_module <object files> -o b.dylib -install_name <path>

这是如何a.dylib构建的:

clang -dynamiclib -fPIC -Wextra -Wall -pedantic -Wl,-single_module <object files> -o a.dylib -install_name <path> b.dylib

a.dylib添加到DYLD_INSERT_LIBRARIES.

标签: macoslinkerclangdyld-insert-libraries

解决方案


您说a.dylib取决于b.dylibb.dylib不取决于a.dylib并且您不希望任何呼叫b.dylib被插入。您open举了一个插入函数的例子。

我给出的示例是a.dylib需要调用processFile其中定义的b.dylib并打开文件。您不希望open调用b.dylib被插入(无论是否a.dylib加载)。

我知道解决这个问题的唯一方法是processFile动态加载 C 库,而不是让它ld自动加载。

这种方法有两个问题。第一个是每个需要调用的函数open都需要一个额外if的语句来执行代码来解析符号。

另一个是您需要提前知道要加载的 C 库的文件名。如果解决符号有问题,那么您必须处理大多数程序不必处理的情况;至少在以后的时间。

代码将如下所示:

void processFile (char * filename) {
    FILE *fp;
    // c_open can have file scope if thread safety isn't needed
    static int (*c_open)() = NULL;

    if (c_open == NULL) {
        // factor this if more than one function needs open
        void *dlh = dlopen(C_LIBRARY_FILENAME, RTLD_LAZY);
        if (dlh == NULL) {
           perror("cannot load C library");
           exit(1);
        }
        c_open = dlsym(dlh, "open");
        if (c_open == NULL) {
           perror("cannot resolve open in the C library");
           exit(1);
        }
    }
    c_open(filename, O_RDONLY);
    ...
}

更新

如果不指定 C 库的完整路径名,dlopen可能会打开意外文件。


推荐阅读