2010-08-24 32 views
17

Tôi đang cố chạy một tệp thực thi từ bộ nhớ như được nêu trong bài viết this. Tôi có thể chạy bất kỳ .net/quản lý exes khá dễ dàng. Nhưng tôi không thể chạy các tệp thi hành như notepad.exe hoặc calc.exe. Làm thế nào tôi có thể nhận được nó vì vậy tôi cũng có thể chạy exman không được quản lý?Tải một tệp EXE và chạy nó từ bộ nhớ

Trả lời

23

Trong trường hợp chạy tệp thi hành .NET từ bộ nhớ, các thư viện và CLR đang thực hiện rất nhiều việc nâng hạng nặng cho bạn. Đối với các tệp thực thi nguyên gốc như notepad.exe và calc.exe, bạn sẽ phải thực hiện rất nhiều công việc thủ công để làm cho nó xảy ra. Về cơ bản, bạn phải hành động như bộ tải Windows.

Có thể có các trang báo trước ở đây, nhưng this in-depth article có các bước bạn cần để tải PE vào bộ nhớ và thực hiện sửa lỗi và sửa lỗi chính xác. Sau đó, bạn sẽ có thể tìm thấy điểm vào (như trong bài viết) và chạy nó.

Nếu bạn thực sự chỉ muốn chạy notepad.exe và calc.exe, cách dễ nhất, tất nhiên, sẽ là sử dụng Process.Start và chạy chúng khỏi đĩa. Nếu không, nếu bạn có một file thực thi được nhúng như một tài nguyên trong quá trình của bạn, thì cách dễ nhất tiếp theo sẽ là viết nội dung ra đĩa ở một vị trí tạm thời (xem Path.GetTempFileName) và sau đó thực thi nó từ đó.

+0

Bạn đang rất tốt trong công cụ đó 'Chris'':> ' – Xaqron

-6

Sử dụng [Process.Start()][1] (hoặc một tình trạng quá tải khác) và để O/S thực hiện việc tải vào bộ nhớ.

17

Tôi không chắc chắn nhưng đoạn mã sau từ thread này có thể hữu ích:

using System; 
using System.Runtime.InteropServices; 

/* 
* Title: CMemoryExecute.cs 
* Description: Runs an EXE in memory using native WinAPI. Very optimized and tiny. 
* 
* Developed by: affixiate 
* Release date: December 10, 2010 
* Released on: http://opensc.ws 
* Credits: 
*   MSDN (http://msdn.microsoft.com) 
*   NtInternals (http://undocumented.ntinternals.net) 
*   Pinvoke (http://pinvoke.net) 
*   
* Comments: If you use this code, I require you to give me credits. Don't be a ripper! ;] 
*/ 

// ReSharper disable InconsistentNaming 
public static unsafe class CMemoryExecute 
{ 
    public struct STARTUPINFO 
    { 
     public uint cb; 
     public string lpReserved; 
     public string lpDesktop; 
     public string lpTitle; 
     public uint dwX; 
     public uint dwY; 
     public uint dwXSize; 
     public uint dwYSize; 
     public uint dwXCountChars; 
     public uint dwYCountChars; 
     public uint dwFillAttribute; 
     public uint dwFlags; 
     public short wShowWindow; 
     public short cbReserved2; 
     public IntPtr lpReserved2; 
     public IntPtr hStdInput; 
     public IntPtr hStdOutput; 
     public IntPtr hStdError; 
    } 

    /// <summary> 
    /// Runs an EXE (which is loaded in a byte array) in memory. 
    /// </summary> 
    /// <param name="exeBuffer">The EXE buffer.</param> 
    /// <param name="hostProcess">Full path of the host process to run the buffer in.</param> 
    /// <param name="optionalArguments">Optional command line arguments.</param> 
    /// <returns></returns> 
    public static bool Run(byte[] exeBuffer, string hostProcess, string optionalArguments = "") 
    { 
     // STARTUPINFO 
     STARTUPINFO StartupInfo = new STARTUPINFO(); 
     StartupInfo.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW; 
     StartupInfo.wShowWindow = SW_HIDE; 

     var IMAGE_SECTION_HEADER = new byte[0x28]; // pish 
     var IMAGE_NT_HEADERS = new byte[0xf8]; // pinh 
     var IMAGE_DOS_HEADER = new byte[0x40]; // pidh 
     var PROCESS_INFO = new int[0x4]; // pi 
     var CONTEXT = new byte[0x2cc]; // ctx 

     byte* pish; 
     fixed (byte* p = &IMAGE_SECTION_HEADER[0]) 
      pish = p; 

     byte* pinh; 
     fixed (byte* p = &IMAGE_NT_HEADERS[0]) 
      pinh = p; 

     byte* pidh; 
     fixed (byte* p = &IMAGE_DOS_HEADER[0]) 
      pidh = p; 

     byte* ctx; 
     fixed (byte* p = &CONTEXT[0]) 
      ctx = p; 

     // Set the flag. 
     *(uint*)(ctx + 0x0 /* ContextFlags */) = CONTEXT_FULL; 

     // Get the DOS header of the EXE. 
     Buffer.BlockCopy(exeBuffer, 0, IMAGE_DOS_HEADER, 0, IMAGE_DOS_HEADER.Length); 

     /* Sanity check: See if we have MZ header. */ 
     if (*(ushort*)(pidh + 0x0 /* e_magic */) != IMAGE_DOS_SIGNATURE) 
      return false; 

     var e_lfanew = *(int*)(pidh + 0x3c); 

     // Get the NT header of the EXE. 
     Buffer.BlockCopy(exeBuffer, e_lfanew, IMAGE_NT_HEADERS, 0, IMAGE_NT_HEADERS.Length); 

     /* Sanity check: See if we have PE00 header. */ 
     if (*(uint*)(pinh + 0x0 /* Signature */) != IMAGE_NT_SIGNATURE) 
      return false; 

     // Run with parameters if necessary. 
     if (!string.IsNullOrEmpty(optionalArguments)) 
      hostProcess += " " + optionalArguments; 

     if (!CreateProcess(null, hostProcess, IntPtr.Zero, IntPtr.Zero, false, CREATE_SUSPENDED, IntPtr.Zero, null, ref StartupInfo, PROCESS_INFO)) 
      return false; 

     var ImageBase = new IntPtr(*(int*)(pinh + 0x34)); 
     NtUnmapViewOfSection((IntPtr)PROCESS_INFO[0] /* pi.hProcess */, ImageBase); 
     if (VirtualAllocEx((IntPtr)PROCESS_INFO[0] /* pi.hProcess */, ImageBase, *(uint*)(pinh + 0x50 /* SizeOfImage */), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE) == IntPtr.Zero) 
      Run(exeBuffer, hostProcess, optionalArguments); // Memory allocation failed; try again (this can happen in low memory situations) 

     fixed (byte* p = &exeBuffer[0]) 
      NtWriteVirtualMemory((IntPtr)PROCESS_INFO[0] /* pi.hProcess */, ImageBase, (IntPtr)p, *(uint*)(pinh + 84 /* SizeOfHeaders */), IntPtr.Zero); 

     for (ushort i = 0; i < *(ushort*)(pinh + 0x6 /* NumberOfSections */); i++) 
     { 
      Buffer.BlockCopy(exeBuffer, e_lfanew + IMAGE_NT_HEADERS.Length + (IMAGE_SECTION_HEADER.Length * i), IMAGE_SECTION_HEADER, 0, IMAGE_SECTION_HEADER.Length); 
      fixed (byte* p = &exeBuffer[*(uint*)(pish + 0x14 /* PointerToRawData */)]) 
       NtWriteVirtualMemory((IntPtr)PROCESS_INFO[0] /* pi.hProcess */, (IntPtr)((int)ImageBase + *(uint*)(pish + 0xc /* VirtualAddress */)), (IntPtr)p, *(uint*)(pish + 0x10 /* SizeOfRawData */), IntPtr.Zero); 
     } 

     NtGetContextThread((IntPtr)PROCESS_INFO[1] /* pi.hThread */, (IntPtr)ctx); 
     NtWriteVirtualMemory((IntPtr)PROCESS_INFO[0] /* pi.hProcess */, (IntPtr)(*(uint*)(ctx + 0xAC /* ecx */)), ImageBase, 0x4, IntPtr.Zero); 
     *(uint*)(ctx + 0xB0 /* eax */) = (uint)ImageBase + *(uint*)(pinh + 0x28 /* AddressOfEntryPoint */); 
     NtSetContextThread((IntPtr)PROCESS_INFO[1] /* pi.hThread */, (IntPtr)ctx); 
     NtResumeThread((IntPtr)PROCESS_INFO[1] /* pi.hThread */, IntPtr.Zero); 


     return true; 
    } 

    #region WinNT Definitions 

    private const uint CONTEXT_FULL = 0x10007; 
    private const int CREATE_SUSPENDED = 0x4; 
    private const int MEM_COMMIT = 0x1000; 
    private const int MEM_RESERVE = 0x2000; 
    private const int PAGE_EXECUTE_READWRITE = 0x40; 
    private const ushort IMAGE_DOS_SIGNATURE = 0x5A4D; // MZ 
    private const uint IMAGE_NT_SIGNATURE = 0x00004550; // PE00 

    private static short SW_SHOW = 5; 
    private static short SW_HIDE = 0; 
    private const uint STARTF_USESTDHANDLES = 0x00000100; 
    private const uint STARTF_USESHOWWINDOW = 0x00000001; 


    #region WinAPI 
    [DllImport("kernel32.dll", SetLastError = true)] 
    private static extern bool CreateProcess(string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, int[] lpProcessInfo); 

    [DllImport("kernel32.dll", SetLastError = true)] 
    private static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect); 

    [DllImport("ntdll.dll", SetLastError = true)] 
    private static extern uint NtUnmapViewOfSection(IntPtr hProcess, IntPtr lpBaseAddress); 

    [DllImport("ntdll.dll", SetLastError = true)] 
    private static extern int NtWriteVirtualMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, uint nSize, IntPtr lpNumberOfBytesWritten); 

    [DllImport("ntdll.dll", SetLastError = true)] 
    private static extern int NtGetContextThread(IntPtr hThread, IntPtr lpContext); 

    [DllImport("ntdll.dll", SetLastError = true)] 
    private static extern int NtSetContextThread(IntPtr hThread, IntPtr lpContext); 

    [DllImport("ntdll.dll", SetLastError = true)] 
    private static extern uint NtResumeThread(IntPtr hThread, IntPtr SuspendCount); 
    #endregion 

    #endregion 
} 
+0

Tôi đã làm ......... –

+0

var dir = System.IO.Directory.GetCurrentDirectory(); byte [] file = Resource1.someExecutable; CMemoryExecute. Chạy (tệp, dir); –

+0

nơi Resorurc e1.someExecutable là tệp thực thi mà tôi muốn thực thi và không hoạt động ... –

-5

nếu bạn đang tìm kiếm chạy file Exe sử dụng C#, sau đó this link cung cấp một lời giải thích tốt với một đơn giản nhưng dễ dàng để làm theo ví dụ về cách sử dụng ProcessProcess.Start.

Tóm lại, bạn có thể làm một

Process.Start("notepad.exe")

để chạy không được quản lý exe/ứng dụng.

nếu điều đó không làm việc, cung cấp các fullpath của ứng dụng, như

Process.Start(@"c:\windows\system32\notepad.exe")

(Tôi chỉ giả notepad.exe tồn tại trên thư mục đó, nhưng bạn sẽ có được ý tưởng.

+1

Anh ta nên chạy từ bộ nhớ chứ không phải HDD. –

+0

Tôi không thấy làm thế nào nó nên là một vấn đề bằng cách sử dụng 'Process.Start()'. – AceMark

+0

Bạn chỉ cần mô tả cách chạy chương trình. Thực thi nó mà không có tập tin giọt là cả hai yêu cầu trong trường hợp cụ thể kết thúc đặc biệt là không tầm thường, do đó câu hỏi. – bytecode77

Các vấn đề liên quan