从内存运行可执行文件

时间:2010-07-18 23:51:56

标签: c# memory interop

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

所以基本上我想直接运行PE的byte []而不需要触摸硬盘。

我正在使用的代码曾经用于工作,但现在已不复存在了。

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

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

http://pastebin.com/18hfFvHm

编辑:

我想运行非托管代码! 任何PE档案......

9 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

这是执行本机代码的一些代码(在字节数组中)。请注意,它并不是您要求的(它不是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);
        }
    }
}

答案 2 :(得分:1)

给所有人留在这里。

使用 RUNPE

查起来,效果很好:)我建议自我注射。

答案 3 :(得分:0)

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

答案 4 :(得分:0)

我没有试过这个,所以它纯粹是专用的,但我相信你想要加载到AppDomain中:

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

答案 5 :(得分:0)

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

答案 6 :(得分:0)

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

要运行任何PE,您要问 - “让我的安全/托管.NET应用程序运行一个不安全/不受管理的应用程序 - 以一种绕过正常安全的方式”。

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

答案 7 :(得分:0)

理论上,如果您正在运行完全信任,那么没有什么能阻止您在rundll32.exe上执行CreateProcess,取消映射rundll32.exe并自行执行初始EXE加载。

我采用的方法是在目标进程中注入一个线程,以非托管方式完成工作。是的,这意味着可堆叠的可重新组装。

一般的想法是调用LdrUnloadModule去除rundll32.exe,调用LdrLoadModule来加载EXE,修复加载链以指示它先被加载,然后重新启动主线程。

祝你好运。

答案 8 :(得分:0)

重新发布Load an EXE file and run it from memory

未经测试但看起来是唯一的方法(第二个答案)