0

我有一个作为第三方应用程序(app.exe)的一部分运行的 solaris 共享对象(common.so 文件)。我无权访问应用程序的源代码。为此,我需要添加发布 http 请求的功能。我的计划是将 libcurl 与 openssl 一起使用。棘手的部分是 app.exe 已经依赖于旧版本的 curl (7.14),它不支持 tls v1.2 的 ssl。

我下载了源代码并构建了 curl (7.55.1) 和 openssl .a 文件。我还能够构建 common.so 并静态依赖这些存档文件。ldd 不显示对 curl 或 ssl .so 文件的依赖,也不会报告任何“未找到符号”错误。

有了这个结果,我希望当 so 作为应用程序的一部分运行时调用我的 curl 版本,但它没有。相反 curl_version() 显示旧版本,我收到错误未知 ssl 协议错误

我正在使用 solaris studio 编译器。该应用程序不直接依赖于 curl 库,而是依赖于一个不同的 .so 文件,该文件导出与 curl 同名的符号。我从 nm 中意识到,我假设这个 .so 文件也静态链接 curl。

4

1 回答 1

0

当 app.exe 加载有问题的两个 SO 时,它会将每个 SO 的函数添加到其符号表中。现在必须出现两种可能的情况之一(其中一种实际上是操作系统细节,但在这里无关紧要......):

  1. 较新的版本在较旧的版本之前加载,较旧的版本会覆盖较新的条目。
  2. 新版本在旧版本之后加载,并且由于表中已经存在条目,因此不再更新。

现在最干净的解决方案——如果适用,即如果您可以访问源代码——将更新另一个 SO 以使用更新版本的 curl。如果这样做,请考虑将 curl 创建为新 SO,而不是将其静态链接到 common.so 和其他 SO。

否则,要直接解决问题,您必须切换应用程序加载 SO 的顺序,这可能意味着反编译 app.exe 并在更改了 SO 的链接顺序后重建它。那么问题:当时可能有两个版本的 app.exe,您必须确保只有正确的版本与您的 common.so 一起分发。潜在的麻烦来源,也是......

除此之外,我能想到的最好的解决方法是:

您可以将 curl 前缀从修改curl_为 eg curl_755_。但是,不要手动尝试,这样你很可能会发疯……使用脚本(例如 perl 或 python)代替。如果你更新了 curl 源,你可以再次运行它......

更快的版本,但可能不安全:只需替换任何出现的地方。更安全:在第一次运行中识别外部可见的函数(可能还有全局对象)并将它们保存在映射中,然后将映射中包含的任何字符串替换为相应的值。

后一种方法(map)还允许在以下形式的头文件中生成宏:

#define curl_xyz curl_755_xyz

这些宏允许 common.so 的来源看起来就像使用了 curl 的原始来源......

于 2017-09-05T13:26:03.223 回答