gpt4 book ai didi

executable - 如何从内存而不是磁盘运行非托管可执行文件

转载 作者:行者123 更新时间:2023-12-04 06:13:08 24 4
gpt4 key购买 nike

我想在我的 C# 应用程序中嵌入一个命令行实用程序,以便我可以将其字节作为数组获取并运行可执行文件,而无需将其作为单独的文件保存到磁盘(避免将可执行文件存储为单独的文件并避免需要能够在任何地方写入临时文件)。

我找不到仅从其字节流运行可执行文件的方法。 Windows 是否要求它位于磁盘上,或者有没有办法从内存中运行它?
如果windows要求它在磁盘上,.NET框架中是否有一种简单的方法来创建某种虚拟驱动器/文件并将文件映射到可执行文件的内存流?

最佳答案

您要求在高级托管环境中实现非常低级的、特定于平台的功能。一切皆有可能……但没有人说这很容易……

(顺便说一句,我不知道您为什么认为临时文件管理繁重。BCL 为您完成:http://msdn.microsoft.com/en-us/library/system.io.path.gettempfilename.aspx)

  • 分配足够的内存来保存可执行文件。当然,它不能驻留在托管堆上,因此与本练习中的几乎所有内容一样,您需要 PInvoke。 (实际上,我推荐 C++/CLI,以免把自己逼疯)。请特别注意应用于分配的内存页的属性位:弄错它们,您将打开一个巨大的安全漏洞,或者让您的进程被 DEP 关闭(即,您将崩溃)。见 http://msdn.microsoft.com/en-us/library/aa366553(VS.85).aspx
  • 在程序集的资源库中找到可执行文件并获得 pinned handle给它。
  • Memcpy() 从托管堆的固定区域到 native block 的代码。
  • 释放 GCHandle。
  • 调用 VirtualProtect以防止进一步写入可执行内存块。
  • 根据您从 VirtualAlloc 获得的句柄和 DUMPBIN 或类似工具显示的文件中的偏移量,计算可执行文件的 Main 函数在进程的虚拟地址空间内的地址。
  • 将所需的命令行参数放在堆栈上。 (Windows Stdcall convention)。当然,任何指针都必须指向 native 或固定区域。
  • 跳转到计算出的地址。可能最容易使用 _call(内联汇编语言)。
  • 向上帝祈祷可执行镜像中没有任何绝对跳转,这些跳转可以通过以正常方式调用 LoadLibrary 来修复。 (当然,除非您想在第 3 步中重新实现 LoadLibrary 的大脑)。
  • 从@eax 寄存器中检索返回值。
  • 调用 VirtualFree。

  • 步骤 #5 和 #11 应该在 finally block 中完成和/或使用 IDisposable 模式。

    另一个主要选项是创建一个 RAMdrive,在那里编写可执行文件,运行它并进行清理。这可能会更安全一些,因为您没有尝试编写自修改代码(这在任何情况下都很难,但尤其是当代码甚至不是您的代码时)。但我相当肯定它需要比动态代码注入(inject)选项更多的平台 API 调用——所有这些都需要 C++ 或 PInvoke,自然而然。

    关于executable - 如何从内存而不是磁盘运行非托管可执行文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1224149/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com