首页 > 解决方案 > 在共享库上实现缺失符号

问题描述

我有一个第三方库(比如说libfoobar.so),它依赖于另一个名为libutils.so. 我只有旧版本的libutils.so,他的旧版本缺少一个只存在于新版本中的符号(导出函数)。

我可以在一个新的共享库中编写函数(比如说libwrapper.so):

extern "C" int missing_function() {
    return 123;
}

现在??如何“告诉”libfoobar.so使用此功能,已经尝试过:

由于兼容性原因,我无法使用“新版本”。有什么解决办法吗?

标签: cunixshared-libraries

解决方案


好的,我以一种奇怪的方式解决了这个问题,创建了一个包含所用函数的“代理”库。

按照上一个示例进行操作:

  1. 在十六进制编辑器中打开libfoobar.so并修补(更改)到新共享库的链接,将字符串替换为libutils.solibutilx.so尊重字符数)
  2. 还要更改 SONAME,在此示例中更改LIBSUTILSLIBUTILX
  3. 对包装器进行编码并编译为libutilx.so. 下面的 C 代码示例
  4. libfoobar.so与 DONE放在同一个文件夹中。
#include <dlfcn.h>

void *lib = dlopen("libutils.so", RTLD_LAZY);// original lib


// delegates
void *(*ORIGmalloc)(size_t size);
int (*ORIGpthread_setspecific)(pthread_key_t key, const void *value);


// functions
extern "C" void *malloc(size_t size) {
    return (*ORIGmalloc)(size_t);
}
extern "C" int pthread_setspecific(pthread_key_t key, const void *value) {
    return (*ORIGpthread_setspecific)(pthread_key_t, value);
}

// implements missing functions in libutils.so required by libfoobar.so
extern "C" const char *get_greeting_string() {
   return "Hello from libutilx.so !!";
}

extern "C" int some_number() {
   return 12345;
}


// assigns (just an example, you must check for errors)
// with the attribute "constructor" this function is called after the lib is opened
void  __attribute__((constructor)) assign_delegates() {
    *(void **) (&ORIGmalloc) = dlsym(lib, "malloc");
    *(void **) (&ORIGpthread_setspecific) = dlsym(lib, "pthread_setspecific");
}

要知道导入了什么函数,请使用命令行实用程序objdump。示例objdump -T libfoobar.so输出将是:

00000000      DF *UND*  00000000  LIBUTILS        pthread_setspecific
00000000      DF *UND*  00000000  LIBUTILS        malloc
00000000      DO *UND*  00000000  LIBUTILS        __sF

干杯


推荐阅读