
Есть ли способ манипулировать (читать, записывать и т. д.) дескриптором файла для любого приложения, которое можно найти в пути ?/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()
зависит от архитектуры, неудобно и, насколько мне известно, никто не реализовал его за вас. Популярное применение — это внедрение fd в процесс, но это примерно противоположно тому, что вам нужно.
Я подумал о том, что для этого потребуется, и это выглядит очень болезненно.
Вы можете использовать подход со скриптом gdb и посмотреть исходный кодэкранировать. Вероятно, все еще очень неудобно передавать FD из gdb. Способ передачи fds заключается в отправке их как «вспомогательных данных» sendmsg()
через сокет unix.
К сожалению, отправка вспомогательных данных обычно выполняется с помощью макроса. Хотя gdb
интерпретатор C производит потрясающее впечатление, я не думаю, что можно использовать макросы.
Другой способ передачи fds — использование fork()
, так что это может предоставить несколько более простых вариантов (в сочетании с exec()
). К сожалению, похоже, что ptrace()
и fork()
не являются лучшими друзьями. Есть некоторыекоманды gdb, специфичные для Linuxчто может сделать работу, но там только упоминается поддержка точек останова; там не говорится, можно ли заставить команду gdb call fork()
работать разумно. Даже если это работает, вам может понадобиться FD_CLOEXEC
также повозиться с (close-on-exec). Это тоже макрос.
Не так уж и сложно найти числовое значение простого макроса (именно так был написан screenify). Интерфейс макроса для отправки вспомогательных данных не очень сложен, поэтому может быть проще выполнить его обратную разработку.