提问人:user1929999 提问时间:10/15/2023 最后编辑:Jonathan Halluser1929999 更新时间:10/16/2023 访问量:55
在 Linux 中动态链接到 libc 没有绑定/连接
Dynamic linked to libc in Linux does not have bind/connect
问:
在 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 一样使用 bind/connect 函数?
答:
0赞
Employed Russian
10/16/2023
#1
在 Linux 上:
二进制文件不依赖于符号,但这并不一定意味着您不能用于插入该二进制文件。bind
LD_PRELOAD
bind
如果该二进制文件是用 构建的,那么它很可能取决于 ,它(在我的系统上)确实依赖于 和 :gccgo
libgo.so.*
bind
connect
readelf -Ws /usr/lib64/libgo.so.22 | grep -E ' (bind|connect)'
77: 0000000000000000 0 FUNC GLOBAL DEFAULT UND connect@GLIBC_2.2.5 (2)
224: 0000000000000000 0 FUNC GLOBAL DEFAULT UND bind@GLIBC_2.2.5 (2)
140156: 0000000000000000 0 FUNC GLOBAL DEFAULT UND connect@GLIBC_2.2.5
163145: 0000000000000000 0 FUNC GLOBAL DEFAULT UND bind@GLIBC_2.2.5
更新:
好奇你的 gccgo 建筑是否真的被LD_PRELOAD简单的绑定函数所吸引?
是的,确实如此。我用 编译了这个例子,并编译了这段代码:gccgo tcp_server.go
void bind() { abort(); }
跟gcc -w -shared -fPIC -o bind.so bind.c
最后我跑了:它产生了:LD_PRELOAD=./bind.so ./a.out
SIGABRT: abort
PC=0x7f83d3965884 m=0 sigcode=18446744073709551610
goroutine 1 [syscall]:
__pthread_kill_implementation
:0
gsignal
:0
__GI_abort
:0
syscall.Bind
:0
...
但是请注意,我的输出显示了对 的依赖性,而您的则没有。这是我所看到的:ldd
libgo.so
ldd a.out
linux-vdso.so.1 (0x00007ffc574f8000)
libgo.so.22 => /lib64/libgo.so.22 (0x00007f21d5f7d000)
libm.so.6 => /lib64/libm.so.6 (0x00007f21d5e9c000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f21d5e78000)
libc.so.6 => /lib64/libc.so.6 (0x00007f21d5c9a000)
/lib64/ld-linux-x86-64.so.2 (0x00007f21d7bb1000)
评论
0赞
user1929999
10/16/2023
您好,感谢您的快速回复。我想我的二进制 dep 也有。仍然LD_PRELOAD没有被迷住 ''' ldd main linux-vdso.so.1 (0x00007ffe545f4000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5609501000) /lib64/ld-linux-x86-64.so.2 (0x00007f56096e7000) ''' ''' readelf -ws /lib/x86_64-linux-gnu/libc.so.6 |grep -E '(连接|绑定)' 845: 0000000000010a4a0 33 FUNC 弱默认值 16 bind@@GLIBC_2.2.5 2556: 0000000000010a4d0 155 FUNC 弱默认值 16 connect@@GLIBC_2.2.5 '''
0赞
user1929999
10/16/2023
好奇你的 gccgo 建筑是否真的被LD_PRELOAD简单的绑定函数所吸引?或者你的二进制文件实际上有这个符号?bind
0赞
Employed Russian
10/16/2023
@user1929999我已经更新了答案。你究竟是如何构建你的二进制文件的?
0赞
user1929999
10/16/2023
了不起。谢谢。> 在 Linux 上:我使用了标准的> 在 macOS 上(交叉编译):将更多地研究 gccgo。go build main.go
❯ CC=x86_64-unknown-linux-gnu-gcc CGO_ENABLED=1 GOARCH=amd64 GOOS=linux go build -o main.linuxamd main.go
评论