Я следующий код теста:Трассировка/перевязать открытая система вызова
#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
, я eventaully увидеть следующий вывод:
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)
I хотел бы подключить открытый системный вызов и выполнить код перед вызовом, чтобы открыть финиш. Я читал об использовании ptrace для этого, однако у меня нет sys/ptrace.h на этой системе (solaris). Я вижу документацию о том, что вместо ptrace() следует использовать интерфейсы отладки/proc, но мне не удалось выяснить, как делать то, что я хочу использовать 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
Executed с LD_PRELOAD_32=./libwrap_open.so.1.0 ./test
я не получаю никакого вывода из общей библиотеки здесь. Только нормальный выход программы.
Любая помощь или указатели оценивается. Заранее спасибо.
Возможно, ваша попытка с LD_PRELOAD завершилась неудачно, поскольку имя функции libc может отличаться (не 'open()'). С опцией truss -u вы можете также отслеживать вызовы функций libc.so и посмотреть, какая функция libc используется. –
Я пробовал это и получал некоторые строки, похожие на – Justin
'/ 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' У меня возникли проблемы с выяснением того, что имя является ли это быть открытым (символ * а, символ * б, символ * с, символ * d) – Justin