【发布时间】:2013-10-15 18:31:29
【问题描述】:
我有以下测试代码:
#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)
我想挂钩 open 系统调用并在调用 open 完成之前执行一些代码。我已阅读有关使用 ptrace 执行此操作的信息,但是我在此系统 (solaris) 上没有 sys/ptrace.h。我看到文档说明应该使用 /proc 调试接口而不是 ptrace(),但我无法弄清楚如何使用 procfs 来做我想做的事情。
有人知道这是否可能吗?如果有,怎么做?
附带说明一下,我还尝试使用 LD_PRELOAD 技巧在我自己的共享库中实现 open 系统调用,并让它调用 dlsym 来查找常规 open 系统调用的地址。我无法 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执行
我没有从这里的共享库中得到任何输出。只有正常的程序输出。
感谢任何帮助或指针。提前致谢。
【问题讨论】:
-
您对 LD_PRELOAD 的尝试可能会失败,因为 libc 函数的名称可能不同(不是
open())。使用 truss 选项 -u,您还可以跟踪 libc.so 函数调用,并查看使用了哪个 libc 函数。 -
我试过这个并得到一些看起来像的线条
-
/1@1: -> libc:open(0x10a50, 0x1, 0x0, 0xa13c8)/1@1: -> libc:_save_nv_regs(0xff362c40, 0x0, 0x0, 0x0) /1@1: <- libc:_save_nv_regs() = 0xff362c40 /1@1: -> libc:_ti_bind_guard(0x1, 0x0, 0x1, 0xff3fa984) ... /1@1: -> libc:_open(0x10a50, 0x1, 0x0, 0x0) /1@1: -> libc:__open(0x10a50, 0x1, 0x0, 0x0) /1: open("somefile.log", O_WRONLY) = 3 /1@1: <- libc:__open() = 3 /1@1: <- libc:_open() = 3我很难弄清楚这个名字是什么。会是 open(char* a, char* b, char* c, char* d) 吗? -
实际上,如果我查看用于 open 的 libc 代码,我会看到: libc_hidden_def (__libc_open) weak_alias (__libc_open, __open) libc_hidden_weak (__open) weak_alias (__libc_open, open) 从谷歌上搜索它听起来像是绕过这些宏PLT,这就是为什么我不能将 LD_PRELOAD 用于这些功能。我会继续寻找......
标签: c gcc system-calls