Выполнить процесс из памяти в другом процессе?

Я хотел бы иметь небольшой "загрузчик приложений" Программа, которая получает другие двоичные файлы приложения через TCP с внешнего сервера и запускает их.

Я мог бы сделать это, сохранив переданный файл на жесткий диск и используя вызов system () для его запуска. Однако мне интересно, можно ли было запустить новое приложение из памяти, не касаясь жесткого диска.

Состояние приложения-загрузчика не имеет значения после загрузки нового приложения. Я предпочитаю придерживаться C, но решения C ++ также приветствуются. Я также хотел бы придерживаться стандартных функций Linux C и не использовать внешние библиотеки, если это возможно.

 TJD09 мая 2012 г., 22:40
Вы можете записать его в файл на виртуальном диске
 BRPocock09 мая 2012 г., 22:44
(Тем не менее, вы можете посмотреть на то, чтоglibc& APOS; sld-linux действительно, делает, поскольку это то, что он делает для обычных исполняемых файлов на диске. Это не красиво & # x2026;)
 BRPocock09 мая 2012 г., 22:43
Я также склонен думать, чтоany уровень безопасности ОС на сравнительно недавнем процессоре сделает все возможное, чтобы этого не случилось. Это, безусловно, выполнимо, но будет реальной болью использовать в реальных дистрибутивах (я надеюсь)
 Seth Carnegie09 мая 2012 г., 22:37
Да, это возможно, но это несколько сложно. Вы должны эмулировать ОС и отображать двоичный файл в память и т. Д.
 ybungalobill09 мая 2012 г., 22:45
@BRPocock: на самом делеit's done very often.

Ответы на вопрос(3)

UPX, который распаковывает исполняемый файл в память, а затем передает управлениеld-linux чтобы начать это.

 08 апр. 2018 г., 19:18
& quot; посмотрите на & quot; как в "расшифровке иероглифов": D
Решение Вопроса

Длинный ответ: возможно, но довольно сложно сделать это без записи на диск. Вы можете теоретически написать свой собственный загрузчик эльфов, который читает двоичный файл, отображает некоторую память, обрабатывает динамическое связывание по мере необходимости, а затем передает управление, но это огромная работа, которая вряд ли когда-нибудь будет стоить усилий.

Следующее лучшее решение - записать его на диск и вызвать unlink как можно скорее. Диск даже не должен быть "реальным" диск, это может быть tmpfs или аналогичный.

Альтернатива, которую я недавно использовал, состоит в том, чтобы не передавать полные скомпилированные двоичные файлы, а вместо этого передавать байт-код LLVM, который затем может быть интерпретирован / сохранен / сохранен / исправлен как JIT. Это также имеет то преимущество, что приложение работает в гетерогенных средах.

Может быть заманчиво попробовать комбинациюfmemopen, fileno а такжеfexecve, но это не сработает по двум причинам:

From fexecve() manpage:

"The file descriptor fd must be opened read-only, and the caller must have permission to execute the file that it refers to"

I.e. it needs to be a fd that refers to a file.

From fmemopen() manpage:

"There is no file descriptor associated with the file stream returned by these functions (i.e., fileno(3) will return an error if called on the returned stream)"

 Flip10 мая 2012 г., 02:43
Спасибо за ответ; это именно то, что я искал. Поиск в теме не дал мне много, и мне нужно было удовлетворить свое любопытство!
 10 мая 2012 г., 08:10
Обратите внимание, что в наши дни это нечто стандартноеtmpfs установлен в/dev/shm/.
 04 февр. 2019 г., 08:29
Теперь можно запускать исполняемый файл в памяти с помощью memfd_create () и fexecve (). Увидетьunix.stackexchange.com/questions/230472/…

чем сделать это, так как C просто настроит файловую систему tmpfs. У вас есть все преимущества интерфейса жесткого диска, от вашей программы / сервера / чего бы вы ни делалиexec, Эти типы виртуальных файловых систем в настоящее время достаточно эффективны, в кеше страницы будет всего одна копия исполняемого файла.

Как указывает Энди, для того, чтобы такая схема была эффективной, вам необходимо убедиться, что вы не используете буферизованные записи в файл, а что вы «пишете» (в более широком смысле) прямо на месте.

you'd have to know how large your executable will be create a file on your tmpfs scale it to that size with ftruncate "map" that file into memory with mmap to obtain the addr of a buffer pass that address directly to the recv call to write the data in place munmap the file call exec with the file rm the file. can be done even when the executable is still running
 09 мая 2012 г., 23:49
Даже это просто избегает копирования в память. Какое здесь ограничение производительности? У меня возникают проблемы с представлением ситуации, когда скорость записи через файловую систему является пределом, а скорость приема пакетов по сети - нет. Кажется, сильно усложняется. Просто откройте / запишите в свою обычную файловую систему и сохраните проблему.
 09 мая 2012 г., 23:25
@ AndyRoss, не используйте буферизованные записи для такой вещи, я обновлю свой ответ.
 09 мая 2012 г., 23:10
Честно говоря, tmpfs будет работать не быстрее, чем собственная файловая система, если ваше хранилище уже не заполнено. Записи буферизируются в памяти, так что немедленный execve () просто отобразит их из кэша. Единственная цена, которую вы платите, это возможный сброс на диск, который является асинхронным.

Ваш ответ на вопрос