2013-10-08 5 views
0

Я следующий код теста:Трассировка/перевязать открытая система вызова

#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

я не получаю никакого вывода из общей библиотеки здесь. Только нормальный выход программы.

Любая помощь или указатели оценивается. Заранее спасибо.

+0

Возможно, ваша попытка с LD_PRELOAD завершилась неудачно, поскольку имя функции libc может отличаться (не 'open()'). С опцией truss -u вы можете также отслеживать вызовы функций libc.so и посмотреть, какая функция libc используется. –

+0

Я пробовал это и получал некоторые строки, похожие на – Justin

+0

'/ 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

ответ

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 и увидел, что мои функции не экспортируются. Немного разбирая голову, прежде чем я понял, что даже не компилирую свой код ...

Смежные вопросы