2016-07-12 44 views
0

I -Wl, -wrap = sendto -Wl, -wrap zu verwenden, ich versuche, sendto in meinem letzten g ++ Link-Befehl, meine App verbindet den Standard sendto zu ersetzen Funktion mit meiner eigenen.Weder ld Wrap noch LD_PRELOAD Arbeitssystemaufruf abfangen

Ich kompiliere den folgenden Quellcode mit gcc -c -o wrap.o wrap.c und die wrap.o in den letzten g ++ Befehl, der die App verbindet (der Rest der App ist C++ daher die Verwendung von 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); 
} 

wenn ich sendto in meinem eigenen Quellcode verwenden, wird die Hülle in der Tat verwendet ok, aber alle 3rd-Party-Objekten gemeinsam i gegen in meinem letzten g ++ gelinkt, dass die Verwendung Befehl immer noch meine verwenden SENDTO das System sendto dh nicht Verpackung. Wie kann ich meinen sendto-Wrapper überall verwenden?

Ich habe auch einen LD_PRELOAD Ansatz mit einem sendto und dlsym (RTLD_NEXT) innerhalb versucht, aber das hat auch nicht funktioniert.

Wie kann ich herausfinden, warum die 3rd-Party-Bibliothek weiterhin die libc sendto direkt verwendet?

Wenn ich LDD verwenden, um alle gemeinsamen Objektabhängigkeiten meiner kompilierten App zu finden, und dann objdump -T auf jedem von ihnen grepping für sendto, bekomme ich UND (undefiniert) für alle gemeinsam genutzten Objekte von Drittanbietern. Die gemeinsam genutzten Objekte, die es definieren jedoch ist:

/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 

ich sehe in glibc sendto.c auf git folgendes:

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

kann dies eine Hilfe sein, eine Lösung in zu bekommen?

Antwort

0

Ich habe es schließlich geschafft, herauszufinden, was hier vor sich ging. Auch wenn die Strace Staaten sendto wird genannt zu werden:

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

was tatsächlich vorging wurde senden (...) genannt wurde (wahrscheinlich möglich, weil 0, null, 0 letzten drei Parameter). In dem Moment, in dem ich einen Abfangjäger zum Senden machte (...), funktionierte es.

0

Die Option --wrap sendto definiert nicht das Symbol sendto in Ihrer Binärdatei. Stattdessen ersetzt es Verweise auf diese Symbole mit __wrap_sendto und verlässt sendto undefined.

Mit anderen Worten, Ihre ausführbare Datei bietet sendto nicht, so dass die Laufzeit-Symbolauflösung die von glibc wählt.

Um dies zu beheben, müssen Sie sendto in Ihrer ausführbaren Datei definieren. Versuchen Sie dlsym noch einmal, aber diesmal ohne LD_PRELOAD/Shim Bibliothek:

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); 
} 

Wenn Bibliotheken von Drittanbietern diese falsche sendto nachdem sie festgestellt halten, dann sehe ich nur einen (nicht besonders wahrscheinlich) Möglichkeit. Shared Libraries sind mit -Bsymbolic/-Bsymbolic-functions verknüpft und stellen ihre eigenen sendto zur Verfügung.

Auch, da Sie diese Frage als g++ gekennzeichnet haben, stellen Sie sicher, dass Ihre Symbolnamen nicht gemangelt werden - verwenden Sie extern "C".

+0

Symbolnamen nicht verändert (kompiliert als c mit gcc und extern "C" mit g ++ kein Unterschied). Versuchte Ihren Vorschlag ohne LD_PRELOAD, aber immer noch keinen Unterschied, ich sehe 'mein Wrap sendto' nur, wenn von meinem eigenen Code, nicht verbunden 3rd Party .so. Ich bin mir sicher, dass sie sendto anrufen, wie ich es von einer strace-Ausgabe sehen kann. Sie liefern definitiv keinen eigenen sendto, wie ich mit objdump -T und allen Shows UND bestätigt habe. – Waslap