2010-07-18 20 views
5

Estoy tratando de ejecutar un ejecutable directamente desde una representación de byte [] de este ejecutable como un recurso en C#.Ejecutando ejecutable desde la memoria

Así que, básicamente, quiero ejecutar un byte [] de un PE directamente sin tocar el disco duro.

El código que estoy usando para esto solía funcionar pero ya no funciona.

El código crea un proceso con un hilo principal congelado, cambia los datos del proceso completo y finalmente lo reanuda para que ejecute el byte [] del PE. Pero parece que el proceso se muere si se reanuda el hilo, realmente no sé cuál es incorrecto.

Así que aquí es el código en un Pastebin porque es demasiado larga para aquí, supongo ...

http://pastebin.com/18hfFvHm

EDIT:

Quiero ejecutar código no administrado! Cualquier archivo PE ...

+0

¿Qué versión de .NET está usando? –

+0

3.5 pero podría migrar a 4 si fuera necesario ... – Chilln

+0

¿Alguna idea de qué cambio hizo que el código dejara de funcionar? ¿Un parche de seguridad, ninguna actualización de antivirus, .NET SP? Parece que las características de NX podrían estar interfiriendo. –

Respuesta

0

No he probado esto, por lo que es puramente specutive, pero yo creo que desea cargar en el dominio de aplicación en:

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

Esto es solo para ensamblados .NET, necesito el código para cada archivo pe ... – Chilln

0

no estoy seguro de si esto va a ser de mucha ayuda, pero here es donde respondo ejecutando opcodes de ensamblaje x86/x64 directamente desde un programa C#.

0

creo que su problema es que usted está pidiendo un agujero de seguridad.

Para ejecutar cualquier PE, usted está preguntando: "Deje que mi aplicación segura/administrada .NET ejecute una aplicación insegura/no administrada - De una manera que eluda la seguridad normal".

Digamos que ejecuto su aplicación (que supongo que es segura). No le he dado permiso para escribir en la carpeta sensible; no puede rebasar los búferes; no puede tocar mi código de modo win32. A continuación, compila, byte por byte, una aplicación maliciosa en un byts [], y la inicia. ¿Dónde interviene Windows para preguntarme si quiero que esto suceda? ¿Y qué dice esa advertencia? "¿Es ese conjunto de bytes de una fuente confiable?"

+0

No estoy pidiendo un agujero de seguridad, si ejecuto mi pe en mi proceso, tiene las mismas limitaciones y no puedo inyectarlo en otro proceso con derechos más altos. Incluso si eludiera las restricciones de seguridad, no soy un codificador de malware, el método para hacerlo solo es interesante. – Chilln

+0

Bzzt. Incorrecto. Él está corriendo con plena confianza. – Joshua

+0

@Joshua: ¡Bzzt! "Confianza total" significa "Confío en usted porque se está ejecutando en .Net Sandbox". Él está tratando de evitar eso. –

1

Aquí hay algunos códigos para ejecutar código nativo (dentro de una matriz de bytes). Tenga en cuenta que no es exactamente lo que está pidiendo (que no es un archivo PE bytes, sino un procedimiento nativa bytes es decir. En lenguaje ensamblador)

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); 
     } 
    } 
} 
+1

Acabo de probarlo, estoy obteniendo un appcrash al crear el hilo :( – mafu

0

En teoría, si está ejecutando plena confianza, no hay nada impidiéndole realizar CreateProcess en rundll32.exe, eliminar rundll32.exe y realizar la carga EXE inicial usted mismo.

La manera en que lo haría es inyectar un hilo en el proceso objetivo que hace el trabajo de una manera no administrada. Sí, esto significa montones de ensamblaje reubicable.

La idea general es llamar a LdrUnloadModule para deshacerse de rundll32.exe, llama a LdrLoadModule para cargar el EXE, arregla la cadena de carga para indicar que se cargó primero, luego reinicia el hilo principal.

Buena suerte para usted.

Cuestiones relacionadas