我有以下测试代码:
#include <stdio.h>
int main(void)
{
fprintf(stderr, "This is a test.\n");
int ret = open("somefile.log", 1);
fprintf(stderr, "Return value is %d.\n", ret);
return 0;
}
使用gcc -m64 test.c -o test
如果我运行truss ./test
,我会看到以下输出:
getrlimit(RLIMIT_STACK, 0xFFFFFFFF7FFFE280) = 0
getpid() = 1984 [1983]
setustack(0xFFFFFFFF7EE002C0)
fstat(2, 0xFFFFFFFF7FFFDAA0) = 0
This is a test.
write(2, " T h i s i s a t e".., 16) = 16
open("somefile.log", O_WRONLY) = 3
Return value is write(2, " R e t u r n v a l u e".., 16) = 16
3.
write(2, " 3 .\n", 3) = 3
_exit(0)
我想在打开完成调用之前挂钩开放系统调用并执行一些代码。我已经阅读了有关使用ptrace执行此操作的信息,但是我在此系统上没有sys / ptrace.h(solaris)。我看到文档声明应该使用/ proc调试接口而不是ptrace(),但我还没有能够弄清楚如何使用procfs做我想做的事情。
有人知道这是否可行?如果是这样,怎么样?
作为旁注,我还尝试使用LD_PRELOAD技巧在我自己的共享库中实现开放系统调用,并让它调用dlsym来查找常规开放系统调用的地址。我无法弄清楚100%为什么不起作用,但它似乎与内联调用有关,而不是使用地址表来查找这些函数。但是不知怎的truss
能够检测到对open()的调用。
这是我尝试的代码:
cat wrap_open.c
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
static int (*next_open) (const char *path, int oflag, /* mode_t mode */) = NULL;
int open(const char *path, int oflag)
{
char *msg;
if(next_open == NULL) {
fprintf(stderr, "wrapping open\n");
next_open = dlsym(RTLD_NEXT, "open");
if((msg = dlerror()) != NULL) {
fprintf(stderr, "open: dlopen failed: %s\n", msg);
} else {
fprintf(stderr, "open: wrapping done\n");
}
}
fprintf(stderr, "open: opening %s\n", msg);
fflush(stderr);
return next_open(path, oflag);
}
使用gcc -fPIC -shared -Wl,-soname,libwrap_open.so.1 -ldl -o libwrap_open.so.1.0
编译
使用LD_PRELOAD_32=./libwrap_open.so.1.0 ./test
我在这里没有从共享库中获得任何输出。只有正常的程序输出。
任何帮助或指示表示赞赏。提前谢谢。
答案 0 :(得分:0)
我的错误比你想象的更愚蠢。
这是我编译的命令
gcc -g -m64 -fPIC -shared -ldl -o libwrap_open64.so.1.0
这是正确的命令
gcc -g -m64 -fPIC -shared -ldl -o libwrap_open64.so.1.0 wrap_open.c
我猜第一个命令构建了一个没有任何内容的库。我通过运行nm -g libwrap_open64.so.1.0
找到了问题,发现我的函数没有被导出。在我意识到我甚至没有编译我的代码之前,我有点头疼......