c 和 LD_PRELOAD。 open 和 open64 调用被拦截,但不是 stat64

Posted

技术标签:

【中文标题】c 和 LD_PRELOAD。 open 和 open64 调用被拦截,但不是 stat64【英文标题】:c and LD_PRELOAD. open and open64 calls intercepted, but not stat64 【发布时间】:2011-07-25 15:03:06 【问题描述】:

我做了一个小共享库,试图拦截 open、open64、stat 和 stat64 sys 调用。 当我导出 LD_PRELOAD 并运行 oracle 的 sqlplus 时,我可以看到 open 和 open64 调用的痕迹,但没有 stat 和 stat64 调用的痕迹。 共享库是一个单独的 c 文件,其中包含 sys 调用的所有定义。 为什么会发生某些系统调用被拦截而其他系统调用不被拦截的情况? 感谢您的帮助。

【问题讨论】:

【参考方案1】:

因为 GNU libc 实现了您所期望的 open()open64()(即它们只是动态链接的符号,您可以使用 LD_PRELOAD 挂钩),但对 stat() 做了一些特别的事情和stat64()

如果您查看libc 导出的符号(例如nm -D /libc/libc.so.6),您会发现它实际上并没有提供符号statstat64

对这些函数的调用被包装 - 在编译时(如果可能的话)由<sys/stat.h> 中的内联函数,或者(失败)由libc_nonshared.a 提供的静态链接定义。

实际调用的动态链接函数是__xstat()__xstat64();这些参数带有一个额外的第一个参数,一个整数,它是一个版本号,表示调用者期望的struct stat 的布局。尝试挂钩这些。

(所有这一切的重点是允许动态链接的libc 支持使用struct stat 的各种不兼容布局和mode_t 中的位定义的二进制文件;如果您查看/usr/include/sys/stat.h,您会发现对此效果的评论。fstat()fstat64()lstat()lstat64()mknod() 也受到同样的影响。)

【讨论】:

嗨,马修。谢谢你的帮助。但我只是注意到不拦截调用的问题只发生在具有“struct stat64”作为参数的函数中。它适用于 fstat,但不适用于 fstat64 或 stat64。这可能是我的函数定义中的问题吗?还是我应该拦截 __xstat64 和 __fxstat64?再次感谢。 @klayme:不客气,感谢您接受答案 - 这是否意味着您可以正常工作? (我认为拦截__xstat64__fxstat64是对的。) 当与tcm.phy.cam.ac.uk/sw/inodes64.html 的源代码结合使用时,这对我来说效果很好。他们不修补 64 位版本,而只声明接口。我也对它们进行了修补,以允许正确调用 stat64() 的 32 位编译器处理 64 位 inode。

以上是关于c 和 LD_PRELOAD。 open 和 open64 调用被拦截,但不是 stat64的主要内容,如果未能解决你的问题,请参考以下文章

LD_PRELOAD和ld --wrap

LD_PRELOAD 和线程局部变量

一种简单的hook方法--LD_PRELOAD变量

从LD_PRELOAD探究子进程的环境变量

LD_PRELOAD - 可以拦截像 + 和 - 这样的原始运算符吗?

在运行时将函数与 LD_PRELOAD 链接