Underc0de

Foros Generales => Dudas y pedidos generales => Mensaje iniciado por: proxy_lainux en Agosto 26, 2016, 02:26:45 AM

Título: RunPE y windows 10 "No se puede ejecutar esta aplicación en el equipo"
Publicado por: proxy_lainux en Agosto 26, 2016, 02:26:45 AM
Hola

Estaba de ocioso, y quise ver si en Windows 10 todavía se podía hacer los RunPE, estoy un poco óxidado y estuve buscando los antoguos manuales que rondan en internet. Quise hacer una nueva sección para ejecutar un MessageBox.

Pero no sé si lo hice bien, porque Notepad.exe queda con la misma cantidad de bytesy no me menciona ningun mensaje de error, ni me avisa que ya no es un DOS, el icono de notepad aparece bien, lo que significa que en téoria, lo hice bien.

pero cuando lo ejecuto, me dice "No se puede ejecutar esta aplicación en el equipo". Y esto es confuso, ya que no sé si está mal o el sistema detecto algo y no permite que se ejecute.

Alguien aquí lo ha hecho con exito, para entonces describir los pasos que hice, talvez algo esta mal y por eso no me funciona... Lo que no recordé bien fue sobre los alinear, pero no creo haberme confundido, ya que Notepad quedó bien, o eso es lo que yo creo.

Saludos





Edición:

Bueno, ya lo solucioné, me había equivocado en la modificación de SizeOfImage y VirtualAddress

me marcaba 35000 y con la operación confundí la alineación y coloque 40000, en vez de su multiplo siguiente 36000 y lo mismo me pasó con VirtualAddress, pero tengo una duda sobre unas secciones

Para encontrar VirtualAddress, ¿es sumando "VirtualAddress + VirtualSize" o es sumando "VirtualAddress + SizeOfRawData"?

Para encontrar SizeOfRawData, ¿es alineando la cantidad que yo agrego y ya, verdad?, por ejemplo

si mi sección tiene 0x15 y FileAlignment es 0x200 entonces sería 0x15 alinear 0x200 = 0x200 --- o también si fuera 0x240 alinear 0x200 = 0x400 y asi sucesivamente, cierto?, SizeOfRawData solo se obtiene verificando tus datos y FileAlignment, nada mas, ¿cierto?

También trate de meter código asm u opcodes del asm, y buscando encontre que se debe reacomodar ImageBase y AddressOfEntryPoint... ya los encontre, supuestamente se suman y ahí es donde se inicia el código... pero no se que hacer después

ya que tengo ImageBase y AddressOfEntryPoint, ¿que se debe hacer, o como se modifica eso?

Perdon si no pongo código, pero lo estoy haciendo manualmente porque ya no recordaba varias cosas y otras no las aprendí, solo estoy usando códigos para facilitarme un poco las busquedas, porque tener que contar byte por byte para llegar a una dirección es horrible.

Espero me puedan ayudar, gracias
Título: Re:RunPE y windows 10 "No se puede ejecutar esta aplicación en el equipo"
Publicado por: grep en Agosto 28, 2016, 07:47:46 PM
No tienes permitido ver enlaces. Registrate o Entra a tu cuenta
Bueno, ya lo solucioné, me había equivocado en la modificación de SizeOfImage y VirtualAddress

me marcaba 35000 y con la operación confundí la alineación y coloque 40000, en vez de su multiplo siguiente 36000 y lo mismo me pasó con VirtualAddress, pero tengo una duda sobre unas secciones

Para encontrar VirtualAddress, ¿es sumando "VirtualAddress + VirtualSize" o es sumando "VirtualAddress + SizeOfRawData"?

Es la suma del VirtualSize y el VirtualAddress de la sección anterior, alineado al múltiplo mayor inmediato, o igual, de SectionAligment.

No tienes permitido ver enlaces. Registrate o Entra a tu cuenta
Para encontrar SizeOfRawData, ¿es alineando la cantidad que yo agrego y ya, verdad?, por ejemplo

si mi sección tiene 0x15 y FileAlignment es 0x200 entonces sería 0x15 alinear 0x200 = 0x200 --- o también si fuera 0x240 alinear 0x200 = 0x400 y asi sucesivamente, cierto?, SizeOfRawData solo se obtiene verificando tus datos y FileAlignment, nada mas, ¿cierto?

SizeOfRawData lo encuentras en el section header correspondiente a dicha sección.

SectionAlignment (que se encuentra en el optional header) especifica el tamaño mínimo en bytes que tendrá el cuerpo de una sección en memoria, pero si (VirtualAddress + VirtualSize) de dicha sección es mayor, entonces el tamaño de la sección en memoria será (VirtualAddress + VirtualSize) redondeado al múltiplo mayor inmediato del SectionAligment.

FileAlignment (que se encuentra en el optional header) especifica el tamaño mínimo en bytes que tendrá el cuerpo de una sección en el archivo, pero si el tamaño del cuerpo de la sección es mayor a FileAlignment, debe ser un múltiplo de este. Los bytes de alineación son ceros. Esto se muestra en la especificación del IMAGE_OPTIONAL_HEADER.

https://msdn.microsoft.com/en-us/library/windows/desktop/ms680339(v=vs.85).aspx

SizeOfRawData (que se encuentra en el section header correspondiente a dicha sección) almacena este tamaño, múltiplo de FileAlignment, del cuerpo de la sección. Osea que también se tiene en cuenta los bytes en cero. Esto se muestra en la especificación del IMAGE_SECTION_HEADER.

https://msdn.microsoft.com/en-us/library/windows/desktop/ms680341(v=vs.85).aspx

Osea que la respuesta es SI.


No tienes permitido ver enlaces. Registrate o Entra a tu cuenta
También trate de meter código asm u opcodes del asm, y buscando encontre que se debe reacomodar ImageBase y AddressOfEntryPoint... ya los encontre, supuestamente se suman y ahí es donde se inicia el código... pero no se que hacer después

ya que tengo ImageBase y AddressOfEntryPoint, ¿que se debe hacer, o como se modifica eso?

No es necesario cambiar el ImageBase cuando agregas código.

Si necesitas calcular el nuevo AddressOfEntryPoint debes seguir estos pasos:
    * Como sabemos, PointerToRawData (que se encuentra en el section header correspondiente a dicha sección) indica el file-offset donde comienza el cuerpo de la sección. Nos movemos a este offset en el archivo.
    * Desde este punto, hasta el punto donde se encuentra la primera instrucción de nuestro nuevo entry point, calculamos la cantidad de bytes (offset del entry-point con respecto al comienzo del cuerpo de la sección). A esto le llamaremos "delta".
    delta = <offset del entry-point en el archivo> - section.PointerToRawData
    * Como sabemos, VirtualAddress (que se encuentra en el section header correspondiente a dicha sección) es el address relativo al ImageBase (que se encuentra en el optional header) que apunta al primer byte de la sección, entonces obtenemos este valor y lo sumamos con "delta".
    optional.AddressOfEntryPoint = section.VirtualAddress + delta

NOTA: Si se quiere saber a que sección pertenece el AddressOfEntryPoint, se debe analizar cada section header y encontrar aquél donde:
    section.VirtualAddress <= optional.AddressOfEntryPoint <  (section.VirtualAddress + section.VirtualSize) redondeado al múltiplo mayor inmediato del SectionAligment

Fuente:
https://www.virusbulletin.com/virusbulletin/2006/06/inside-pe-file-format/
http://stackoverflow.com/questions/33724306/calculating-the-file-offset-of-a-entry-point-in-a-pe-file

Un comentario interesante:

Cita de: Practical Malware Analysis: The Hands-On Guide to Dissecting Malicious Software
According to the Windows PE specification, VirtualSize should contain the total size of the section when loaded into memory, and SizeOfRawData should contain the size of data on disk. The Windows loader uses the smaller of VirtualSize and SizeOfRawData to map the section data into memory. If the SizeOfRawData is larger than VirtualSize, only VirtualSize data is copied into memory; the rest is ignored.

Como las secciones se cargan en memoria en el orden de su VirtualAddress, y no en el orden como se encuentran sus section headers, es importante que los VirtualAddress sean calculados correctamente para que no se solapen las secciones.


Para el tema de RunPE, basado en el PoC "LoadEXE: Dynamic Forking of Win32 EXE – Tan Chew Keong", sabemos que se crea un proceso en modo suspendido y con el API GetThreadContext() se obtiene el "thread context", osea los valores de los registros, del "primary thread" del proceso nuevo. La mágia se encuentra en los valores de los registros de ese contexto:
- [EAX] apunta al entry-point
- [EBX] apunta al PEB (Process Environment Block), con lo que [EBX+8] apunta al base-address del proceso suspendido.

Esto lo puedes ver en el siguiente código:

- ImageBase = El resultado devuelto por VirtualAllocEx(), que puede o no ser igual a OptionalHeader.ImageBase
   https://github.com/NateBrune/Simple-XTEA-Crypter/blob/master/runPE.h#L37

- EAX = ImageBase + OptionalHeader.AddressOfEntryPoint
   https://github.com/NateBrune/Simple-XTEA-Crypter/blob/master/runPE.h#L47

- [EBX + 8] = PEB.ImageBaseAddress = OptionalHeader.ImageBase
   https://github.com/NateBrune/Simple-XTEA-Crypter/blob/master/runPE.h#L46

Saludos