2016-03-03 3 views
3

Я использую LD_PRELOAD трюк, чтобы поймать open64() звонки, и я думаю, что я знаю, как сделать это правильно: с программой foobar составленной изПочему не LD_PRELOAD трюк catch open() при вызове fopen()?

#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 

int main() { 
    open64("foobar.txt", 0); 
    return 0; 
} 

Я ловлю open64 как я ожидаю:

>LD_PRELOAD=$PWD/catch.so ./foobar 
open64 called 

Однако , когда open64 заменяется fopen64:

#include <stdio.h> 

int main() { 
    fopen64("foobar.txt", "r"); 
    return 0; 
} 

сейчас open64 не пойман. Зачем?

В случае, если fopen64 звонков open, у меня есть как open, так и open64 перехвачено, никто не поймал.

Обе версии программы foobar при исполнении с strace, показывают, что open называется, что означает, что fopen64 заколлирует внутренне open или open64.

Я думал, что, возможно, что-то статически связаны между собой, но, кажется, не так:

>ldd foobar 

показывает

libc.so.6 => /lib64/libc.so.6 

, который совместно используемую библиотеку, и

>nm /lib64/libc.so.6 

показывает оба open64 и fopen64 как определено (но не fopen, поэтому в вопросе я использовал версии «64» для аргументации; возможно, fopen - это макрос до fopen64 или что-то в этом роде, не имеет значения, так как проблема возникает с 64 или без).

+0

Какие отличия между ними делают _ltrace_ [sic] и/или LD_DEBUG = все показывают вам? – pilcrow

+0

@pilcrow не уверен, что вы имеете в виду ... Я объяснил все это выше, 'strace' показывает' open (foobar.txt' ... (и другие нерелевантные вещи), 'LD_PRELOAD' ничего не показывает. –

+0

Имея ту же проблему Удивление, что происходит. – JC1

ответ

4

Я думаю, что он работает следующим образом: программы пользовательского пространства вызывают функции библиотеки в libc, а libc вызывает системные вызовы в ядре. С LD_PRELOAD можно перехватывать вызовы libc между программой и libc. Вы не можете перехватывать системные вызовы. Если glibc вызывает другую функцию внутри (например, fopen calls open), вы не можете ее перехватить.

Вместо использования strace в этом случае лучше использовать ltrace, потому что это показывает, какие вызовы библиотеки выполняются. Это вызовы, которые вы можете перехватить.

enter image description here