2013-07-21 24 views
0

我發現了一些問題,詢問如何從RAM運行本機EXE。我用這個例子的代碼:爲什麼從字節數組示例運行本機exe不適合我?

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; 

     int ERROR_CODE = 0; 

     if (!CreateProcess(null, hostProcess, IntPtr.Zero, IntPtr.Zero, false, CREATE_SUSPENDED, IntPtr.Zero, null, ref StartupInfo, PROCESS_INFO)) 
     { 
      ERROR_CODE = Marshal.GetLastWin32Error(); 
      return false; 
     } 

     var ImageBase = new IntPtr(*(int*)(pinh + 0x34)); 
     NtUnmapViewOfSection((IntPtr)PROCESS_INFO[0] /* pi.hProcess */, ImageBase); 

     ERROR_CODE = Marshal.GetLastWin32Error(); 

     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); 

     ERROR_CODE = Marshal.GetLastWin32Error(); 

     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); 

      ERROR_CODE = Marshal.GetLastWin32Error(); 
     } 

     NtGetContextThread((IntPtr)PROCESS_INFO[1] /* pi.hThread */, (IntPtr)ctx); 

     ERROR_CODE = Marshal.GetLastWin32Error(); 

     NtWriteVirtualMemory((IntPtr)PROCESS_INFO[0] /* pi.hProcess */, (IntPtr)(*(uint*)(ctx + 0xAC /* ecx */)), ImageBase, 0x4, IntPtr.Zero); 

     ERROR_CODE = Marshal.GetLastWin32Error(); 

     *(uint*)(ctx + 0xB0 /* eax */) = (uint)ImageBase + *(uint*)(pinh + 0x28 /* AddressOfEntryPoint */); 
     NtSetContextThread((IntPtr)PROCESS_INFO[1] /* pi.hThread */, (IntPtr)ctx); 

     ERROR_CODE = Marshal.GetLastWin32Error(); 

     NtResumeThread((IntPtr)PROCESS_INFO[1] /* pi.hThread */, IntPtr.Zero); 

     ERROR_CODE = Marshal.GetLastWin32Error(); 

     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 
} 

我的.NET PROG是32位結構體系,我被注射到C:\ Windows \ Microsoft.NET \框架\ V2.0.50727 \ VBC.EXE:

OpenFileDialog ofd = new OpenFileDialog(); 
    ofd.Filter = "EXE Files (*.exe)|*.exe;"; 

    if (ofd.ShowDialog(this) == System.Windows.Forms.DialogResult.OK) 
     CMemoryExecute.Run(File.ReadAllBytes(ofd.FileName), "C:\\WINDOWS\\Microsoft.NET\\Framework\\v2.0.50727\\vbc.exe"); 

當我運行這個,只是沒有發生什麼,但vbc.exe實際上啓動和任務管理器中可見,但隱藏。我也嘗試注入其他exes。

我用32位贏得8,並試圖運行的notepad.exe和其他一些Win32的exe文件。 沒有任何Windows內部錯誤出現,如DEP預防等。

我加了ERROR_CODE = Marshal.GetLastWin32Error();代碼檢查到的代碼,卻處處是零,那種沒有錯誤和沒有工作:(

我在框架2.0測試和4.0

回答

1

我要指出,我不很瞭解這是什麼代碼是幹什麼的,但看到這一行:

StartupInfo.wShowWindow = SW_HIDE; 

無處被wShowWindow分配給

我試圖訪問該註釋中http://opensc.ws,並得到了一個奇怪的頁面要求輸入驗證碼和原因用於臨時訪問。永久訪問需要網站管理員批准。請求「臨時」訪問後,我收到一條消息,稱該網站處於離線狀態。非常可疑。

我把錢這個代碼最初是用比其他好用心開發,但我可能是錯的。

+0

通常,所有「不好」的代碼都可用於使反向工程變得更加困難,以保護您的軟件免受黑客攻擊。就我而言,我的老闆給了我一個瘋狂的任務,他不明白是什麼意思。我需要讓第三方程序要求獲得許可證,並且不要在未獲得許可的其他PC上運行。所以,我認爲,簡單的方法是加密這個編程,並在我的prog中編譯,然後在需要時解密並運行。當然,我沒有其他編程的來源,它的開發人員不會爲我做任何事情。 – Kosmos

+0

您是否可以讓您的過程顯示一個窗口? – Steve

+0

沒有。經過一些嘗試,主機進程停止產卵(我認爲所有的東西都是SW_HIDE文件,我不需要顯示自己注入的過程,這是我抓住這個例子的地方:http:// forums.mydigitallife.info/threads/24348-C-Run-non-NET-exe-from-memory – Kosmos