有没有什么方法可以操作(读取、写入等)路径中可以找到的任何应用程序的文件描述符?/proc/{pid}/fd
特别是对于插座。
$ ll /proc/4229/fd
total 0
lrwx------. 1 vagrant vagrant 64 May 18 01:10 0 -> socket:[34147]
lrwx------. 1 vagrant vagrant 64 May 18 01:10 1 -> socket:[34149]
lr-x------. 1 vagrant vagrant 64 May 18 01:10 10 -> /dev/null
lrwx------. 1 vagrant vagrant 64 May 18 01:10 11 -> socket:[34943]
lrwx------. 1 vagrant vagrant 64 May 18 01:10 13 -> socket:[34945]
lrwx------. 1 vagrant vagrant 64 May 18 01:10 14 -> socket:[34948]
lrwx------. 1 vagrant vagrant 64 May 18 01:10 15 -> socket:[34950]
lrwx------. 1 vagrant vagrant 64 May 18 01:10 2 -> socket:[34151]
lrwx------. 1 vagrant vagrant 64 May 18 01:10 3 -> socket:[34153]
lr-x------. 1 vagrant vagrant 64 May 18 01:10 4 -> pipe:[34155]
l-wx------. 1 vagrant vagrant 64 May 18 01:10 5 -> pipe:[34155]
lrwx------. 1 vagrant vagrant 64 May 18 01:10 6 -> anon_inode:[eventpoll]
lr-x------. 1 vagrant vagrant 64 May 18 01:10 7 -> pipe:[34156]
l-wx------. 1 vagrant vagrant 64 May 18 01:10 8 -> pipe:[34156]
lrwx------. 1 vagrant vagrant 64 May 18 01:10 9 -> anon_inode:[eventfd]
答案1
ptrace()
从技术上讲,使用/几乎一切皆有可能gdb
。 搜索结果。
使用ptrace()
依赖于架构,很尴尬,而且 AFAICT 没有人为你实现它。流行的应用程序是将 fd 注入到进程中,但这与您想要的相反。
我想到了需要什么,看起来很痛苦。
您可以使用 gdb 脚本方法,并查看源代码筛选。从 gdb 内部通信 FD 可能仍然非常尴尬。通信 fd 的方式是通过sendmsg()
unix 套接字将它们作为“辅助数据”发送。
不幸的是,发送辅助数据通常是使用宏完成的。虽然gdb
C 解释器给人留下了深刻的印象,但我认为不可能使用宏。
传递 fds 的另一种方法是使用fork()
,因此这可能会提供一些稍微简单的选项(与 结合使用exec()
)。不幸的是,它看起来ptrace()
并不是fork()
最好的朋友。有一些Linux 特定的 gdb 命令这可能可以完成工作,但它只提到对断点的支持;它没有说明您是否可以让 gdb 命令call fork()
正常工作。即使它有效,您可能也需要搞乱FD_CLOEXEC
(close-on-exec) 。这也是一个宏。
找到一个简单宏的数值并不难(这就是 screenify 的编写方式)。用于发送辅助数据的宏接口并不是很复杂,因此对其进行逆向工程可能更容易。