从另一个进程的内存中执行进程?

我想有一个小的“应用程序加载器”程序,通过TCP从外部服务器接收其他二进制应用程序文件,并运行它们。

我可以通过将传输的文件保存到硬盘并使用system()调用来运行它。 但是,我想知道是否有可能从内存中启动新的应用程序,而不会触及硬盘驱动器。

加载新应用程序后,加载器应用程序的状态并不重要。 我更喜欢坚持C,但也欢迎C ++解决scheme。 如果可能的话,我也想坚持使用标准的Linux C函数,而不是使用任何外部库。

简短的回答:不。

长的答案:这可能,但相当棘手的做到这一点,而不写出到磁盘。 理论上你可以编写你自己的elf loader来读取二进制文件,映射一些内存,根据需要处理动态链接,然后转移控制权,但这是一项非常多的工作,这是不值得的。

下一个最佳解决方案是将其写入磁盘并尽快调用unlink。 磁盘甚至不必是“真正的”磁盘,它可以是tmpfs或类似的。

我最近一直使用的替代方法是不传递完整的编译二进制文件,而是传递LLVM字节码,然后可以将JIT /解释/保存为适合。 这也有使您的应用程序在异构环境中工作的优势。

尝试fmemopenfilenofexecve的组合可能是诱人的,但是这不起作用有两个原因:

  1. fexecve()页:

    “文件描述符fd必须以只读方式打开,并且调用者必须有权执行它引用的文件

    也就是说它需要是一个指向文件的fd。

  2. fmemopen()页:

    “没有文件描述符与这些函数返回的文件流相关联(即,如果在返回的流上调用, fileno(3)将返回一个错误)”

C做起来要容易得多,只需要建立一个tmpfs文件系统即可。 你将拥有硬盘接口的所有优点,从你的程序/服务器/无论你只是做一个exec 。 现在这些类型的虚拟文件系统非常高效,页面缓存中只有一个可执行文件副本。

正如Andy所指出的那样,为了保证这种方案的高效性,您必须确保不使用缓冲写入的文件,而是直接在“写入”(更广泛的意义上)。

  • 你将不得不知道你的可执行文件的大小
  • 在你的tmpfs上创建一个文件
  • ftruncate缩放到这个尺寸
  • 使用mmap将该文件“映射”到内存中以获取缓冲区的地址
  • 直接将该地址传递给recv调用以将数据写入到位
  • munmap文件
  • 用这个文件调用exec
  • 该文件。 即使在可执行程序仍在运行时也可以完成

您可能需要查看并重新使用将可执行文件解压缩到内存的UPX ,然后将控制权转交给ld-linux以启动它。