Tema 6

6. Formatos ejecutables: PE, ELF, secciones, imports, exports y metadatos

Antes de ejecutar una muestra, el archivo ya entrega información valiosa. Las cabeceras, secciones, imports, exports, símbolos y metadatos permiten estimar capacidades, plataforma, arquitectura, empaquetado y posibles puntos de análisis.

Objetivo Comprender la estructura básica de ejecutables PE y ELF
Enfoque Cabeceras, secciones, imports, exports y metadatos
Resultado Extraer pistas útiles sin ejecutar la muestra

6.1 Introducción

Un ejecutable no es solo una secuencia de instrucciones. Es un archivo estructurado que le indica al sistema operativo cómo cargarlo, dónde ubicar sus secciones, qué bibliotecas necesita, cuál es su punto de entrada y qué permisos requiere cada región.

En análisis de malware, revisar el formato ejecutable es una etapa temprana fundamental. Permite identificar arquitectura, tipo de archivo, dependencias, señales de empaquetado, nombres sospechosos, recursos embebidos y metadatos que orientan el resto del trabajo.

En este tema veremos PE, usado principalmente en Windows, y ELF, común en Linux y otros sistemas Unix. No necesitamos memorizar cada campo, pero sí entender qué preguntas responde cada parte del archivo.

6.2 Qué es un formato ejecutable

Un formato ejecutable define cómo se organiza un archivo que puede ser cargado y ejecutado por un sistema operativo. Incluye cabeceras, secciones, tablas, referencias a bibliotecas, información de reubicación, símbolos y otros datos necesarios para la ejecución.

El loader del sistema operativo usa esa estructura para preparar el proceso en memoria. Por eso, muchas propiedades visibles en el archivo tienen una relación directa con lo que luego veremos en un debugger o monitor de procesos.

El análisis estático comienza leyendo el archivo como estructura. Antes de preguntar "qué hace", conviene preguntar "qué tipo de archivo es y cómo está organizado".

6.3 PE y ELF en contexto

PE y ELF resuelven problemas parecidos, pero pertenecen a ecosistemas distintos. PE aparece en ejecutables, DLLs, drivers y otros binarios de Windows. ELF aparece en ejecutables, bibliotecas compartidas, objetos y componentes de Linux o Unix.

Formato Plataformas comunes Ejemplos de archivo
PE Windows .exe, .dll, .sys, .scr, .ocx
ELF Linux, BSD, Unix, sistemas embebidos Ejecutables, .so, objetos, loaders
Mach-O macOS e iOS Aplicaciones, frameworks, bibliotecas
Scripts Multiplataforma PowerShell, Bash, Python, JavaScript

Aunque este tema se centra en PE y ELF, el hábito de leer estructura, metadatos y dependencias se aplica a otros tipos de archivo.

6.4 Identificación inicial del archivo

La extensión no es confiable. Un archivo llamado documento.pdf.exe puede ocultar su naturaleza real, y una muestra puede carecer de extensión o usar una falsa. La identificación debe basarse en contenido, cabeceras y firmas.

En una inspección inicial conviene registrar:

  • Hash criptográfico de la muestra.
  • Tamaño del archivo.
  • Tipo detectado por cabecera o magic bytes.
  • Arquitectura: x86, x64, ARM u otra.
  • Plataforma esperada.
  • Fecha de compilación, si existe y si parece confiable.
  • Firmas digitales o certificados asociados.

6.5 Estructura general de un PE

Un archivo PE contiene varias estructuras que permiten a Windows cargarlo correctamente. Algunas son heredadas de compatibilidad histórica y otras son esenciales para ejecución moderna.

Parte Función Valor para el análisis
DOS Header Cabecera inicial con firma MZ Confirma formato y ubicación de cabecera PE
PE Header Identifica arquitectura y propiedades generales Indica máquina, número de secciones y características
Optional Header Datos de carga y ejecución Punto de entrada, ImageBase, subsistema y mitigaciones
Section Table Describe secciones del archivo Permisos, tamaños, nombres y posibles anomalías
Data Directories Ubica imports, exports, recursos y reubicaciones Guía hacia estructuras de interés

6.6 Campos PE importantes

No todos los campos merecen la misma atención en un triage inicial. Algunos aportan señales rápidas sobre plataforma, comportamiento esperado o rarezas.

  • Machine: indica arquitectura, por ejemplo x86 o x64.
  • NumberOfSections: cantidad de secciones; valores inusuales pueden requerir revisión.
  • TimeDateStamp: fecha de compilación, útil pero manipulable.
  • AddressOfEntryPoint: dirección relativa donde comienza la ejecución.
  • ImageBase: dirección preferida para cargar el módulo.
  • Subsystem: indica si es consola, GUI, driver u otro tipo.
  • DllCharacteristics: incluye flags relacionados con mitigaciones y comportamiento de carga.

6.7 Secciones en PE

Las secciones agrupan código, datos, recursos y otras estructuras. Cada sección tiene nombre, tamaño en archivo, tamaño en memoria, dirección relativa y permisos.

Sección común Contenido típico Qué observar
.text Código ejecutable Tamaño, entropía y permisos de ejecución
.rdata Datos de solo lectura, imports, cadenas Strings, tablas y referencias útiles
.data Datos globales modificables Configuración, buffers y estructuras
.rsrc Recursos del ejecutable Iconos, manifiestos, archivos embebidos
.reloc Información de reubicación Soporte para cargar en direcciones alternativas

Nombres extraños, secciones ejecutables y escribibles a la vez, o alta entropía pueden indicar packing, cifrado u ofuscación, aunque siempre hay que confirmar con más evidencia.

6.8 Imports en PE

La tabla de imports indica qué bibliotecas y funciones externas espera usar el ejecutable. Es una de las fuentes más útiles para inferir capacidades sin ejecutar la muestra.

Ejemplos de lectura:

  • Funciones de red pueden sugerir comunicación externa.
  • Funciones de archivos pueden sugerir lectura, escritura o borrado.
  • Funciones de registro pueden sugerir configuración o persistencia.
  • Funciones criptográficas pueden sugerir cifrado, hashing o protección de datos.
  • Funciones de procesos y memoria pueden sugerir inyección o manipulación avanzada.
Un import muestra capacidad potencial, no prueba de ejecución. Debe correlacionarse con análisis dinámico, strings, flujo de código o evidencia de comportamiento.

6.9 Exports y DLLs

Los exports son funciones que un módulo ofrece a otros programas. Son especialmente importantes en DLLs, plugins, librerías y componentes cargados por procesos externos.

Analizar exports ayuda a responder:

  • Qué funciones expone la biblioteca.
  • Si los nombres son descriptivos, genéricos u ofuscados.
  • Si hay ordinales sin nombres claros.
  • Qué función podría ser llamada por un loader o proceso legítimo.
  • Si el archivo está diseñado para ejecutarse directamente o ser cargado por otro componente.

6.10 Recursos, manifiestos y versión

Los recursos PE pueden contener iconos, diálogos, texto, configuraciones, manifiestos, archivos embebidos o datos usados por el programa. En malware, los recursos pueden usarse para ocultar payloads, señuelos o configuración cifrada.

Los metadatos de versión pueden incluir nombre de producto, compañía, descripción y número de versión. Pueden ser legítimos, falsificados o copiados de software real para parecer confiables.

  • Comparar icono, nombre interno y comportamiento esperado.
  • Revisar si hay recursos grandes o de alta entropía.
  • Detectar manifiestos que pidan privilegios elevados.
  • Contrastar metadatos con firma digital y ruta de ejecución.

6.11 Firmas digitales y confianza

Una firma digital permite verificar integridad y atribución criptográfica del archivo. Sin embargo, una firma válida no convierte automáticamente un archivo en benigno: puede haber certificados comprometidos, abuso de software legítimo o componentes firmados usados con fines maliciosos.

Aspectos a revisar:

  • Si el archivo está firmado.
  • Si la firma es válida o está rota.
  • Quién emitió el certificado y para quién.
  • Si el certificado estaba vigente al momento de firma.
  • Si el nombre del editor coincide con el contexto esperado.

6.12 Estructura general de un ELF

ELF organiza ejecutables y bibliotecas en cabeceras, program headers, section headers, segmentos, símbolos, relocaciones y tablas dinámicas. La estructura exacta depende de si el archivo es ejecutable, biblioteca compartida u objeto intermedio.

Parte Función Valor para el análisis
ELF Header Identifica formato, arquitectura y tipo Confirma plataforma, endianness y punto de entrada
Program Headers Describen segmentos para carga en memoria Permisos, mapeos y comportamiento del loader
Section Headers Describen secciones lógicas del archivo Código, datos, símbolos, strings y relocaciones
Dynamic Section Información para enlazado dinámico Bibliotecas requeridas y funciones resueltas
Symbol Tables Nombres y referencias a funciones o variables Pistas sobre lógica interna cuando no está despojado

6.13 Secciones comunes en ELF

Las secciones ELF ayudan a ubicar código, datos, tablas y metadatos. En binarios despojados, parte de esta información puede faltar, pero muchas estructuras necesarias para ejecución permanecen.

  • .text: código ejecutable.
  • .rodata: datos de solo lectura, incluidas muchas cadenas.
  • .data: datos inicializados modificables.
  • .bss: datos no inicializados reservados en memoria.
  • .plt y .got: estructuras usadas para llamadas a funciones externas.
  • .dynamic: información de enlazado dinámico.
  • .symtab y .strtab: símbolos y cadenas, si no fueron eliminados.

6.14 Imports, símbolos y bibliotecas en ELF

En ELF, las dependencias dinámicas y símbolos importados permiten inferir capacidades. Un binario que usa funciones de sockets, ejecución de comandos, criptografía o manipulación de archivos puede orientar la investigación.

La diferencia entre un binario con símbolos y uno despojado es importante. Si conserva nombres de funciones, variables o rutas de compilación, el análisis inicial será más directo. Si está stripped, el analista deberá apoyarse más en strings, imports, flujo y comportamiento dinámico.

6.15 Punto de entrada

El punto de entrada indica dónde comienza la ejecución cuando el loader transfiere control al programa. En PE suele encontrarse como AddressOfEntryPoint; en ELF aparece en la cabecera como entry point.

En malware empaquetado, el punto de entrada suele apuntar al stub del packer, no al código original del programa. Por eso, el entry point es importante, pero no siempre representa la lógica principal.

Durante debugging, iniciar en el punto de entrada permite observar desempaquetado, resolución dinámica de APIs, verificaciones del entorno y preparación antes de llegar al comportamiento principal.

6.16 Entropía y señales de empaquetado

La entropía mide, de forma aproximada, qué tan aleatorios parecen los datos. Secciones con entropía alta pueden contener datos comprimidos, cifrados o empaquetados. Esto es común en malware, pero también aparece en software legítimo protegido o comprimido.

Señales que merecen revisión:

  • Muy pocos imports visibles.
  • Secciones con nombres extraños o generados.
  • Secciones ejecutables y escribibles al mismo tiempo.
  • Entry point ubicado en una sección no habitual.
  • Alta entropía en secciones grandes.
  • Strings escasas para el tamaño del archivo.
Alta entropía no significa malware. Significa que conviene investigar si hay compresión, cifrado, packing u ofuscación.

6.17 Relocaciones y carga en memoria

Las relocaciones permiten ajustar direcciones cuando un binario no se carga en su dirección preferida. Esto se relaciona con ASLR y con cómo el loader prepara el proceso.

En análisis, las relocaciones importan porque el archivo en disco y la imagen en memoria no siempre coinciden byte a byte. Direcciones relativas, bases de carga y offsets deben interpretarse correctamente para no confundir ubicaciones.

La distinción entre offset de archivo, dirección virtual relativa y dirección virtual absoluta aparecerá con frecuencia en debugging y reversing.

6.18 Offset de archivo, RVA y VA

En PE se habla mucho de offset de archivo, RVA y VA. Entender la diferencia evita errores al saltar entre una herramienta de análisis estático y un debugger.

Concepto Significado Uso
File offset Posición dentro del archivo en disco Editar o ubicar bytes en el archivo
RVA Dirección relativa a la base de imagen Ubicar estructuras dentro de la imagen cargada
VA Dirección virtual real en memoria Debugging y ejecución en proceso

La conversión entre estos valores depende de secciones, base de carga y alineación.

6.19 Metadatos útiles para triage

Los metadatos no prueban por sí solos si algo es malicioso, pero ayudan a priorizar y formular hipótesis.

  • Hash, tamaño y tipo exacto de archivo.
  • Arquitectura y subsistema.
  • Fecha de compilación y coherencia con otros artefactos.
  • Nombre interno, descripción, compañía y versión.
  • Firmas digitales y certificados.
  • Número, nombres, tamaños y permisos de secciones.
  • Imports, exports, recursos y strings destacadas.
  • Indicadores de packing u ofuscación.

6.20 Limitaciones del análisis del formato

Leer el formato ejecutable es una etapa potente, pero incompleta. Un archivo puede ocultar imports, cifrar strings, resolver APIs en tiempo de ejecución, descargar componentes o comportarse de forma distinta según el entorno.

Limitaciones comunes:

  • Metadatos falsificados o manipulados.
  • Fechas de compilación poco confiables.
  • Imports mínimos por packing o resolución dinámica.
  • Secciones modificadas por protectores legítimos.
  • Recursos cifrados o comprimidos.
  • Comportamiento condicionado por red, idioma, usuario o VM.

Por eso, el análisis del formato debe combinarse con strings, desensamblado, debugging y análisis dinámico cuando corresponda.

6.21 Checklist de análisis inicial

  1. Calcular hashes y registrar tamaño.
  2. Confirmar tipo de archivo por cabecera, no por extensión.
  3. Identificar arquitectura y plataforma.
  4. Revisar cabeceras principales y punto de entrada.
  5. Enumerar secciones, tamaños, permisos y entropía aproximada.
  6. Revisar imports, exports, símbolos y bibliotecas.
  7. Examinar recursos, metadatos de versión y firma digital.
  8. Buscar señales de packing, ofuscación o anomalías estructurales.
  9. Registrar hipótesis para confirmar con análisis posterior.

6.22 Errores frecuentes

  • Confiar en la extensión del archivo.
  • Tratar una fecha de compilación como verdad absoluta.
  • Concluir comportamiento solo por imports sin evidencia adicional.
  • Confundir offset de archivo con dirección en memoria.
  • Asumir que toda alta entropía implica malware.
  • Ignorar recursos y metadatos porque no son código ejecutable directo.
  • No registrar hashes antes de manipular o transferir la muestra.

6.23 Qué debes recordar de este tema

  • PE y ELF describen cómo un binario debe cargarse y ejecutarse.
  • Cabeceras, secciones, imports, exports y metadatos ofrecen pistas sin ejecutar la muestra.
  • Imports y símbolos sugieren capacidades, pero no prueban comportamiento ejecutado.
  • Alta entropía, pocos imports o secciones extrañas pueden indicar packing u ofuscación.
  • Distinguir archivo en disco de imagen en memoria es esencial para debugging y reversing.

6.24 Conclusión

El formato ejecutable es la primera capa técnica de un binario. Leerlo bien permite orientar el análisis, detectar anomalías, preparar el entorno de debugging y formular hipótesis antes de correr cualquier código.

En el próximo tema estudiaremos la clasificación de malware: troyanos, ransomware, spyware, worms, rootkits y loaders, para conectar estructura técnica con objetivos y comportamientos típicos.