簡體   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