【问题标题】:run native(unmanaged) exe from memory in C#在 C# 中从内存中运行本机(非托管)exe
【发布时间】:2011-04-23 06:35:15
【问题描述】:

你好,我有一些 c 程序使用我的 c# 程序中的程序。 我不想将那些 c exe 发送给客户端。这意味着我不希望用户可以看到那些 exe。 我想将这些字节加载到内存并从内存中运行。

我该怎么做。

非常感谢。

【问题讨论】:

  • 这听起来很可疑。将 .exe 与您的代码一起打包有什么问题?您是否侵犯了任何版权,您是否在要求上作弊?
  • 随心所欲是制造病毒的关键。 Windows 不希望你这样做

标签: c# .net visual-studio performance security


【解决方案1】:

如果程序是非托管代码,即 C 程序,则不能直接从 .Net 内存中启动它。您可以做的是将其打包为资源,将其流式传输到磁盘(临时文件夹),然后使用 System.Diagnostics.Process 类启动它。但它会显示在进程列表中。

但我同意@tdammers 的评论,你为什么不能将它包含在你的程序中?为什么一定要隐藏?

如果它已被管理,您可以获取嵌入式资源(exe 文件),将其放入字节数组并使用 Assembly.Load 加载。

如果您的 C 程序是 dll,您可以作为资源嵌入,流式传输到磁盘并使用 p/invoke 执行它。

【讨论】:

  • 实际上,如果它打算在进程内运行(这是 DLL 所做的),那将非常简单。
  • 具体来说,将非托管代码放入内存缓冲区并直接调用它,没有相应的磁盘文件,这是 CLR 即时编译器为托管程序中的每个函数所做的事情。
  • @Ben 你读过这个问题吗? OP 要求 C 程序,这是非托管的。
  • @ben:澄清了我关于程序和 dll 的回答。我猜你也可以在 exe 上调用 p/invoke。
  • p/invoke 通常对于 DLL 是必需的,但如果您在设计 C 代码时考虑到这一点(即没有导入,请接受 kernel32.dll HMODULE 和指向 GetProcAddress 的函数指针作为参数,以便 C 代码可以加载它想要的所有其他函数),您可以只创建一个指向包含机器代码的内存缓冲区的函数指针。 P/invoke 对于运行本机代码实际上并不是必需的。
【解决方案2】:

我同意所有告诉你这是一个坏主意的人的观点。但这远非不可能。

在你和你在内存中的某个缓冲区中运行的代码之间唯一存在的就是 DEP,调用 VirtualProtectEx 将解决这个问题(如果你正在加载进程中的代码,而不是加载到新进程中) ,VirtualProtect(不是-Ex)就足够了)。请确保缓冲区已固定并且不会被垃圾收集器移动(使用本机分配器可能是个好主意)。

【讨论】:

  • 导入和重定位怎么样?
  • 他们怎么样?您必须找到 ntdll.dll 和 kernel32.dll 的映射位置,调用 GetProcAddress,并在调用代码之前编写一些函数指针。不平凡,但正如我所说,“远非不可能”。
  • 是的,但你说得太简单了——OP 会抱有错误的希望。看看 ntdll 中的加载程序代码 - 它非常大。
  • 显然,以最小化导入的方式编写有效负载会使其更简单。仅作为二进制文件提供的 .exe 的一般情况几乎需要复制 OS 加载程序逻辑,正如您所说,这是一项艰巨的任务。
【解决方案3】:

这是不可能的,Windows 的硬性要求是从磁盘上的文件启动和加载 EXE。这是 Windows 设计方式的核心,与内存映射文件相关联。

您必须将非托管 EXE 与您的 C# 程序一起提供。做一些讨厌的事情,比如在运行时从你的资源中提取 EXE,你的客户、她使用的病毒扫描程序和 UAC 都不会喜欢。您可以使用 ProcessStartInfo.CreateNoWindow 属性静默运行它。

【讨论】:

  • 不要求正在运行的代码实际上与启动 .exe 的文件相匹配。
  • 很好的观察 :) 但是,我想我们都同意 OP 可能不想将 EXE 映射到进程中,创建一个新的 LDR_DATA_TABLE_ENTRY 并将其链接起来,设置 NtCurrentPeb()- >ImageBaseAddress 等
  • @wj32:我不知道“将 exe 映射到进程中”与它有什么关系,您可以使用 VirtualAllocWriteProcessMemory 来避免需要文件映射和一个实际的磁盘文件,但是创建挂起的进程并覆盖初始线程的指令指针将是成功的关键,所以你的想法是正确的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-14
  • 2011-02-08
  • 2013-04-28
  • 2015-05-28
  • 2013-07-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多