2016-07-12 35 views
0

我正嘗試使用-Wl,-wrap = sendto -Wl,-wrap,sendto在我的最終g ++鏈接命令中鏈接我的應用程序來替換標準sendto功能與我自己的。ld wrap或LD_PRELOAD都不能攔截系統調用

我使用gcc -c -o wrap.o wrap.c編譯以下源代碼,並將wrap.o包含在鏈接應用程序的最終g ++命令中(應用程序的其餘部分是C++,因此使用了g ++ )

#include <stdio.h> 
#include <sys/types.h> 
#include <sys/socket.h> 

ssize_t __real_sendto(int, const void *, size_t, int, const struct sockaddr *, socklen_t); 

ssize_t __wrap_sendto 
(
    int sockfd, 
    const void *buf, 
    size_t len, 
    int flags, 
    const struct sockaddr *dest_addr, 
    socklen_t addrlen 
) 
{ 
    printf("my wrap sendto ...\n"); 
    return __real_sendto(sockfd, buf, len, flags, dest_addr, addrlen); 
} 

當我使用的sendto在我自己的源代碼,包裝,其實是在用好,但所有的第三方共享對象我鏈接的是我最終的G ++吩咐使用仍然SENDTO使用該系統的sendto即不是我的包裝。我怎樣才能讓我的sendto包裝在整個過程中使用?

我也試過了一個LD_PRELOAD方法,裏面有一個sendto和dlsym(RTLD_NEXT),但那也不起作用。

如何找出第三方庫爲什麼直接使用libc sendto?

當我使用ldd查找已編譯應用程序的所有共享對象依賴關係,然後在其中每個對象上使用objdump -T greto sendto時,我得到所有第三方共享對象的UND(未定義)。然而那些定義它的共享對象是:

/lib64/libpthread.so.0 
000000000000ed80 w DF .text 0000000000000064 GLIBC_2.2.5 sendto 
/lib64/libc.so.6 
00000000000e98d0 w DF .text 0000000000000064 GLIBC_2.2.5 sendto 

我的glibc sendto.c看到git的以下內容:

weak_alias (__libc_sendto, sendto) 
weak_alias (__libc_sendto, __sendto) 

能這樣在得到一個解決一些幫助?

回答

0

我終於弄清楚了這裏發生了什麼。儘管strace的狀態SENDTO被稱爲:

[pid 17956] sendto(4, "abc"..., 2052, 0, NULL, 0) = 2052 

什麼,其實是發生在發送(...)被調用(可能是可能的,因爲0,NULL,0最後三個參數)。我做了一個攔截器發送(...)它的工作。

0

--wrap sendto選項沒有在您的二進制文件中定義sendto符號。取而代之的是,它用__wrap_sendto替代對此符號的引用,並保留sendto未定義。

換句話說,您的可執行文件不提供sendto,所以運行時符號分辨率會從glibc中選擇一個。

要解決此問題,您需要在可執行文件中定義sendto。再次嘗試dlsym,但這次沒有LD_PRELOAD /墊片庫:

ssize_t sendto 
(
    int sockfd, 
    const void *buf, 
    size_t len, 
    int flags, 
    const struct sockaddr *dest_addr, 
    socklen_t addrlen 
) 
{ 
    ssize_t (*libc_sendto)(int, const void *, size_t, int, const struct sockaddr *, socklen_t) 
     = dlsym(RTLD_NEXT, "sendto"); 
    printf("my wrap sendto ...\n"); 
    return libc_sendto(sockfd, buf, len, flags, dest_addr, addrlen); 
} 

如果第三方庫的不斷髮現後,這個錯誤sendto,然後我看到的只有一個(不是特別有可能的)可能性。共享庫鏈接到-Bsymbolic/-Bsymbolic-functions並提供自己的sendto

此外,由於您已將此問題標記爲g++,請確保您的符號名稱不會被損壞 - 請使用extern "C"

+0

未重整符號名稱(編譯爲c使用gcc和extern「C」使用克++沒有區別)。嘗試沒有LD_PRELOAD你的建議,但仍然沒有區別,我看到'我的包sendto'只有從我自己的代碼調用,沒有鏈接的第三方.so。我確定他們正在調用sendto,因爲我可以從strace輸出中看到它。他們絕對不會提供自己的sendto,因爲我已經用objdump -T確認並且都顯示UND。 – Waslap