2008-11-20 20 views
33

Puedo usar CreateProcess para iniciar un EXE. Quiero tener el contenido de un EXE en un búfer de memoria y hacer CreateProcess (o un equivalente) en él sin tener que escribirlo en un archivo. ¿Hay alguna forma de hacer eso?CreateProcess desde el búfer de memoria

Antecedentes: hacemos juegos. Enviamos un EXE simple a nuestros distribuidores, que luego lo envuelven con su DRM favorito y se lo venden a sus usuarios. Ha habido casos en que los usuarios encuentran bloqueos. La mayoría de los fallos demoran 5 minutos en solucionarse, pero el parche debe pasar por el distribuidor y puede llevar varios días, incluso semanas. No puedo simplemente enviar el EXE parcheado a los jugadores porque no tendría el DRM del distribuidor. Estoy pensando en distribuir el juego real EXE dentro de un archivo de datos encriptado, así que lo que se envuelve (el EXE externo) simplemente descifra y ejecuta el EXE real. De esta forma podría distribuir de manera segura una solución sin deshabilitar el DRM.

Respuesta

2

¿Por qué necesita crear un nuevo proceso? Pensé que podrías ejecutar en el contexto del proceso que realiza el desempaquetado/descifrado.

+0

Definitivamente puedo hacer eso. Mencioné CreateProcess porque es mi mejor alternativa, pero lo que dices podría funcionar. – ggambett

1

Lo que desea se puede lograr con algo llamado "Packer". En realidad, es posible lanzar un exe desde la memoria, pero es mucho más difícil que un empacador;)

Uno de los empaquetadores más conocidos es UPX (google it). Hay herramientas para descifrarlo, pero al menos debería darle un punto de partida para trabajar. También estoy bastante seguro de que UPX es de código abierto.

+0

Había usado UPX anteriormente, pero esta vez no lo pensé. Puede valer la pena explorar ¡Gracias! – ggambett

+0

Es un hilo muy antiguo;) pero solo para precisar que, aunque UPX es de hecho de código abierto, su licencia prohíbe explícitamente su uso con fines de encriptación/ofuscación. – Ale

3

Lo que quiere hacer requiere NtCreateProcess, pero no está documentado y, por lo tanto, es frágil. This book aparentemente cubre su uso.

¿Quizás podrías construir un sistema de parches? P.ej. en el lanzamiento, el programa comprueba el parche DLL en el mismo directorio y lo carga si existe.

11

Puede compilar el juego como un archivo DLL y colocar el archivo DLL en el archivo de datos cifrados. Se puede cargar una DLL desde la memoria sin escribirla en el disco. Consulte este tutorial (con código de muestra al final): Loading a DLL From Memory

+0

Véase también http://stackoverflow.com/questions/638277/loading-dll-from-a-location-in-memory – Suma

40

En realidad es bastante fácil. Se ha descrito una técnica similar en un documento que leí hace 3 años.

de Windows le permiten llamar a la función CreateProcess con CREATE_SUSPENDED bandera, que le dice a la API para mantener el proceso en suspensión hasta que la función se llama ResumeThread.

Esto nos da tiempo para captar el contexto del hilo suspendido usando la función GetThreadContext, luego el registro EBX mantendrá un puntero a la estructura PBE(Process Enviroment Block), que necesitamos para determinar la dirección base.

Desde el diseño de la estructura PBE, podemos ver que la ImageBaseAddress se almacena en el octavo byte, por lo tanto, [EBX + 8] nos dará la dirección base real del proceso que se suspende.

Ahora necesitamos el EXE en memoria y alinearnos apropiadamente si la alineación de la memoria y el EXE en la memoria son diferentes.

Si la dirección base del proceso suspendido y el exe en memoria coinciden, más si el tamaño de la imagen del exe en la memoria es menor o igual que el proceso suspendido 'simplemente podemos usar WriteProcessMemory para escribir el exe en la memoria espacio de memoria del proceso suspendido.

Pero si las condiciones antes mencionadas no se cumplen, necesitamos un poco más de magia. Primero, necesitamos desasignar la imagen original usando ZwUnmapViewOfSection, y luego asignar suficiente memoria usando VirtualAllocEx dentro del espacio de memoria del proceso suspendido. Ahora tenemos que escribir el exe en memoria en el espacio de memoria del proceso suspendido usando la función WriteProcessMemory.

A continuación, aplique un parche a la BaseAddress del exe en memoria en PEB-> ImageBaseAddress del proceso suspendido.

El registro EAX del contexto de subproceso contiene la dirección de EntryPoint, que necesitamos reescribir con la dirección de EntryPoint del exe en la memoria. Ahora tenemos que guardar el contexto de subproceso alterado utilizando la función SetThreadContext.

Voila! ¡Estamos listos para llamar a la función ResumeThread en el proceso suspendido para ejecutarla!

+0

Esto no funciona si el EXE tiene un manifiesto. Oh, carga bien, pero pueden pasar cosas malas. – Joshua

+0

El documento que también tiene una visión general (podría ser ahora el mismo ...) se puede encontrar aquí: http://www.security.org.sg/code/loadexe.html – Urchin

+0

Para cualquier persona que pase, aquí hay un ejemplo código: https://groups.google.com/forum/#!msg/comp.os.ms-windows.programmer.win32/Md3GKPc279A/Ax3bYgXhpD8J –

0

Mira BoxedAppSDK

Es compatible con el lanzamiento de exe de un búfer de memoria.

Espero que ayude.

+0

¿Cómo funciona? ejecutan ejecutable sin archivos temporales? Ningún otro software dice hacer esto. – Navin

+0

Conectando muchas funciones :) –

Cuestiones relacionadas