У меня возникли проблемы с перехватом open()
на Linux (Debian в моем случае). Вот это минималистичный источник C, который будет построен в общий объект:LD_PRELOAD-ed ловушки общего объекта read(), но не открыты() .. Почему?
/* 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()
. Что тут происходит? Заранее спасибо ...
`
два possibilites. 1) не используя библиотеку правильно, см. Справочную страницу для примера. 2) открытая функция фактически является макросом для встроенного в ОС или SHELL. – user3629249