使用LD_PRELOAD时如何拦截普通符号?

How can I intercept normal symbols when using LD_PRELOAD?

提问人:Berlin 提问时间:6/27/2023 最后编辑:MathieuBerlin 更新时间:6/28/2023 访问量:111

问:

LD_PRELOAD只是可以拦截动态符号,有什么方法可以拦截普通符号吗?

nm -D /usr/lib64/libc-2.17.so显示动态符号。而这些符号可以通过使用 .LD_PRELOAD

但是我不知道如何拦截正常符号(显示所有正常符号)。nm libc-2.17.so

例如:是一个普通的符号,而不是一个动态的符号,我尝试过用我自己重写这个函数并用来拦截。但是使用时有一个错误:__opendirattest.cppLD_PRELOADLD_DEBUG

/lib/libc.so.6: error: symbol lookup error: undefined symbol: __opendirat (fatal)
C++ C Linux LD 预加载

评论

0赞 Barmar 6/27/2023
LD_PRELOAD由动态链接器实现。它只能拦截它处理的符号。
3赞 Ulrich Eckhardt 6/27/2023
为什么这是一个“正常”的符号?什么是普通符号?请注意,如果您查看编译器/链接器工具,编译器会生成带有所谓符号的二进制代码(我猜这些符号是您所说的正常代码),链接器将它们组合到可执行文件或库(“*.so”)中。如果你使用它们,链接器以前使用的符号就消失了。一般来说,这听起来像是一个“XY问题”,如果你描述你的目标,而不是问为什么你有缺陷的方法不起作用,也许你会得到更好的回应。strip
0赞 Armali 6/27/2023
@123go – 还要注意,用 C++ 编写的函数没有 e. g. 将使其名称被破坏。extern "C"
0赞 Paul Floyd 6/28/2023
为什么要更换__opendirat?
0赞 Berlin 6/28/2023
对不起,令人困惑的表达,普通符号应该是局部函数。我的目标是取代__opendirat。

答:

0赞 Paul Floyd 6/28/2023 #1

您使用的术语有点令人困惑。

符号可见性主要有两种。局部(例如,“t”表示函数,如图所示 ny )和全局或外部(例如,“T”表示函数,如 所示)。nmnm

由于局部函数只能从库内调用,因此它们使用静态链接。

全局函数可以从库外部调用,因此它们具有动态链接。

替换动态库中的静态函数是不可能的(至少使用像LD_PRELOAD这样的简单技术是不可能的。

评论

0赞 Berlin 6/28/2023
谢谢你的回答。看来我需要找到另一种方法来弄清楚。对不起,术语令人困惑。我提出的普通符号正是局部函数的含义。