2012-03-03 23 views
1

我构建了一个linux共享对象,我将其注入到第三方程序中,以使用LD_PRELOAD拦截一些动态函数调用。Linux库代码注入&调用SO中相同命名的函数

第三方程序使用位于某个路径的SO“libabc.so”。我注入的SO使用另一个SO,也称为“libabc.so”,位于另一条路径(基本相同但略有代码差异)。

我现在的问题是,调用一个函数“def”出现在两个libabc.so总是由第一个解决。 (大概是因为它是第一次加载?!)我怎样才能让他们解决与第二个libabc.so?

非常感谢!

回答

2

除非因为我以前做过这些事情而有所改变,您将需要dlopen()您想要传递调用的库并手动调用该函数,例如;

​​

有一个完整的例子,如何做到这一点很件事LinuxJournal

+0

我可以从/ proc/PID/maps看到我要调用的库已经被加载。有没有办法避免必须明确指定库的路径?原则上,我只需要将函数解析从一个库转移到列表中的下一个库,不是吗? – ARF 2012-03-03 14:38:39

+0

不知道是否需要将它们称为相同的名称,但是如果您将预加载的库重命名为'libabc_shim.so',那么您应该可以只对'libabc.so'进行dlopen并获得已加载的句柄图书馆。 – 2012-03-03 14:45:35

2

如果你只想使用一个libabc.so版本,你可以随时使用LD_PRELOAD其他任何事情之前,你自己的共享对象一起加载它。

如果你想使用多个版本,你有几个选择:在您的共享对象

  • 使用dlopen()加载该库。既然你已经创建了一个函数注入对象,你应该熟悉这个过程。这是更通用和更强大的方式 - 你甚至可以混合来自不同库版本的匹配函数。

  • 使用不同的DT_SONAME作为共享对象链接的库版本。不幸的是,这需要(稍微)更改该库的构建系统并重新编译。

  • 将您的共享对象静态链接到相关库。并非总是可行,但它不需要修改相关库。这个替代方案的主要问题是,在库中的任何更改之后应该重新链接共享对象,以便将更改拉入。

    警告:您可能需要使用自定义链接描述文件或特定链接器选项避免符号冲突。

+0

感谢您对可用选项的全面了解! – ARF 2012-03-03 16:52:17