2012-05-14 37 views
2

我試圖掛鉤glibc的一些函數,如fopen,fread等。但是在hook函數中,我必須使用與glibc中相同的函數。就像這樣:如何在linux中不使用dlsym掛鉤

// this is my fopen 
FILE *fopen(.....) 
{ 
    fopen(....);// this is glibc fopen 
} 

我發現做到這一點使用dlsym的一種方式,但這種方式我不得不更換所有的glibc的功能與包裝內,其使用dlsym調用glibc的函數調用。 我很好奇,在沒有對包裝函數進行編碼的情況下,另一種方式可以做同樣的工作。我曾經tryed這一點:

fopen.c

....fopen(..) 
{ 
    myfopen(..); 
} 

myfopen.c

myfopen(..) 
{ 
    fopen(...);// glibc version 
} 

的main.c

int main() 
{ 
    fopen(...); 
} 

$ gcc -c *.c 
$ gcc -shared -o libmyopen.so myopen.o 
$ gcc -o test main.o fopen.o libmyopen.so 

在我的理解,GCC將鏈接從左至右如命令行中指定的那樣,main.o將在fopen.o中使用fopen.o,fopen.o將在libmyfopen.so中使用myfopen,libmyfopen.so將在glibc中使用fopen。但是在運行時,我得到了段錯誤,gdb顯示有一個fopen和myfopen的recusive調用。我有點困惑。誰能解釋爲什麼?

回答

2

我的理解,GCC將連接左在命令行中指定,所以main.o將在fopen.o使用的fopen,fopen.o將在libmyfopen.so使用myfopen,libmyfopen.so將右在glibc中使用fopen

你的理解是不正確。來自libmyfopen.somyfopen將使用的第一個定義fopen可用於它。在你的設置中,該定義將來自鏈接到test程序的fopen.o,並且最終會導致無限遞歸,並且由於堆棧耗盡而導致崩潰。

您可以通過運行gdb ./test來觀察此情況,運行至崩潰並使用backtrace。你會看到一個無休止的序列fopenmyfopen調用。

符號的fopen編譯

時,這是正確的不粘結到libc中:在ELF格式來定義,它需要(在這種情況下fopen)符號庫記錄,但它不會「記住」或關心哪個其他模塊定義該符號。

您可以通過運行readelf -Wr libmyfopen.so | grep fopen來查看。

這與Windows DLL不同。

是的。

+0

所以你的意思是libmyfopen.so將使用第一個加載的fopen,而不是libc中的那個。編譯時符號fopen與libc中的符號沒有聯繫?這與Windows DLL不同。 我想我需要學習一些關於精靈加載過程的東西。 感謝您的回覆,非常感謝。 – D3Hunter