2010-08-24 14 views
17

Sto provando a eseguire un eseguibile dalla memoria come descritto nell'articolo this. Posso eseguire qualsiasi .net/managed exes abbastanza facilmente. Ma non riesco a eseguire file eseguibili come notepad.exe o calc.exe. Come posso ottenerlo così posso anche eseguire exe non gestiti?Carica un file EXE ed eseguilo dalla memoria

risposta

23

Nel caso di esecuzione di eseguibili .NET dalla memoria, le librerie e lo stesso CLR stanno facendo molto per voi. Per eseguibili nativi come notepad.exe e calc.exe, dovrai fare un sacco di lavoro manuale per farlo accadere. Fondamentalmente, devi comportarti come il caricatore di Windows.

Ci sono probabilmente pagine di avvertimenti qui, ma this in-depth article ha i passaggi necessari per caricare un PE in memoria e fare il corretto rebasing e correzioni. Quindi, dovresti essere in grado di trovare il punto di ingresso (come nell'articolo) ed eseguirlo.

Se si desidera eseguire notepad.exe e calc.exe, il modo più semplice, ovviamente, è utilizzare Process.Start ed eseguirli dal disco. Altrimenti, se si ha un eseguibile incorporato come risorsa nel processo, il modo più semplice sarebbe semplicemente scrivere il contenuto su disco in una posizione temporanea (vedere Path.GetTempFileName) e quindi eseguirlo da lì.

+0

Sei molto bene in quella roba 'Chris'':> ' – Xaqron

-6

Utilizzare [Process.Start()][1] (o un altro sovraccarico) e lasciare che l'O/S esegua il caricamento in memoria.

17

non sono sicuro, ma il seguente codice da questo thread potrebbe essere utile:

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

Ho fatto ......... –

+0

var dir = System.IO.Directory.GetCurrentDirectory(); byte [] file = Resource1.someExecutable; CMemoryExecute. Esegui (file, dir); –

+0

dove Resorurc e1.someExecutable è l'eseguibile che mi piacerebbe eseguire e che non ha funzionato ... –

-5

se siete alla ricerca per l'esecuzione di file Exe utilizzando C#, quindi this link fornisce una buona spiegazione con un semplice ma facile da seguire esempio su come utilizzare Process e Process.Start.

In poche parole, si può fare un

Process.Start("notepad.exe")

a correre non gestiti exe/applicazioni.

se questo non funziona, forniscono la fullpath dell'applicazione, come

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

(io sono solo assumendo notepad.exe esiste in quella cartella, ma si ottiene l'idea.

+1

Dovrebbe essere eseguito dalla memoria e non dall'HDD. –

+0

Non vedo come dovrebbe essere un problema usando 'Process.Start()'. – AceMark

+0

Hai semplicemente descritto come eseguire un programma. Eseguirlo senza file drop è sia un requisito in casi specifici che finire soprattutto non banale, quindi la domanda. – bytecode77

Problemi correlati