C++ 如何在Linux上钩住send()/recv()函数?
我试图在Linux上勾上<代码> ReVE(<代码)>和<代码> sEnter())/Cuff>函数,C++在Linux上。< /P> 我知道。 但我想了解如何查找函数的地址(在运行时,或使用独立于版本的解决方案),以获得一些帮助 我愿意接受任何类型的文档或建议,可以帮助我理解这里涉及的机制C++ 如何在Linux上钩住send()/recv()函数?,c++,c,unix,elf,abi,C++,C,Unix,Elf,Abi,我试图在Linux上勾上 ReVE(和 sEnter())/Cuff>函数,C++在Linux上。< /P> 我知道。 但我想了解如何查找函数的地址(在运行时,或使用独立于版本的解决方案),以获得一些帮助 我愿意接受任何类型的文档或建议,可以帮助我理解这里涉及的机制 [编辑]澄清:我不想使用LD\u PRELOAD=,因为我用这个工具注入了我的共享库:。如果目标程序不是为注入而设计的 一个地点是通过gdb注入,不过。但你已经做到了 至于在运行时查找地址,您应该签出。您可能会发现一些库封装了这种
[编辑]澄清:我不想使用
LD\u PRELOAD=
,因为我用这个工具注入了我的共享库:。如果目标程序不是为注入而设计的
一个地点是通过gdb注入,不过。但你已经做到了
至于在运行时查找地址,您应该签出。您可能会发现一些库封装了这种确切的行为
如果你能设计挂钩的目标程序
有更简单的方法来实现这一点,比如LD_PRELOAD
技巧和其他共享库技巧,可能还有无数其他技巧。但是要获得recv
和send
的地址,您可以按照
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
int main()
{
printf("pid %d\n", getpid());
printf("Address of recv: %p\n", recv);
printf("Address of send: %p\n", send);
for (;;) {
sleep(1);
}
}
与gdb进行双重检查
$ gdb -p 21266
(gdb) p (void*)recv
$4 = (void *) 0x7fff86abedf3 <recv>
$gdb-p 21266
(gdb)p(无效*)recv
$4=(无效*)0x7fff86abedf3
请参阅
基本上,您编写的方法具有与要挂钩的方法相同的签名。在这种情况下,send
和recv
。然后将LD_PRELOAD设置为指向新库。加载程序将首先找到您的函数并调用它
在您的库中,您可以包装原始代码,完全替换它,修改输入或输出,基本上是任何内容
有关一些示例代码,请参见本教程
send的一个例子是:
ssize_t (*original_send)(int sockfd, const void *buf, size_t len, int flags);
original_send = dlsym(RTLD_NEXT, "send");
return (*original_send)( /args/ );
考虑使用图书馆。幸运的是,有一个如何在主页上钩住recv的示例。该库对给定模块的所有目标函数进行迭代并替换所有出现的函数
函数地址就是存储函数指令的地方。如果您想通过指针替换轻松地在Linux(ELF)上钩住某些东西,那么您必须更改调用此函数的所有位置,而不是函数本身
如果您只想更改代码> RecV<代码> />代码>发送<代码>代码,请考虑函数。p> 你的问题是?告诉我们你已经试过做什么。@Robboy牛仔我什么都没试过,我在谷歌上搜索了我的问题,但我找到的都是关于Windows的。。。我的问题是如何在运行时查找函数的
recv()
或send()?我只在LD_PRELOAD=
中看到一种注入库的方法…send和recv似乎是syscall包装器。也许它们是内联在您的程序中的,这将使得不可能通过预加载技巧“钩住”它们。你到底想拦截什么?系统调用recv
和send
或者glibc系统调用包装器?@Johannes Schaub-litbrecv
和send
都是libc函数
ssize_t (*original_send)(int sockfd, const void *buf, size_t len, int flags);
original_send = dlsym(RTLD_NEXT, "send");
return (*original_send)( /args/ );