【问题标题】:Running executable from memory从内存运行可执行文件
【发布时间】:2010-07-18 23:51:56
【问题描述】:

我正在尝试直接从这个可执行文件的 byte[] 表示作为 C# 中的资源运行一个可执行文件。

所以基本上我想在不接触硬盘的情况下直接运行 PE 的一个字节 []。

我用于此的代码曾经可以工作,但现在不行了。

代码创建了一个带有冻结主线程的进程,更改了整个进程数据并最终恢复它,以便运行 PE 的 byte[]。但是如果线程恢复,似乎进程会死掉,我真的不知道出了什么问题。

所以这里是 pastebin 中的代码,因为我猜它太长了...

http://pastebin.com/18hfFvHm

编辑:

我想运行非托管代码! 任何 PE 文件...

【问题讨论】:

  • 您使用的是什么版本的 .NET?
  • 3.5 但如果有必要我可以迁移到 4...
  • 知道是什么变化导致代码停止工作吗?安全补丁,没有防病毒更新,.NET SP?听起来 NX 功能可能会产生干扰。
  • “不再存在”。除了不再工作之外,发生了什么变化?就像,它是否有效,然后您重新安装了您的操作系统,但现在它没有?你升级了一些东西吗?卸载了什么?还是它在一次调用中起作用,但在下一次调用中不起作用?
  • @Benjamin,当应用程序因违规而被杀死时,NX 不会留下事件日志消息吗?

标签: c# memory interop


【解决方案1】:

此代码可能会有所帮助: Vrillon / Venus 的便携式可执行文件的动态进程分叉: http://forum.gamedeception.net/threads/16557-Process-Forking-Running-Process-From-Memory

【讨论】:

    【解决方案2】:

    这是一些执行本机代码的代码(在字节数组中)。请注意,这并不是您所要求的(它不是 PE 文件字节,而是本机过程字节,即汇编语言)

    using System;
    using System.Runtime.InteropServices;
    
    namespace Native
    {
        class Program
        {
            private const UInt32 MEM_COMMIT = 0x1000;
            private const UInt32 PAGE_EXECUTE_READWRITE = 0x40;
            private const UInt32 MEM_RELEASE = 0x8000;
    
            [DllImport("kernel32")] private static extern UInt32 VirtualAlloc(UInt32 lpStartAddr, UInt32 size, UInt32 flAllocationType, UInt32 flProtect);
            [DllImport("kernel32")] private static extern bool VirtualFree(IntPtr lpAddress, UInt32 dwSize, UInt32 dwFreeType);
            [DllImport("kernel32")]
            private static extern IntPtr CreateThread(
              UInt32 lpThreadAttributes,
              UInt32 dwStackSize,
              UInt32 lpStartAddress,
              IntPtr param,
              UInt32 dwCreationFlags,
              ref UInt32 lpThreadId
            );
    
            [DllImport("kernel32")] private static extern bool CloseHandle(IntPtr handle);
            [DllImport("kernel32")] private static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
            static void Main(string[] args)
            {
    
                byte[] nativecode = new byte[] { /* here your native bytes */ };
    
                UInt32 funcAddr = VirtualAlloc(0, (UInt32)nativecode.Length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
                Marshal.Copy(nativecode, 0, (IntPtr)(funcAddr), nativecode.Length);
                IntPtr hThread = IntPtr.Zero;
                UInt32 threadId = 0;
    
                hThread = CreateThread(0, 0, funcAddr, IntPtr.Zero, 0, ref threadId);
                WaitForSingleObject(hThread, 0xFFFFFFFF);
    
                CloseHandle(hThread);
                VirtualFree((IntPtr)funcAddr, 0, MEM_RELEASE);
            }
        }
    }
    

    【讨论】:

    • 我刚试了一下,创建线程时出现应用崩溃:(
    【解决方案3】:

    这里留给大家。

    使用 RUNPE

    查一下,效果很好 :) 我建议自我注入。

    【讨论】:

      【解决方案4】:

      我找到了那个样本,希望它对你有用。 http://www.cyberhackers.mybbnew.com/showthread.php?tid=178

      【讨论】:

      • 运行 .net 程序集而不是任何 PE 文件
      【解决方案5】:

      我没有尝试过这个,所以这纯粹是推测,但我相信你想加载到 AppDomain:

      byte[] myAssm = ...
      AppDomain.CurrentDomain.Load(myAssm);
      AppDomain.CurrentDomain.ExecuteAssemblyByName(nameOfMyAssm);
      

      【讨论】:

        【解决方案6】:

        我不确定这是否会有很大帮助,但here 是我回答从 C# 程序直接运行 x86/x64 汇编操作码的地方。

        【讨论】:

          【解决方案7】:

          我相信你的问题是你要求一个安全漏洞。

          要运行任何 PE,您要问——“让我的安全/托管 .NET 应用程序运行不安全/非托管应用程序——以绕过正常安全性的方式”。

          假设我运行您的应用程序(我认为它是安全的)。我没有授予它写入敏感文件夹的权限;它不能溢出缓冲区;它无法触及我的 win32 模式代码。然后,您在 byts[] 中逐字节构建恶意应用程序并启动它。 Windows 在哪里介入询问我是否要让这种情况发生?那警告说什么? “该字节数组是否来自可信来源?”

          【讨论】:

          • 我不是在要求安全漏洞,如果我在我的进程中运行我的 pe,它具有相同的限制,我不能将它注入到另一个具有更高权限的进程中。即使它会回避安全限制,我也不是恶意软件编码员,这样做的方法本身就很有趣。
          • Bzzt。错误的。他完全信任他。
          • @Joshua:Bzzt! “完全信任”的意思是“我信任你,因为你在 .Net 沙盒中运行”。他正试图解决这个问题。
          • 完全信任意味着可以 P/Invoke 一些讨厌的东西,比如 VirtualAlloc 和 CreateThread。因此,如果他想做一些真正恶意的事情,他可能已经可以了。
          【解决方案8】:

          理论上,如果您运行完全信任,则没有什么可以阻止您对 rundll32.exe 执行 CreateProcess、取消映射 rundll32.exe 以及自己执行初始 EXE 加载。

          我的做法是将一个线程注入到目标进程中,该进程以非托管方式完成工作。是的,这意味着成堆的可重定位组件。

          大体思路是调用LdrUnloadModule去掉rundll32.exe,调用LdrLoadModule加载EXE,修正加载链表示先加载,然后重启主线程。

          祝你好运。

          【讨论】:

            【解决方案9】:

            转发Load an EXE file and run it from memory

            未经测试,但似乎是唯一的方法(第二个答案)

            【讨论】:

              猜你喜欢
              • 2017-11-23
              • 1970-01-01
              • 2014-06-03
              • 2013-03-12
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2010-11-16
              相关资源
              最近更新 更多