我的Linux应用程序(A)链接到我没有源代码的第三方共享库(B).该库使用了我没有源代码(C)的另一个第三方共享库.我相信(B)使用dlopen来访问(C)而不是直接链接.我的理由是(B)上的’ldd’不显示(C),而objdump -X(B)显示对dlopen / dlclose / dlsym的引用.
我的要求是我需要在代码中为(A)获取指向位于(C)中的函数foo()的函数指针.通常,我会为此使用dlsym,但是我需要将它传递给我从dlopen返回的句柄,因为(B)没有公开它,所以我没有这个句柄.
—
对于更大的上下文:我需要修改(C)中的函数,以便每次它调用其辅助函数bar()(也位于(C)中)时,它还使用(A)中具有相同签名的函数来调用相同的参数(基本上将我的代码注入到(C)foo()-> bar()的代码路径中.我相信我已经找到了一种使用gdb来实现此目的的方法,但是为了移植我的gdb命令列表,但是我坚持获取函数指针的步骤,也愿意接受替代方法来完成相同的任务,而不是如上所述的确切问题
编辑:编写此代码后,我意识到我可能可以在代码中对该文件执行另一个dlopen,并且通过该句柄上的dlsym返回的符号应该与通过原始dlopen收到的符号相同,如果我正确地阅读了dlopen手册页.但是,我仍然对我的大背景感兴趣,如果有更好的方法可以解决这个问题
解决方法:
您可以轻松握住(C)的手柄;只是dlopen正确的文件.您可能已经知道要dlopen的文件(因为需要符号“ foo”),或者在(A)上运行strace -e open,mmap,mmap2并查看它打开了哪些共享库.
创建(C)时,对“ bar”的任何引用(例如,从“ foo”中的jmp指令获得的引用)通常在创建时就已经部分解析了,因为(C)本身具有一个“ bar”.因此,对bar的调用不会通过PLT进行,换句话说,通过简单的黑客操作覆盖bar是无效的,并且像gdb一样需要asm级别的调整.
听起来所有这些工作都过于繁琐,以至于产生了一个问题:是否值得进行这项工作,或者扔掉封闭源代码的组件是否会更好.