在不同的动态加载对象中以不同方式解析符号

时间:2017-01-06 20:07:27

标签: linux ld dynamic-linking dynamic-loading symbol-table

在阅读these questions后,我正在寻找有关如何控制符号解析顺序的更多细节。

在我的问题中,我有主要的可执行文件execexec动态链接到a.soc.soa.so动态链接到b.sob.so调用函数foo,该函数通常由c.so提供,但在这种情况下也由exec提供。 b.so仅适用于c.so foo的实施。

情况图:

exec      (foo caller and provider)
   | \
a.so  |
   |  |
b.so  |   (foo caller)
   | /
c.so      (foo provider)

我只能控制a.so的编译/来源,并使用a.soexecLD_PRELOAD相关联。

我希望拨打foo中的exec来解析exec的实施,并拨打b.so来解析c.so 1}}的实施。这种类型的东西在不同的对象中可能有不同的符号查找吗?

1 个答案:

答案 0 :(得分:0)

不幸的是,没有办法在每个库级别调整符号解析,所以没有简单的方法来实现这一点。

如果foo实际上是在主可执行文件中实现的(不仅仅是copy-relocated),那么你无能为力,因为主要可执行文件中的符号在解析期间获得最高优先级(除非你没事最终是对GOT进行hacky运行时修补,但事实并非如此。

但是如果

  • foo在c.so
  • 中实施
  • 你很绝望

您可以执行以下操作:

  • 在a.so中获取拦截器内的返回地址(使用__builtin_return_address
  • 将其与b.so的边界匹配(可以从/proc/self/maps获得)
  • 取决于结果,要么进行特殊处理(如果来电者在b.so中),要么转发至RTLD_NEXT

这当然有明显的局限性,例如如果b.so从另一个d.so调用函数然后调用foo,则无效,但在许多情况下可能就足够了。是的,我已经看到这种方法在实践中得到了部署。