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

时间:2012-05-09 20:32:50

标签: c++ c linux memory

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

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

加载新应用程序后,加载程序应用程序的状态无关紧要。我更喜欢坚持C,但也欢迎C ++解决方案。我还想坚持使用标准的Linux C函数,如果可能的话,不要使用任何外部库。

3 个答案:

答案 0 :(得分:3)

简答:不。

答案很长:如果不将其写入磁盘,这样做可能相当棘手。理论上你可以编写自己的elf加载器来读取二进制文件,映射一些内存,根据需要处理动态链接,然后转移控制,但这是一项非常多的工作,这几乎不值得付出努力。

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

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

尝试fmemopenfilenofexecve的组合可能很有吸引力,但这不会有两个原因:

  1. 来自fexecve()联页:

      

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

    即。它需要是一个引用文件的fd。

  2. 来自fmemopen()联页:

      

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

答案 1 :(得分:0)

比做它容易多了就是设置一个tmpfs文件系统。你可以拥有硬盘接口的所有优点,从你的程序/服务器/你只需做exec。这些类型的虚拟文件系统现在非常高效,页面缓存中实际上只有一个可执行文件副本。

正如Andy指出的那样,为了使这种方案更有效率,你必须确保不对文件使用缓冲写入,而是直接在适当位置“写入”(广义上)。

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

答案 2 :(得分:0)

您可能希望查看并重用UPX,将可执行文件解压缩到内存,然后将控制转移到ld-linux以启动它。