Linux 和 Mac 中的 Go 动态链接到 libc 是不同的吗?我正在尝试评估使用 LD_PRELOAD (Linux) 或 DYLD_INSERT_LIBRARIES (macOS) 来拦截绑定(监听)函数。它可以在 macOS 上运行,但不能在 Linux 上运行。
在 macOS 上:
❯ otool -tV main | grep bind
_x_cgo_bindm:
0000000100090134 bl _syscall.bind
_syscall.bind:
0000000100090578 b _syscall.bind
_syscall.libc_bind_trampoline.abi0:
在 Linux 上:
# objdump -T ./main
./main: file format elf64-x86-64
DYNAMIC SYMBOL TABLE:
0000000000545a80 g DF .text 0000000000000063 Base crosscall2
0000000000545a40 g DF .text 0000000000000037 Base _cgo_panic
0000000000466ae0 g DF .text 0000000000000019 Base _cgo_topofstack
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.2.5) __errno_location
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.2.5) getaddrinfo
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.2.5) free
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.2.5) freeaddrinfo
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.2.5) gai_strerror
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.2.5) stderr
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.2.5) fwrite
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.2.5) vfprintf
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.2.5) fputc
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.2.5) abort
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.2.5) pthread_mutex_lock
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.3.2) pthread_cond_wait
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.2.5) pthread_mutex_unlock
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.3.2) pthread_cond_broadcast
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.34) pthread_create
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.2.5) nanosleep
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.34) pthread_detach
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.2.5) strerror
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.2.5) fprintf
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.2.5) malloc
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.2.5) pthread_attr_init
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.34) pthread_attr_getstacksize
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.2.5) pthread_attr_destroy
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.2.5) sigfillset
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.32) pthread_sigmask
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.2.5) mmap
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.2.5) munmap
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.2.5) setenv
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.2.5) unsetenv
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.2.5) sigemptyset
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.2.5) sigaddset
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.2.5) sigaction
0000000000000000 DO *UND* 0000000000000000 (GLIBC_2.2.5) sigismember
是否有办法强制 Linux 中的 Go 二进制文件像 macOS 一样使用绑定/连接函数?
在 Linux 上:
binary 不依赖于
bind
符号,但这并不一定意味着您不能使用 LD_PRELOAD
为该二进制插入 bind
。
如果该二进制文件是使用
gccgo
构建的,那么它很可能取决于 libgo.so.*
,(在我的系统上)确实取决于 bind
:
readelf -Ws /usr/lib64/libgo.so.22 | grep ' bind'
224: 0000000000000000 0 FUNC GLOBAL DEFAULT UND bind@GLIBC_2.2.5 (2)
163145: 0000000000000000 0 FUNC GLOBAL DEFAULT UND bind@GLIBC_2.2.5