【发布时间】:2015-03-18 18:03:22
【问题描述】:
我在 Linux(在我的情况下是 Debian)上拦截 open() 时遇到问题。这是一个内置到共享对象中的简约 C 源代码:
/* Defines are needed for dlfcn.h (RTLD_NEXT) */
#define __USE_GNU
#define _GNU_SOURCE
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <unistd.h>
int open(char const *path, int oflag, ...) {
int (*real_open)(char const *, int, ...);
char *msg;
va_list args;
int mflag;
fprintf(stderr, ">>>>> in open <<<<<<\n");
real_open = dlsym(RTLD_NEXT, "open");
if ( (msg = dlerror()) ) {
fprintf(stderr, "dlsym error: %s\n", msg);
exit(1);
}
va_start(args, oflag);
mflag = va_arg(args, int);
return real_open(path, oflag, mflag);
}
ssize_t read(int fd, void *buf, size_t count) {
ssize_t (*real_read)(int, void*, size_t);
char *msg;
fprintf(stderr, ">>>>> in read <<<<<\n");
real_read = dlsym(RTLD_NEXT, "read");
if ( (msg = dlerror()) ) {
fprintf(stderr, "dlsym error: %s\n", msg);
exit(1);
}
return real_read(fd, buf, count);
}
共享对象的构建使用:
cc -c -fPIC -Wall funcs.c
cc -shared -o libfuncs.so funcs.o -ldl -lc
现在当我尝试
export LD_PRELOAD=/path/to/libfuncs.so
cat somefile
然后我只在输出中看到read() 的跟踪,即>>>>> in read <<<<<。我从来没有看到open() 的踪迹。我检查了 cat Makefile 使用 strace 做了什么,果然 - open() 和 read() 都被调用了:
open("Makefile", O_RDONLY|O_LARGEFILE) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=213, ...}) = 0
read(3, "testrun: libfuncs.so\n\tLD_PRELOAD"..., 32768) = 213
顺便说一句,我还检查了其他程序,例如 od 或 bash,从未拦截过 open()。这里发生了什么?提前谢谢...
`
【问题讨论】:
-
两种可能性。 1) 未正确使用库,请参阅手册页以获取示例。 2)open函数其实是OS或者SHELL中内置的宏。
标签: c linux shared-libraries ld-preload