Ejecutable portátil

Ejecutable portátil
Extensión .exe, .dll, .ocx, .sys, .scr, .drv, .cpl, .efi, .acm, .ax, .muio.tsp
tipo MIME aplicación/vnd.microsoft.portable-ejecutable [1] y aplicación/efi [2]
Tipo de formato binario , ejecutable , objeto , biblioteca dinámica
 Archivos multimedia en Wikimedia Commons

Portable Executable  ( PE , “ejecutable portátil”) es un formato de archivos ejecutables , código objeto y bibliotecas dinámicas (DLL) que se utiliza en las versiones de 32 y 64 bits del sistema operativo Microsoft Windows . El formato PE es una estructura de datos que contiene toda la información que necesita un cargador PE para asignar un archivo a la memoria. El código ejecutable incluye enlaces para vincular bibliotecas cargadas dinámicamente, tablas de exportación e importación de API , datos de administración de recursos y datos de almacenamiento local de subprocesos ( TLS ). En los sistemas operativos de la familia Windows NT , el formato PE se utiliza para EXE , DLL , SYS (controladores de dispositivos) y otros tipos de archivos ejecutables.

PE es una versión modificada del formato de archivo COFF para Unix . PE/COFF  es un término alternativo en el desarrollo de Windows.

En los sistemas operativos de la familia Windows NT, el formato PE admite actualmente las siguientes arquitecturas de conjuntos de instrucciones : IA-32 , IA-64 y x86-64 (AMD64/Intel64). Antes de Windows 2000 , Windows NT (y por lo tanto PE) admitía MIPS , Alpha y PowerPC . Debido a que PE se usa en Windows CE , continúa admitiendo varios tipos de MIPS , ARM (incluido Thumb ) y SuperH .

Los principales competidores de PE son ELF (usado en Linux y la mayoría de las otras versiones de Unix ) y Mach-O (usado en Mac OS X ).

Breve historia

Con la llegada del sistema operativo Windows NT 3.1 , Microsoft cambió al formato PE. Todas las versiones posteriores de Windows, incluido Windows 95/98/ME, admiten este formato. El formato mantuvo un soporte limitado para el existente ( MZ ) para cerrar la brecha entre los sistemas basados ​​en DOS y los sistemas NT. Por ejemplo, los encabezados PE/COFF aún incluyen el programa ejecutable de MS-DOS, que de forma predeterminada es un código auxiliar que muestra un mensaje simple "This program cannot be run in DOS mode" : "Este programa no se puede ejecutar en modo DOS" (o similar). PE sigue sirviendo a la cambiante plataforma de Windows. Algunas extensiones incluyen el formato PE.NET (ver más abajo), una versión de 64 bits llamada PE32+ (a veces PE+) y una especificación para Windows CE.

Detalles técnicos

Firma

Los primeros 2 bytes del archivo PE contienen la firma 0x4D 0x5A - "MZ" (como sucesor del formato MZ ). A continuación, la palabra doble en el desplazamiento 0x3C contiene la dirección del encabezado PE. Este último comienza con la firma 0x50 0x45 - "PE".

Estructura

Un archivo PE consta de varios encabezados y secciones que le indican al enlazador dinámico cómo asignar el archivo a la memoria. La imagen ejecutable consta de varias áreas (secciones) diferentes, cada una de las cuales requiere diferentes derechos de acceso a la memoria; por lo tanto, el comienzo de cada sección debe estar alineado con el límite de la página. Por ejemplo, normalmente la sección .text, que contiene el código del programa, se muestra como ejecutable/de solo lectura, y la sección .data, que contiene variables globales, se muestra como no ejecutable/de lectura y escritura. Sin embargo, para no desperdiciar espacio en el disco duro, las distintas secciones no están alineadas con el límite de la página. Parte del trabajo del enlazador dinámico es asignar cada sección a la memoria por separado y asignar los permisos correctos a las áreas resultantes según lo indiquen los encabezados.

Importar tabla

Una sección muy conocida es la Tabla de direcciones de importación (IAT), que se utiliza como tabla de búsqueda cuando una aplicación llama a una función desde otro módulo. Esto se puede hacer tanto en forma de importación por función ordinal (ordinal) como de importación por nombre de función. Dado que el programa compilado no conoce la ubicación de las bibliotecas de las que depende, debe saltar indirectamente cada vez que se realiza una llamada a la API. Cuando el enlazador dinámico carga módulos y los combina, escribe las direcciones reales en el área IAT para que apunten a las ubicaciones de memoria de las funciones de biblioteca correspondientes. Si bien esto agrega un paso adicional dentro del módulo, lo que resulta en una reducción del rendimiento, proporciona un beneficio clave: se minimiza la cantidad de páginas de memoria que debe copiar el cargador al escribir, lo que genera ahorros en la memoria y el tiempo de E/S del disco. . Si el compilador sabe de antemano que la llamada será entre módulos (a través del atributo dllimport), entonces puede producir un código más optimizado que simplemente resulta en el código de operación de la llamada indirecta .

Exportar tabla

La tabla de direcciones de exportación (EAT - Tabla de direcciones de exportación) es necesaria para que un módulo (generalmente una biblioteca cargada dinámicamente ) pueda decirle a otros módulos qué funciones pueden importar desde él y en qué direcciones se encuentran estos últimos.

Tabla de movimientos

Los archivos PE no contienen código independiente de la posición . En su lugar, se compilan en una dirección base preferida y todas las direcciones generadas por el compilador/enlazador se fijan de antemano. Si el archivo PE no se puede cargar en su dirección preferida (porque otra cosa ya lo tomó), el sistema operativo lo reorganizará . Esto incluye volver a calcular cada dirección absoluta y cambiar el código para usar los nuevos valores. El descargador hace esto comparando las direcciones de descarga preferidas y reales, y calculando la diferencia . Luego, para obtener una nueva dirección de celda de memoria, esta diferencia se suma a la dirección preferida. Las direcciones de reubicación base se almacenan en una lista y se agregan a una ubicación de memoria existente según sea necesario. El código resultante ahora está separado del proceso y ya no se comparte, por lo que muchos de los beneficios de ahorro de memoria de las bibliotecas cargadas dinámicamente se pierden de esta manera. Este método también ralentiza significativamente la carga del módulo. Por esta razón, se deben evitar las rebases siempre que sea posible; por ejemplo, las bibliotecas proporcionadas por Microsoft tienen direcciones base precalculadas que no se superponen. En ausencia de una reorganización, los archivos PE tienen la ventaja de un código muy eficiente, pero en presencia de una reorganización, la sobrecarga en el uso de la memoria puede ser significativa. Esto distingue el formato PE de ELF , que utiliza un código completamente independiente de la posición y una tabla de compensación global que sacrifica el tiempo de ejecución a favor de desperdiciar memoria.

.NET, metadatos y el formato PE

La plataforma .NET de Microsoft ha ampliado el formato PE con funciones compatibles con Common Language Runtime (CLR). Las adiciones incluyen un encabezado CLR y una sección de datos CLR. Después de cargar el binario, el cargador del sistema operativo hace que se ejecute CLR a través de un enlace en la tabla de importación de PE/COFF. Luego, CLR carga el encabezado y las secciones de datos de CLR.

La sección de datos de CLR contiene dos segmentos importantes: el segmento de metadatos y el segmento de código de idioma intermedio (IL):

Uso en otros sistemas operativos

ReactOS también utiliza el formato PE , ya que ReactOS está diseñado para ser compatible binariamente con Windows a nivel de código. Además, históricamente ha sido utilizado por muchos otros sistemas operativos, incluidos SkyOS y BeOS R3. Sin embargo, tanto SkyOS como BeOS finalmente cambiaron al formato ELF.

Debido a que la plataforma de desarrollo Mono tiene la intención de ser compatible binariamente con Microsoft .NET , utiliza el mismo formato PE que la implementación de Microsoft.

En la plataforma x86 en sistemas operativos similares a Unix, algunos binarios de Windows (en formato PE) se pueden ejecutar usando Wine . HX DOS Extender también usa el formato PE para binarios nativos de DOS de 32 bits y puede ejecutar binarios de Windows existentes en DOS hasta cierto punto, actuando así como Wine para DOS.

Mac OS X 10.5 tiene la capacidad de cargar e interpretar archivos PE, sin embargo, no son compatibles binariamente con Windows.

Véase también

Notas

  1. https://www.iana.org/assignments/media-types/application/vnd.microsoft.portable-executable
  2. https://www.iana.org/assignments/media-types/application/efi

Enlaces