golang 實現 LD_PRELOAD 攔截 libc

基於的工作:Hooking libc using Go shared libraries

先把 socket() 的 libc 調用攔截下來

package mainnn// #cgo LDFLAGS: -ldln// #include <stddef.h>n// #include <netinet/in.h>n// #include "network_hook.h"nimport "C"nimport (nt"fmt"nt"syscall"n)nnfunc init() {ntC.libc_hook_init()n}nn//export socketnfunc socket(domain C.int, type_ C.int, protocol C.int) C.int {ntfmt.Println(fmt.Sprintf("open socket from thread id: %v", syscall.Gettid()))ntreturn C.orig_socket(domain, type_, protocol)n}nnfunc main() {n}n

把這個編譯成 so

go build -buildmode=c-shared -o libmotrix.so main.gon

然後調用

LD_PRELOAD=libmotrix.so curl http://www.baidu.comn

就會把 socket 的 lib 調用給攔截下來

把 socket() 透明轉交給 libc

network_hook.h

#ifndef __DLSYM_WRAPPER_H__n#define __DLSYM_WRAPPER_H__nnvoid libc_hook_init();nint orig_socket(int, int, int);nn#endifn

network_hook.c

#include <dlfcn.h>n#include <stddef.h>n#include <stdio.h>n#include <string.h>n#include <netdb.h>n#include <math.h>n#include "network_hook.h"n#include "_cgo_export.h"nn#define RTLD_NEXTt((void *) -1l)nn#define HOOK_SYS_FUNC(name) if( !orig_##name##_func ) { orig_##name##_func = (name##_pfn_t)dlsym(RTLD_NEXT,#name); }nntypedef int (*socket_pfn_t)(int, int, int);nstatic socket_pfn_t orig_socket_func;nnvoid libc_hook_init() {n HOOK_SYS_FUNC( socket );n}nnint orig_socket(int domain, int type, int protocol) {n return orig_socket_func(domain, type, protocol);n}n

其中

  • orig_socket 是函數暴露給 golang 調用
  • orig_socket_func 是函數指針,指向了libc的原來的實現
  • socket_pfn_t 是socket()這個函數指針的類型定義

原來文章里的實現在我的機器上報錯,原因未知。感覺這樣用 cgo 包裝一下更簡單直接一些,還少了一次反射。

推薦閱讀:

《網路勝利組》腳本陣對談
如何搞垮情敵?
為什麼最近通過163郵箱註冊steam賬號容易被盜!?
速度超快、小巧的代理掃描器(xsec-proxy-scanner)
【人物】滴滴吳樹鵬:變動不居,四十不惑

TAG:Go语言 | 网络安全 | 网络编程 |