Mic*_*elD 12 .net c# resources
是否可以执行作为资源包含在项目中的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的功能.您需要遍历此表并调用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,但如果其中的代码没有吓到你,你可以将这个过程扩展到可执行文件.
归档时间: |
|
查看次数: |
5356 次 |
最近记录: |