El Formato PE, Parte 1

En esta serie de papers hablaré sobre el formato de archivo de los ejecutables del sistema Windows ya que se trata de un tema muy importante cuando se quieren analizar ciertos aspectos del funcionamiento del malware asi como del reversing de programas, áreas en las cuales me estoy iniciando. Intentaré ser conciso y terminar la serie de papers cubriendo todos los detalles que entraña dicho formato. Espero que resulte interesante también para vosotros y que seáis comprensivos conmigo ya que aun soy un novato y puede que este cometiendo errores al realizarlos. Agradeceré correcciones y mejoras sobre estos.

Empecemos...

1. Introducción al Formato PE
El formato de archivo ejecutable de un sistema operativo es en cierto modo un reflejo del propio sistema operativo. Aunque el estudio de un formato de archivo ejecutable no se tiene muy en cuenta entre la mayoria de programadores, se trata de algo importante para comprender con mas profundidad como funciona el sistema operativo.
Las siglas del Formato PE significan "Portable Executable". El Formato PE es el formato de archivo ejecutable nativo de Windows. Todos los archivos ejecutables de Windows como EXEs, DLLs, OCXs, COM, etc... usan este formato con algunas excepciones como las librerias DLL de 16 bits. Incluso los drivers en modo kernel de Windows usan este formato de archivo. Se trata de un formato cuyas especificaciones son derivadas del formato Coff de Unix. El significado de "Portable Executable" es que el formato es universal en todas las plataformas Windows: el PE Loader de toda plataforma Windows reconoce y usa este formato de archivo aun cuando la plataforma Windows en cuestión corre bajo una arquitectura distinta a la de los procesadores x86 de Intel. Esto no quiere decir que el archivo PE en cuestión sea de por si portable a otras arquitecturas sin realizar cambio alguno en él. El Formato PE es usado por Windows para almacenar los archivos ejecutables tambien conocidos como la imagen de un ejecutable. Aunque un archivo PE contiene toda la información necesaria para hacer funcionar un programa, este debe ser analizado, procesado y cargado en memoria. Este proceso implica la asignación de memoria, traslados, importaciones, etc... Así el archivo PE es sencillamente una imagen del ejecutable, del ejecutable que se refiere al programa en memoria.
Un aspecto muy útil de los archivos PE es que las estructuras de datos en disco son las mismas estructuras de datos utilizadas en memoria. Cargar un ejecutable en memoria (por ejemplo llamando a LoadLibrary) es principalmente una cuestión de asignación de ciertos rangos de un archivo PE en el espacio de direcciones en memoria. Por lo tanto una estructura de datos como IMAGE_NT_HEADERS és identica tanto en disco como en memoria.
Es importante tener en cuenta que los archivos PE no són unicamente mapeados en memoria en bloque de forma monolitica. En lugar de eso el Loader de Windows busca en el archivo y decide que porciones deben ser mapeadas en memoria. Este modo de mapear los archivos mapea los offsets mas altos del archivo en disco de modo que se correspondan con las direcciones mas altas en memoria. El offset de un elemento de un archivo en disco puede diferir del offsets una vez cargado en memoria. Sin embargo, toda la información está presente para permitir hacer una traducción del offset en disco al offset en memoria.