2016-07-12 21 views
0

Я пытаюсь использовать -Wl, -wrap = SendTo -Wl, -wrap, SendTo в моей последней г ++ команды ссылку, которая связывает мое приложение, чтобы заменить стандартный SendTo функция с моим собственным.Ни л.д. обертка ни 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 в моем собственном исходном коде, обертка на самом деле используются в порядке, но все третья сторона общих объекты я, связанные с в моем окончательном г ++ повелевает, что использование SENDTO до сих пор использует систему SendTo т.е. не мой обертка. Как я могу получить свою оболочку sendto, используемую повсюду?

Я также попытался использовать LD_PRELOAD с помощью sendto и dlsym (RTLD_NEXT) внутри, но это тоже не сработало.

Как я могу понять, почему сторонняя библиотека продолжает использовать libc sendto напрямую?

Когда я использую ldd для поиска всех общих объектов зависимостей моего скомпилированного приложения, а затем objdump -T для каждого из них grepping для sendto, я получаю UND (undefined) для всех сторонних общих объектов. Общие объекты, которые определяют его, как это:

/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 на мерзавца следующее:

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» с использованием g ++ без разницы). Пробовал ваше предложение без LD_PRELOAD, но все равно никакой разницы, я вижу «мой перенос sendto» только при вызове из моего собственного кода, а не связан с сторонним .so. Я уверен, что они звонят в sendto, поскольку я могу видеть это с выхода strace. Они определенно не предоставляют собственный sendto, поскольку я подтвердил с objdump -T, и все показывает UND. – Waslap

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

  • Нет связанных вопросов^_^