Foro de elhacker.net

Seguridad Informática => Análisis y Diseño de Malware => Mensaje iniciado por: The Swash en 23 Mayo 2012, 18:44 pm



Título: [Taller en construcción]Secciones en archivos PE.
Publicado por: The Swash en 23 Mayo 2012, 18:44 pm
(http://dl.dropbox.com/u/26610132/Sin%20t%C3%ADtulo-1.png)

(http://dl.dropbox.com/u/26610132/Sin%20t%C3%ADtulo-33.png)
Un saludo a todos los foreros, hoy les traigo un taller práctico-teórico sobre secciones de archivos ejecubles (PE).
Creo que será conveniente recordar conceptos y estructuras básicas sobre el formato PE, si desean profundizar no duden en leer otro documento que he realizado anteriormente sobre el tema "Formato PE bajo Windows", está en español y lo pueden encontrar en el siguiente enlace:
Código:
http://foro.elhacker.net/empty-t332157.0.html

O preferiblemente el documento que muchos llamamos la bíblia del Formato PE, el PECOFF que es la documentación oficial de Microsoft sobre el tema:
Código:
http://msdn.microsoft.com/en-us/library/windows/hardware/gg463119.aspx

Herramientas de práctica:
HexWorkShop v6.0.1: Editor hexadecimal.
Código:
http://dl.dropbox.com/u/26610132/HexWorkShop%206.rar

OllyDBG 1.10: Depurador.
Código:
http://dl.dropbox.com/u/26610132/OllyDGB%201.10.rar

Temas que tratará el taller:
  • Conceptos básicos y repaso sobre la estructura PE.
  • Agregando una sección.
  • El problema de la BOUND_IMPORT_TABLE.
  • Desorden en datos de secciones.
  • Ampliando el tamaño de una sección.
  • Datos entre secciones (no mapeados).
  • Secciones "Dummy".
  • Archivos sin ninguna sección.
  • Lo que realmente hace el TinyPE.
  • Explicación de medios de inyección (RunPE e inyección dependiente de relocaciones). -> A pedido de mi amigo _Enko

Repaso de conceptos y estructuras:
Bueno, nuestro enfoque es hacia los archivos ejecutables y su estructura. Un archivo ejecutable, ahora en adelante lo llamaré PE (Portable Executable) y presenta la siguiente estructura:

(http://dl.dropbox.com/u/26610132/Sin%20t%C3%ADtulo.png)

Estructuras:
IMAGE_DOS_HEADER:
  • DOS_SIGNATURE = 'MZ' -> WORD
  • [29 WORDS] -> Aquí abreviaremos son campos poco utilizados.
  • l_fanew = Apunta hacia IMAGE_NT_HEADERS -> DWORD

IMAGE_NT_HEADERS:
  • Signature = PEx0x0 -> Firma de validación de archivos PE. DWORD
  • IMAGE_FILE_HEADER 0x20
  • IMAGE_OPTIONAL_HEADER 0xE0

IMAGE_FILE_HEADER:
  • Machine: WORD -> Define la arquitectura del computador o emulador para ejecutar el programa
  • NumberOfSections: WORD -> Este valor numerico define la cantidad de secciones que tendrá el archivo.
  • TimeDateStamp: DWORD -> Fecha de creación del archivo.
  • PointerToSymbolTable: DWORD -> Utilizado solo en archivos COFF (.obj)
  • NumberOfSymbols: DWORD -> -> Utilizado solo en archivos COFF (.obj)
  • SizeOfOptinalHeader: WORD -> "Contiene el tamaño del IMAGE_OPTIONAL_HEADER"
  • Characteristics: DWORD -> Atributos u opciones que puede tener el archivo.

IMAGE_OPTIONAL_HEADER:
  • Magic: WORD -> Determina si el programa es para 32 o 64 bits.
  • MajorLinkerVersion: BYTE Versión más alta del linker.
  • MinorLinkerVersion: BYTE Versión más baja del linker.
  • SizeOfCode: DWORD Tamaño de la sección de código generalmente .text o .code.
  • SizeOfInitializedData: DWORD -> Tamaño de datos inicializados.
  • SizeOfUninitializedData: DWORD -> Tamaño de datos no inicializados.
  • AddressOfEntryPoint: DWORD -> RVA del punto de entrada del programa.
  • BaseOfCode: DWORD -> RVA Base de la sección de código.
  • BaseOfData: DWORD -> RVA Base de la sección de datos.
  • ImageBase: DWORD -> VA Base donde se cargará el PE.
  • SectionAlignment: DWORD -> Tamaño de alineación de datos en memoria.
  • FileAlignment: DWORD -> Tamaño de alineación de datos en disco.
  • MajorOperatingSystemVersion: WORD -> Versión principal del S.O requerido.
  • MinorOperatingSystemVersion: WORD -> Versión mínima del S.O requerido.
  • MajorImageVersion: WORD -> Versión principal del PE.
  • MinorImageVersion: WORD -> Versión mínima del PE.
  • MajorSubsystemVersion: WORD -> Versión principal del subsistema requerido.
  • MinorSubsystemVersion: WORD -> Versión mínima del subsistema requerido.
  • Win32VersionValue: DWORD -> Reservado.
  • SizeOfImage: DWORD -> Tamaño que ocupará el ejecutable en memoria, multiplo del SectionAlignment.
  • SizeOfHeaders: DWORD -> Tamaño de toda la cabecera PE.
  • CheckSum: DWORD -> Valor de comprobación por suma.
  • Subsystem: WORD -> Subsistema (consola, gráfico, etc).
  • DllCharacteristics: WORD -> Atributos u opciones pero en caso de librerías DLL.
  • SizeOfStackReserve: DWORD -> Tamaño de reserva para la pila.
  • SizeOfStackCommit: DWORD -> Tamaño de datos de la pila comprometidos.
  • SizeOfHeapReserve: DWORD -> Tamaño de reserva del montículo.
  • SizeOfHeapCommit: DWORD -> Tamaño de datos comprometidos del montículo.
  • LoaderFlags: DWORD -> Parámetros pasados al Loader.
  • NumberOfRvaAndSizes: DWORD -> Número de directorios en IMAGE_DATA_DIRECTORY.
  • IMAGE_DATA_DIRECTORY[NumberOfRVAAndSizes] -> Directorios de datos, conocidos como Tablas, donde tenemos otras estructuras como las importaciones y demás.

IMAGE_SECTION_HEADER
  • Name: (BYTE*8) -> Nombre de la sección.
  • VirtualSize: DWORD -> Tamaño de la sección en memoria.
  • VirtualAddress: DWORD -> RVA donde se carga la sección en memoria.
  • SizeOfRawData: DWORD -> Tamaño de la sección en disco.
  • PointerToRawData: DWORD -> Ubicación de la sección en disco.
  • PointerToRelocations: DWORD -> Campo ya no utilizado, reemplazado por uno de los directorios de datos.
  • PointerToLineNumbers: DWORD -> Solo usado en COFF (.obj).
  • NumberOfRelocations: WORD -> Campo no utilizado ya reemplazado.
  • NumberOfLineNumbers: WORD -> Solo usado en COFF (.obj).
  • Characteristics: DWORD -> Características de la sección (opciones).

Direcciones físicas, virtuales relativas y virtuales:
Antes de continuar quiero también recordar un poco del tema, ya que será necesario que tengan claro que es cada una de estas direcciones para el desarrollo práctico del taller.

Direcciones físicas:
También podemos llamar posición física y corresponden a los valores del archivo en disco osea físicamente al archivo. Va en rango de (0, Tamaño del archivo).

Direcciones virtuales relativas:
Decimos que son relativas porque son el desplazamiento respecto a una dirección virtual. Como se explicará a continuación cuando el archivo es cargado en memoria cambia mucho respecto a como esta en disco. Las direcciones virtuales relativas funcionan como lo sería una dirección física pero en memoria y además son relativas al ImageBase que recordemos es donde se carga el ejecutable. Si hablamos por ejemplo de un RVA 0x3000 en memoria correspondderá a ImageBase + 0x3000, si os verificáis sería muy distinto en obtener el mismo dato en dicha posición.

Direcciones virtuales:
Son direcciones que directamente se encuentran en el rango ImageBase, (ImageBase + SizeOfImage). En escencia sería eso, por ejemplo 0x401000 teniendo como ImageBase 0x400000 estaríamos dentro de dicho rango. Estas hacen referencia directa a una posición en memoria.

Un archivo cargado en memoria:
Bueno justamente quería hacer énfasis en como se vería un archivo cargado en memoria, podemos saber que será distinto que en disco empezando por el detalle de que en memoria será más "grande". Si miramos el SizeOfImage y comparamos en disco tendremos un valor relativamente más grande. Cabe decir que la carga de un archivo en memoria depende su un factor importante y es el campo "SectionAligment" No lo olvidéis.

Lo primero que hará es reservar el espacio, y justo en el ImageBase empezará a "plasmar" el archivo en memoria.

Lo primero que mapeará será la cabecera, cuyo tamaño está determinado por el campo SizeOfHeaders.
Posteriormente tendrá que cargar el cuerpo del archivo, pero es aquí donde entran las alineaciones. Generalmente el SectionAligment tiene el valor correspondiente al tamaño de una página en memoria (0x1000), entonces el mínimo tamaño que tendrá una sección en memoria será el valor del SectionAlignment asi en disco tenga 1 solo byte. Si es mayor entonces su tamaño corresponderá a (VirtualAddress + VirtualSize) redondeado al múltiplo mayor inmediato del SectionAligment.

Ejemplo:
VirtualAddress = 0x1000
VirtualSize = 0x250

Recueden que vamos en múltiplos del SectionAlignment generalmente 0x1000 entonces 0x1000 + 0x250 = 0x1250 el múltiplo mayor inmediato sería 0x2000. El resto será plasmado con muchos 00 hasta completar el tamaño.

Todo lo de la alineación es con el fin de tener orden y fácilidad de acceso a los datos. Entonces las secciones van cargadas en orden de su VirtualAddres sin importar el orden en que se encuentren en el IMAGE_SECTION_HEADER.

Os ilustro con u pequeño gráfico con el que os aclararéis un poco:

(http://dl.dropbox.com/u/26610132/Cc301805.pefig01%28en-us%2CMSDN.10%29.gif)

Si comprendiste seguramente se te van vieniendo ideas respecto a las secciones.

Nuestro trabajo con secciones:
Bueno esta será la parte que más agradará seguramente, aquí trataremos teoría y práctica de cosas que podemos hacer con las secciones de un archivo.

(http://dl.dropbox.com/u/26610132/Sin%20t%C3%ADtulo-23.png)
Parte teórica:
Espero si si estáis leyendo esto tengas los conceptos anteriores muy claros, serán bastante necesarios para que no te confundas.

¿Que define una sección?
Bueno hablemos sobre los campos involucrados en una sección.
  • NumerOfSections: Este campo contiene el número de secciones del ejecutable. Si agregamos una sección deberemos modificarle.
  • SizeOfImage: Este valor contiene el tamaño del ejecutable en memoria, si añadimos una sección entonces agregaremos datos, necesitamos sumar el valor "físico" de la sección al SizeOfImage.
Ahora hay unos campos que entran de manera opcional de acuerdo al campo "Characteristics" de la sección que agregaremos. Por ejemplo si utilizamos las opciones de InitializedData, deberemos actualizar el valor SizeOfInitializedData perteneciente al IMAGE_OPTIONAL_HEADER.

Parte práctica involucrando teoría:

Creando los datos para nuestra sección:
Ahora necesitaremos armar una sección aplicando la parte conceptual vista más arriba. Miremos los campos de una sección:

  • Name.
  • VirtualSize.
  • VirtualAddress.
  • SizeOfRawData.
  • PointerToRawData.
  • PointerToRelocations.
  • PointerToLineNumbers.
  • NumberOfRelocations.
  • NumberOfLineNumbers.
  • Characteristics.

Hay valores que deberemos calcular y otros que simplemente deberemos utilizarlos. Antes de pasar a como obtener los valores quiero mencionar que el IMAGE_FILE_HEADER tiene la declaración de NumberOfSections secciones. Todas las sección ubicada de manera consecutiva y todas utilizando la estructura standard ya mencionada. Cada sección tiene un tamaño de 0x28 bytes, entonces nuestra sección irá al final de la última sección.

De la sección necesitamos:
  • Su definición.
  • Su contenido.

Su definición es lo que va en IMAGE_SECTION_HEADERS donde proporciona todos los datos para que se cargue con el ejecutable.

Bueno para trabajar lo haremos con un pequeño EXE standard para todos nos podamos ubicar correctamente y puedamos seguir este taller.

Es un ejecutable de 1.5k y solo muestra un mensaje y se cierra, será suficiente por ahora.

Descarga:
Código:
http://dl.dropbox.com/u/26610132/Practica%201.exe
Para armar nuestra sección necesitaremos leer información del archivo, donde estan ubicadas las secciones, etc. Vamos!

Utilizaremos un editor hexadecimal y nada más.
Comencemos:
  • Primero deberemos ubicarnos al inicio y comprobar que es un archivo ejecutable válido, para ello comparamos los 2 primeros bytes con 'MZ'. (Está con azul en la imagen).
  • Ahora deberemos proceder a encontrar el campo l_fanew recueden ver la estructura, lo conseguimos así:
    El campo se encuentra despues de justo 30 WORDs y un WORD equivale a 2 bytes. Entonces 30*2 = 60, ahí se encuentra el campo l_fanew. (Está con rojo en la imagen).

(http://dl.dropbox.com/u/26610132/Sin%20t%C3%ADtulo5.png)

Citar
¿Ey, se han dado cuenta?
Justo en el offset 60 en decimal, se encuentra este valor "80 00 00 00", recueden que el campo es de tamaño DWORD -> 4 bytes. Pero y este campo ¿no apuntaba a la firma 'PE\x0\x0'?
Bueno si, contiene el valor donde empieza la firma 'PE\x0\x0' y posteriormente las demás estructuras. Pero ese valor ¿no es muy grande? Bueno, en realidad no. En windows se utiliza algo llamado Orden Little Endian, donde los bytes se organizan por decirlo al "reves", esto sucede con valores numericos y no con cadenas. Es cuestión de arquitectura y demás, en memoria este valor "80 00 00 00" será equivalente a "00 00 00 80" Vén como ahora tiene sentido? Ah una cosa, todos los valores de la cabecera PE estarán en formato Hexadecimal, y para que nos entendamos, cuando les menciones 60d = 60 en decimal y si menciono 0x80 = 80 en hexadecimal. Con la calculadora de Windows podréis hacer las conversiones.

Bien, ahora tenemos que PE\x0\x0 estará ubicado en el offset: 0x80 o 128d. ¿Es cierto?, bueno podemos darnos cuenta de que sí!. Ahora posterior a esta firma tendremos el IMAGE_FILE_HEADER, justo 4 bytes más adelante, osea en 0x84 o 132d. Tomemos nota con los valores reales:
  • Machine: 01 4C -> Posición: 0x84 o 132d
  • NumberOfSections: 00 02 -> Posición 0x86 o 134d
  • TimeDateStamp: 4F BD 28 3D -> Posición: 0x88 o 136d
  • PointerToSymbolTable: 00 00 00 00 -> Posición: 0x8C o 140d
  • NumberOfSymbols: 00 00 00 00 -> Posición: 0x90 o 144d
  • SizeOfOptionalHeader: 00 E0 -> Posición: 0x94 o 148d
  • Characteristics: 01 0F -> Posición: 0x96 o 150d

Tenemos el primer directorio, vamos con el segundo (?). Bueno era broma quería que vieran el mecanismo. Tienen que leer muy bien la estructura y sus tamaños recuerden:
  • BYTE = 1 byte
  • WORD = 2 bytes
  • DWORD = 4 bytes
  • BYTE * X = X bytes

Haremos exáctamente lo mismo, nos ubicamos al principio de cada directorio y así podemos obtener los datos que necesitamos. Entonces nos ubicamos en 0x98, porque Characteristics está en 0x96 y su tamaño es WORD, entonces el otro campo empieza en 0x98.
De IMAGE_OPTIONAL_HEADER necesitamos por ahora:
  • SizeOfImage -> Lo encontramos con 0x98 + 0x38 = 0xD0 y tiene un valor de 00 30 00 00 (real: 00 00 30 00)
  • SectionAlignment: -> Lo encontramos con 0x98(base IMAGE_OPTIONAL_HEADER) + 0x20 = 0xB8 y tiene un valor 00 10 00 00 (real: 00 00 10 00).
  • FileAlignment: -> Lo encontramos con 0x98 + 0x24 = 0xBC y tiene un valor 00 02 00 00 (real: 00 00 02 00).

Bien lo tenemos, ahora necesitamos ubicarnos en el inicio de IMAGE_SECTION_HEADER. Para ello utilizaremos el inicio del IMAGE_OPTIONAL_HEADER y sumaremos el valor de SizeOfOptionalHeader = 0xE0. Tenemos como resultado: 0x178, como podéis ver estamos en la primera sección. Pero necesitamos la estar parados justo al final de la última para escribir nuestra sección no? Bueno es fácil conseguirla, les había mencionado que el tamaño de esta estructura es 0x28, lo multiplicamos por el valor de NumberOfSections = 2 y tenemos que el final de la última sección está en: 0x178 + (0x28*2) = 0x1C8.

Pero que cerca estamos ahora deberemos generar los datos de nuestra sección, agregaremos una simple cadena "TALLER DE SECCIONES EHN" cuyo tamaño de 0x17 + :
  • Name: El que ustedes quieran que contenga 8 bytes. Usemos '.EHN' sin comillas.
  • VirtualSize: Corresponderá al tamaño de los datos de la sección, nuestro caso es 0x17 bytes
  • VirtualAddress: Corresponderá a la dirección virtual relativa donde se cargará la sección. Como sabemos nuestra sección esta justo al final, si tomamos el Valor del VirtualSize y el VirtualAddress de la sección anterior a nosotros, los sumamos y lo alineamos al SectionAligment podremos calcular nuestro VirtualAddress. Entonces:
    - Tendremos que ubicarnos en la sección anterior, recuerdan que estamos en el final? si restamox 0x28 a 0x1C8 estaremos parados justo en la sección anterior: 0x1A0. Ahora utilizando el mismo procedimiento obtendremos lo valores VirtualSize: 00 00 00 17 y VirtualAddress: 00 00 20 00, procedemos a sumarlos: 0x2017 y alineamos, recuerden el múltiplo mayor inmediato es 0x3000 y listo, tenemos nuestro VirtualAddress.
  • SizeOfRawData: Corresponderá al tamaño de los datos de la sección en disco, piensan que 0x17? Bueno pues no!, En disco al igual que en memoria todo debe ser alineado, y como en disco no hay nadie que nos alineé los datos deberemos hacerlo. ¿Como? Igual que como hacíamos antes solo que ahora alineamos al múltiplo mayor inmediato del FileAlignment. Ya lo habíamos conseguido entonces sería 0x17 y su múltiplo mayor inmediato es 0x200. Esos será el total de datos que deberemos agregar en disco al final del archivo, correspondientes a los datos de nuestra nueva sección.
  • PointerToRawData: Corresponderá a la ubicación o posición en el archivo físicamente de los datos de nuestra nueva sección. Tenemos 2 formas de conseguir dicho valor, una es con el tamaño exácto del archivo y ya, y la otra es sumando los valores PointerToRawData + SizeOfRawData de la sección anterior. De ambas formas llegamos a que es: 0x600, si se dan cuenta es múltiplo del FileAlignment por lo cúal constatamos que la sección anterior a nosotros está alineada.
  • PointerToRelocations: Como ya habíamos mencionado no se utiliza, lo dejamos a 0.
  • PointerToLineNumbers: Como ya lo habíamos mencionado no se utiliza, lo dejamos a 0.
  • NumberOfRelocations: Tampoco se utiliza, lo dejamos a 0.
  • NumberOfLineNumbers: Tampoco se utiliza lo dejamos a 0.
  • Characteristics: Sabía que este momento llegaría  :¬¬. Bueno habíamos mencionado ya algo de este campo en las secciones y era sobre atributos u opciones. Aquí podremos definir que atributos tendrá nuestra sección. Entre los atributos tenemos: Lectura, Escritura, Ejecución y demas. Para referencia exácta de estos valores consulte en las 2 fuentes mencionadas al principio. Por ahora utilizaremos 0xC0 00 00 00 el cual corresponde a atributos de Lectura y escritura.

Datos concretos y legíbles:
  • Name: .EHN -> Valor a plasmar: 2E 45 48 4E 00 00 00 00
  • VirtualSize: 0x17 -> Valor a plasmar: 17 00 00 00
  • VirtualAddress: 0x3000 -> Valor a plasmar: 00 30 00 00
  • SizeOfRawData: 0x200 -> Valor a plasmar: 00 02 00 00
  • PointerToRawData: 0x600 -> Valor a plasmar: 00 06 00 00
  • PointerToRelocations: 00 00 00 00
  • PointerToLineNumbers: 00 00 00 00
  • NumberOfRelocations: 00 00
  • NumberOfLineNumbers: 00 00
  • Characteristics: C0 00 00 00 -> Valor a plasmar: 00 00 00 C0

Cuando digo plasmar no me refiero a "INSERTAR" bytes sino a sobreescribir los 00 suficientes, si insertamos dañamos el ejecutable.
Quedará así:

(http://dl.dropbox.com/u/26610132/Sin%20t%C3%ADtulo2.png)

Ahora nos restan los siguientes detalles:
  • Actualizar el valor del SizeOfImage.
  • Actualizar el valor del NumberOfSections.
  • Añadir los datos de la sección justo al final.

Nuevos valores:
  • SizeOfImage: SizeOfImage + SizeOfRawData de nuestra sección =  0x3200 y lo alineamos al SectionAlignment dando como resultado: 0x4000. Editarlo como 00 40 00 00 recordad lo del Little Endian.
  • NumberOfSections: NumberOfSections +1 = 3 Editarlo como 03 00
  • Añadimos al final 0x200 bytes, entre esos al principio estará nuestra cadena: "TALLER DE SECCIONES EHN", osea la cadena + 0x1E9 byes en 00.

Nuestro ejecutable ya tiene su sección y debe funcionar correctamente. Podemos constatar que la función se agregó con éxito si al cargarlo en OllyDBG e ir a la ventana Memory (M) ver la ImageBase de nuestro ejecutable y constatar que está cargada la otra sección, veamos:

Sección en memoria:

(http://dl.dropbox.com/u/26610132/Sin%20t%C3%ADtulo3.png)

Datos de la sección mapeados en memoria:

(http://dl.dropbox.com/u/26610132/Sin%20t%C3%ADtulo34.png)

Descarga archivo de práctica con sección agregada:
Código:
http://dl.dropbox.com/u/26610132/Practica%201-With%20section.exe

Con esto finalizamos la introducción en las secciones, posteriormente veremos otras situaciones en las que agregar una sección se puede complicar un poco, podéis empezar a seguir el taller con confianza.

(http://dl.dropbox.com/u/26610132/bi.png)
Anteriormente había mencionado que se nos vendrían un par de obstáculos, que si no los miramos bien nos pueden dejar algo perdidos. Uno de ellos es el Directorio de datos #12 conocido como BOUND_IMPORT_TABLE.

Descarga archivo de practica #2:
Código:
http://dl.dropbox.com/u/26610132/Practica%202.exe

¿Que problema me puede causar este directorio?
Analicemos un poco las secciones, tiene 3 secciones código, datos y recursos. Es un ejecutable normal compilado en Visual Basic. Se preguntarán ¿Por qué lo elegí?, bueno por que la mayoría de los ejecutables Visual Basic tienen la BOUND_IMPORT_TABLE.
Ustedes se preguntarán ¿Que bronca me traigo con esa estructura?, no es solo mi bronca será la suya también  :D, Me interesa que nos ubiquemos en el final de la última sección (ya sabemos como, sino sabes vuelve a leer la parte superior del taller).

(http://dl.dropbox.com/u/26610132/bit.png)

Si miramos nuestro anterior archivo de práctica veremos una gran diferencia, y es que hay algo despues de la última sección, bueno es la BOUND_IMPORT_TABLE.

Te cuento..
Te cuento que necesitas ese espacio para agregar la declaración de tu sección, pero alguien más ya lo está ocupando. Si intentamos escribir encima de ello nos toparemos con esto:

(http://dl.dropbox.com/u/26610132/error.png)

En realidad es fácil explicar el porque nuestro programa termina explotando, mirando el error:
  • 0xC0000005 - STATUS_ACCESS_VIOLATION
En realidad corresponde a una violación por acceso a un lugar al cúal no se puede acceder, cómo punteros nulos o valores inaccesibles en nuestro anillo de permisos. Todo se dá cuando se trata de validar el BOUND_IMPORT_DIRECTORY.

¿Hay solución?
Si, te cuento que hay 2 una menos ortodoxa que la otra pero ambas funcionan. Una preservadora y otra no presevadora.
  • Primera solución: Yoda(creador de LordPE) alguna vez mencionó que se puede establecer el RVA del directorio BOUND_IMPORT_DIRECTORY a 00 porque este era poco importante. Mi amigo karmany opinó al respecto y estoy de acuerdo con él, este directorio tiene como utilidad optimizar entonces me parece que importa. El ejecutable no deja de funcionar pero no preserva el estado original del ejecutable.
  • Segunda solución: Personalmente me parece la mejor y consiste en mover de sitio el BOUND_IMPORT_DIRECTORY. Si sabemos que está justo despues de la última sección, tranquilamente lo desplazamos 0x28 bytes y así tenemos espacio para una función. Posteriormente se actualiza el RVA en el Directorio de datos y lo habríamos solucionado.

Manos a la obra!
Bueno, probemos que todo lo que hemos dicho es cierto e intentemos añadir una sección al ejecutable de práctica teniendo en cuenta las 2 soluciones.

Creo que necesito hacer un breve recuerdo sobre el IMAGE_DATA_DIRECTORY asi que nombraré algunas de sus características.
  • Se ubíca justo antes de IMAGE_SECTION_HEADER.
  • Tiene como tamaño (8*IMAGE_OPTIONAL_HEADER.NumberOfRvaAndSizes).
  • Cuenta con un total de 16 directorios generalmente (aunque puede alterarse).
  • Cada directorio tiene 2 entradas, RVA(DWORD) y Size(DWORD).

Ya les había mencionado que el directorio correspondiente al BOUND_IMPORT_TABLE es el número 12, si aplicamos un poco de matemáticas y nos paramos justo al inicio de IMAGE_SECTION_HEADER y restamos (5*8) estaremos justo en la declaración del directorio. 0x1B0 - 0x28 = 0x188 -> BOUND_IMPORT_DIRECTORY, leamos los valores del directorio.
  • RVA: 0x228
  • Size: 0x20


Relizamos los desplazamientos:
Lo unico que deberemos hacer es cambiar el RVA del BOUND_IMPORT_DIRECTORY por RVA + 0x28 y posteriormente desplazar los datos en el archivo (Con desplazar me refiero a correr, nada de insertar.)

Nuevos datos:
  • RVA: 0x250
  • Size: 0x20


Y desplazando los datos tendríamos algo así:

(http://dl.dropbox.com/u/26610132/mbit.png)

Si miramos quedó desplazado y los bytes que quedaron en color rojo vendrá a ser el espacio para nuestra sección. Aún si no la agregasemos el ejecutable de igual forma quedaría funcionando y se preservaría.

Igual ya teníamos los datos sobre el archivo de práctica original, para aplicar el segundo método cambiamos el RVA por 00 00 00 00 y el Size por 00 00 00 00 y listo.

Descarga práctica con sección y método de desplazamiento de la BOUND_IMPORT_TABLE:
Código:
http://dl.dropbox.com/u/26610132/Metodo%20desplazamiento.exe

Descarga práctica con sección y método de eliminación de la BOUND_IMPORT_TABLE:
Código:
http://dl.dropbox.com/u/26610132/Metodo%20de%20eliminacion.exe

Con esto habríamos terminado la parte de agregar secciones aunque agregaré lo siguiente:
El otro problema sería para más que un problema un caso de profundización y vendría a ser el siguiente. Primero habría que hablar de un límite de secciones que si mal no recuerdo en Windows XP es de 96 y en >= Windows Vista es de 0xFFFF, todo cuestion de versión del Loader. Ahora si físicamente te quedas sin espacio porque por ejemplo ya tienes enseguida de la última sección la primera sección del ejecutable.

¿No se pueden agregar más?
Claro que se puede y tienes que tener en cuenta el SizeOfHeaders, lo puedes expandir y seguir agregando secciones. Solo que deberás tener un factor en cuenta, si aumentaste el tamaño ahí deberías arreglar nuevamente los datos de todas las secciones, VirtualAddress y PointerToRawData de cada una.

Esto es todo sobre agregar secciones, practiquen y si tienen dudas para eso estamos, disfrutenlo!, hasta el siguiente tema.

(http://dl.dropbox.com/u/26610132/desorden.png)
Bueno hablaremos sobre el orden de las secciones en el cuerpo del archivo. Si hemos visto determinada cantidad de archivos ejecutables nos daremos cuenta que en el cuerpo del archivo se preserva el orden en el que están declaradas las secciones.

¿Es necesario que se respete este orden?
No, realmente las secciones en disco pueden estar ubicadas en completo desorden mientras cumplan el requisito de estar bien referenciadas en su declaración (IMAGE_SECTION_HEADER). Me refiero a que todos los punteros deben estar correctos.

¿Por que no afecta el orden de las secciones?
En realidad como mencioné las secciones en disco se ven referenciadas o "apuntadas" por su definición en el IMAGE_SECTION_HEADER, el mapeo en memoria no se verá afectado ya que igual esta mapeando datos que provienen de distintias posiciones en el archivo. Si os preguntáis por qué no se puede cambiar el orden de las secciones en su declaración? En realidad por problemas de fragmentación y garantía, no se puede asegurar si no se escriben en orden posicional no se pisen entre sí.

¿No entiendes lo de desorden?
Bueno espero este gráfico te ilustre un poco:

(http://dl.dropbox.com/u/26610132/des.png)

Si lo llevamos a la parte práctica podríamos sacar las siguientes conclusiones:
  • El orden del IMAGE_SECTION_HEADER no se debe alterar.
  • Tendremos que modificar el orden del contenido de las secciones.
  • Tendremos que actualizar los campos PointerToRawData y SizeOfRawdata de las secciones.

Descar archivo de práctica número #3:
Código:
http://dl.dropbox.com/u/26610132/Practica%203.exe

Nuestro archivo:
  • Tiene 3 secciones (.text, .idata y .data).
  • Intercambiaremos .text y .data en el cuerpo del archivo.

Manos a la obra!
  • Primero obtendremos datos de las secciones, recordad lo siguiente: los cambios serán en físico con el hecho de que en memoria el archivo se cargará igual siempre.
    • Sección .text: PointerToRawData: 0x200 SizeOfRawData: 0x200
    • Sección .idata: PointerToRawData: 0x400 SizeOfRawData: 0x200
    • Sección .data: PointerToRawData: 0x600 SizeOfRawData: 0x200
  • Todas las secciones tienen el mismo tamaño, lo cual nos facilitará las cosas.
  • Nuevos datos:
    • Sección .text: PointerToRawData: 0x600 SizeOfRawData: 0x200
    • Sección .idata: PointerToRawData: 0x400 SizeOfRawData: 0x200
    • Sección .data: PointerToRawData: 0x200 SizeOfRawData: 0x200

Declaración de IMAGE_SECTION_HEADER antes:

(http://dl.dropbox.com/u/26610132/sec.png)

Declaración de IMAGE_SECTION_HEADER después:

(http://dl.dropbox.com/u/26610132/secd.png)

En disco debemos cambiar todos los 0x200 bytes de una sección por otra:

Nueva ubicación sección .text:

(http://dl.dropbox.com/u/26610132/secd2.png)

Nueva ubicación sección .data
(http://dl.dropbox.com/u/26610132/secd3.png)

Eso es todo, lo considero uno de esos detallitos que son importantes resaltar. Ya podéis prácticar cualquier duda pregunta!, Hasta el siguiente tema.

(https://dl.dropbox.com/u/26610132/as.png)
Hola chicos, en este nuevo capitulo hablaremos sobre como ampliar la sección de un archivo ejecutable. Requiere todo lo visto previamente, algo de cuidado y solo un poquito de imaginación, eso es todo.

¿Por qué podemos querer ampliar una sección?
Podemos verlo desde distintas perspectivas pero siempre llegando a la conclusión de que nos crearemos un espacio en el archivo. Al agregar una sección agregamos datos en un espacio que nosotros mismos previamente creamos, al ampliar una sección con seguridad queremos meter datos y nuevamente nos estamos haciendo un espacio, solo que ahora es "compartido".

¿Que debemos hacer para ampliar una sección?
Debemos tener claro que ampliaremos el rango de los valores de una sección física y virtualmente. Hay que tener especial cuidado si ampliamos una sección que se encuentra en medio de otras 2, puesto que tendremos que modificar los valores de la siguiente sección para no desalinear el ejecutable.

Ilustración de una sección ampliada:

(https://dl.dropbox.com/u/26610132/as2.png)

Descargar archivo de práctica #4:
Código:
https://dl.dropbox.com/u/26610132/Practica%204.exe

Manos a la obra!
Ampliaremos las sección .idata 0x150 bytes en el archivo de práctica.

Debemos:
  • Obtener los siguientes valores de la sección que ampliaremos:
    • VirtualSize: 0x98
    • PointerToRawData: 0x400
    • SizeOfRawData: 0x200
  • Si hay una sección posterior a la que ampliaremos obtedremos de dicha sección (.data) los siguientes valores:
    • VirtualAddress: 0x3000
    • VirtualSize: 0x4
    • PointerToRawData: 0x600
    • SizeOfRawData: 0x200
  • Debemos alinear la cantidad de bytes que ampliaremos en base al FileAlignmente: 0x150 Alineado 0x200 : 0x200 y será la cantidad que ampliaremos.
  • Nos ubicamos al final de la sección que ampliaremos: PointerToRawData + SizeOfRawData: 0x600.
  • Añadimos la cantidad de bytes ya caculada.
  • Actualizaremos valores de la sección de la siguiente manera:
    • VirtualSize: Teniendo en cuenta que este tamaño corresponde a los bytes que se mapearán en memoria debemos saber cuanto espacio usaremos. Podemos escribir en el nuevo espacio generado y modificar este campo en base hasta donde queremos que mapee. En este caso pongámoslo a 0x400 para que cubra todos los bytes de la sección.
    • SizeOfRawData: Aumentaremos el valor de bytes alineados que agregamos: 0x200 + 0x200 : 0x400.
  • Debemos actualizar de la sección posterior (si la hay) los siguientes valores:
    • VirtualAddress: Se actualizará unicamente si al sumar VirtualAddress + SizeOfRawData de la sección ampliada el resultado es mayor que el VirtualAddress de esta sección. En nuestro caso no se cumple y no modificamos el valor.
    • PointerToRawData: Se actualizará con el valor resultante de la suma de los valores PointerToRawData + SizeOfRawData de la sección ampliada, en nuestro caso 0x400 + 0x400 : 0x800.
  • Debemos actualizar el SizeOfImage con el valor equivalente a: VirtualAddress + (VirtualSize Alineado a SectionAlignment): 0x3000 + (0x400 Alineado 0x1000 = 0x1000) = 0x4000.

Con esto ya debebemos tener nuestro ejecutable funcionando y totalmente alineado.
Nota: Cuando la sección que se amplíe también este referenciada por el directorio de datos, debes actualizar el tamaño en el mismo.


Nuevos bytes en disco:

(https://dl.dropbox.com/u/26610132/as3.png)

Nuevos bytes en memoria:

(https://dl.dropbox.com/u/26610132/as4.png)

Descarga archivo resultante (con una pequeña modificación):
Código:
https://dl.dropbox.com/u/26610132/Practica%204%20Resultado.exe

Con esto terminamos este capitulo, practiquen y no olviden poner sus dudas, Nos vemos en el próximo.


(http://dl.dropbox.com/u/26610132/EnConstruccion%20copia.png)


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: x64core en 24 Mayo 2012, 18:42 pm
 :D
Grande el taller, muchas gracias por compartirlo con todos nosotros The Swash  :)


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: Belial & Grimoire en 24 Mayo 2012, 19:21 pm
hola The Swash

muy bueno el taller espero pongas mas, tenia ganas de continuar con esto hace tiempo pero tuve un problema que espero me puedas decir que podria ser

hace tiempo intente modificar PE en windows XP y me funciono perfecto, pero quise hacer el intento en windows 7 y no logre expandir PE para agregar mi sección en notepad

y quisiera preguntarte... con cual windows te basaste para hacer este taller?, y haz logrado hacerlo en windows 7?

espero me puedas responder, y ojala continues agregando mas cosas a tu taller

salu2


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: The Swash en 24 Mayo 2012, 20:02 pm
Hola,
Gracias a todos por vuestros comentarios, en realidad todo fue hecho bajo Windows 7 pero puedo asegurarte que lo hecho hasta el momento funciona bajo todas las versiones de Windows, porque lo hacemos de manera correcta y standard.

En cuanto a lo de la ampliación de las secciones también hace parte del taller, aún no llegamos pero en nada lo veréis.


Un saludo.


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: $Edu$ en 24 Mayo 2012, 20:08 pm
Perfecto, buen aporte, muchas gracias por compartir!


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: Belial & Grimoire en 24 Mayo 2012, 20:15 pm

que bien, a ver si ahora puedo lograrlo en windows 7, bueno, pues ya ansioso de la continuacion del taller  ;-)

salu2 y suerte


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: jackgris en 25 Mayo 2012, 01:43 am
Exelente, ya habia leido el pdf Formato PE bajo Windows, pero con este taller esta muy bueno recordar cosas escenciales, muchas gracias  ;-) ;-) ;-)


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: _Enko en 25 Mayo 2012, 06:20 am
Excelente aporte, muy buen tuto :)


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: Belial & Grimoire en 25 Mayo 2012, 19:45 pm
hola

espero me puedas explicar algunas cosas que no entendi, todavia no lo hago en windows, por ahorita solo revise las aplicaciones que pusiste con linux para poder seguir el taller

pero tengo algunas dudas

Citar
1.- Pero que cerca estamos ahora deberemos generar los datos de nuestra sección, agregaremos una simple cadena "TALLER DE SECCIONES EHN" con un tamaño de 0x17

de donde sale ese tamaño 0x17?

tampoco entendi muy bien como encontrar VirtualAddress

Citar
2.-VirtualAddress: Corresponderá a la dirección virtual relativa donde se cargará la sección. Como sabemos nuestra sección esta justo al final, si tomamos el Valor del VirtualSize y el VirtualAddress de la sección anterior a nosotros, los sumamos y lo alineamos al SectionAligment podremos calcular nuestro VirtualAddress. Entonces:
- Tendremos que ubicarnos en la sección anterior, recuerdan que estamos en el final? si restamox 0x28 a 0x1C8 estaremos parados justo en la sección anterior: 0x1A0. Ahora utilizando el mismo procedimiento obtendremos lo valores VirtualSize: 00 00 00 98 y VirtualAddress: 00 00 20 00, procedemos a sumarlos: 0x2098 y alineamos, recuerden el múltiplo mayor inmediato es 0x3000 y listo, tenemos nuestro VirtualAddress.

segun lo que entendi, es que para encontrar VirtualAddress... ¿hay que sumar 98, que seria el inicio de IMAGE_OPTIONAL_HEADER + FileAlignment 00 00 02 00?

Código:
lo que seria 2098 y como multiplo seria 3000

aqui vienen 2 preguntas... ¿siempre es asi para encontrar VirtualAddress? y ¿cuando se habla de multiplos se refieren a redondear?, por ejemplo

Código:
si fuera 2234, aun seria 3000?, y si fuera 3005, entonces seria 4000?

Citar
3.-SizeOfRawData: Corresponderá al tamaño de los datos de la sección en disco, piensan que 0x98? Bueno pues no!, En disco al igual que en memoria todo debe ser alineado, y como en disco no hay nadie que nos alineé los datos deberemos hacerlo. ¿Como? Igual que como hacíamos antes solo que ahora alineamos al múltiplo mayor inmediato del FileAlignment. Ya lo habíamos conseguido entonces sería 0x98 y su múltiplo mayor inmediato es 0x200. Esos será el total de datos que deberemos agregar en disco al final del archivo, correspondientes a los datos de nuestra nueva sección.

SizeofRawData es lo mismo que FileAlignment?, y por ejemplo si fuera asi?

Código:
FileAlignment 00 00 02 05, entonces SizeofRawData seria 0x205, y entonces lo tendria que pasar al multiplo mayor?, para que quede 0x300?

Citar
4.-PointerToRawData: Corresponderá a la ubicación o posición en el archivo físicamente de los datos de nuestra nueva sección. Tenemos 2 formas de conseguir dicho valor, una es con el tamaño exácto del archivo y ya, y la otra es sumando los valores PointerToRawData + SizeOfRawData de la sección anterior. De ambas formas llegamos a que es: 0x600, si se dan cuenta es múltiplo del FileAlignment por lo cúal constatamos que la sección anterior a nosotros está alineada.

Este la verdad no entendi como encontrar, solo se que SizeofRawData equivale a 0x200, pero como llegaste a 0x600?

y la ultima que es una confusion seria

Citar
    Name: .EHN -> Valor a plasmar: 2E 45 48 4E 00 00 00 00
    VirtualSize: 0x98 -> Valor a plasmar: 98 00 00 00
    VirtualAddress: 0x3000 -> Valor a plasmar: 00 30 00 00
    SizeOfRawData: 0x200 -> Valor a plasmar: 00 02 00 00
    PointerToRawData: 0x600 -> Valor a plasmar: 00 06 00 00
    PointerToRelocations: 00 00 00 00
    PointerToLineNumbers: 00 00 00 00
    NumberOfRelocations: 00 00
    NumberOfLineNumbers: 00 00
    Characteristics: C0 00 00 00 -> Valor a plasmar: 00 00 00 C0

en VirtualSize pusiste 0x98, lo que me imagino seria el inicio de IMAGE_OPTIONAL_HEADER, pero en el antiguo taller de Ferchu menciona

Citar
Name:   .Ferchu   (8 bytes)
VirtualSize:    0x00000050    (4 bytes)

Y finalmente agregamos nuestra frase "Hola yo soy la sección de prueba, y ocupo exactamente la cantidad de 0x50 bytes." al final del archivo, como los datos de la nueva sección.


aqui esto me confundio, cual es la diferencia entre los 0x50 de la frase y 0x98 que tu pusiste

bueno, por el momento seria todo, jeje creo tuve muchas dudas, pero me interesa el tema y espero no te moleste jeje XD

bueno salu2


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: The Swash en 25 Mayo 2012, 21:13 pm
En cuanto a lo de la cadena me refería a su tamaño, ya lo he editado de una manera que quede más explícito.

En cuanto a lo del campo VirtualAddress de la estructura IMAGE_SECTION_HEADER, me refiero a la dirección virtual relativa(explicado al principio) donde se cargará la sección en memoria. Osea es allí donde empieza a cargarse la sección que como te darás cuenta es distinto comparandolo con la posición en disco, esto se debe a los alineamientos virtuales y físicos.

Para encontrar el VirtualAddress debe tomar como base la sección inmediatamente anterior a la que vamos a agregar, la que era la última. De aquí tomaremos los datos VirtualAddress y SizeOfRawData, los sumamos y luego alineamos al SectionAlignment -> Alineación virtual.

Cuando me refiero a alinear en teoría si, es redondear pero hacia el múltiplo de determinado valor pero mayor mayor. Ejemplo:

0x1000 + 0x05 = 0x1005 -> Múltiplo más proximo de 0x1000 es 0x2000.
Además el ejemplo que diste también es válido.

SizeOfRawData NO es lo mismo que FileAlignment aunque pueden coincidir sus valores, este corresponde al tamaño que ocupa la sección en el archivo. El FileAlignment es la base de alineamientos físicos. Osea que todo lo que que en disco deba estar alineado a este campo debe cumplir como valor mínimo, y cualquier otro valor mayor debe ser múltiplo mayor inmediato de este.

Ejemplo:
0x202 -> Alineado 0x400 (FileAlignment = 0x200).

El PointerToRawData es la ubicación de los datos de la nueva sección en disco. Igualmente debes tomar como referencia la sección inmediatamente anterior. Si el PointerToRawData de la sección inmediatamente anterior es 0x400 esa será su posición en disco, pero para llegar al final de los datos de esta sección debes sumar su tamaño SizeOfRawData, con eso estarás al final de la sección inmediatamente anterior. Así llego a 0x600.

En cuanto al valor del VirtualSize correpsonde al tamaño de los datos que mapeará en memoria el Loader, 0x98 fue un error mío de puro despiste, en realidad sería 0x17, en este caso no se alinea a ningún valor entonces pasamos el valor neto de los datos explicitos de la sección.

Espero haya resuelto tus dudas.

Un saludo,
Iván Portilla








Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: x64core en 25 Mayo 2012, 21:40 pm
The Swash, Una pregunta... bueno estoy seguro que sobreescribes 28 bytes de la Bound cierto?
tambien puse a pensar y si el exe tiene muchas secciones e intento agregar otra sección se rompe... pero
estamos hablando de 8,10 secciones... por cierto todos los ejecuatbles albolutamente todos tiene bound... aunque no
sea ocupada?


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: The Swash en 25 Mayo 2012, 22:08 pm
Expliqué los 2 métodos:
  • Mover la BOUND_IMPORT_TABLE.
  • Remover la BOUND_IMPORT_TABLE.

Todos los ejecutables NO tienen BOUND_IMPORT_TABLE, y para comprobar si tienen o no debes comparar el directorio de datos número 12 y ver si su RVA es 0 o no.

Un saludo,
Iván Portilla.


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: Belial & Grimoire en 25 Mayo 2012, 23:26 pm
bueno, entonces lo de 0x17... es la frase y tambien virtualsize

ya entendi mas sobre los multiplos que me tenia confundido

pero a ver, para obtener VirtualAddress, como mencionas en el taller, hay que regresar una sección y tomar el virtualaddress + SizeOfRawData que seria algo asi
Código:
0x28 - 0x1C8 = 0x1A0
Código:
000001a0  2e 69 64 61 74 61 00 00  98 00 00 00 00 20 00 00  |.idata....... ..|

Código:
2e 69 64 61 74 61 <--- esto debe ser .idata
00 00 <--- esto debe ser virtualsize
98 00 00 00 <---- esto es VitualAddress
00 20 00 00 <---- esto es SizeOfRawData
bueno, esto esta en little endian, lo que seria

Código:
00 00 00 98
00 02 00 00

si sumo esos 2, seria 00 02 00 98, equivalente a 2098, si lo redondeo seria 3000

y finalmente quedaria asi, cierto?

Código:
00 00 00 98
00 02 00 00
/////////////
00 03 00 00

para encontrar SizeOfRawData entonces seria lo que sigue de VirtualAddress

Código:
000001a0  2e 69 64 61 74 61 00 00  98 00 00 00 || 00 20 00 00 <--- seria este

entonces si busco FileAlignment + SizeOfRawData seria

Citar
FileAlignment: -> Lo encontramos con 0x98 + 0x24 = 0xBC y tiene un valor 00 02 00 00 (real: 00 00 02 00).

Código:
00 20 00 00
00 02 00 00

seria 0x220, su multiplo seria 400

aqui una duda, porque 400?, y porque no 300?

y para encontrar PointerToRawData, seria el siguiente de SizeOfRawData

Código:
000001b0  00 02 00 00 <---- aqui se encuentra 00 04 00 00  00 00 00 00 00 00 00 00  |................|

si se lo sumo al resultado de FileAlignment + SizeOfRawData + PointerToRawData... seria
Código:
0x400 + 200 = 0x600 <--- 00 06 00 00

espero haber entendido, si tengo algun error, espero puedan coregirme

bueno, al rato intentare hacerlo en windows, salu2


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: The Swash en 25 Mayo 2012, 23:56 pm
Creo que lo entendiste mucho mejor.

Recuerda que todos los campos de IMAGE_SECTION_HEADER tienen un tamaño cada uno de 4 bytes con excepción del nombre de la sección que ocupa 8 y NumberOfRelocations y NumberOfLineNumers (WORD) estos últimos. (Debes tener muy en cuenta el tamaño de cada campo).

Ahora tienes un pequeño problema con las alineaciones.
NO se deben sumar, solamente un valor debe ser múltiplo del otro, cuando digo múltiplo es que al hacer la operación:

Num mod Alineamiendo = 0.

Entonces no es 0x220, mira bien que esos 2 valores que marcaste:
Citar
00 20 00 00
00 02 00 00

Son VirtualAddress y SizeOfRawData correspondientemente. Entonces para encontrar SizeOfRawData, este valor corresponde al tamaño de los datos de TU sección, y ese valor se debe alinear al FileAlignment:

FileAlignment: 0x200
Tus datos: 0x17
0x17 alineado a 0x200 = 0x200.

Citar
2e 69 64 61 74 61 <--- esto debe ser .idata
00 00 <--- esto debe ser virtualsize
98 00 00 00 <---- esto es VitualAddress
00 20 00 00 <---- esto es SizeOfRawData

Estás mal, idata cubre 8 bytes, los siguientes 4 corresponden al VirtualSize que sería 0x98, los siguientes 4 al VirtualAddress, los siguientes 4 SizeOfRawData, los siguientes 4 a PointerToRawData...



Un saludo.


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: x64core en 26 Mayo 2012, 01:26 am
ok, entonces me pongo a pensar si un ejecutable no tiene bound... entonces creo que sería un gran problema no...
ya que ningun metodo mecionado se podría aplicar...


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: x64core en 26 Mayo 2012, 02:46 am
ok chicos solucionado error mío :D que viva el taller


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: 79137913 en 26 Mayo 2012, 03:05 am
HOLA!!!

El lunes hablame por msn que quiero ver si me armas una cosa artesanal XD.

GRACIAS POR LEER!!!


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: Belial & Grimoire en 26 Mayo 2012, 21:37 pm
hola

ya hice la primera parte igual en windows 7 y funciono perfecto

ahora quise hacer el intento con notepad en windows 7, pero me encontre con un problema

notepad, tiene 4 secciones, el ultimo es .reloc, al intentar calcular VirtualAddress, me aparece de esta forma

Código:
00000242 00 00 00 00 00 00 00 00 00 00 40 00 00 40 2E 72 65 ..........@..@.re
00000253 6C 6F 63 00 00 34 0E 00 00 00 F0 02 00 00 10 00 00 loc..4...........
00000264 00 AE 02 00 00 00 00 00 00 00 00 00 00 00 00 00 40 ................@
00000275 00 00 42                                           ..B             

por lo visto aqui esta

Código:
----> 00 F0 02 00 || 00 10 00 00 loc..4...........

de que manera se obtendria aqui VirtualAddress?

Citar
VirtualSize: 00 00 00 17 y VirtualAddress: 00 00 20 00, procedemos a sumarlos: 0x2017 y alineamos, recuerden el múltiplo mayor inmediato es 0x3000 y listo, tenemos nuestro VirtualAddress.

seria 00 f0 02 17?, y cual seria el resultado?

por cierto, usare la misma cantidad de 0x17 para no revolver tanto y seguir el ejemplo del taller

y otra cosa, esto hice para obtener la direccion donde se encontrara mi sección pero no encontre espacios vacios

28 * 4= A0 + 1D8 = 278

habra algun problema si le agrego 28 bytes para agregar mi sección?

salu2


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: Karcrack en 26 Mayo 2012, 23:50 pm
Muy buen trabajo, espero que lo sigas ampliando :P

Lo añado a la biblioteca en cuanto llegue a casa.

saludos >:D


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: The Swash en 27 Mayo 2012, 00:15 am
Amigo,
Te felicito por lo de la primera parte. En cuanto al notepad.

Si tu VirtualAddress de la ultima sección es 0x2F000 y el VirtualAddress es Tamaño (0xE34 Alineado 0x1000 = 0x1000) = 0x30000 -> Ese es el nuevo VirtualAddress.

En cuanto a lo de tus espacios, eso se especifica en la parte del Taller llamada "We vs BOUND_IMPORT"

Un saludo,
Iván Portilla


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: Belial & Grimoire en 27 Mayo 2012, 04:38 am
hola

bueno, pues ya voy entendiendo mas, por lo menos el ejemplo del taller lo logre hacer bien, pero sigo teniendo problemas con el block

a ver, primero sigo los pasos de la primer parte

en el caso de mi sistema es
Citar
   Name: .EHN -> Valor a plasmar: 2E 45 48 4E 00 00 00 00
    VirtualSize: 0x17 -> Valor a plasmar: 17 00 00 00
    VirtualAddress: 0x3000 -> Valor a plasmar: 00 30 00 00
    SizeOfRawData: 0x200 -> Valor a plasmar: 00 02 00 00

me imagino que si son 0x200, porque reloc es

00100000 + los 17, quedaria alineado con FileAlignment (11C)

FileAlignment lo encuentro asi 00020000

Aqui tengo una duda, como mencionas una de las 2 formas de encontrar esto es colocando la
cantidad exacta de la aplicaion

Citar
Corresponderá a la ubicación o posición en el archivo físicamente de los datos de nuestra nueva sección. Tenemos 2 formas de conseguir dicho valor, una es con el tamaño exácto del archivo y ya

en mi caso es "0002BE00", hacer esto y dejarlo asi esta bien? o se tiene que alinear?

lo menciono porque tambien mencionaste

Citar
De ambas formas llegamos a que es: 0x600, si se dan cuenta es múltiplo del FileAlignment por lo cúal constatamos que la sección anterior a nosotros está alineada.
 

PointerToRawData: 0002BE00 esto es la cantidad exacta del archivo -> entonces quedaria 0x00BE0200

porque la sección .reloc de PointerToRawData y SizeOfRawData seria

00100000 --> PoniterToRawData
00AE0200 --> SizeOfRawData


Citar
   PointerToRelocations: 00 00 00 00
    PointerToLineNumbers: 00 00 00 00
    NumberOfRelocations: 00 00
    NumberOfLineNumbers: 00 00
    Characteristics: C0 00 00 00 -> Valor a plasmar: 00 00 00 C0


de la ultima sección que es .reloc recorro 0x20h o 40 bytes, alli escribo mi sección

despues busco la sección BOUND_IMPORT_TABLE

Citar
Ya les había mencionado que el directorio correspondiente al BOUND_IMPORT_TABLE es el número 12, si aplicamos un poco de matemáticas y nos paramos justo al inicio de IMAGE_SECTION_HEADER y restamos (5*8) estaremos justo en la declaración del directorio. 0x1B0 - 0x28 = 0x188 -> BOUND_IMPORT_DIRECTORY

bueno, en mi caso IMAGE_SECTION_HEADER se encuentra en

1D8 - 0x28 = 1B0

otra forma de llegar es con PE + 0xD0

0xE0 + 0xD0 = 0x1B0

bueno la cuestion es... que me encuentro con BOUND_IMPORT_TABLE


000001A9 6D 00 00 40 00 00 00 78 02 00 00 28 01 00 00 00 10 m..@...x...(.....

me imagino que quedaria asi si borro RVA y Size

000001A9 6D 00 00 40 00 00 00 00 00 00 00 00 00 00 00 00 10 m..@.............

despues al final, agrego los 200 bytes para escribir la frase

y lo guardo

pero cuando lo ejecuto me menciona que no es una aplicacion win32

dejo el notepad con toda la modificacion que hice

http://www.mediafire.com/?1azivv26r9a9jce

bueno, ya descansare porque creo ya me bloque y cosas que ya hice se me estan dificultando de nuevo, mejor continuare despues, gracias por la ayuda de hoy

salu2


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: m0rf en 27 Mayo 2012, 22:18 pm
Muchas gracias, me va a ser útil.

Saludos.


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: The Swash en 27 Mayo 2012, 23:02 pm
En cuanto al SizeOfRawData:
Es la cantidad de bytes que añadirás en tu sección, Si este valor no es múltiplo del FileAlignment debes alinearlo y por tanto agregar la cantidad de bytes alineada, si alineas 0x17 con 0x200 te dará 0x200, equivalente al total de bytes a agregar, pero de esos 0x200 0x17 bytes serán los que contienen tus datos así que serán los primeros 0x17 bytes de los 0x200 en total.

En cuanto al PointerToRawData:
Tienes 4 secciones, la última con los siguientes datos:
  • VirtualAddress: 0x2F000
  • VirtualSize: 0xE34
  • PointerToRawData: 0x2AE000
  • SizeOfRawData: 0x1000

Si calculamos, el VirtualAddress de nuestra sección será: 0x2F000 + 0xE34 = 0x2FE34 Alineado a SectionAlignment (Se alinea al SectionAlignment porque ambos valores hacen referencia a memoria) = 0x30000 -> Nuevo VirtualAddress.

VirtualSize: La cantidad de datos que agregarás (0x17, esto se alinea solo en memoria).

PointerToRawData: (0x2AE00 + 0x1000 = 0x2BE00) Podemos comprobar que dicho valor está alineado ya que al hacer 0x2BE00 mod 0x200 será 0.

SizeOfRawData: Ya lo mencioné arriba.

Ahora, como te pudiste dar cuenta, hay datos justo al final de la última sección y estos corresponden a BOUND_IMPORT_TABLE. Comienza justo en: 0x278 y tiene un tamaño de 0x128. Esto lo podemos ver al ubicarnos primero al inicio del IMAGE_DATA_DIRECTORY, para esto nos basamos el donde inicia la primera sección y restamos la cantidad de directorios por el tamaño de cada uno (0x10* 0x8 =  0x80). Entonces sería 0x1D8 (inicio de primera sección) - 0x80 = 0x158 (inicio de IMAGE_DATA_DIRECTORY) + 0x58(posición del BOUND_IMPORT_TABLE). = 0x1B0 -> Aquí estarán los datos del BOUND_IMPORT_TABLE, en tu caso quedará más fácil "pisarla", entonces establece el RVA correspondiente a los primeros 4 bytes del BOUND_IMPORT_TABLE a 0, y los siguientes 4 correspondientes su tamaño también a 0.

Ahora puedes tranquilamente sobrescribir 0x28 bytes y todo andará bien.
No olvides actualizar NumberOfSectiosn y SizeOfImage.

Si quieres guiarte aquí te subo el notepad con la sección agregada.
Código:
https://dl.dropbox.com/u/26610132/notepad%20-%20copia.exe

Sigue prácticando.

Un saludo,
Iván Portilla.


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: Hendrix en 28 Mayo 2012, 20:43 pm
Como te dije por MP, felicidades por el taller y ánimo en lo que te queda! Es realmente interesante :D Espero que la gente se anime a publicar documentos como este, sería un buen empujón para este subforo :)

Un Saludo :)


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: Belial & Grimoire en 28 Mayo 2012, 21:59 pm
hola

ya vi mis errores, me sobraban 40 bytes, quitandoselos se volvio a colocar el icono

el segundo error que note es que no coloque bien los hexa

asi lo pusiste tu

Código:
00000300

asi lo puse yo

Código:
00030000

la siguente sección hice lo mismo

Código:
00020000
Código:
00000200

solo que note que en SizeOfImage tu pusiste

Citar
00100300

y no recordaba que era la suma de SizeofImage y SizeOfRawData

Código:
00030000
00001000
00031000

00100300

y yo lo deje como

Código:
00000400

y olvide que NO son 200 decimales, son 200 en hexa y no aumente la cantidad exacta

continuare con la ultima sección a ver que tal

gracias por la ayuda


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: The Swash en 28 Mayo 2012, 22:03 pm
Hola,

Cosas que pasan mi amigo, practicad y seguro corregiréis esos pequeños pero importantes detalles. Ánimo.

Un saludo,
Iván Portilla.


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: Belial & Grimoire en 31 Mayo 2012, 02:19 am
hola

si creiste que ya te habias librado de mi, jeje te equivocas... solo que era fastidioso cambiar de particiones de linux a windows y viceversa y tuve que reacomodar todo para instalar vitualbox jeje

bueno, tengo 2 preguntas... una pregunta que ya me explicaste como 20 veces y no logro entender y otra sobre el cambio de secciones

logre cambiar la sección .text con .idata del primer programa de ejemplo que pusiste, pero el programa con VB6 tuve un problema...

en la primera aplicacion, PointerToRawData era de 00000200 y 00000400

lo cambie y quedo bien, no tuve problema de ejecutarlo y con ollydbg verfique el mapeo y esta bien

pero en el de VB6, me encontre con esto

00200000
00100000

al cambiarlo 00001000 y el otro es 00002000, tambien SizeOfRawData era de 0x1000.... y al cambiarlo me volvio a funcionar bien, pero el icono desaparecio, solo al executar el programa me aparece MessageBox, con el mensaje "hola mundo", pero como podria reaparecer el icono?

y la segunda y perdon por se tan insistente,es que no logro comprender SizeOfRawData, ya todo lo comprendi bien, agregue mi sección, pero solo en esa sección me volvi a equivocar

algo que me tiene confundido, es que yo pensaba que solo era la cantidad de sección a agregar, por ejemplo

si eran 0x17 ->0x00000017, si era 0x50 -> 0x00000050

ahora, la primera explicacion que me diste era que se alineara con FileAligment, si esa sección era 0x200, de 0x17 seria 0x200

pero en la otra explicacion me mencionas que para alinear 0x17 a FileAligment, es 0x100

y efectivamente, son 0x100 pero ya me confundi, creia que era 0x200

la verdad no entiendo como alinear

acaso, de 0x17, deberia alinarlo a 0x100? para que sea multiplo de 0x200?

y si fuera 0x50, tambien se aliena con 0x100?

y si fuera 0x201, entonces deberia agregar 0x300? o 0x400?

perdon, pero ya solo es esa sección que no entiendo como alinear, espero me puedas explicar con manzanas XD

salu2, que estes bien


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: The Swash en 31 Mayo 2012, 15:44 pm
Hola,

Mira te respondo lo primero. Acabo de hacer la prueba y en realidad con el ejecutable de Visual Basic sigue funcionando correctamente y mostrando el icono. Debes tratar de cambiar bien los valores y nada más. Además si quieres darme valores por aquí hazlo especificando a que campos se refiere y de que sección.
Te doy enlace del el ejecutable en Visual Basic al que intercambié la sección .text -> .rsrc:
Código:
https://dl.dropbox.com/u/26610132/Change.exe

En cuanto a lo segundo. He verificado y en ningún momento te he siquiera mencionado el valor 0x100, quizá si 0x1000 porque es un múltiplo de los FileAlignment con que hemos trabajado en el taller. Te vuelvo a explicar con 2 ejemplos distintos, pero la teoría es la misma, si tienes un valor, debes hacer que ese valor cumpla que (valor módulo FileAlignment) == 0. Y dicho valor no puede ser menor que el original, por lo tanto decimos que deberás alinearlo o redondearlo a su múltiplo mayor inmediato.

Ejemplo:
FileAlignment: 0x200
Valor 0x17
Si miras 0x17 módulo 0x200 = 0x17. Ya que es un valor menor, el más próximo que vas a encontrar múltiplo de 0x200 es el mismo 0x200. ya que 0x200 módulo 0x200 = 0.

Valor: 0x405
0x405 módulo 0x200 = 0x05. Es un valor mayor, pero ahora igual que en el anterior debes buscar el múltiplo mayor inmediato a 0x405 que haga que el módulo sea 0. En este caso, 0x600.

Si no lo entiendes aún te doy la siguiente fórmula, pero se trata de que tú seas capaz de entenderlo.

Aligned = (Valor + FileAlignment)-(Valor módulo FileAlignment).

Prueba:
Aligned = (0x405 + 0x200) - (0x405 módulo 0x200) => 0x605 - 0x05 = 0x600.
Aligned = (0x17 + 0x200) - (0x17 módulo 0x200) =>  0x217 - 0x17 = 0x200.
Aligned = (0x340 + 0x200) - (0x340 módulo 0x200) => 0x540 - 0x140 = 0x400.

Un saludo,
Iván Portilla.


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: Belial & Grimoire en 31 Mayo 2012, 20:16 pm
creo ya comprendi

entonces si a mi me aparece FileAligment como

00 20 00 00 -> 00 00 20 00

seria

00 00 20 17 -> 0x2017 - 0x17 = 0x2000

y si me apareciera

00 00 10 17 -> 0x1017 - 0x17 = 0x1000

acaso es asi?

pero, en el block de notas me aparece como 0x2000, entonces porque no funciona con 0x2000 y si funciona con 0x1000

porque bueno, al revisarlo, lo tengo en la posicion 11C

00 20 00 00, al agregar 0x17, entonces seria 17 20 00 00 - 0x17 = 00 20 00 00, pero de esa manera no funciona, tengo que dejarlo como 0x1000

00 10 00 00, pero porque?

y de lo de VB6, ya lo logre, movi ".Text" y ".rsrc" y si quedo bien y el icono tambien quedo bien

solo que intente mover ".Text" y ".data", e igual desaparece el mensaje, incluso ahora me aparece Messagebox, pero vacio, jeje, quien sabe porque con ese me sale raro

salu2


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: Belial & Grimoire en 1 Junio 2012, 02:14 am
hola

estaba haciendo lo mismo de cambiar secciones en el block de notas, pero una pregunta

si SizeOfRawData, no esta lineado como en tu ejemplo

Citar
Sección .text: PointerToRawData: 0x200 SizeOfRawData: 0x200
    Sección .idata: PointerToRawData: 0x400 SizeOfRawData: 0x200
    Sección .data: PointerToRawData: 0x600 SizeOfRawData: 0x200

tendria que modficar eso tambien, por ejemplo en FileAligment me aprece 0x200

pero en .text es

Código:
 .text: PointerToRawData: 00A80000 y SizeOfRawData: 00040000

y el de .reloc es

Código:
.reloc: PointerToRawData: 00100000 y SizeOfRawData: 00AE0200

en el caso de que fuece diferente, trendria que alinerlo, o que tendria que hacer?

salu2


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: The Swash en 1 Junio 2012, 02:40 am
Hola,

Estás leyendo bien los datos del ejecutable?, los punteros se se me hacen un poco altos como para el tamaño de un "notepad". Y sin duda, si esos fuesen los valores están alineados. Para verificar si un valor está alineado o no debes hacer (valor módulo FileAlignment), si esto es igual a 0, está alineado.

Un saludo,
Iván Portilla.


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: Belial & Grimoire en 1 Junio 2012, 05:24 am
si hice basicamente lo mismo que con la aplicacion VB6, el archivo queda con la misma cantidad de datos al final

Código:
0x2BE00

lo repeti varias veces para verificar que no me equivoque al cambiar los bytes, y conte poco a pco los hexa de las secciones

en la aplicacion de VB6, me salio bien, y se que practicamente es lo mismo, pero no se que podria ser ahora

mira esto es lo de la PE

Código:
000000E0 50 45 00 00 4C 01 04 00 0F C6 5B 4A 00 00 00 00 00 PE..L.....[J.....
000000F1 00 00 00 E0 00 02 01                               .......          

FileAligment

Código:
00020000

Esto es .text

Código:
000001D8 2E 74 65 78 74 00 00 00 8C A6 00 00 00 10 00 00 00 .text............
000001E9 A8 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 .................
000001FA 00 00 20 00 00 60                                  .. ..`          

este es .reloc

Código:
00000250 2E 72 65 6C 6F 63 00 00 34 0E 00 00 00 F0 02 00 00 .reloc..4........
00000261 10 00 00 00 AE 02 00 00 00 00 00 00 00 00 00 00 00 .................
00000272 00 00 40 00 00 42                                  ..@..B          

Y como te menciono, en la aplicacion de VB6 lo hice bien, pero aqui no se que podria pasar


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: The Swash en 1 Junio 2012, 05:56 am
Hola,

Si leemos los datos (recuerda lo del endian byte). Tenemos que:
  • .text:
  • VirtualAddress: 0x1000
  • VirtualSize: 0xA68C
  • PointerToRawData: 0x400
  • SizeOfRawData: 0xA800

  • .data:
  • VirtualAddress: 0xC000
  • VirtualSize: 0x2164
  • PointerToRawData: 0xAC00
  • SizeOfRawData: 0x1000

  • .rsrc:
  • VirtualAddress: 0xF000
  • VirtualSize: 0x1F160
  • PointerToRawData: 0xBC00
  • SizeOfRawData: 0x1F200

  • .reloc:
  • VirtualAddress: 0x2F000
  • VirtualSize: 0xE34
  • PointerToRawData: 0x2AE000
  • SizeOfRawData: 0x1000

Ahora resulta que los tamaños de las secciones a intercambiar no son iguales, por ende deberás "desbaratar" y rearmar todo el cuerpo del archivo. Para ello deberás trabajar con sus SizeOfRawData y cambiarles el orden, luego actualizar las cabeceras.

Si vamos a cambiar ".reloc" por ".text" primero que todo analizamos que todas las otras secciones se desplazarán debido a que ".text" es más grande.

Entonces vamos de a poco:
  • .reloc:
  • VirtualAddress: 0x1000
  • VirtualSize: 0xE34
  • PointerToRawData: 0x2AE000
  • SizeOfRawData: 0x1000

Luego seguiría:

  • .data:
  • VirtualAddress: 0xC000
  • VirtualSize: 0x2164
  • PointerToRawData: 0x2000 -> Suma de PointerToRawData y SizeOfRawData de ".reloc".
  • SizeOfRawData: 0x1000

Luego:

  • .rsrc:
  • VirtualAddress: 0xF000
  • VirtualSize: 0x1F160
  • PointerToRawData: 0x3000 -> Hacemos lo mismo con ".data".
  • SizeOfRawData: 0x1F200

Y por último:

  • .text:
  • VirtualAddress: 0x1000
  • VirtualSize: 0xA68C
  • PointerToRawData: 0x22200
  • SizeOfRawData: 0xA800

Y en base a estos datos es que debes ubicar las secciones en el cuerpo del archivo en el orden tal cual porque ese era el cambio que querías hacer.

Recuerda CUERPO DEL ARCHIVO, no en la cabecera de secciones, en la cabecera solo actualizas los nuevos valores pero no el orden.

Un saludo,
Iván Portilla.




Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: Belial & Grimoire en 2 Junio 2012, 21:47 pm
Hola

Ok creo si se tenia que modificar algunas cosas, bueno creo ahora haré el intento y como ejercicio tratare de agregar una secciona mia y vere si puedo cambiarla por. Text

Solo una última duda, porque quedo 0x1000 Reloc si la suma de la sección anterior no da. 0x1000?

Y otra pregunta, si filealigment es de 0x200 como podría estar alineado con 0xA800?

Bueno mientras haré esto y el ejercicio a ver que tal me va

Salu2


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: The Swash en 3 Junio 2012, 00:23 am
Hola,

Te explico:
Tú vas a cambiar de posición ".reloc" y ".data", el 0x1000 que ahora vale el PointerToRawData de ".reloc" sale de donde estaba ubicado ".text" recuerda que ahí es justamente donde finaliza la cabecera y empieza la primera sección.

En cuanto a lo otro:
0xA800 %(modulo, residuo) 0x200 = 0. Entonces es múltiplo.

Un saludo,
Iván Portilla.


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: Belial & Grimoire en 9 Junio 2012, 20:54 pm
hola

bueno, pues ya logre agregar al block de notas mi sección y cambiarla con .reloc

solo que cambiar la secciones del block .text, .data, .rsrc y .reloc, he tenido problemas

si cambio .data y .reloc se alinea a 0x22200, pero .text y .rsrc son muy grandes y cuando los selecciono

0x1f200 ---> .rsrc

0xA800 ----> .text

abarca mucho incluso, se selecciona parte de .data y .reloc y no puedo borralos

ahora si primero cambio .rsrc y .text pasan dos cosas

si .text tiene que quedar en 0x22200, al seleccionar y luego eliminar 0xA800 ya no queda lineado con 0x22200, y pensando que si alineo .data y .reloc se alienaria todo... pero no alcanza y lo mismo pasa con .rsrc --> 0x1f200, es muy grande y si lo elimino ya no quedan alineados

lo unico que se me ocurre, es fijarme donde quedan alineados y volver a modificar PointerToRawData con las nuevas direcciones

Aunque...

de la misma manera que hice con el ejercicio de poner mi sección y cambiarlo por otra, al modificarlo ya no queda en 0x2BE00, la nueva direccion fue 0x2B000 y con cambiar eso funciono, aunque si al intentar cambiar .text con mi sección tambien hay algo mal

0x400 ---> .text

0x2BE00 --> .BAG

al cambiarlo quedo

0x400 ---> .BAG

0x21800 --> .text

queda como 0x21800 porque al borrar A800 de 0x2CA00 se eliminan hasta quedar en 0x21800

y son 0x2CA00 por la suma de mi sección agregada

pero me dice que ya no es un aplicacion win32

creo al eliminar A800, tambien elimino parte de .data incluso tambien .rsrc, talvez por eso falla

pero entonces tendria que eliminar de A800, el tamaño de las secciones siguientes para no tocarlas?


bueno almenos, ya logre agregar mi sección y cambiarla con .reloc, jeje ahora no tuve tiempo de practicar, pero creo cada vez entiendo mas  ;-)

salu2


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: d(-_-)b en 11 Junio 2012, 22:30 pm
Exelente material muchas gracias.


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: franfis en 11 Julio 2012, 02:02 am
Muy buen tutorial, felicitaciones  ;-) , no se mucho de esto pero donde quedan las estructuras IMAGE_RESOURCE_DIRECTORY, IMAGE_RESOURCE_DIRECTORY_ENTRY, IMAGE_RESOURCE_DATA_ENTRY , _IMAGE_RESOURCE_DIRECTORY_STRING, etc, etc. No los veo ni con el Olly, ni en programas complejos como el abode acrobat los veo.

Por otro lado seria aun mas interesante que expliques que pasa con el PE header cuando el exe esta empaquetado y como desempaquetarlo.

Saludos





Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: avzila en 15 Julio 2012, 06:24 am
muy buen aporte, los tomo en cuenta gracias ....


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: Danyfirex en 12 Agosto 2012, 01:40 am
Excelente Taller. muy Bien explicado.  ;-)  Felicidades Crack


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: Danyfirex en 12 Agosto 2012, 22:43 pm
tengo una duda :S

como podria obtener el valor de SizeofinitializedData.

Osea no se que parametros tomar para actualizarlo.


Perdon por la doble respuesta.  saludos The Swash





Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: The Swash en 18 Agosto 2012, 04:13 am
Hola,

Danyfirex, para encontrar dicho campo debes primero:
  • Encontrar el valor de e_lfanew.
  • Sumarle 0x24 que corresponde a PE_SIGNATURE + SIZE_IMAGE_FILE_HEADER.
  • Luego súmale la posición del campo SizeOfInitializedData que es 0x08.
  • Ya estás en el campo que requieres.

Un saludo,
Iván Portilla.


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: Danyfirex en 21 Agosto 2012, 14:53 pm
Hola,

Danyfirex, para encontrar dicho campo debes primero:
  • Encontrar el valor de e_lfanew.
  • Sumarle 0x24 que corresponde a PE_SIGNATURE + SIZE_IMAGE_FILE_HEADER.
  • Luego súmale la posición del campo SizeOfInitializedData que es 0x08.
  • Ya estás en el campo que requieres.

Un saludo,
Iván Portilla.


Gracias. hasta ahi lo entiendo. pero realmente quiero saber como haces para actualizarlos.

Osea como lo hace to Realing PE. que parámetros tomo en cuenta para actualizarlo.

Saludos perdón por liarte tanto :S


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: Cauch en 7 Septiembre 2012, 21:06 pm
Hola gente,
Primero de todo felicitar a The Swash por ese taller tan bien escrito y estructurado :p

Hice las practicas #1 y #2 (Agregar una sección y We vs Bound Import) y después cuando quise practicar por mi cuenta, al primer intento batacazo (las prácticas me salieron bien ;)).
Resulta que el ejecutable tiene 5 secciones, añado una y ese es el resultado que yo creía que debería tener (aún me falta incluir las ‘Characteristics’):

Nota: El recuadro amarillo es la sección añadida, el recuadro que no es amarillo es la sección previa.
(http://i46.tinypic.com/258m5o9.png)

Para obtener la Virtual Adress, sumo la Virtual Adress y Virtual Size de la sección anterior, con lo cual nos queda:
0x43A0 + 0x3F000 = 0x433A0

Redondeamos el valor acuerdo con el valor de SectionAlignment, el cual es 0x1000, con lo que nos queda lo siguiente:
0x433A0 -> 0x44000

Finalmente, cuando voy a introducir el código, por ejemplo un texto que ponga ‘Hola mundo’ en la dirección 0x44000 (debería incluir 200 Bytes dado que FileAlignment = 0x200), ésta está totalmente ocupada.
De hecho la última dirección del archivo es  DF9D0.

Tiene pinta que he calculado algo mal, alguien me puede ayudar?



Una pantalla completa de todo por si las moscas
http://i50.tinypic.com/11mc3tw.png


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: The Swash en 7 Septiembre 2012, 21:23 pm
Hola,

Gracias por leer el material de he dejado.
En cuanto a tu duda temo que es porque el archivo tiene "overlay" que es información sobrante que no pertenece a ninguna sección.

Estaría bien si puedes subirlo y así lo miramos todos.

Un saludo,
Iván Portilla.


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: s7evin en 1 Octubre 2012, 15:39 pm
Buenas tardes a tod@s :)

Lo primero agradecer a The Swash por sus aportes y paciencia; he aprendido muchisimo gracias a él.

Y ahora a lo que iba... jeje
A ver si alguien puede ayudarme/guiarme... ando algo perdido.
He realizado las prácticas de este taller y he logrado el resultado esperado.
(todo desde código C/C++ en vez de editores hex)

Ahora bien, estoy intentando añadir una nueva sección donde pretendo copiar el código de un segundo ejecutable (lanza un MessageBox y ya está) para que aparezca nada más ejecutar el original y después siga con su proceso normal.

El problema está en que no se si debo añadir todas las secciones de este segundo ejecutable o tan solo una sección determinada. Si fuera solo una sección... como determino de cual se trata? (el tamaño me imagino que sabría sacarlo)

Enfin.. no me enrollo más, que me estoy liando yo sólito..
Gracias por adelantado y saludos!

PD: ya puestos a pedir... podríais explicarme las distintas secciones que se generan en los ejecutables? Porque veo que normalmente se generan las mismas: .text, .data, .rdata, .bss, .idata, etc. Son imprescindibles? Que datos contienen? Hay alguna forma de evitar que se creen tantas secciones y se genere 1 sola?


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: The Swash en 1 Octubre 2012, 18:19 pm
Hola,

Respecto a lo de agregar un ejecutable dentro de otro, si bien miraste el material y leíste un poco de teoría sabrás que la información de referencia para el lanzador, cargador de Windows se encuentra en la cabecera así que si vas a hacer eso se debe copiar todo el ejecutable. Que lo metas en una sola sección sería lo "ideal" puesto que  tu necesitas la información para hacer una ejecución "casera". Luego tienes unas dependencias de que tu mismo le tienes que dar espacio en memoria, un thread, etc.
Es aquí donde se presentan los problemas, porque además de eso debes resolver las importaciones y relocaciones.

Generalmente muchos ejecutables traen un ImageBase similar a 0x400000 y la única forma de cambiar estos campos sería teniendo una tabla .reloc en tu exe y no todos lo tienen.

Como ves que complica un poco la cosa, cualquier cosa preguntas y con gusto.

En cuanto a las secciones, son muchísimas y la mejor explicación está en el PE COFF de Microsoft, pero entonces te digo las más conocidas:

  • .text -> Sección de código ejecutable
  • .code -> Sección de código ejecutable
  • .data -> Sección de datos (variables)
  • .idata -> Sección de importación de librerías (import data)
  • .rdata -> Igual que la anterior
  • .rsrc -> Sección de recursos.
  • .reloc -> Sección de relocaciones.
  • .debug -> Sección con datos para la depuración

Y esos son los que momentáneamente recuerdo.

Saludos.


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: Newhack32 en 7 Octubre 2012, 01:12 am
la estructura IMAGE_DOS_HEADER: que acaso no tiene esto  :huh:

Código:
   IMAGE_DOS_HEADER = record lleno
     e_magic: Word; / / Número mágico ("MZ")
     e_cblp: Word; / / Bytes en la última página del archivo
     e_cp: Word; / / Artículos en el archivo
     e_crlc: Word; / / Movimientos
     e_cparhdr: Word; / / Tamaño de la cabecera en los párrafos
     e_minalloc: Word; párrafos supletorias / / mínimos necesarios
     e_maxalloc: Word; / / Máximo párrafos adicionales necesarios
     e_ss: Word; / / inicial (relativa) SS valor
     e_sp: Word, valor SP / / Inicial
     e_csum: Word; / / Suma de comprobación
     e_ip: Word, valor IP / / Inicial
     e_cs: Word; / / inicial (relativa) de valor CS
     e_lfarlc: Word; / / Dirección de la tabla de reubicación
     e_ovno: Word; / / Overlay número
     e_res: arsenal lleno [0 .. 3] de la Palabra / / palabras reservadas
     e_oemid: Word; / / OEM identificador (por e_oeminfo)
     e_oeminfo: Word; / / Información OEM; e_oemid específico
     e_res2: arsenal lleno de [0 .. 9] de la Palabra / / palabras reservadas
     e_lfanew: Entero; / / Archivo dirección del encabezado exe nuevo


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: The Swash en 7 Octubre 2012, 04:18 am
Hola,

Con todo respeto se nota mucho lo poco que has leído o al menos el poco cuidado que has prestado.

Citar
[29 WORDS] -> Aquí abreviaremos son campos poco utilizados.

Saludos.


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: s7evin en 19 Octubre 2012, 09:33 am
Buenos días a tod@s!

Estoy haciendo la última práctica, bueno de hecho ya la terminé y el ejecutable resultante funciona perfectamente.

La cuestión es que he descargado tu ejecutable final ("Practica 4 Resultado") y al examinar la estructura PE veo que hay algunas cosas que difieren del mio... por ejemplo:
Código:

   OptionalHeader->SizeOfImage = 0x3400

- No debería estar alineado a 0x4000 ?

   Sección: .idata->VirtualSize = 0x98
   Sección: .data->VirtualSize = 0x400

- ? La sección ampliada no era la .idata?? como es que le has aumentado el VirtualSize al .data en vez de al .idata?


Y ya por último... como lo has hecho para que el MessageBox coja el texto insertado al final de la sección? :S

Serias tan amable de aclararme estos puntos?

Gracias y saludos! :)
   


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: COND0R en 21 Noviembre 2012, 06:19 am
Muy bueno tu tutorial!! gracias a vos me inicie en la infectacion de PEs!!


PD: El tamaño de Characteristics en IMAGE_FILE_HEADER es de 2 bytes no de 4, aqui tienen la web de microsoft (http://msdn.microsoft.com/en-us/library/ms809762.aspx)
donde aparece el tamaño  ;D


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: COND0R en 29 Noviembre 2012, 17:49 pm
Tengo una duda... AddressOfEntryPoint es la direccion relativa donde empieza el codigo? si lo cambio por la direccion de mi sección... empesaria el programa en mi sección de codigo?? y si fuera asi luego de ejecutar mi codigo malisioso puedo hacer un salto a la sección .text donde esta el codigo del programa?? gracias de antemano  :rolleyes:


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: limiaspasdaniel en 29 Agosto 2013, 14:36 pm
Hola.. perdonar por reabrir el tema pero he estado mirando y no me queda claro lo del 0x17 , porque exactamente ese tamaño? De verdad que me he repasado el Taller unas cuantas veces y no encuentro el porque. Muchas gracias :D


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: Danyfirex en 30 Agosto 2013, 19:11 pm
Hola.. perdonar por reabrir el tema pero he estado mirando y no me queda claro lo del 0x17 , porque exactamente ese tamaño? De verdad que me he repasado el Taller unas cuantas veces y no encuentro el porque. Muchas gracias :D

porque el es tamaño que tiene la cadena TALLER DE SECCIONES EHN

23 decimal = 0x17 Hexadecimal.

saludos


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: magicboiz en 17 Enero 2014, 11:06 am
Hola "The Swash"

soy un novatillo en esto. El caso es que me estoy haciendo un script en python para "expandir" la sección .text, y siguiendo tus pasos (que seguramente no los haya seguido al 100%) no me funciona.

El problema que me encuentro, es que los DATA_DIRECTORIES que hay dentro del PE, hacen referencia a distintas secciones (.data, .idata, .rss, etc) que claro, al verse desplazadas por el incremento de .text, pues cambian sus direcciones. Eso por no hablar de los jodido que es navegar por dentro de los resource directories, sus subdirectorios....

¿Qué pista me das para resolver este tema de los DATA_DIRECTORIES y las refencias a las secciones?


gracias majo.


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: x64core en 17 Enero 2014, 21:09 pm
Hola "The Swash"

soy un novatillo en esto. El caso es que me estoy haciendo un script en python para "expandir" la sección .text, y siguiendo tus pasos (que seguramente no los haya seguido al 100%) no me funciona.

El problema que me encuentro, es que los DATA_DIRECTORIES que hay dentro del PE, hacen referencia a distintas secciones (.data, .idata, .rss, etc) que claro, al verse desplazadas por el incremento de .text, pues cambian sus direcciones. Eso por no hablar de los jodido que es navegar por dentro de los resource directories, sus subdirectorios....

¿Qué pista me das para resolver este tema de los DATA_DIRECTORIES y las refencias a las secciones?


gracias majo.

Para expandir la sección de codigo ( .text normalmente ) que es la primera sección además, y que la imagen del ejecutable quede totalmente funcional debes de incrementar a todos campos en el PE header,instrucciones que hacen referencia a las posteriores secciones de la sección objectivo el valor a incrementar a la sección alineado por SectionAlignement. Un simple ejemplo, Tenemos una imagen PE que contiene dos secciones ( .text y .data ):


Código:
        Virtual size    Virtual address     Raw size    Raw Offset
.text   0x1000          0x1000              0x1000      0x400
.data   0x1000          0x2000              0x1000      0x1400

Así, si incrementados 0x1000 bytes a la sección de codigo (.text) debes actualizar todas las secciones posteriores a esta, en este caso solo es .data.
de lo contrario se estaria generando una malformacion en la estructura ya que la primera sección tendria un nuevo tamaño de 0x2000 bytes y la sección .data se supondria que estaria cargandose desde la direccion 0x2000 lo cual es incorrecto. así debemos actualizar el Campo Virtual Address de la sección .data ( 0x2000 ) y sumarle ese valor alineado ( 0x1000 ) quedando como resultado 0x3000. Con eso actualizamos los IMAGE_SECTION_HEADER's pero en
la imagen del PE no solo se deben actualizar esas estructuras sino también DATA_DIRECTORIES->VirtualAddress, y todas las referencias que se hagan en la sección objetivo a las posteriores secciónes, por ejemplo si en la sección .text existe un instruccion como esta:

PUSH dword ptr [0x2000]

Lo cual "pushearia" los primeros cuatro bytes de la sección .data entonces tambíen se tendria que actualizar esta instrucción y todas las instrucciones que hacen referencia como dije antes. Realmente esto no es una tarea facil ya que se require una reprogramación total de la imagen y analisis del codigo tomando en cuenta además punteros a punteros:

MOV eax, dword ptr [0x2000] ; 0x2000 = 0x2000
XXX Reg,dword ptr [eax+Off]
XXX Reg,dword ptr [eax+Off]
....

Lo que podria ayudar es si la imagen PE tiene tabla de relocalización asi de evita el analisis de codigo en busca de referencias a las posteriores secciones,
así tomando la tabla de relocalización y actualizandola. A pesar de eso no realmente asegura que se obtendra una imagen totalmente funcional ya que
si el programa no esta bien estructura y por alguna razon toma en cuenta cierto campos de la imagen del PE que han sido modificados entonces tambien se tendrian que actualizar. A pesar de todo eso puedo decir que es posible.













Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: MixGammers en 19 Enero 2014, 17:52 pm
Excelente el taller, espero mas con ansias


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: magicboiz en 20 Enero 2014, 15:14 pm
x64Core

gracias por tu respuesta. Estoy intentando añadir el espacio al final de la sección .text, por lo que el código entiendo que no debiera presentar problemas no? ¿O me podría encontrar código ejecutable en las secciones .data/.idata/.rsc/etc?

Mi objetivo es simplemente hacer un hueco grande al final de la sección .text.

¿Cómo lo ves?


Para expandir la sección de codigo ( .text normalmente ) que es la primera sección además, y que la imagen del ejecutable quede totalmente funcional debes de incrementar a todos campos en el PE header,instrucciones que hacen referencia a las posteriores secciones de la sección objectivo el valor a incrementar a la sección alineado por SectionAlignement. Un simple ejemplo, Tenemos una imagen PE que contiene dos secciones ( .text y .data ):


Código:
        Virtual size    Virtual address     Raw size    Raw Offset
.text   0x1000          0x1000              0x1000      0x400
.data   0x1000          0x2000              0x1000      0x1400

Así, si incrementados 0x1000 bytes a la sección de codigo (.text) debes actualizar todas las secciones posteriores a esta, en este caso solo es .data.
de lo contrario se estaria generando una malformacion en la estructura ya que la primera sección tendria un nuevo tamaño de 0x2000 bytes y la sección .data se supondria que estaria cargandose desde la direccion 0x2000 lo cual es incorrecto. así debemos actualizar el Campo Virtual Address de la sección .data ( 0x2000 ) y sumarle ese valor alineado ( 0x1000 ) quedando como resultado 0x3000. Con eso actualizamos los IMAGE_SECTION_HEADER's pero en
la imagen del PE no solo se deben actualizar esas estructuras sino también DATA_DIRECTORIES->VirtualAddress, y todas las referencias que se hagan en la sección objetivo a las posteriores secciónes, por ejemplo si en la sección .text existe un instruccion como esta:

PUSH dword ptr [0x2000]

Lo cual "pushearia" los primeros cuatro bytes de la sección .data entonces tambíen se tendria que actualizar esta instrucción y todas las instrucciones que hacen referencia como dije antes. Realmente esto no es una tarea facil ya que se require una reprogramación total de la imagen y analisis del codigo tomando en cuenta además punteros a punteros:

MOV eax, dword ptr [0x2000] ; 0x2000 = 0x2000
XXX Reg,dword ptr [eax+Off]
XXX Reg,dword ptr [eax+Off]
....

Lo que podria ayudar es si la imagen PE tiene tabla de relocalización asi de evita el analisis de codigo en busca de referencias a las posteriores secciones,
así tomando la tabla de relocalización y actualizandola. A pesar de eso no realmente asegura que se obtendra una imagen totalmente funcional ya que
si el programa no esta bien estructura y por alguna razon toma en cuenta cierto campos de la imagen del PE que han sido modificados entonces tambien se tendrian que actualizar. A pesar de todo eso puedo decir que es posible.














Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: x64core en 20 Enero 2014, 18:36 pm
x64Core

gracias por tu respuesta. Estoy intentando añadir el espacio al final de la sección .text, por lo que el código entiendo que no debiera presentar problemas no? ¿O me podría encontrar código ejecutable en las secciones .data/.idata/.rsc/etc?

Mi objetivo es simplemente hacer un hueco grande al final de la sección .text.

¿Cómo lo ves?



Todo depende de como sea la estructura del diseño del programa y sí yo podria facilmente almacenar código/bytes en cualquier sección
y tener un puntero/dirección absoluta que indicara el inicio del código o bien guiandome en la estructura PE y tener un offset hacia el código.
De hecho la primera opción es bien usada por los compiladores cuando almacenamos datos y hacemos referencia a ellos desde la sección de código.
La segunda podria ser implementada por el programador, por lo que todo estos asuntos debes de estar considerando a la hora de modificar las secciónes de lo
contrario generarias una imagen del PE invalidad.


Título: Re: [Taller en construcción]Secciones en archivos PE.
Publicado por: kisk en 2 Abril 2017, 05:11 am
Buenas alguien sabe que archivo uso The Swash en la pirmera parte dice que es un archivo que pesa 1.5kb alguien sabe si uso c++( si usaron c++ como hizo un archivo tan pequeño ) y la api MessageBoxA o fasm? gracias
Saludos