Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在Linux上钩住send()/recv()函数?_C++_C_Unix_Elf_Abi - Fatal编程技术网

C++ 如何在Linux上钩住send()/recv()函数?

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注入,不过。但你已经做到了 至于在运行时查找地址,您应该签出。您可能会发现一些库封装了这种

我试图在Linux上勾上<代码> ReVE(<代码)>和<代码> sEnter())/Cuff>函数,C++在Linux上。< /P> 我知道。 但我想了解如何查找函数的地址(在运行时,或使用独立于版本的解决方案),以获得一些帮助

我愿意接受任何类型的文档或建议,可以帮助我理解这里涉及的机制


[编辑]澄清:我不想使用
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-litb
recv
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/ );