繁体   English   中英

如何在Linux上挂钩send()/ recv()函数?

[英]How to hook send() / recv() functions on Linux?

我正在尝试挂钩Linux上C ++中的recv()send()函数。

我知道如何钩函数(github:zeek / subhook) 但是,我希望获得一些帮助,以学习如何查找recv()send()函数的地址(在运行时或使用版本无关的解决方案 )。

我乐于接受任何可以帮助我了解此处涉及的机制的文档或建议。


[编辑]说明:我不想使用LD_PRELOAD=因为我使用此工具linux-inject注入了共享库。

请参阅什么是LD_PRELOAD技巧?

基本上,您编写的方法具有与要挂接的方法相同的签名。 在这种情况下, sendrecv 然后,您将LD_PRELOAD设置为指向新库。 加载程序将首先找到您的函数并调用它。

在您的库中,您可以包装原始代码,完全替换它,修改输入或输出,基本上是任何东西。

有关一些示例代码,请参见turorial dlsym和ld预加载

发送的一个示例是:

ssize_t (*original_send)(int sockfd, const void *buf, size_t len, int flags);
original_send = dlsym(RTLD_NEXT, "send");
return (*original_send)( /args/ );

如果目标程序不是为注射设计的

一种场所是通过gdb注入。 不过,这并非微不足道 但是您已经了解了这一点。

至于在运行时查找地址,您应该检查一下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);
  }
}

在我的系统上运行它

$ ./a.out
pid 21266
Address of recv: 0x7fff86abedf3
Address of send: 0x7fff86abee03

用gdb仔细检查,

$ gdb -p 21266
(gdb) p (void*)recv
$4 = (void *) 0x7fff86abedf3 <recv>

考虑使用plthook库。 幸运的是,有一个示例如何在主页上挂钩recv。 该库遍历所有加载时间重定位,并替换给定模块的所有出现的目标函数。

功能地址只是功能说明的存储位置。 如果要通过指针替换轻松地在Linux(ELF)上挂接某些东西,则必须更改调用此函数的所有位置,但不能更改函数本身。

如果只想更改recv / send代码,请考虑踩踏功能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM