如何执行作为资源嵌入的可执行文件

是否可以执行作为资源包含在项目中的exe文件? 我可以将文件作为字节数组获取并在内存中执行吗?

我不想将文件写入临时位置并在那里执行。 我正在寻找一种可以在内存中执行它的解决方案。 (这不是.NET程序集。)

这很有可能 – 我自己也做过 – 但是从托管代码来看它更加繁琐。 它没有.NET API,也没有可以PInvoke的原生API。 因此,您必须手动对负载进行分类,这需要了解用于DLL和EXE等模块的PE(可移植可执行文件)文件格式 – http://msdn.microsoft.com/en-us/magazine /cc301805.aspx 。 将会有很多指针操作(强制使用不安全的{}块)和PInvoke。

首先将PE文件加载到内存中(或使用MapViewOfFile)。 PE文件内部由包含代码,数据或资源的不同部分组成。 文件中每个部分的偏移量并不总是与预期的内存偏移量匹配,因此需要进行一些小的调整。

每个PE文件都假定它将被加载到虚拟内存中的某个基址。 除非你能确保这一点,否则你需要走PE文件的重定位表来相应地调整指针。

每个PE文件还有一个导入表,列出了它想要调用的其他DLL的function。 您需要遍历此表并调用LoadLibrary()/ GetProcAddress()来填充每个导入。

接下来,需要为每个部分正确设置内存保护。 每个部分的标题都记录了它想要的保护,因此只需要为每个具有正确标志的部分调用VirtualProtect()。 您至少需要使用PAGE_EXECUTE_READWRITE VirtualProtect加载的模块,否则您不太可能执行任何代码。

最后,对于DLL,您需要调用其入口点,其地址可以在PE头中找到; 然后,您可以自由调用导出的函数。

既然你想运行一个EXE,你会有一些额外的麻烦。 您可以启动一个新线程并从中调用EXE的入口点,但是许多EXE可能会因为为您设置过程而感到不安,而不是EXE。 当它试图退出时,它也可能会杀死你的进程。 因此,您可能希望生成一个新进程 – 也许您的主EXE的另一个副本带有特殊参数,告诉它它将运行一些不同的代码 – 在这种情况下,您必须将EXE驱逐到其内存空间。 您可能希望在新流程中完成上述大部分工作,而不是旧流程。 您可以创建命名管道并将数据从一个EXE发送到另一个EXE,也可以使用MapViewOfFile分配命名的共享内存区域。 当然,EXE可能仍然会感到不安,因为它运行的过程仍然不是它自己的。

总而言之,只需写入临时文件然后使用Process.Start()就可以了。

如果您仍想以艰难的方式去做,请在非托管代码中查看此示例: http : //www.joachim-bauch.de/tutorials/loading-a-dll-from-memory/ 。 这不包括可执行文件,只包括DLL,但如果其中的代码没有吓到你,你可以将这个过程扩展到可执行文件。

更好的方法是使用FILE_FLAG_DELETE_ON_CLOSE属性创建临时DLL文件。 这样,文件将在不再使用时自动删除。

我认为没有办法从内存(而不是文件)加载DLL。

从内存映像创建新进程并不容易,所有内核函数都适合从磁盘加载映像。 有关详细信息,请参阅Windows NT / 2000本机API参考的进程部分 – 第161页有一个手动分支进程的示例。

如果可以从您自己的进程中运行代码,那么您可以创建一个小DLL,它将获取指向可执行数据的指针并运行它。