我想更改程序侦听的端口号。该程序是专有的 linux 二进制文件 Plex,它始终侦听 tcp 端口 32400(硬编码)。因为我想在共享服务器上运行它,其他人可能已经在使用这个端口。我在服务器上没有 root 访问权限。VPS 提供商可以在其服务器上运行 Plex。
是否可以使用 LD_PRELOAD 之类的东西来更改端口号?如果是这样,我将如何做这件事?如果没有,我还能如何做到这一点?
我想更改程序侦听的端口号。该程序是专有的 linux 二进制文件 Plex,它始终侦听 tcp 端口 32400(硬编码)。因为我想在共享服务器上运行它,其他人可能已经在使用这个端口。我在服务器上没有 root 访问权限。VPS 提供商可以在其服务器上运行 Plex。
是否可以使用 LD_PRELOAD 之类的东西来更改端口号?如果是这样,我将如何做这件事?如果没有,我还能如何做到这一点?
您有几个选择:
使用十六进制编辑器手动更改值。这可能是最简单的选择,前提是您不要太频繁地更新该二进制文件。找到要修改的偏移量的方法将涉及分解二进制文件并识别要更改的值。
使用容器,如 docker,其中二进制文件仍可在容器内侦听 32400 ,但您可以将其映射到其外部的另一个端口。
使用 LD_PRELOAD,您可以使用它来拦截调用bind()并更改传递给它的内容
如果您没有任何特殊工具,可能最简单的方法是plex在 的控制下运行gdb,并输入gdb来自脚本的comping。为此,您需要找到硬编码 32400 的地址。
objdump -D plex | grep -i 7e90
应该给你类似的东西
40090b: bf 90 7e 00 00 mov $0x7e90,%edi
启动gdb,在那里设置一个断点,运行程序直到遇到断点。
gdb plex
break *0x40090b
run
第一步指令,改变寄存器值,继续运行程序:
stepi
>> 0x0000000000400910 in main () <-- address of next instruction
info registers <-- just to make sure
>> rdi 0x7e90 32400
set $rdi=0x7e91 <-- patch the value
info registers <-- again, just to make sure
>> rdi 0x7e91 32401
cont
在另一个窗口中,检查 plex 是否真的在另一个端口上侦听:
netstat -ntap | grep plex
tcp 0 0 0.0.0.0:32401 0.0.0.0:* LISTEN 22018/plex
是的,它确实!
现在在脚本中自动执行此操作:
gdb plex <<EOF
break *0x400910 <-- note this is the instruction AFTER the load, not the one we breaked on last time
run
set $rdi=0x7e91
cont
EOF
并运行该脚本,而不是plex每次要在不同的端口上启动它。
当然,您也可以使用十六进制编辑器直接更改二进制文件中的值。如果设置侦听端口的例程被重复调用(因此您无法预测 gdb 需要哪个确切的输入),您甚至必须这样做。然而,在许多情况下,这可能是最简单的方法,因为它不需要更改二进制文件或编程 LD_PRELOAD 处理程序,并且稍后更改端口号非常容易。