Formato PE
Esta especificación describe la estructura de los archivos ejecutables (imagen) y los archivos objeto en la familia de sistemas operativos Windows. Estos archivos se conocen como archivo portable ejecutable (PE) y formato de archivo de objeto común (COFF), respectivamente.
Nota:
Este documento se proporciona para ayudar en el desarrollo de herramientas y aplicaciones para Windows, pero no se garantiza que sea una especificación completa en todos los aspectos. Microsoft se reserva el derecho de modificar este documento sin previo aviso.
Esta revisión de la especificación de archivo portable ejecutable y formato de archivo de objeto común de Microsoft reemplaza todas las revisiones anteriores de esta especificación.
Conceptos generales
En este documento se especifica la estructura de los archivos ejecutables (imagen) y los archivos de objeto en la familia de sistemas operativos Windows. Estos archivos se conocen como archivo portable ejecutable (PE) y formato de archivo de objeto común (COFF), respectivamente. El nombre "portable ejecutable" se refiere al hecho de que el formato no es específico de la arquitectura.
Algunos conceptos que aparecen a lo largo de esta especificación se describen en la siguiente tabla:
Nombre | Descripción |
---|---|
certificado de atributo |
Certificado que se usa para asociar instrucciones verificables a una imagen. Se pueden asociar varias instrucciones verificables diferentes a un archivo; uno de los más útiles es una instrucción de un fabricante de software que indica cuál se espera que sea la síntesis del mensaje de la imagen. Una síntesis de mensaje es similar a una suma de comprobación, excepto que es extremadamente difícil de falsificar. Por lo tanto, es muy difícil modificar un archivo para que tenga la misma síntesis de mensaje que el archivo original. La instrucción se puede verificar como realizada por el fabricante mediante esquemas criptográficos de clave pública o privada. Este documento describe detalles sobre los certificados de atributos distintos de permitir su inserción en archivos de imagen. |
marca de fecha/hora |
Marca que se usa con distintos fines en varios lugares de un archivo PE o COFF. En la mayoría de los casos, el formato de cada marca es el mismo que el usado por las funciones de tiempo de la biblioteca de tiempo de ejecución de C. Para conocer las excepciones, consulte la descripción de IMAGE_DEBUG_TYPE_REPRO en Tipo de depuración. Si el valor de la marca es 0 o 0xFFFFFFFF, no representa una marca de fecha y hora real o significativa. |
puntero de archivo |
La ubicación de un elemento dentro del propio archivo, antes de ser procesado por el enlazador (en el caso de los archivos de objeto) o el cargador (en el caso de los archivos de imagen). En otras palabras, se trata de una posición dentro del archivo tal y como está almacenado en el disco. |
enlazador |
Referencia al enlazador que se proporciona con Microsoft Visual Studio. |
archivo de objeto |
Archivo que se proporciona como entrada al enlazador. El enlazador genera un archivo de imagen que, a su vez, el cargador usa como entrada. El término "archivo de objeto" no implica necesariamente ninguna conexión a la programación orientada a objetos. |
reservado, debe ser 0 |
Descripción de un campo que indica que el valor del campo debe ser cero para los generadores y los consumidores deben omitir el campo. |
Dirección relativa virtual (RVA) |
Esta especificación describe la estructura de los archivos ejecutables (imagen) y los archivos objeto en la familia de sistemas operativos Windows. La RVA de un elemento casi siempre difiere de su posición dentro del archivo en disco (puntero de archivo). En un archivo de objeto, una RVA es menos significativa porque no se asignan ubicaciones de memoria. En este caso, una RVA sería una dirección dentro de una sección (descrita más adelante en esta tabla), a la que se aplica una reubicación más adelante durante la vinculación. Para simplificar, el compilador solo debería establecer en cero la primera RVA de cada sección. |
sección |
Unidad básica de código o datos dentro de un archivo PE o COFF. Por ejemplo, todo el código de un archivo objeto se puede combinar dentro de una sola sección o (dependiendo del comportamiento del compilador) cada función puede ocupar su propia sección. Con más secciones, hay más sobrecarga de archivos, pero el enlazador puede enlazar en código de forma más selectiva. Una sección es similar a un segmento de la arquitectura Intel 8086. Todos los datos sin procesar de una sección deben cargarse de forma contigua. Además, un archivo de imagen puede contener una serie de secciones, tales como .tls o .reloc, que tienen propósitos especiales. |
Dirección virtual (VA) |
Igual que una RVA, excepto que no se resta la dirección base del archivo de imagen. La dirección se denomina VA porque Windows crea un espacio VA distinto para cada proceso, independientemente de la memoria física. Para casi todos los propósitos, una VA debe considerarse solo una dirección. Una VA no es tan predecible como una RVA porque es posible que el cargador no cargue la imagen en su ubicación preferida. |
Información general
En la lista siguiente se describe el formato ejecutable de Microsoft PE, con la base del encabezado de la imagen en la parte superior. La sección desde el encabezado EXE compatible con MS-DOS 2.0 hasta la sección no usada justo antes del encabezado PE es la sección MS-DOS 2.0 y se usa solo para la compatibilidad con MS-DOS.
Encabezado EXE compatible con MS-DOS 2.0
no se usa
Identificador de OEM
Información de OEM
Desplazamiento al encabezado PE
Programa de código auxiliar de MS-DOS 2.0 y tabla de reubicación
no se usa
Encabezado PE (alineado en el límite de 8 bytes)
Encabezados de sección
Páginas de imágenes:
información de importación
información de exportación
reubicaciones base
información de recursos
En la siguiente lista se describe el formato de módulo de objeto COFF de Microsoft:
Encabezado COFF de Microsoft
Encabezados de sección
Datos sin formato:
code
data
información de depuración
reubicaciones
Encabezados de archivo
- Código auxiliar de MS-DOS (solo imagen)
- Firma (solo imagen)
- Encabezado de archivo COFF (objeto e imagen)
- Encabezado opcional (solo imagen)
El encabezado de archivo PE consta de un código auxiliar MS-DOS de Microsoft, la firma de PE, el encabezado de archivo COFF y un encabezado opcional. Un encabezado de archivo de objeto COFF consta de un encabezado de archivo COFF y un encabezado opcional. En ambos casos, los encabezados de archivo van seguidos inmediatamente de encabezados de sección.
Código auxiliar de MS-DOS (solo imagen)
El código auxiliar de MS-DOS es una aplicación válida que se ejecuta en MS-DOS. Se coloca en la parte frontal de la imagen EXE. El enlazador coloca aquí un código auxiliar predeterminado, que imprime el mensaje "Este programa no se puede ejecutar en modo DOS" cuando la imagen se ejecuta en MS-DOS. El usuario puede especificar otro código auxiliar mediante la opción del enlazador /STUB.
En la ubicación 0x3c, el código auxiliar tiene el desplazamiento de archivo a la firma de PE. Esta información permite a Windows ejecutar correctamente el archivo de imagen, aunque tenga un código auxiliar MS-DOS. Este desplazamiento de archivo se coloca en la ubicación 0x3c durante la vinculación.
Firma (solo imagen)
Después del código auxiliar MS-DOS, en el desplazamiento de archivo especificado en la ubicación 0x3c del desplazamiento, existe una firma de 4 bytes que identifica el archivo como un archivo de imagen con formato PE. Esta firma es "PE\0\0" (las letras "P" y "E" seguidas de dos bytes nulos).
Encabezado de archivo COFF (objeto e imagen)
Al principio de un archivo objeto, o inmediatamente después de la firma de un archivo de imagen, hay un encabezado de archivo COFF estándar en el siguiente formato. Tenga en cuenta que el cargador de Windows limita el número de secciones a 96.
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
2 |
Máquina |
El número que identifica el tipo de máquina de destino. Para obtener más información, consulte Tipos de máquinas. |
2 |
2 |
NumberOfSections |
El número de secciones. Esto indica el tamaño de la tabla de la secciones, que sigue inmediatamente a los encabezados. |
4 |
4 |
TimeDateStamp |
Los 32 bits bajos del número de segundos desde las 00:00 del 1 de enero de 1970 (un valor time_t en tiempo de ejecución de C), que indica cuándo se creó el archivo. |
8 |
4 |
PointerToSymbolTable |
Desplazamiento de archivo de la tabla de símbolos COFF o cero si no hay ninguna tabla de símbolos COFF presente. Este valor debe ser cero para una imagen porque la información de depuración de COFF está en desuso. |
12 |
4 |
NumberOfSymbols |
Número de entradas en la tabla de símbolos. Estos datos se pueden usar para buscar la tabla de cadenas, que sigue inmediatamente a la tabla de símbolos. Este valor debe ser cero para una imagen porque la información de depuración de COFF está en desuso. |
16 |
2 |
SizeOfOptionalHeader |
El tamaño del encabezado opcional, que es necesario para los archivos ejecutables, pero no para los archivos objeto. Este valor debe ser cero para un archivo objeto. Para obtener una descripción del formato de encabezado, consulte Encabezado opcional (solo imagen). |
18 |
2 |
Características |
Marcas que indican los atributos del archivo. Para conocer los valores de marca específicos, consulte Características. |
Tipos de máquinas
El campo Máquina tiene uno de los siguientes valores, que especifican el tipo de CPU. Un archivo de imagen solo se puede ejecutar en la máquina especificada o en un sistema que emule la máquina especificada.
Constante | Value | Descripción |
---|---|---|
IMAGE_FILE_MACHINE_UNKNOWN |
0x0 |
Se supone que el contenido de este campo es aplicable a cualquier tipo de máquina |
IMAGE_FILE_MACHINE_ALPHA |
0x184 |
Alpha AXP, espacio de direcciones de 32 bits |
IMAGE_FILE_MACHINE_ALPHA64 |
0x284 |
Alpha 64, espacio de direcciones de 64 bits |
IMAGE_FILE_MACHINE_AM33 |
0x1d3 |
Matsushita AM33 |
IMAGE_FILE_MACHINE_AMD64 |
0x8664 |
x64 |
IMAGE_FILE_MACHINE_ARM |
0x1c0 |
ARM little endian |
IMAGE_FILE_MACHINE_ARM64 |
0xaa64 |
ARM64 little endian |
IMAGE_FILE_MACHINE_ARMNT |
0x1c4 |
ARM Thumb-2 little endian |
IMAGE_FILE_MACHINE_AXP64 |
0x284 |
AXP 64 (igual que Alpha 64) |
IMAGE_FILE_MACHINE_EBC |
0xebc |
EFI byte code |
IMAGE_FILE_MACHINE_I386 |
0x14c |
Procesadores Intel 386 o posteriores y procesadores compatibles |
IMAGE_FILE_MACHINE_IA64 |
0x200 |
Familia de procesadores Intel Itanium |
IMAGE_FILE_MACHINE_LOONGARCH32 |
0x6232 |
Familia de procesadores LoongArch de 32 bits |
IMAGE_FILE_MACHINE_LOONGARCH64 |
0x6264 |
Familia de procesadores LoongArch de 64 bits |
IMAGE_FILE_MACHINE_M32R |
0x9041 |
Mitsubishi M32R little endian |
IMAGE_FILE_MACHINE_MIPS16 |
0x266 |
MIPS16 |
IMAGE_FILE_MACHINE_MIPSFPU |
0x366 |
MIPS con FPU |
IMAGE_FILE_MACHINE_MIPSFPU16 |
0x466 |
MIPS16 con FPU |
IMAGE_FILE_MACHINE_POWERPC |
0x1f0 |
Power PC little endian |
IMAGE_FILE_MACHINE_POWERPCFP |
0x1f1 |
Power PC con compatibilidad con punto flotante |
IMAGE_FILE_MACHINE_R4000 |
0x166 |
MIPS little endian |
IMAGE_FILE_MACHINE_RISCV32 |
0x5032 |
Espacio de direcciones de RISC-V de 32 bits |
IMAGE_FILE_MACHINE_RISCV64 |
0x5064 |
Espacio de direcciones de RISC-V de 64 bits |
IMAGE_FILE_MACHINE_RISCV128 |
0x5128 |
Espacio de direcciones de RISC-V de 128 bits |
IMAGE_FILE_MACHINE_SH3 |
0x1a2 |
Hitachi SH3 |
IMAGE_FILE_MACHINE_SH3DSP |
0x1a3 |
Hitachi SH3 DSP |
IMAGE_FILE_MACHINE_SH4 |
0x1a6 |
Hitachi SH4 |
IMAGE_FILE_MACHINE_SH5 |
0x1a8 |
Hitachi SH5 |
IMAGE_FILE_MACHINE_THUMB |
0x1c2 |
Thumb |
IMAGE_FILE_MACHINE_WCEMIPSV2 |
0x169 |
MIPS little-endian WCE v2 |
Características
El campo Características contiene marcas que indican atributos del archivo de objeto o imagen. Actualmente están definidas las marcas siguientes:
Marca | Value | Descripción |
---|---|---|
IMAGE_FILE_RELOCS_STRIPPED |
0x0001 |
Solo imagen, Windows CE y Microsoft Windows NT y versiones posteriores. Esto indica que el archivo no contiene reubicaciones base y, por lo tanto, debe cargarse en su dirección base preferida. Si la dirección base no está disponible, el cargador informa de un error. El comportamiento predeterminado del vinculador es eliminar las reubicaciones base de los archivos ejecutables (EXE). |
IMAGE_FILE_EXECUTABLE_IMAGE |
0x0002 |
Solo imagen. Esto indica que el archivo de imagen es válido y se puede ejecutar. Si no se establece esta marca, indica un error del vinculador. |
IMAGE_FILE_LINE_NUMS_STRIPPED |
0x0004 |
Se han eliminado los números de línea COFF. Esta marca está en desuso y debe ser cero. |
IMAGE_FILE_LOCAL_SYMS_STRIPPED |
0x0008 |
Se han eliminado las entradas de tabla de símbolos COFF para símbolos locales. Esta marca está en desuso y debe ser cero. |
IMAGE_FILE_AGGRESSIVE_WS_TRIM |
0x0010 |
Obsoleto. Recorte agresivo del conjunto de trabajo. Esta marca está en desuso para Windows 2000 y versiones posteriores y debe ser cero. |
IMAGE_FILE_LARGE_ADDRESS_ AWARE |
0x0020 |
La aplicación puede manejar > direcciones de 2 GB. |
0x0040 |
Esta marca está reservada para un uso futuro. |
|
IMAGE_FILE_BYTES_REVERSED_LO |
0x0080 |
Little endian: el bit menos significativo (LSB) precede al bit más significativo (MSB) en la memoria. Esta marca está en desuso y debe ser cero. |
IMAGE_FILE_32BIT_MACHINE |
0x0100 |
La máquina se basa en una arquitectura de 32 bits. |
IMAGE_FILE_DEBUG_STRIPPED |
0x0200 |
La información de depuración se elimina del archivo de imagen. |
IMAGE_FILE_REMOVABLE_RUN_ FROM_SWAP |
0x0400 |
Si la imagen está en un medio extraíble, cárguela completamente y cópiela en el archivo de intercambio. |
IMAGE_FILE_NET_RUN_FROM_SWAP |
0x0800 |
Si la imagen está en medios de red, cárguela completamente y cópiela en el archivo de intercambio. |
IMAGE_FILE_SYSTEM |
0x1000 |
El archivo de imagen es un archivo del sistema, no un programa de usuario. |
IMAGE_FILE_DLL |
0x2000 |
El archivo de imagen es una biblioteca de vínculos dinámicos (DLL). Estos archivos se consideran ejecutables a casi todos los efectos, aunque no se pueden ejecutar directamente. |
IMAGE_FILE_UP_SYSTEM_ONLY |
0x4000 |
El archivo solo debe ejecutarse en una máquina de un solo procesador. |
IMAGE_FILE_BYTES_REVERSED_HI |
0x8000 |
Big endian: el MSB precede al LSB en la memoria. Esta marca está en desuso y debe ser cero. |
Encabezado opcional (solo imagen)
Cada archivo de imagen tiene un encabezado opcional que proporciona información al cargador. Este encabezado es opcional en el sentido de que algunos archivos (específicamente, archivos objeto) no lo tienen. Para los archivos de imagen, este encabezado es obligatorio. Un archivo objeto puede tener un encabezado opcional, pero generalmente este encabezado no tiene ninguna función en un archivo objeto, excepto aumentar su tamaño.
Tenga en cuenta que el tamaño del encabezado opcional no es fijo. El campo SizeOfOptionalHeader del encabezado COFF debe usarse para validar que un sondeo en el archivo de un directorio de datos determinado no vaya más allá de SizeOfOptionalHeader. Para obtener más información, consulte Encabezado de archivo COFF (objeto e imagen).
El campo NumberOfRvaAndSizes del encabezado opcional también debe usarse para asegurarse de que ningún sondeo de una entrada del directorio de datos determinado vaya más allá del encabezado opcional. Además, es importante validar el número mágico de encabezado opcional para la compatibilidad de formatos.
El número mágico de encabezado opcional determina si una imagen es un ejecutable PE32 o PE32+.
Número mágico | Formato PE |
---|---|
0x10b |
PE32 |
0x20b |
PE32+ |
Las imágenes PE32+ permiten un espacio de direcciones de 64 bits al tiempo que limitan el tamaño de la imagen a 2 gigabytes. Otras modificaciones de PE32+ se abordan en sus respectivas secciones.
El encabezado opcional en sí tiene tres partes principales.
Desplazamiento (PE32/PE32+) | Tamaño (PE32/PE32+) | Parte de encabezado | Descripción |
---|---|---|---|
0 |
28/24 |
Campos estándar |
Campos definidos para todas las implementaciones de COFF, incluido UNIX. |
28/24 |
68/88 |
Campos específicos de Windows |
Campos adicionales para admitir características específicas de Windows (por ejemplo, subsistemas). |
96/112 |
Variable |
Directorios de datos |
Los pares de dirección/tamaño de las tablas especiales que se encuentran en el archivo de imagen las usa el sistema operativo (por ejemplo, la tabla de importación y la tabla de exportación). |
Campos estándar de encabezado opcionales (solo imagen)
Los ocho primeros campos del encabezado opcional son campos estándar definidos para cada implementación de COFF. Estos campos contienen información general que resulta útil para cargar y ejecutar un archivo ejecutable. No se modifican para el formato PE32+.
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
2 |
Magic |
Entero sin signo que identifica el estado del archivo de imagen. El número más común es 0x10B, que lo identifica como un archivo ejecutable normal. 0x107 lo identifica como una imagen de ROM y 0x20B lo identifica como un ejecutable PE32+. |
2 |
1 |
MajorLinkerVersion |
El número de versión principal del enlazador. |
3 |
1 |
MinorLinkerVersion |
El número de versión secundaria del enlazador. |
4 |
4 |
SizeOfCode |
El tamaño de la sección de código (texto) o la suma de todas las secciones de código si hay varias secciones. |
8 |
4 |
SizeOfInitializedData |
El tamaño de la sección de datos inicializada o la suma de todas esas secciones, si hay varias secciones de datos. |
12 |
4 |
SizeOfUninitializedData |
El tamaño de la sección de datos no inicializados (BSS) o la suma de todas esas secciones si hay varias secciones BSS. |
16 |
4 |
AddressOfEntryPoint |
La dirección del punto de entrada relativa a la base de la imagen cuando el archivo ejecutable se carga en la memoria. En el caso de las imágenes de programa, esta es la dirección de inicio. En el caso de los controladores de dispositivo, esta es la dirección de la función de inicialización. Un punto de entrada es opcional para los archivos DLL. Cuando no hay ningún punto de entrada, este campo debe ser cero. |
20 |
4 |
BaseOfCode |
Dirección relativa a la base de imagen de la sección de inicio de código cuando se carga en memoria. |
PE32 contiene este campo adicional, que está ausente en PE32+, después de BaseOfCode.
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
24 |
4 |
BaseOfData |
Dirección relativa a la base de imagen de la sección de inicio de datos cuando se carga en memoria. |
Campos opcionales específicos de Windows de encabezado (solo imagen)
Los siguientes 21 campos son una extensión para el formato de encabezado opcional COFF. Contienen información adicional que requiere tanto el enlazador como el cargador en Windows.
Desplazamiento (PE32/PE32+) | Tamaño (PE32/PE32+) | Campo | Descripción |
---|---|---|---|
28/24 |
4/8 |
ImageBase |
Dirección preferida del primer byte de la imagen cuando se carga en la memoria; debe ser un múltiplo de 64 K. El valor predeterminado para los archivos DLL es 0x10000000. El valor predeterminado para los EXE de Windows CE es 0x00010000. El valor predeterminado para Windows NT, Windows 2000, Windows XP, Windows 95, Windows 98 y Windows Me es 0x00400000. |
32/32 |
4 |
SectionAlignment |
La alineación (en bytes) de las secciones cuando se cargan en la memoria. Debe ser mayor o igual que FileAlignment. El valor predeterminado es el tamaño de página de la arquitectura. |
36/36 |
4 |
FileAlignment |
El factor de alineación (en bytes) que se usa para alinear los datos sin procesar de las secciones del archivo de imagen. El valor debe ser una potencia de 2 entre 512 y 64 K, ambos inclusive. El valor predeterminado es 512. Si SectionAlignment es menor que el tamaño de página de la arquitectura, FileAlignment debe coincidir con SectionAlignment. |
40/40 |
2 |
MajorOperatingSystemVersion |
El número de versión principal del sistema operativo obligatorio. |
42/42 |
2 |
MinorOperatingSystemVersion |
El número de versión secundaria del sistema operativo obligatorio. |
44/44 |
2 |
MajorImageVersion |
El número de versión principal de la imagen. |
46/46 |
2 |
MinorImageVersion |
El número de versión secundaria de la imagen. |
48/48 |
2 |
MajorSubsystemVersion |
El número de versión principal del subsistema. |
50/50 |
2 |
MinorSubsystemVersion |
El número de versión secundaria del subsistema. |
52/52 |
4 |
Win32VersionValue |
Reservado, debe ser cero. |
56/56 |
4 |
SizeOfImage |
Tamaño (en bytes) de la imagen, incluidos todos los encabezados, a medida que la imagen se carga en la memoria. Debe ser un múltiplo de SectionAlignment. |
60/60 |
4 |
SizeOfHeaders |
Tamaño combinado de un código auxiliar de MS DOS, un encabezado PE y encabezados de sección redondeados a un múltiplo de FileAlignment. |
64/64 |
4 |
CheckSum |
Suma de comprobación del archivo de imagen. El algoritmo para calcular la suma de comprobación se incorpora en IMAGHELP.DLL. A continuación se comprueba la validación en tiempo de carga: todos los controladores, cualquier DLL cargado en tiempo de arranque y cualquier DLL que se cargue en un proceso crítico de Windows. |
68/68 |
2 |
Subsystem |
El subsistema necesario para ejecutar esta imagen. Para obtener más información, consulte Subsistema de Windows. |
70/70 |
2 |
DllCharacteristics |
Para obtener más información, consulte Características de DLL más adelante en esta especificación. |
72/72 |
4/8 |
SizeOfStackReserve |
El tamaño de la pila que se va a reservar. Solo se confirma SizeOfStackCommit; el resto se pone a disposición página a página hasta alcanzar el tamaño de reserva. |
76/80 |
4/8 |
SizeOfStackCommit |
El tamaño de la pila que se va a confirmar. |
80/88 |
4/8 |
SizeOfHeapReserve |
El tamaño del espacio de montón local que se va a reservar. Solo se confirma SizeOfHeapCommit; el resto se pone a disposición página a página hasta alcanzar el tamaño de reserva. |
84/96 |
4/8 |
SizeOfHeapCommit |
El tamaño del espacio de montón local que se va a confirmar. |
88/104 |
4 |
LoaderFlags |
Reservado, debe ser cero. |
92/108 |
4 |
NumberOfRvaAndSizes |
Número de entradas del directorio de datos en el resto del encabezado opcional. Cada una describe una ubicación y un tamaño. |
Subsistema de Windows
Los siguientes valores definidos para el campo Subsistema del encabezado opcional determinan qué subsistema de Windows (si existe) se necesita para ejecutar la imagen.
Constante | Value | Descripción |
---|---|---|
IMAGE_SUBSYSTEM_UNKNOWN |
0 |
Subsistema desconocido |
IMAGE_SUBSYSTEM_NATIVE |
1 |
Controladores de dispositivos y procesos nativos de Windows |
IMAGE_SUBSYSTEM_WINDOWS_GUI |
2 |
Subsistema de interfaz gráfica de usuario (GUI) de Windows |
IMAGE_SUBSYSTEM_WINDOWS_CUI |
3 |
Subsistema de caracteres de Windows |
IMAGE_SUBSYSTEM_OS2_CUI |
5 |
Subsistema de caracteres OS/2 |
IMAGE_SUBSYSTEM_POSIX_CUI |
7 |
Subsistema de caracteres Posix |
IMAGE_SUBSYSTEM_NATIVE_WINDOWS |
8 |
Controlador Win9x nativo |
IMAGE_SUBSYSTEM_WINDOWS_CE_GUI |
9 |
Windows CE |
IMAGE_SUBSYSTEM_EFI_APPLICATION |
10 |
Aplicación Extensible Firmware Interface (EFI) |
IMAGE_SUBSYSTEM_EFI_BOOT_ SERVICE_DRIVER |
11 |
Controlador EFI con servicios de arranque |
IMAGE_SUBSYSTEM_EFI_RUNTIME_ DRIVER |
12 |
Controlador EFI con servicios en tiempo de ejecución |
IMAGE_SUBSYSTEM_EFI_ROM |
13 |
Imagen de ROM EFI |
IMAGE_SUBSYSTEM_XBOX |
14 |
XBOX |
IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION |
16 |
Aplicación de arranque de Windows. |
Características de DLL
Los siguientes valores se definen para el campo DllCharacteristics del encabezado opcional.
Constante | Value | Descripción |
---|---|---|
0x0001 |
Reservado, debe ser cero. |
|
0x0002 |
Reservado, debe ser cero. |
|
0x0004 |
Reservado, debe ser cero. |
|
0x0008 |
Reservado, debe ser cero. |
|
IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA |
0x0020 |
La imagen puede controlar un espacio de direcciones virtuales de alta entropía de 64 bits. |
IMAGE_DLLCHARACTERISTICS_ DYNAMIC_BASE |
0x0040 |
El archivo DLL se puede reubicar en tiempo de carga. |
IMAGE_DLLCHARACTERISTICS_ FORCE_INTEGRITY |
0x0080 |
Se aplican comprobaciones de integridad de código. |
IMAGE_DLLCHARACTERISTICS_ NX_COMPAT |
0x0100 |
La imagen es compatible con NX. |
IMAGE_DLLCHARACTERISTICS_ NO_ISOLATION |
0x0200 |
Con reconocimiento de aislamiento, pero no aísla la imagen. |
IMAGE_DLLCHARACTERISTICS_ NO_SEH |
0x0400 |
No usa el control de excepciones estructuradas (SE). No se puede llamar a ningún controlador SE en esta imagen. |
IMAGE_DLLCHARACTERISTICS_ NO_BIND |
0x0800 |
No enlace la imagen. |
IMAGE_DLLCHARACTERISTICS_APPCONTAINER |
0x1000 |
La imagen debe ejecutarse en un AppContainer. |
IMAGE_DLLCHARACTERISTICS_ WDM_DRIVER |
0x2000 |
Un controlador WDM. |
IMAGE_DLLCHARACTERISTICS_GUARD_CF |
0x4000 |
La imagen es compatible con la Protección de flujo de control. |
IMAGE_DLLCHARACTERISTICS_ TERMINAL_SERVER_AWARE |
0x8000 |
Compatible con los servicios de Terminal Server. |
Directorios de datos de encabezado opcionales (solo imagen)
Cada directorio de datos proporciona la dirección y el tamaño de una tabla o cadena que usa Windows. Todas estas entradas del directorio de datos se cargan en la memoria para que el sistema pueda usarlas en el momento de la ejecución. Un directorio de datos es un campo de 8 bytes que tiene la siguiente declaración:
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;
DWORD Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
El primer campo, VirtualAddress, es en realidad el RVA de la tabla. El RVA es la dirección de la tabla relativa a la dirección base de la imagen cuando se carga la tabla. El segundo campo indica el tamaño en bytes. Los directorios de datos, que se encuentran en la última parte del encabezado opcional, se enumeran en la siguiente tabla.
Tenga en cuenta que el número de directorios no es fijo. Antes de buscar un directorio específico, compruebe el campo NumberOfRvaAndSizes en el encabezado opcional.
Tampoco suponga que las RVA de esta tabla señalan el comienzo de una sección o que las secciones que contienen tablas específicas tienen nombres concretos.
Desplazamiento (PE/PE32+) | Size | Campo | Descripción |
---|---|---|---|
96/112 |
8 |
Tabla de exportación |
Dirección y tamaño de la tabla de exportación. Para obtener más información, consulte la Sección .edata (solo imagen). |
104/120 |
8 |
Tabla de importación |
Dirección y tamaño de la tabla de importación. Para obtener más información, consulte la Sección .idata. |
112/128 |
8 |
Tabla de recursos |
Dirección y tamaño de la tabla de recursos. Para obtener más información, consulte la Sección .rsrc. |
120/136 |
8 |
Tabla de excepción |
Dirección y tamaño de la tabla de excepciones. Para obtener más información, consulte la Sección .pdata. |
128/144 |
8 |
Tabla de certificados |
Dirección y tamaño de la tabla de certificados de atributos. Para obtener más información, consulte la Tabla de certificados de atributos (solo imagen) . |
136/152 |
8 |
Tabla de reubicación de base |
Dirección y tamaño de la tabla de reubicaciones base. Para obtener más información, consulte la Sección .reloc (solo imagen). |
144/160 |
8 |
Depurar |
La dirección inicial y el tamaño de los datos de depuración. Para obtener más información, consulte la Sección .debug. |
152/168 |
8 |
Arquitectura |
Reservado, debe ser 0 |
160/176 |
8 |
Puntero global |
El RVA del valor que se va a almacenar en el registro de puntero global. El miembro de tamaño de esta estructura debe establecerse en cero. |
168/184 |
8 |
TLS Table |
La dirección y el tamaño de la tabla del almacenamiento local de subprocesos (TLS). Para obtener más información, consulte la Sección .tls. |
176/192 |
8 |
Tabla de configuración de carga |
Dirección y tamaño de la tabla de configuración de carga. Para obtener más información, consulte la Estructura de configuración de carga (solo imagen). |
184/200 |
8 |
Importación enlazada |
Dirección y tamaño de la tabla de importación enlazada. |
192/208 |
8 |
IAT |
Dirección y tamaño de la tabla de direcciones de importación. Para obtener más información, consulte la Tabla de direcciones de importación. |
200/216 |
8 |
Descriptor de importación retrasada |
Dirección y tamaño del descriptor de importación retrasada. Para obtener más información, consulte las Tablas de importación de carga diferida (solo imagen). |
208/224 |
8 |
Encabezado en tiempo de ejecución de CLR |
Dirección y tamaño del encabezado en tiempo de ejecución de CLR. Para obtener más información, consulte la Sección .cormeta (solo objeto). |
216/232 |
8 |
Reservado, debe ser cero |
La entrada de la tabla de certificados apunta a una tabla de certificados de atributos. Estos certificados no se cargan en la memoria como parte de la imagen. Por ello, el primer campo de esta entrada, que normalmente es una RVA, es en cambio un puntero de archivo.
Tabla de sección (encabezados de sección)
Cada fila de la tabla de secciones es, en efecto, un encabezado de sección. Esta tabla sigue inmediatamente al encabezado opcional, si lo hay. Este posicionamiento es necesario porque el encabezado del archivo no contiene un puntero directo a la tabla de sección. En su lugar, la ubicación de la tabla de sección se determina calculando la ubicación del primer byte después de los encabezados. Asegúrese de usar el tamaño del encabezado opcional como se especifica en el encabezado del archivo.
El número de entradas en la tabla de sección viene dado por el campo NumberOfSections en el encabezado del archivo. Las entradas de la tabla de secciones están numeradas a partir del uno (1). Las entradas de la sección de código y memoria de datos están en el orden elegido por el vinculador.
En un archivo de imagen, el enlazador debe asignar las máquinas virtuales de las secciones para que estén en orden ascendente y adyacente, y deben ser un múltiplo del valor de SectionAlignment en el encabezado opcional.
Cada encabezado de sección (entrada de la tabla de secciones) tiene el formato siguiente, para un total de 40 bytes por entrada.
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
8 |
Nombre |
Una cadena codificada UTF-8 de 8 bytes con relleno nulo. Si la cadena tiene exactamente 8 caracteres, no hay ningún valor nulo de terminación. Para nombres más largos, este campo contiene una barra diagonal (/) seguida de una representación ASCII de un número decimal que es un desplazamiento en la tabla de cadenas. Las imágenes ejecutables no usan una tabla de cadenas y no admiten nombres de sección de más de 8 caracteres. Los nombres largos de los archivos objeto se truncan si se emiten a un archivo ejecutable. |
8 |
4 |
VirtualSize |
Tamaño total de la sección cuando se carga en la memoria. Si este valor es mayor que SizeOfRawData, la sección se rellena con ceros. Este campo solo es válido para imágenes ejecutables y debe establecerse en cero para los archivos objeto. |
12 |
4 |
VirtualAddress |
En el caso de las imágenes ejecutables, la dirección del primer byte de la sección relativa a la base de la imagen cuando la sección se carga en la memoria. En el caso de los archivos objeto, este campo es la dirección del primer byte antes de aplicar la reubicación. Para simplificar, los compiladores deben establecerlo en cero. De lo contrario, es un valor arbitrario que se resta de los desplazamientos durante la reubicación. |
16 |
4 |
SizeOfRawData |
El tamaño de la sección (en el caso de los archivos objeto) o el tamaño de los datos inicializados en el disco (en el caso de los archivos de imagen). En el caso de las imágenes ejecutables, debe ser un múltiplo de FileAlignment del encabezado opcional. Si es menor que VirtualSize, el resto de la sección se rellena con ceros. Dado que el campo SizeOfRawData se redondea pero el campo VirtualSize no, es posible que SizeOfRawData también sea mayor que VirtualSize. Cuando una sección contiene solo datos no inicializados, este campo debe ser cero. |
20 |
4 |
PointerToRawData |
El puntero de archivo a la primera página de la sección dentro del archivo COFF. En el caso de las imágenes ejecutables, debe ser un múltiplo de FileAlignment del encabezado opcional. En el caso de los archivos objeto, el valor debe estar alineado en un límite de 4 bytes para obtener el mejor rendimiento. Cuando una sección contiene solo datos no inicializados, este campo debe ser cero. |
24 |
4 |
PointerToRelocations |
El puntero de archivo al principio de las entradas de reubicación de la sección. Se establece en cero para las imágenes ejecutables o si no hay reubicaciones. |
28 |
4 |
PointerToLinenumbers |
Puntero de archivo al principio de las entradas de número de línea de la sección. Se establece en cero si no hay números de línea COFF. Este valor debe ser cero para una imagen porque la información de depuración de COFF está en desuso. |
32 |
2 |
NumberOfRelocations |
El número de entradas de reubicación para la sección. Se establece en cero para las imágenes ejecutables. |
34 |
2 |
NumberOfLinenumbers |
El número de entradas de número de línea para la sección. Este valor debe ser cero para una imagen porque la información de depuración de COFF está en desuso. |
36 |
4 |
Características |
Las banderas que describen las características de la sección. Para obtener más información, consulte Marcas de sección. |
Marcas de sección
Las marcas de sección del campo Características del encabezado de sección indican las características de la sección.
Marca | Value | Descripción |
---|---|---|
0x00000000 |
Reservado para uso futuro. |
|
0x00000001 |
Reservado para uso futuro. |
|
0x00000002 |
Reservado para uso futuro. |
|
0x00000004 |
Reservado para uso futuro. |
|
IMAGE_SCN_TYPE_NO_PAD |
0x00000008 |
La sección no debe rellenarse hasta el siguiente límite. Esta marca está obsoleta y se sustituye por IMAGE_SCN_ALIGN_1BYTES. Solo es válido para archivos objeto. |
0x00000010 |
Reservado para uso futuro. |
|
IMAGE_SCN_CNT_CODE |
0x00000020 |
La sección contiene código ejecutable. |
IMAGE_SCN_CNT_INITIALIZED_DATA |
0x00000040 |
La sección contiene datos inicializados. |
IMAGE_SCN_CNT_UNINITIALIZED_ DATA |
0x00000080 |
La sección contiene datos no inicializados. |
IMAGE_SCN_LNK_OTHER |
0x00000100 |
Reservado para uso futuro. |
IMAGE_SCN_LNK_INFO |
0x00000200 |
La sección contiene comentarios u otra información. La sección .drectve tiene este tipo. Esto solo es válido para archivos objeto. |
0x00000400 |
Reservado para uso futuro. |
|
IMAGE_SCN_LNK_REMOVE |
0x00000800 |
La sección no pasará a formar parte de la imagen. Solo es válido para archivos objeto. |
IMAGE_SCN_LNK_COMDAT |
0x00001000 |
La sección contiene datos de COMDAT. Para obtener más información, consulte las Secciones COMDAT (solo objeto). Solo es válido para archivos objeto. |
IMAGE_SCN_GPREL |
0x00008000 |
La sección contiene datos a los que se hace referencia a través del puntero global (GP). |
IMAGE_SCN_MEM_PURGEABLE |
0x00020000 |
Reservado para uso futuro. |
IMAGE_SCN_MEM_16BIT |
0x00020000 |
Reservado para uso futuro. |
IMAGE_SCN_MEM_LOCKED |
0x00040000 |
Reservado para uso futuro. |
IMAGE_SCN_MEM_PRELOAD |
0x00080000 |
Reservado para uso futuro. |
IMAGE_SCN_ALIGN_1BYTES |
0x00100000 |
Alinee los datos en un límite de 1 byte. Válido solo para archivos objeto. |
IMAGE_SCN_ALIGN_2BYTES |
0x00200000 |
Alinee los datos en un límite de 2 bytes. Válido solo para archivos objeto. |
IMAGE_SCN_ALIGN_4BYTES |
0x00300000 |
Alinee los datos en un límite de 4 bytes. Válido solo para archivos objeto. |
IMAGE_SCN_ALIGN_8BYTES |
0x00400000 |
Alinee los datos en un límite de 8 bytes. Válido solo para archivos objeto. |
IMAGE_SCN_ALIGN_16BYTES |
0x00500000 |
Alinee los datos en un límite de 16 bytes. Válido solo para archivos objeto. |
IMAGE_SCN_ALIGN_32BYTES |
0x00600000 |
Alinee los datos en un límite de 32 bytes. Válido solo para archivos objeto. |
IMAGE_SCN_ALIGN_64BYTES |
0x00700000 |
Alinee los datos en un límite de 64 bytes. Válido solo para archivos objeto. |
IMAGE_SCN_ALIGN_128BYTES |
0x00800000 |
Alinee los datos en un límite de 128 bytes. Válido solo para archivos objeto. |
IMAGE_SCN_ALIGN_256BYTES |
0x00900000 |
Alinee los datos en un límite de 256 bytes. Válido solo para archivos objeto. |
IMAGE_SCN_ALIGN_512BYTES |
0x00A00000 |
Alinee los datos en un límite de 512 bytes. Válido solo para archivos objeto. |
IMAGE_SCN_ALIGN_1024BYTES |
0x00B00000 |
Alinee los datos en un límite de 1024 bytes. Válido solo para archivos objeto. |
IMAGE_SCN_ALIGN_2048BYTES |
0x00C00000 |
Alinee los datos en un límite de 2048 bytes. Válido solo para archivos objeto. |
IMAGE_SCN_ALIGN_4096BYTES |
0x00D00000 |
Alinee los datos en un límite de 4096 bytes. Válido solo para archivos objeto. |
IMAGE_SCN_ALIGN_8192BYTES |
0x00E00000 |
Alinee los datos en un límite de 8192 bytes. Válido solo para archivos objeto. |
IMAGE_SCN_LNK_NRELOC_OVFL |
0x01000000 |
La sección contiene reubicaciones extendidas. |
IMAGE_SCN_MEM_DISCARDABLE |
0x02000000 |
La sección se puede descartar según sea necesario. |
IMAGE_SCN_MEM_NOT_CACHED |
0x04000000 |
La sección no se puede almacenar en la memoria caché. |
IMAGE_SCN_MEM_NOT_PAGED |
0x08000000 |
La sección no es paginable. |
IMAGE_SCN_MEM_SHARED |
0x10000000 |
La sección se puede compartir en memoria. |
IMAGE_SCN_MEM_EXECUTE |
0x20000000 |
La sección se puede ejecutar como código. |
IMAGE_SCN_MEM_READ |
0x40000000 |
La sección se puede leer. |
IMAGE_SCN_MEM_WRITE |
0x80000000 |
Se puede escribir en la sección. |
IMAGE_SCN_LNK_NRELOC_OVFL indica que el recuento de reubicaciones de la sección supera los 16 bits que están reservados para ella en el encabezado de la sección. Si se establece el bit y el campo NumberOfRelocations del encabezado de sección es 0xffff, el recuento real de reubicaciones se almacena en el campo VirtualAddress de 32 bits de la primera reubicación. Es un error si se establece IMAGE_SCN_LNK_NRELOC_OVFL y hay menos de 0xffff reubicaciones en la sección.
Secciones agrupadas (solo objeto)
El carácter "$" (signo de dólar) tiene una interpretación especial en los nombres de las secciones de los archivos objeto.
Al determinar la sección de imagen que contendrá el contenido de una sección de objeto, el vinculador descarta el "$" y todos los caracteres que le siguen. Por lo tanto, una sección de objeto denominada .text$X contribuye realmente a la sección .text de la imagen.
Sin embargo, los caracteres que siguen a "$" determinan el orden de las contribuciones a la sección de imagen. Todas las contribuciones con el mismo nombre de sección de objeto se asignan de forma contigua en la imagen y los bloques de contribuciones se ordenan en orden léxico por nombre de sección de objeto. Por lo tanto, todo lo que hay en los archivos objeto con nombre de sección .text$X acaba junto, después de las contribuciones .text$W y antes de las contribuciones .text$Y.
El nombre de la sección en un archivo de imagen nunca contiene un carácter "$".
Otros contenidos del archivo
- Datos de la sección
- Reubicaciones de COFF (solo objeto)
- Números de línea COFF (en desuso)
- Tabla de símbolos COFF
- Registros de símbolos auxiliares
- Tabla de cadenas de COFF
- Tabla de certificados de atributos (solo imagen)
- Tablas de importación de carga diferida (solo imagen)
Todas las estructuras de datos descritas hasta ahora, incluido el encabezado opcional, están situadas en un desplazamiento corregido desde el principio del archivo (o desde el encabezado PE si el archivo es una imagen que contiene un código auxiliar MS-DOS).
El resto de un objeto COFF o archivo de imagen contiene bloques de datos que no están necesariamente en ningún desplazamiento de archivo específico. En su lugar, las ubicaciones se definen mediante punteros en el encabezado opcional o en un encabezado de sección.
Una excepción es para las imágenes con un valor de SectionAlignment inferior al tamaño de página de la arquitectura (4 K para Intel x86 y para MIPS, y 8 K para Itanium). Para obtener una descripción de SectionAlignment, consulte el Encabezado opcional (solo imagen). En este caso, hay restricciones en el desplazamiento del archivo de los datos de sección, como se describe en la sección 5.1, "Datos de sección". Otra excepción es que el certificado de atributo y la información de depuración deben colocarse al final de un archivo de imagen, con la tabla de certificados de atributos inmediatamente antes que la sección de depuración, ya que el cargador no los asigna a la memoria. Sin embargo, la regla sobre el certificado de atributo y la información de depuración no se aplica a los archivos de objeto.
Datos de sección
Los datos inicializados de una sección constan de bloques simples de bytes. Sin embargo, para las secciones que contienen todos los ceros, no es necesario incluir los datos de sección.
Los datos de cada sección se encuentran en el desplazamiento de archivo que proporciona el campo PointerToRawData en el encabezado de sección. El tamaño de estos datos en el archivo se indica mediante el campo SizeOfRawData. Si SizeOfRawData es menor que VirtualSize, el resto se rellena con ceros.
En un archivo de imagen, los datos de sección deben alinearse en un límite, tal y como especifica el campo FileAlignment en el encabezado opcional. Los datos de sección deben aparecer en orden de los valores de RVA para las secciones correspondientes (al igual que los encabezados de sección individuales de la tabla de secciones).
Hay restricciones adicionales en los archivos de imagen si el valor SectionAlignment del encabezado opcional es menor que el tamaño de página de la arquitectura. Para estos archivos, la ubicación de los datos de sección del archivo debe coincidir con su ubicación en la memoria cuando se carga la imagen, de modo que el desplazamiento físico de los datos de sección sea el mismo que el de la RVA.
Reubicaciones de COFF (solo objeto)
Los archivos de objeto contienen reubicaciones COFF, que especifican cómo se deben modificar los datos de sección cuando se colocan en el archivo de imagen y posteriormente se cargan en la memoria.
Los archivos de imagen no contienen reubicaciones COFF, ya que a todos los símbolos a los que se hace referencia ya se les han asignado direcciones en un espacio de direcciones plano. Una imagen contiene información de reubicación en forma de reubicaciones base en la sección .reloc (a menos que la imagen tenga el atributo IMAGE_FILE_RELOCS_STRIPPED). Para obtener más información, consulte la Sección .reloc (solo imagen).
Para cada sección de un archivo objeto, una matriz de registros de longitud fija contiene las reubicaciones COFF de la sección. La posición y la longitud de la matriz se especifican en el encabezado de la sección. Cada elemento de la matriz tiene el siguiente formato.
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
4 |
VirtualAddress |
La dirección del elemento al que se aplica la reubicación. Este es el desplazamiento desde el principio de la sección, más el valor del campo RVA/Desplazamiento de la sección. Consulte la Tabla de secciones (encabezados de sección). Por ejemplo, si el primer byte de la sección tiene una dirección de 0x10, el tercer byte tiene una dirección de 0x12. |
4 |
4 |
SymbolTableIndex |
Un índice de base cero en la tabla de símbolos. Este símbolo indica la dirección que se usará para la reubicación. Si el símbolo especificado tiene una clase de almacenamiento de sección, la dirección del símbolo es la dirección con la primera sección del mismo nombre. |
8 |
2 |
Tipo |
Valor que indica el tipo de reubicación que se debe realizar. Los tipos de reubicación válidos dependen del tipo de máquina. Consulte Indicadores de tipo. |
Si el símbolo al que hace referencia el campo SymbolTableIndex tiene la clase de almacenamiento IMAGE_SYM_CLASS_SECTION, la dirección del símbolo es el principio de la sección. La sección suele estar en el mismo archivo, excepto cuando el archivo de objeto forma parte de un archivo (biblioteca). En ese caso, la sección se puede encontrar en cualquier otro archivo de objeto del archivo que tenga el mismo nombre de miembro de archivo que el archivo de objeto actual. (La relación con el nombre del miembro de archivo se usa para el enlace de tablas de importación, es decir, la sección .idata).
Indicadores de tipo
El campo Tipo del registro de reubicación indica qué tipo de reubicación se debe realizar. Se definen diferentes tipos de reubicación para cada tipo de máquina.
Procesadores x64
Los siguientes indicadores de tipo de reubicación están definidos para procesadores x64 y compatibles.
Constante | Value | Descripción |
---|---|---|
IMAGE_REL_AMD64_ABSOLUTE |
0x0000 |
La reubicación se omite. |
IMAGE_REL_AMD64_ADDR64 |
0x0001 |
VA de 64 bits del destino de reubicación. |
IMAGE_REL_AMD64_ADDR32 |
0x0002 |
VA de 32 bits del destino de reubicación. |
IMAGE_REL_AMD64_ADDR32NB |
0x0003 |
Dirección de 32 bits sin una base de imagen (RVA). |
IMAGE_REL_AMD64_REL32 |
0x0004 |
Dirección relativa de 32 bits del byte después de la reubicación. |
IMAGE_REL_AMD64_REL32_1 |
0x0005 |
Dirección de 32 bits relativa a la distancia de byte 1 de la reubicación. |
IMAGE_REL_AMD64_REL32_2 |
0x0006 |
Dirección de 32 bits relativa a la distancia de byte 2 de la reubicación. |
IMAGE_REL_AMD64_REL32_3 |
0x0007 |
Dirección de 32 bits relativa a la distancia de byte 3 de la reubicación. |
IMAGE_REL_AMD64_REL32_4 |
0x0008 |
Dirección de 32 bits relativa a la distancia de byte 4 de la reubicación. |
IMAGE_REL_AMD64_REL32_5 |
0x0009 |
Dirección de 32 bits relativa a la distancia de byte 5 de la reubicación. |
IMAGE_REL_AMD64_SECTION |
0x000A |
Índice de sección de 16 bits de la sección que contiene el destino. Se usa para admitir la información de depuración. |
IMAGE_REL_AMD64_SECREL |
0x000B |
Desplazamiento de 32 bits del destino desde el principio de su sección. Se usa para admitir la información de depuración y el almacenamiento local de subprocesos estáticos. |
IMAGE_REL_AMD64_SECREL7 |
0x000C |
Desplazamiento sin signo de 7 bits desde la base de la sección que contiene el destino. |
IMAGE_REL_AMD64_TOKEN |
0x000D |
Tokens de CLR. |
IMAGE_REL_AMD64_SREL32 |
0x000E |
Valor dependiente del intervalo con signo de 32 bits emitido en el objeto. |
IMAGE_REL_AMD64_PAIR |
0x000F |
Par que debe seguir inmediatamente a cada valor dependiente del intervalo. |
IMAGE_REL_AMD64_SSPAN32 |
0x0010 |
Valor dependiente del intervalo con signo de 32 bits que se aplica en el momento del enlace. |
Procesadores ARM
Los siguientes indicadores de tipo de reubicación están definidos para los procesadores ARM.
Constante | Value | Descripción |
---|---|---|
IMAGE_REL_ARM_ABSOLUTE |
0x0000 |
La reubicación se omite. |
IMAGE_REL_ARM_ADDR32 |
0x0001 |
VA de 32 bits del destino. |
IMAGE_REL_ARM_ADDR32NB |
0x0002 |
RVA de 32 bits del destino. |
IMAGE_REL_ARM_BRANCH24 |
0x0003 |
Desplazamiento relativo de 24 bits respecto al destino. |
IMAGE_REL_ARM_BRANCH11 |
0x0004 |
Referencia a una llamada de subrutina. La referencia consta de dos instrucciones de 16 bits con desplazamientos de 11 bits. |
IMAGE_REL_ARM_REL32 |
0x000A |
Dirección relativa de 32 bits del byte después de la reubicación. |
IMAGE_REL_ARM_SECTION |
0x000E |
Índice de sección de 16 bits de la sección que contiene el destino. Se usa para admitir la información de depuración. |
IMAGE_REL_ARM_SECREL |
0x000F |
Desplazamiento de 32 bits del destino desde el principio de su sección. Se usa para admitir la información de depuración y el almacenamiento local de subprocesos estáticos. |
IMAGE_REL_ARM_MOV32 |
0x0010 |
VA de 32 bits del destino. Esta reubicación se aplica usando una instrucción MOVW para los 16 bits bajos seguida de una MOVT para los 16 bits altos. |
IMAGE_REL_THUMB_MOV32 |
0x0011 |
VA de 32 bits del destino. Esta reubicación se aplica usando una instrucción MOVW para los 16 bits bajos seguida de una MOVT para los 16 bits altos. |
IMAGE_REL_THUMB_BRANCH20 |
0x0012 |
La instrucción se corrige con el desplazamiento relativo de 21 bits respecto al destino alineado de 2 bytes. El bit menos significativo del desplazamiento es siempre cero y no se almacena. Esta reubicación corresponde a una instrucción B condicional Thumb-2 de 32 bits. |
No se usa |
0x0013 |
|
IMAGE_REL_THUMB_BRANCH24 |
0x0014 |
La instrucción se fija con el desplazamiento relativo de 25 bits al destino alineado de 2 bytes. El bit menos significativo del desplazamiento es cero y no se almacena. Esta reubicación corresponde a una instrucción Thumb-2 B. |
IMAGE_REL_THUMB_BLX23 |
0x0015 |
La instrucción se fija con el desplazamiento relativo de 25 bits al destino alineado de 4 bytes. Los 2 bits bajos del desplazamiento son cero y no se almacenan. Esta reubicación corresponde a una instrucción BLX de Thumb-2. |
IMAGE_REL_ARM_PAIR |
0x0016 |
La reubicación es válida solo cuando sigue inmediatamente a un ARM_REFHI o THUMB_REFHI. Su SymbolTableIndex contiene un desplazamiento y no un índice en la tabla de símbolos. |
Procesadores ARM64
Los siguientes indicadores de tipo de reubicación se definen para los procesadores ARM64.
Constante | Value | Descripción |
---|---|---|
IMAGE_REL_ARM64_ABSOLUTE |
0x0000 |
La reubicación se omite. |
IMAGE_REL_ARM64_ADDR32 |
0x0001 |
VA de 32 bits del destino. |
IMAGE_REL_ARM64_ADDR32NB |
0x0002 |
RVA de 32 bits del destino. |
IMAGE_REL_ARM64_BRANCH26 |
0x0003 |
El desplazamiento relativo de 26 bits al objetivo, para las instrucciones B y BL. |
IMAGE_REL_ARM64_PAGEBASE_REL21 |
0x0004 |
Base de página del destino, para la instrucción ADRP. |
IMAGE_REL_ARM64_REL21 |
0x0005 |
Desplazamiento relativo de 12 bits respecto al destino, para la instrucción ADR |
IMAGE_REL_ARM64_PAGEOFFSET_12A |
0x0006 |
Desplazamiento de página de 12 bits del destino, para instrucciones ADD/ADDS (inmediatas) con desplazamiento cero. |
IMAGE_REL_ARM64_PAGEOFFSET_12L |
0x0007 |
Desplazamiento de página de 12 bits del destino, para la instrucción LDR (indexada, sin signo inmediato). |
IMAGE_REL_ARM64_SECREL |
0x0008 |
Desplazamiento de 32 bits del destino desde el principio de su sección. Se usa para admitir la información de depuración y el almacenamiento local de subprocesos estáticos. |
IMAGE_REL_ARM64_SECREL_LOW12A |
0x0009 |
Bit 0:11 de desplazamiento de sección del destino, para instrucciones ADD/ADDS (inmediatas) con desplazamiento cero. |
IMAGE_REL_ARM64_SECREL_HIGH12A |
0x000A |
Bit 12:23 de desplazamiento de sección del destino, para instrucciones ADD/ADDS (inmediatas) con desplazamiento cero. |
IMAGE_REL_ARM64_SECREL_LOW12L |
0x000B |
Bit 0:11 de desplazamiento de sección del destino, para la instrucción LDR (indexada, sin signo inmediato). |
IMAGE_REL_ARM64_TOKEN |
0x000C |
Token de CLR. |
IMAGE_REL_ARM64_SECTION |
0x000D |
Índice de sección de 16 bits de la sección que contiene el destino. Se usa para admitir la información de depuración. |
IMAGE_REL_ARM64_ADDR64 |
0x000E |
VA de 64 bits del destino de reubicación. |
IMAGE_REL_ARM64_BRANCH19 |
0x000F |
El desplazamiento de 19 bits al destino de reubicación, para la instrucción B condicional. |
IMAGE_REL_ARM64_BRANCH14 |
0x0010 |
El desplazamiento de 14 bits al destino de reubicación, para las instrucciones TBZ y TBNZ. |
IMAGE_REL_ARM64_REL32 |
0x0011 |
Dirección relativa de 32 bits del byte después de la reubicación. |
Procesadores Hitachi SuperH
Los siguientes indicadores de tipo de reubicación se definen para los procesadores SH3 y SH4. Las reubicaciones específicas de SH5 se anotan como SHM (SH Media).
Constante | Value | Descripción |
---|---|---|
IMAGE_REL_SH3_ABSOLUTE |
0x0000 |
La reubicación se omite. |
IMAGE_REL_SH3_DIRECT16 |
0x0001 |
Referencia a la ubicación de 16 bits que contiene la VA del símbolo de destino. |
IMAGE_REL_SH3_DIRECT32 |
0x0002 |
VA de 32 bits del símbolo de destino. |
IMAGE_REL_SH3_DIRECT8 |
0x0003 |
Referencia a la ubicación de 8 bits que contiene la VA del símbolo de destino. |
IMAGE_REL_SH3_DIRECT8_WORD |
0x0004 |
Referencia a la instrucción de 8 bits que contiene el VA efectivo de 16 bits del símbolo de destino. |
IMAGE_REL_SH3_DIRECT8_LONG |
0x0005 |
Referencia a la instrucción de 8 bits que contiene la VA de 32 bits efectiva del símbolo de destino. |
IMAGE_REL_SH3_DIRECT4 |
0x0006 |
Referencia a la ubicación de 8 bits cuyos 4 bits bajos contienen la VA del símbolo de destino. |
IMAGE_REL_SH3_DIRECT4_WORD |
0x0007 |
Referencia a la instrucción de 8 bits cuyos 4 bits bajos contienen la VA efectiva de 16 bits del símbolo de destino. |
IMAGE_REL_SH3_DIRECT4_LONG |
0x0008 |
Referencia a la instrucción de 8 bits cuyos 4 bits bajos contienen la VA efectiva de 32 bits del símbolo de destino. |
IMAGE_REL_SH3_PCREL8_WORD |
0x0009 |
Referencia a la instrucción de 8 bits que contiene el desplazamiento relativo de 16 bits efectivo del símbolo de destino. |
IMAGE_REL_SH3_PCREL8_LONG |
0x000A |
Referencia a la instrucción de 8 bits que contiene el desplazamiento relativo efectivo de 32 bits del símbolo de destino. |
IMAGE_REL_SH3_PCREL12_WORD |
0x000B |
Referencia a la instrucción de 16 bits cuyos 12 bits bajos contienen el desplazamiento relativo de 16 bits efectivo del símbolo de destino. |
IMAGE_REL_SH3_STARTOF_SECTION |
0x000C |
Referencia a una ubicación de 32 bits que es la VA de la sección que contiene el símbolo de destino. |
IMAGE_REL_SH3_SIZEOF_SECTION |
0x000D |
Referencia a la ubicación de 32 bits que es el tamaño de la sección que contiene el símbolo de destino. |
IMAGE_REL_SH3_SECTION |
0x000E |
Índice de sección de 16 bits de la sección que contiene el destino. Se usa para admitir la información de depuración. |
IMAGE_REL_SH3_SECREL |
0x000F |
Desplazamiento de 32 bits del destino desde el principio de su sección. Se usa para admitir la información de depuración y el almacenamiento local de subprocesos estáticos. |
IMAGE_REL_SH3_DIRECT32_NB |
0x0010 |
El RVA de 32 bits del símbolo de destino. |
IMAGE_REL_SH3_GPREL4_LONG |
0x0011 |
GP relativo. |
IMAGE_REL_SH3_TOKEN |
0x0012 |
Token de CLR. |
IMAGE_REL_SHM_PCRELPT |
0x0013 |
Desplazamiento de la instrucción actual en palabras largas. Si el bit NOMODE no se ha establecido, inserte el inverso del bit bajo en el bit 32 para seleccionar PTA o PTB. |
IMAGE_REL_SHM_REFLO |
0x0014 |
Los 16 bits bajos de la dirección de 32 bits. |
IMAGE_REL_SHM_REFHALF |
0x0015 |
Los 16 bits altos de la dirección de 32 bits. |
IMAGE_REL_SHM_RELLO |
0x0016 |
Los 16 bits inferiores de la dirección relativa. |
IMAGE_REL_SHM_RELHALF |
0x0017 |
Los 16 bits altos de la dirección relativa. |
IMAGE_REL_SHM_PAIR |
0x0018 |
La reubicación solo es válida cuando sigue inmediatamente a una reubicación REFHALF, RELHALF o RELLO. El campo SymbolTableIndex de la reubicación contiene un desplazamiento y no un índice en la tabla de símbolos. |
IMAGE_REL_SHM_NOMODE |
0x8000 |
La reubicación ignora el modo de sección. |
Procesadores IBM PowerPC
Los siguientes indicadores de tipo de reubicación se definen para los procesadores PowerPC.
Constante | Value | Descripción |
---|---|---|
IMAGE_REL_PPC_ABSOLUTE |
0x0000 |
La reubicación se omite. |
IMAGE_REL_PPC_ADDR64 |
0x0001 |
VA de 64 bits del destino. |
IMAGE_REL_PPC_ADDR32 |
0x0002 |
VA de 32 bits del destino. |
IMAGE_REL_PPC_ADDR24 |
0x0003 |
Los 24 bits bajos de la VA del destino. Esto solo es válido cuando el símbolo de destino es absoluto y se puede extender con signo a su valor original. |
IMAGE_REL_PPC_ADDR16 |
0x0004 |
Los 16 bits bajos de la VA del destino. |
IMAGE_REL_PPC_ADDR14 |
0x0005 |
Los 14 bits bajos de la VA del destino. Esto solo es válido cuando el símbolo de destino es absoluto y se puede extender con signo a su valor original. |
IMAGE_REL_PPC_REL24 |
0x0006 |
Desplazamiento relativo a PC de 24 bits con respecto a la ubicación del símbolo. |
IMAGE_REL_PPC_REL14 |
0x0007 |
Desplazamiento relativo a PC de 14 bits con respecto a la ubicación del símbolo. |
IMAGE_REL_PPC_ADDR32NB |
0x000A |
RVA de 32 bits del destino. |
IMAGE_REL_PPC_SECREL |
0x000B |
Desplazamiento de 32 bits del destino desde el principio de su sección. Se usa para admitir la información de depuración y el almacenamiento local de subprocesos estáticos. |
IMAGE_REL_PPC_SECTION |
0x000C |
Índice de sección de 16 bits de la sección que contiene el destino. Se usa para admitir la información de depuración. |
IMAGE_REL_PPC_SECREL16 |
0x000F |
Desplazamiento de 16 bits del destino desde el principio de su sección. Se usa para admitir la información de depuración y el almacenamiento local de subprocesos estáticos. |
IMAGE_REL_PPC_REFHI |
0x0010 |
Los 16 bits altos de la VA de 32 bits del destino. Se usa para la primera instrucción de una secuencia de dos instrucciones que carga una dirección completa. Esta reubicación debe ir seguida inmediatamente de una reubicación PAIR cuyo SymbolTableIndex contiene un desplazamiento de 16 bits con signo que se agrega a los 16 bits superiores que se tomaron de la ubicación que se está reubicando. |
IMAGE_REL_PPC_REFLO |
0x0011 |
Los 16 bits bajos de la VA del destino. |
IMAGE_REL_PPC_PAIR |
0x0012 |
Reubicación válida solo cuando sigue inmediatamente a una reubicación REFHI o SECRELHI. Su SymbolTableIndex contiene un desplazamiento y no un índice en la tabla de símbolos. |
IMAGE_REL_PPC_SECRELLO |
0x0013 |
Los 16 bits bajos del desplazamiento de 32 bits del destino desde el principio de su sección. |
IMAGE_REL_PPC_GPREL |
0x0015 |
Desplazamiento con signo de 16 bits del destino en relación con el registro de GP. |
IMAGE_REL_PPC_TOKEN |
0x0016 |
Token de CLR. |
Procesadores Intel 386
Los siguientes indicadores de tipo de reubicación están definidos para procesadores Intel 386 y compatibles.
Constante | Value | Descripción |
---|---|---|
IMAGE_REL_I386_ABSOLUTE |
0x0000 |
La reubicación se omite. |
IMAGE_REL_I386_DIR16 |
0x0001 |
No admitida. |
IMAGE_REL_I386_REL16 |
0x0002 |
No admitida. |
IMAGE_REL_I386_DIR32 |
0x0006 |
VA de 32 bits del destino. |
IMAGE_REL_I386_DIR32NB |
0x0007 |
RVA de 32 bits del destino. |
IMAGE_REL_I386_SEG12 |
0x0009 |
No admitida. |
IMAGE_REL_I386_SECTION |
0x000A |
Índice de sección de 16 bits de la sección que contiene el destino. Se usa para admitir la información de depuración. |
IMAGE_REL_I386_SECREL |
0x000B |
Desplazamiento de 32 bits del destino desde el principio de su sección. Se usa para admitir la información de depuración y el almacenamiento local de subprocesos estáticos. |
IMAGE_REL_I386_TOKEN |
0x000C |
Token de CLR. |
IMAGE_REL_I386_SECREL7 |
0x000D |
Desplazamiento de 7 bits desde la base de la sección que contiene el destino. |
IMAGE_REL_I386_REL32 |
0x0014 |
Desplazamiento relativo de 32 bits al destino. Admite la rama relativa x86 y las instrucciones de llamada. |
Familia de procesadores Intel Itanium (IPF)
Los siguientes indicadores de tipo de reubicación se definen para la familia de procesadores Intel Itanium y los procesadores compatibles. Tenga en cuenta que las reubicaciones en las instrucciones usan el desplazamiento del paquete y el número de ranura para el desplazamiento de reubicación.
Constante | Value | Descripción |
---|---|---|
IMAGE_REL_IA64_ABSOLUTE |
0x0000 |
La reubicación se omite. |
IMAGE_REL_IA64_IMM14 |
0x0001 |
La reubicación de instrucciones puede ir seguida de una reubicación ADDEND cuyo valor se agrega a la dirección de destino antes de insertarse en la ranura especificada en el lote IMM14. El destino de reubicación debe ser absoluto o la imagen debe corregirse. |
IMAGE_REL_IA64_IMM22 |
0x0002 |
La reubicación de instrucciones puede ir seguida de una reubicación ADDEND cuyo valor se añade a la dirección de destino antes de que se inserte en la ranura especificada en el paquete IMM22. El destino de reubicación debe ser absoluto o la imagen debe corregirse. |
IMAGE_REL_IA64_IMM64 |
0x0003 |
El número de ranura de esta reubicación debe ser uno (1). La reubicación puede ir seguida de una reubicación ADDEND cuyo valor se agrega a la dirección de destino antes de que se almacene en las tres ranuras del paquete IMM64. |
IMAGE_REL_IA64_DIR32 |
0x0004 |
VA de 32 bits del destino. Esto solo se admite para las imágenes /LARGEADDRESSAWARE:NO. |
IMAGE_REL_IA64_DIR64 |
0x0005 |
El VA de 64 bits del destino. |
IMAGE_REL_IA64_PCREL21B |
0x0006 |
La instrucción se corrige con el desplazamiento relativo de 25 bits respecto al destino alineado de 16 bits. Los 4 bits bajos del desplazamiento son cero y no se almacenan. |
IMAGE_REL_IA64_PCREL21M |
0x0007 |
La instrucción se corrige con el desplazamiento relativo de 25 bits respecto al destino alineado de 16 bits. Los 4 bits bajos del desplazamiento, que son cero, no se almacenan. |
IMAGE_REL_IA64_PCREL21F |
0x0008 |
Los LSB del desplazamiento de esta reubicación deben contener el número de ranura, mientras que el resto es la dirección del lote. El lote se corrige con el desplazamiento relativo de 25 bits respecto al destino alineado de 16 bits. Los 4 bits bajos del desplazamiento son cero y no se almacenan. |
IMAGE_REL_IA64_GPREL22 |
0x0009 |
La reubicación de instrucciones puede ir seguida de una reubicación ADDEND cuyo valor se agrega a la dirección de destino y, a continuación, un desplazamiento relativo de GP de 22 bits que se calcula y se aplica al lote de GPREL22. |
IMAGE_REL_IA64_LTOFF22 |
0x000A |
La instrucción se corrige con el desplazamiento relativo de GP de 22 bits respecto a la entrada de la tabla de literales del símbolo de destino. El enlazador crea esta entrada de la tabla de literales basada en esta reubicación y la reubicación ADDEND que puede seguir. |
IMAGE_REL_IA64_SECTION |
0x000B |
Índice de sección de 16 bits de la sección que contiene el destino. Se usa para admitir la información de depuración. |
IMAGE_REL_IA64_SECREL22 |
0x000C |
La instrucción se corrige con el desplazamiento de 22 bits del destino desde el principio de su sección. Esta reubicación puede ir seguida inmediatamente de una reubicación ADDEND, cuyo campo Valor contiene el desplazamiento sin signo de 32 bits del destino desde el principio de la sección. |
IMAGE_REL_IA64_SECREL64I |
0x000D |
El número de ranura para esta reubicación debe ser uno (1). La instrucción se corrige con el desplazamiento de 64 bits del destino desde el principio de su sección. Esta reubicación puede ir seguida inmediatamente de una reubicación ADDEND cuyo campo Valor contiene el desplazamiento sin signo de 32 bits del destino desde el principio de la sección. |
IMAGE_REL_IA64_SECREL32 |
0x000E |
Dirección de los datos que se van a corregir con el desplazamiento de 32 bits del destino desde el principio de su sección. |
IMAGE_REL_IA64_DIR32NB |
0x0010 |
RVA de 32 bits del destino. |
IMAGE_REL_IA64_SREL14 |
0x0011 |
Esto se aplica a un inmediato de 14 bits firmado que contiene la diferencia entre dos destinos reubicables. Se trata de un campo declarativo para el enlazador que indica que el compilador ya ha emitido este valor. |
IMAGE_REL_IA64_SREL22 |
0x0012 |
Esto se aplica a un inmediato de 22 bits firmado que contiene la diferencia entre dos destinos reubicables. Se trata de un campo declarativo para el enlazador que indica que el compilador ya ha emitido este valor. |
IMAGE_REL_IA64_SREL32 |
0x0013 |
Esto se aplica a un inmediato de 32 bits con signo que contiene la diferencia entre dos valores reubicables. Se trata de un campo declarativo para el enlazador que indica que el compilador ya ha emitido este valor. |
IMAGE_REL_IA64_UREL32 |
0x0014 |
Esto se aplica a un inmediato de 32 bits sin signo que contiene la diferencia entre dos valores reubicables. Se trata de un campo declarativo para el enlazador que indica que el compilador ya ha emitido este valor. |
IMAGE_REL_IA64_PCREL60X |
0x0015 |
Una corrección relativa a PC de 60 bits que siempre permanece como una instrucción BRL de un paquete MLX. |
IMAGE_REL_IA64_PCREL60B |
0x0016 |
Una corrección de 60 bits relativa a PC. Si el desplazamiento de destino encaja en un campo de 25 bits con signo, convierte todo el lote en un lote MBB con NOP.B en la ranura 1 y una instrucción BR de 25 bits (con los 4 bits más bajos cero y eliminados) en la ranura 2. |
IMAGE_REL_IA64_PCREL60F |
0x0017 |
Una corrección de 60 bits relativa a PC. Si el desplazamiento de destino encaja en un campo de 25 bits con signo, convierte todo el lote en un lote MFB con NOP.F en la ranura 1 y una instrucción BR de 25 bits (con los 4 bits más bajos cero y eliminados) en la ranura 2. |
IMAGE_REL_IA64_PCREL60I |
0x0018 |
Una corrección de 60 bits relativa a PC. Si el desplazamiento de destino encaja en un campo de 25 bits con signo, convierte todo el lote en un lote MIB con NOP.I en la ranura 1 y una instrucción BR de 25 bits (con los 4 bits más bajos cero y eliminados) en la ranura 2. |
IMAGE_REL_IA64_PCREL60M |
0x0019 |
Una corrección de 60 bits relativa a PC. Si el desplazamiento de destino encaja en un campo de 25 bits con signo, convierte todo el lote en un lote MMB con NOP.M en la ranura 1 y una instrucción BR de 25 bits (con los 4 bits más bajos cero y eliminados) en la ranura 2. |
IMAGE_REL_IA64_IMMGPREL64 |
0x001a |
Una corrección relativa a GP de 64 bits. |
IMAGE_REL_IA64_TOKEN |
0x001b |
Un token CLR. |
IMAGE_REL_IA64_GPREL32 |
0x001c |
Una corrección relativa a GP de 32 bits. |
IMAGE_REL_IA64_ADDEND |
0x001F |
La reubicación solo es válida cuando sigue inmediatamente a una de las siguientes reubicaciones: IMM14, IMM22, IMM64, GPREL22, LTOFF22, LTOFF64, SECREL22, SECREL64I o SECREL32. Su valor contiene el sumando que se aplicará a las instrucciones dentro de un paquete, no a los datos. |
Procesadores MIPS
Los siguientes indicadores de tipo de reubicación se definen para los procesadores MIPS.
Constante | Value | Descripción |
---|---|---|
IMAGE_REL_MIPS_ABSOLUTE |
0x0000 |
La reubicación se omite. |
IMAGE_REL_MIPS_REFHALF |
0x0001 |
Los 16 bits altos de la VA de 32 bits del destino. |
IMAGE_REL_MIPS_REFWORD |
0x0002 |
VA de 32 bits del destino. |
IMAGE_REL_MIPS_JMPADDR |
0x0003 |
Los 26 bits bajos de la VA del destino. Esto es compatible con las instrucciones MIPS J y JAL. |
IMAGE_REL_MIPS_REFHI |
0x0004 |
Los 16 bits altos de la VA de 32 bits del destino. Se usa para la primera instrucción de una secuencia de dos instrucciones que carga una dirección completa. Esta reubicación debe ir seguida inmediatamente de una reubicación PAIR cuyo SymbolTableIndex contenga un desplazamiento de 16 bits con signo que se agrega a los 16 bits superiores que se toman de la ubicación que se está reubicando. |
IMAGE_REL_MIPS_REFLO |
0x0005 |
Los 16 bits bajos de la VA del destino. |
IMAGE_REL_MIPS_GPREL |
0x0006 |
Desplazamiento con signo de 16 bits del destino en relación con el registro GP. |
IMAGE_REL_MIPS_LITERAL |
0x0007 |
Lo mismo que IMAGE_REL_MIPS_GPREL. |
IMAGE_REL_MIPS_SECTION |
0x000A |
Índice de sección de 16 bits de la sección que contiene el destino. Se usa para admitir la información de depuración. |
IMAGE_REL_MIPS_SECREL |
0x000B |
Desplazamiento de 32 bits del destino desde el principio de su sección. Se usa para admitir la información de depuración y el almacenamiento local de subprocesos estáticos. |
IMAGE_REL_MIPS_SECRELLO |
0x000C |
Los 16 bits bajos del desplazamiento de 32 bits del destino desde el principio de su sección. |
IMAGE_REL_MIPS_SECRELHI |
0x000D |
Los 16 bits altos del desplazamiento de 32 bits del destino desde el principio de su sección. Una reubicación IMAGE_REL_MIPS_PAIR debe seguir inmediatamente a esta. SymbolTableIndex de la reubicación PAIR contiene un desplazamiento de 16 bits con signo que se agrega a los 16 bits superiores que se toman de la ubicación que se está reubicando. |
IMAGE_REL_MIPS_JMPADDR16 |
0x0010 |
Los 26 bits bajos de la VA del destino. Esto es compatible con la instrucción MIPS16 JAL. |
IMAGE_REL_MIPS_REFWORDNB |
0x0022 |
RVA de 32 bits del destino. |
IMAGE_REL_MIPS_PAIR |
0x0025 |
La reubicación es válida solo cuando sigue inmediatamente a una reubicación REFHI o SECRELHI. Su SymbolTableIndex contiene un desplazamiento y no un índice en la tabla de símbolos. |
Mitsubishi M32R
Los siguientes indicadores de tipo de reubicación se definen para los procesadores Mitsubishi M32R.
Constante | Value | Descripción |
---|---|---|
IMAGE_REL_M32R_ABSOLUTE |
0x0000 |
La reubicación se omite. |
IMAGE_REL_M32R_ADDR32 |
0x0001 |
VA de 32 bits del destino. |
IMAGE_REL_M32R_ADDR32NB |
0x0002 |
RVA de 32 bits del destino. |
IMAGE_REL_M32R_ADDR24 |
0x0003 |
VA de 24 bits del destino. |
IMAGE_REL_M32R_GPREL16 |
0x0004 |
Desplazamiento de 16 bits del destino con respecto al registro GP. |
IMAGE_REL_M32R_PCREL24 |
0x0005 |
Desplazamiento de 24 bits del destino desde el contador de programa (PC), desplazado a la izquierda por 2 bits y con signo extendido |
IMAGE_REL_M32R_PCREL16 |
0x0006 |
Desplazamiento de 16 bits del destino desde el PC, desplazado a la izquierda por 2 bits y con signo extendido |
IMAGE_REL_M32R_PCREL8 |
0x0007 |
Desplazamiento de 8 bits del destino desde el PC, desplazado a la izquierda por 2 bits y con signo extendido |
IMAGE_REL_M32R_REFHALF |
0x0008 |
Los 16 MSB de la VA de destino. |
IMAGE_REL_M32R_REFHI |
0x0009 |
Los 16 MSB de la VA de destino, ajustados para la extensión de signo LSB. Esto se usa para la primera instrucción de una secuencia de dos instrucciones que carga una dirección completa de 32 bits. Esta reubicación debe ir seguida inmediatamente de una reubicación PAIR cuyo SymbolTableIndex contenga un desplazamiento de 16 bits con signo que se agrega a los 16 bits superiores que se toman de la ubicación que se está reubicando. |
IMAGE_REL_M32R_REFLO |
0x000A |
Los 16 LSB de la VA de destino. |
IMAGE_REL_M32R_PAIR |
0x000B |
La reubicación debe seguir a la reubicación de REFHI. Su SymbolTableIndex contiene un desplazamiento y no un índice en la tabla de símbolos. |
IMAGE_REL_M32R_SECTION |
0x000C |
Índice de sección de 16 bits de la sección que contiene el destino. Se usa para admitir la información de depuración. |
IMAGE_REL_M32R_SECREL |
0x000D |
Desplazamiento de 32 bits del destino desde el principio de su sección. Se usa para admitir la información de depuración y el almacenamiento local de subprocesos estáticos. |
IMAGE_REL_M32R_TOKEN |
0x000E |
Token de CLR. |
Números de línea COFF (en desuso)
Los números de línea COFF ya no se producen y, en el futuro, no se consumirán.
Los números de línea COFF indican la relación entre el código y los números de línea en los archivos de código fuente. El formato de Microsoft para los números de línea COFF es similar al COFF estándar, pero se ha ampliado para permitir que una sola sección se relacione con los números de línea en varios archivos de código fuente.
Los números de línea COFF consisten en una matriz de registros de longitud fija. La ubicación (desplazamiento de archivo) y el tamaño de la matriz se especifican en el encabezado de la sección. Cada registro de número de línea tiene el siguiente formato.
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
4 |
Tipo (*) |
Se trata de una unión de dos campos: SymbolTableIndex y VirtualAddress. El uso de SymbolTableIndex o RVA depende del valor de Linenumber. |
4 |
2 |
Linenumber |
Cuando es distinto de cero, este campo especifica un número de línea basado en uno. Cuando es cero, el campo Tipo se interpreta como un índice de tabla de símbolos para una función. |
El campo Tipo es una unión de dos campos de 4 bytes: SymbolTableIndex y VirtualAddress.
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
4 |
SymbolTableIndex |
Se usa cuando Linenumber es cero: índice para la entrada de la tabla de símbolos para una función. Este formato se usa para indicar la función a la que se refiere un grupo de registros de número de línea. |
0 |
4 |
VirtualAddress |
Se usa cuando Linenumber es distinto de cero: el RVA del código ejecutable que corresponde a la línea de origen indicada. En un archivo de objeto, contiene la VA dentro de la sección. |
Un registro de número de línea puede establecer el campo Linenumber en cero y apuntar a una definición de función en la tabla de símbolos o puede funcionar como una entrada de número de línea estándar proporcionando un entero positivo (número de línea) y la dirección correspondiente en el código de objeto.
Un grupo de entradas de número de línea siempre comienza con el primer formato: el índice de un símbolo de función. Si este es el primer registro de número de línea de la sección, también es el nombre del símbolo COMDAT para la función si se establece el indicador COMDAT de la sección. Consulte las secciones COMDAT (solo objeto). El registro auxiliar de la función en la tabla de símbolos tiene un puntero al campo Linenumber que apunta a este mismo registro de número de línea.
Un registro que identifica una función va seguido de cualquier número de entradas de número de línea que proporcionan información real del número de línea (es decir, entradas con Linenumber mayor que cero). Estas entradas se basan en una sola línea, relativa al principio de la función, y representan cada línea de origen de la función, excepto la primera línea.
Por ejemplo, el primer registro de número de línea del ejemplo siguiente especificaría la función ReverseSign (SymbolTableIndex de ReverseSign y Linenumber establecido en cero). A continuación, seguirían los registros con valores de Linenumber de 1, 2 y 3, correspondientes a líneas de origen, como se muestra:
// some code precedes ReverseSign function
int ReverseSign(int i)
1: {
2: return -1 * i;
3: }
Tabla de símbolos COFF
La tabla de símbolos de esta sección se hereda del formato COFF tradicional. Es distinta de la información de depuración de Microsoft Visual C++. Un archivo puede contener tanto una tabla de símbolos COFF como información de depuración de Visual C++, y las dos se mantienen separadas. Algunas herramientas de Microsoft usan la tabla de símbolos con fines limitados pero importantes, como comunicar información de COMDAT al enlazador. Los nombres de sección y de archivo, así como los símbolos de código y datos, se muestran en la tabla de símbolos.
La ubicación de la tabla de símbolos se indica en el encabezado COFF.
La tabla de símbolos es una matriz de registros, cada uno de 18 bytes de longitud. Cada registro es un registro de tabla de símbolos estándar o auxiliar. Un registro estándar define un símbolo o nombre y tiene el siguiente formato.
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
8 |
Nombre (*) |
El nombre del símbolo, representado por una unión de tres estructuras. Se usa una matriz de 8 bytes si el nombre no tiene más de 8 bytes de longitud. Para obtener más información, consulte Representación del nombre del símbolo. |
8 |
4 |
Value |
Valor asociado al símbolo. La interpretación de este campo depende de SectionNumber y StorageClass. Un significado típico es la dirección reubicable. |
12 |
2 |
SectionNumber |
Entero con signo que identifica la sección, usando un índice basado en uno en la tabla de secciones. Algunos valores tienen un significado especial, como se define en la sección 5.4.2, "Valores de número de sección". |
14 |
2 |
Tipo |
Número que representa el tipo. Las herramientas de Microsoft establecen este campo en 0x20 (función) o 0x0 (no es una función). Para obtener más información, consulte Representación de tipos. |
16 |
1 |
StorageClass |
Valor enumerado que representa la clase de almacenamiento. Para obtener más información, consulte Clase de almacenamiento. |
17 |
1 |
NumberOfAuxSymbols |
Número de entradas de tabla de símbolos auxiliares que siguen a este registro. |
Cero o más registros auxiliares de tabla de símbolos siguen inmediatamente a cada registro estándar de tabla de símbolos. Sin embargo, normalmente no más de un registro auxiliar de tabla de símbolos sigue a un registro estándar de tabla de símbolos (excepto para los registros .file con nombres de archivo largos). Cada registro auxiliar tiene el mismo tamaño que un registro de tabla de símbolos estándar (18 bytes), pero en lugar de definir un nuevo símbolo, el registro auxiliar proporciona información adicional sobre el último símbolo definido. La elección de cuál de los distintos formatos usar depende del campo StorageClass. Los formatos definidos actualmente para los registros de la tabla de símbolos auxiliares se muestran en la sección 5.5, "Registros de símbolos auxiliares".
Las herramientas que leen las tablas de símbolos COFF deben omitir los registros de símbolos auxiliares cuya interpretación es desconocida. Esto permite ampliar el formato de la tabla de símbolos para agregar nuevos registros auxiliares, sin interrumpir las herramientas existentes.
Representación del nombre del símbolo
El campo ShortName de una tabla de símbolos consta de 8 bytes que contienen el propio nombre, si no tiene más de 8 bytes de longitud, o el campo ShortName proporciona un desplazamiento en la tabla de cadenas. Para determinar si se proporciona el propio nombre o un desplazamiento, pruebe los primeros 4 bytes para que sean iguales a cero.
Por convención, los nombres se tratan como cadenas codificadas UTF-8 terminadas en cero.
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
8 |
ShortName |
Una matriz de 8 bytes. Esta matriz se rellena con valores nulos a la derecha si el nombre tiene menos de 8 bytes de longitud. |
0 |
4 |
Ceros |
Un campo que se establece en ceros si el nombre tiene más de 8 bytes. |
4 |
4 |
Desplazamiento |
Desplazamiento en la tabla de cadenas. |
Valores de número de sección
Normalmente, el campo Valor de la sección de una entrada de la tabla de símbolos es un índice basado en uno en la tabla de secciones. Sin embargo, este campo es un entero con signo y puede tomar valores negativos. Los siguientes valores, menores que uno, tienen significados especiales.
Constante | Value | Descripción |
---|---|---|
IMAGE_SYM_UNDEFINED |
0 |
Al registro de símbolos aún no se le ha asignado una sección. Un valor de cero indica que una referencia a un símbolo externo está definida en otro lugar. Un valor distinto de cero es un símbolo común con un tamaño especificado por el valor. |
IMAGE_SYM_ABSOLUTE |
1- |
El símbolo tiene un valor absoluto (no reubicable) y no es una dirección. |
IMAGE_SYM_DEBUG |
2- |
El símbolo proporciona información general de tipo o depuración, pero no corresponde a una sección. Las herramientas de Microsoft usan esta configuración junto con los registros .file (clase de almacenamiento FILE). |
Representación de tipos
El campo tipo de una entrada de tabla de símbolos contiene 2 bytes, donde cada byte representa información de tipo. El LSB representa el tipo de datos simple (base) y el MSB representa el tipo complejo, si existe:
MSB | LSB |
---|---|
Tipo complejo: ninguno, puntero, función, matriz. |
Tipo base: entero, punto flotante, etc. |
Los siguientes valores están definidos para el tipo base, aunque las herramientas de Microsoft generalmente no usan este campo y establecen el LSB en 0. En su lugar, se usa la información de depuración de Visual C++ para indicar tipos. Sin embargo, los posibles valores de COFF se enumeran aquí para completar la lista.
Constante | Value | Descripción |
---|---|---|
IMAGE_SYM_TYPE_NULL |
0 |
No hay información de tipo ni tipo base desconocido. Las herramientas de Microsoft usan esta configuración |
IMAGE_SYM_TYPE_VOID |
1 |
No hay ningún tipo válido; se usa con punteros y funciones void |
IMAGE_SYM_TYPE_CHAR |
2 |
Carácter (byte con signo) |
IMAGE_SYM_TYPE_SHORT |
3 |
Entero de 2 bytes con signo |
IMAGE_SYM_TYPE_INT |
4 |
Tipo de entero natural (normalmente 4 bytes en Windows) |
IMAGE_SYM_TYPE_LONG |
5 |
Entero de 4 bytes con signo |
IMAGE_SYM_TYPE_FLOAT |
6 |
Número de punto flotante de 4 bytes |
IMAGE_SYM_TYPE_DOUBLE |
7 |
Número de punto flotante de 8 bytes |
IMAGE_SYM_TYPE_STRUCT |
8 |
Una estructura |
IMAGE_SYM_TYPE_UNION |
9 |
Una unión |
IMAGE_SYM_TYPE_ENUM |
10 |
Un tipo enumerado |
IMAGE_SYM_TYPE_MOE |
11 |
Un miembro de la enumeración (un valor específico) |
IMAGE_SYM_TYPE_BYTE |
12 |
Un byte; entero de 1 byte sin signo |
IMAGE_SYM_TYPE_WORD |
13 |
Una palabra; entero de 2 bytes sin signo |
IMAGE_SYM_TYPE_UINT |
14 |
Un entero sin signo de tamaño natural (normalmente, 4 bytes) |
IMAGE_SYM_TYPE_DWORD |
15 |
Un entero de 4 bytes sin signo |
El byte más significativo especifica si el símbolo es un puntero, una función que devuelve o una matriz del tipo base que se especifica en el LSB. Las herramientas de Microsoft usan este campo solo para indicar si el símbolo es una función, de modo que los dos únicos valores resultantes sean 0x0 y 0x20 para el campo Tipo. Sin embargo, otras herramientas pueden usar este campo para comunicar más información.
Es muy importante especificar correctamente el atributo de la función. Esta información es necesaria para que la vinculación incremental funcione correctamente. Para algunas arquitecturas, la información puede ser necesaria para otros fines.
Constante | Value | Descripción |
---|---|---|
IMAGE_SYM_DTYPE_NULL |
0 |
Sin tipo derivado; el símbolo es una variable escalar simple. |
IMAGE_SYM_DTYPE_POINTER |
1 |
El símbolo es un puntero al tipo base. |
IMAGE_SYM_DTYPE_FUNCTION |
2 |
El símbolo es una función que devuelve un tipo base. |
IMAGE_SYM_DTYPE_ARRAY |
3 |
El símbolo es una matriz de tipo base. |
Clase de almacenamiento
El campo StorageClass de la tabla de símbolos indica qué variante de definición representa un símbolo. La siguiente tabla muestra los valores posibles. Tenga en cuenta que el campo StorageClass es un entero de 1 byte sin signo. Por lo tanto, el valor especial -1 debe entenderse como su equivalente sin signo, 0xFF.
Aunque el formato COFF tradicional usa muchos valores de clase de almacenamiento, las herramientas de Microsoft se basan en el formato de depuración de Visual C++ para la mayor parte de la información de símbolos y generalmente usan solo cuatro valores de clase de almacenamiento: EXTERNAL (2), STATIC (3), FUNCTION (101) y FILE (103). Salvo en el encabezado de la segunda columna, por "Valor" debe entenderse el campo Valor del registro de símbolos (cuya interpretación depende del número encontrado como clase de almacenamiento).
Constante | Valor | Descripción/interpretación del campo Valor |
---|---|---|
IMAGE_SYM_CLASS_END_OF_FUNCTION |
-1 (0xFF) |
Símbolo especial que representa el final de la función, con fines de depuración. |
IMAGE_SYM_CLASS_NULL |
0 |
No hay ninguna clase de almacenamiento asignada. |
IMAGE_SYM_CLASS_AUTOMATIC |
1 |
Variable automática (pila). El campo Valor especifica el desplazamiento del marco de pila. |
IMAGE_SYM_CLASS_EXTERNAL |
2 |
Valor que las herramientas de Microsoft usan para los símbolos externos. El campo Valor indica el tamaño si el número de sección es IMAGE_SYM_UNDEFINED (0). Si el número de sección no es cero, el campo Valor especifica el desplazamiento dentro de la sección. |
IMAGE_SYM_CLASS_STATIC |
3 |
El desplazamiento del símbolo dentro de la sección. Si el campo Valor es cero, el símbolo representa el nombre de una sección. |
IMAGE_SYM_CLASS_REGISTER |
4 |
Una variable de registro. El campo Valor especifica el número de registro. |
IMAGE_SYM_CLASS_EXTERNAL_DEF |
5 |
Símbolo que se define externamente. |
IMAGE_SYM_CLASS_LABEL |
6 |
Etiqueta de código que se define dentro del módulo. El campo Valor especifica el desplazamiento del símbolo dentro de la sección. |
IMAGE_SYM_CLASS_UNDEFINED_LABEL |
7 |
Referencia a una etiqueta de código que no está definida. |
IMAGE_SYM_CLASS_MEMBER_OF_STRUCT |
8 |
Miembro de la estructura. El campo Valor especifica el n-ésimo miembro. |
IMAGE_SYM_CLASS_ARGUMENT |
9 |
Argumento formal (parámetro) de una función. El campo Valor especifica el n-ésimo argumento. |
IMAGE_SYM_CLASS_STRUCT_TAG |
10 |
Entrada de nombre de etiqueta de estructura. |
IMAGE_SYM_CLASS_MEMBER_OF_UNION |
11 |
Miembro de la unión. El campo Valor especifica el n-ésimo miembro. |
IMAGE_SYM_CLASS_UNION_TAG |
12 |
Entrada de nombre de la etiqueta Unión. |
IMAGE_SYM_CLASS_TYPE_DEFINITION |
13 |
Entrada Typedef. |
IMAGE_SYM_CLASS_UNDEFINED_STATIC |
14 |
Declaración de datos estáticos. |
IMAGE_SYM_CLASS_ENUM_TAG |
15 |
Entrada tagname de tipo enumerado. |
IMAGE_SYM_CLASS_MEMBER_OF_ENUM |
16 |
Miembro de una enumeración. El campo Valor especifica el n-ésimo miembro. |
IMAGE_SYM_CLASS_REGISTER_PARAM |
17 |
Parámetro de registro. |
IMAGE_SYM_CLASS_BIT_FIELD |
18 |
Referencia de campo de bits. El campo Valor especifica el n-ésimo bit del campo de bits. |
IMAGE_SYM_CLASS_BLOCK |
100 |
Un registro .bb (principio del bloque) o .eb (final del bloque). El campo Valor es la dirección reubicable de la ubicación del código. |
IMAGE_SYM_CLASS_FUNCTION |
101 |
Valor que las herramientas de Microsoft usan para los registros de símbolos que definen la extensión de una función: inicio de función (.bf ), fin de función ( .ef ) y líneas en función ( .lf ). En el caso de los registros .lf, el campo Valor proporciona el número de líneas de origen de la función. En el caso de los registros .ef, el campo Valor proporciona el tamaño del código de la función. |
IMAGE_SYM_CLASS_END_OF_STRUCT |
102 |
Una entrada de fin de estructura. |
IMAGE_SYM_CLASS_FILE |
103 |
Un valor que las herramientas de Microsoft, así como el formato COFF tradicional, usan para el registro de símbolo del archivo de origen. El símbolo va seguido de registros auxiliares que nombran el archivo. |
IMAGE_SYM_CLASS_SECTION |
104 |
Definición de una sección (las herramientas de Microsoft usan la clase de almacenamiento STATIC en su lugar). |
IMAGE_SYM_CLASS_WEAK_EXTERNAL |
105 |
Externo débil. Para obtener más información, consulte Formato auxiliar 3: Externos débiles. |
IMAGE_SYM_CLASS_CLR_TOKEN |
107 |
Símbolo de token CLR. El nombre es una cadena ASCII que consiste en el valor hexadecimal del token. Para obtener más información, consulte Definición de token de CLR (solo objeto). |
Registros de símbolos auxiliares
Los registros de la tabla de símbolos auxiliares siempre siguen y se aplican a algún registro de la tabla de símbolos estándar. Un registro auxiliar puede tener cualquier formato que las herramientas puedan reconocer, pero deben asignársele 18 bytes para que la tabla de símbolos se mantenga como una matriz de tamaño normal. Actualmente, las herramientas de Microsoft reconocen formatos auxiliares para los siguientes tipos de registros: definiciones de funciones, símbolos de inicio y fin de funciones (.bf y .ef), externos débiles, nombres de archivo y definiciones de sección.
El diseño tradicional de COFF también incluye formatos de registro auxiliar para matrices y estructuras. Las herramientas de Microsoft no los usan, sino que colocan esa información de símbolos en formato de depuración de Visual C++ en las secciones de depuración.
Formato auxiliar 1: Definiciones de funciones
Un registro de la tabla de símbolos marca el comienzo de la definición de una función si tiene todo lo siguiente: una clase de almacenamiento EXTERNAL (2), un valor de Tipo que indica que es una función (0x20) y un número de sección mayor que cero. Tenga en cuenta que un registro de la tabla de símbolos que tiene un número de sección de UNDEFINED (0) no define la función y no tiene un registro auxiliar. Los registros de símbolos de definición de función van seguidos de un registro auxiliar en el formato que se describe a continuación:
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
4 |
TagIndex |
El índice de la tabla de símbolos del registro de símbolo .bf (función de inicio) correspondiente. |
4 |
4 |
TotalSize |
El tamaño del código ejecutable de la propia función. Si la función está en su propia sección, el valor de SizeOfRawData en el encabezado de sección es mayor o igual que este campo, en función de las consideraciones de alineación. |
8 |
4 |
PointerToLinenumber |
Desplazamiento del archivo de la primera entrada de número de línea COFF para la función, o cero si no existe ninguno. Para obtener más información, consulte Números de línea COFF (en desuso). |
12 |
4 |
PointerToNextFunction |
Índice de la tabla de símbolos del registro de la siguiente función. Si la función es la última de la tabla de símbolos, este campo se establece en cero. |
16 |
2 |
No se usa |
Formato auxiliar 2: Símbolos .bf y .ef
Para cada definición de función en la tabla de símbolos, tres elementos describen el principio, el final y el número de líneas. Cada uno de estos símbolos tiene la clase de almacenamiento FUNCTION (101):
Un registro de símbolo denominado .bf (inicio de función). El campo Valor no se usa.
Un registro de símbolo denominado .lf (líneas en función). El campo Valor proporciona el número de líneas de la función.
Un registro de símbolos denominado .ef (fin de la función). El campo Valor tiene el mismo número que el campo Tamaño total en el registro de símbolo de definición de función.
Los registros de símbolos .bf y .ef (pero no los registros .lf) van seguidos de un registro auxiliar con el siguiente formato:
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
4 |
No se usa |
|
4 |
2 |
Linenumber |
El número de línea ordinal real (1, 2, 3, etc.) dentro del archivo de origen, correspondiente al registro .bf o .ef. |
6 |
6 |
No se usa |
|
12 |
4 |
PointerToNextFunction (solo .bf) |
Índice de la tabla de símbolos del siguiente registro de símbolos .bf. Si la función es la última de la tabla de símbolos, este campo se establece en cero. No se usa para registros .ef. |
16 |
2 |
No se usa |
Formato auxiliar 3: Externos débiles
Los "externos débiles" son un mecanismo para los archivos de objetos que permite flexibilidad en el momento del enlace. Un módulo puede contener un símbolo externo sin resolver (sym1), pero también puede incluir un registro auxiliar que indica que si sym1 no está presente en el momento del enlace, se usa otro símbolo externo (sym2) para resolver las referencias en su lugar.
Si hay una definición de sym1 enlazada, una referencia externa al símbolo se resuelve normalmente. Si no hay una definición de sym1 enlazada, todas las referencias al externo débil de sym1 harán referencia a sym2. El símbolo externo, sym2, siempre debe estar enlazado; normalmente se define en el módulo que contiene la referencia débil a sym1.
Los externos débiles se representan mediante un registro de la tabla de símbolos con la clase de almacenamiento EXTERNAL, el número de sección UNDEF y un valor de cero. El registro de símbolo externo débil va seguido de un registro auxiliar con el siguiente formato:
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
4 |
TagIndex |
El índice de la tabla de símbolos de sym2, el símbolo que se vinculará si no se encuentra sym1. |
4 |
4 |
Características |
Un valor de IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY indica que no se debe realizar ninguna búsqueda de biblioteca para sym1. Un valor de IMAGE_WEAK_EXTERN_SEARCH_LIBRARY indica que se debe realizar una búsqueda de biblioteca para sym1. Un valor de IMAGE_WEAK_EXTERN_SEARCH_ALIAS indica que sym1 es un alias de sym2. |
8 |
10 |
No se usa |
Tenga en cuenta que el campo Características no está definido en WINNT.H; en su lugar, se usa el campo Tamaño total.
Formato auxiliar 4: Archivos
Este formato sigue un registro de tabla de símbolos con la clase de almacenamiento FILE (103). El nombre del símbolo en sí debe ser .file, y el registro auxiliar que le sigue da el nombre de un archivo de código fuente.
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
18 |
Nombre de archivo |
Cadena ANSI que proporciona el nombre del archivo de origen. Se rellena con valores nulos si es menor que la longitud máxima. |
Formato auxiliar 5: Definiciones de sección
Este formato sigue a un registro de tabla de símbolos que define una sección. Un registro de este tipo tiene un nombre de símbolo que es el nombre de una sección (como .text o .drectve) y tiene la clase de almacenamiento STATIC (3). El registro auxiliar proporciona información sobre la sección a la que se refiere. Por lo tanto, duplica parte de la información en el encabezado de la sección.
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
4 |
Length |
Tamaño de los datos de la sección; igual que SizeOfRawData en el encabezado de sección. |
4 |
2 |
NumberOfRelocations |
El número de entradas de reubicación para la sección. |
6 |
2 |
NumberOfLinenumbers |
El número de entradas de número de línea para la sección. |
8 |
4 |
CheckSum |
Suma de comprobación de los datos comunes. Es aplicable si el indicador IMAGE_SCN_LNK_COMDAT se establece en el encabezado de la sección. Para obtener más información, consulte las Secciones COMDAT (solo objeto). |
12 |
2 |
Número |
Índice basado en uno en la tabla de secciones de la sección asociada. Se usa cuando el valor de selección de COMDAT es 5. |
14 |
1 |
Selección |
El número de selección COMDAT. Esto es aplicable si la sección es una sección COMDAT. |
15 |
3 |
No se usa |
Secciones COMDAT (solo objeto)
El campo Selección del formato auxiliar de definición de sección es aplicable si la sección es una sección COMDAT. Una sección COMDAT es una sección que puede ser definida por más de un archivo objeto. (La marca IMAGE_SCN_LNK_COMDAT se establece en el campo Marcas de sección del encabezado de sección). El campo Selección determina la forma en que el enlazador resuelve las diversas definiciones de las secciones COMDAT.
El primer símbolo que tiene el valor de sección de la sección COMDAT debe ser el símbolo de sección. Este símbolo tiene el nombre de la sección, el campo Valor igual a cero, el número de sección de la sección COMDAT en cuestión, el campo Tipo igual a IMAGE_SYM_TYPE_NULL, el campo Clase igual a IMAGE_SYM_CLASS_STATIC y un registro auxiliar. El segundo símbolo se denomina "símbolo COMDAT" y lo usa el enlazador junto con el campo Selección.
A continuación se muestran los valores del campo Selección.
Constante | Value | Descripción |
---|---|---|
IMAGE_COMDAT_SELECT_NODUPLICATES |
1 |
Si este símbolo ya está definido, el enlazador emite un error de "multiplicar símbolo definido". |
IMAGE_COMDAT_SELECT_ANY |
2 |
Cualquier sección que defina el mismo símbolo COMDAT se puede enlazar; el resto se quitan. |
IMAGE_COMDAT_SELECT_SAME_SIZE |
3 |
El enlazador elige una sección arbitraria entre las definiciones de este símbolo. Si todas las definiciones no tienen el mismo tamaño, se emite un error de "multiplicar símbolo definido". |
IMAGE_COMDAT_SELECT_EXACT_MATCH |
4 |
El enlazador elige una sección arbitraria entre las definiciones de este símbolo. Si todas las definiciones no coinciden exactamente, se emite un error de "multiplicar símbolo definido". |
IMAGE_COMDAT_SELECT_ASSOCIATIVE |
5 |
La sección se enlaza si se enlaza otra sección COMDAT. Esta otra sección se indica mediante el campo Número del registro de símbolos auxiliares para la definición de sección. Esta configuración es útil para las definiciones que tienen componentes en varias secciones (por ejemplo, código en una y datos en otra), pero en las que todos deben vincularse o descartarse como un conjunto. La otra sección a la que está asociada esta sección debe ser una sección COMDAT, que puede ser otra sección COMDAT asociativa. La cadena de asociación de secciones de una sección COMDAT asociativa no puede formar un bucle. La cadena de asociación de secciones debe llegar finalmente a una sección COMDAT que no tiene IMAGE_COMDAT_SELECT_ASSOCIATIVE establecido. |
IMAGE_COMDAT_SELECT_LARGEST |
6 |
El enlazador elige la definición más grande de entre todas las definiciones para este símbolo. Si varias definiciones tienen este tamaño, la elección entre ellas es arbitraria. |
Definición de token de CLR (solo objeto)
Este símbolo auxiliar suele seguir al IMAGE_SYM_CLASS_CLR_TOKEN. Se usa para asociar un token al espacio de nombres de la tabla de símbolos COFF.
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
1 |
bAuxType |
Debe ser IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF (1). |
1 |
1 |
bReserved |
Reservado, debe ser cero. |
2 |
4 |
SymbolTableIndex |
Índice de símbolo del símbolo COFF al que hace referencia esta definición de token de CLR. |
6 |
12 |
Reservado, debe ser cero. |
Tabla de cadenas de COFF
Inmediatamente después de la tabla de símbolos COFF está la tabla de cadenas COFF. La posición de esta tabla se encuentra tomando la dirección de la tabla de símbolos en el encabezado COFF y agregando el número de símbolos multiplicado por el tamaño de un símbolo.
Al principio de la tabla de cadenas COFF hay 4 bytes que contienen el tamaño total (en bytes) del resto de la tabla de cadenas. Este tamaño incluye el propio campo de tamaño, por lo que el valor de esta ubicación sería 4 si no hubiera ninguna cadena presente.
Después del tamaño, se muestran cadenas terminadas en null a las que apuntan los símbolos de la tabla de símbolos COFF.
Tabla de certificados de atributos (solo imagen)
Los certificados de atributo se pueden asociar a una imagen agregando una tabla de certificados de atributos. La tabla de certificados de atributos se compone de un conjunto de entradas de certificados de atributos contiguas y alineadas por cuatro palabras. Para lograr esta alineación, se inserta un relleno cero entre el final original del archivo y el principio de la tabla de certificados de atributos. Cada entrada de certificado de atributo contiene los siguientes campos.
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
4 |
dwLength |
Especifica la longitud de la entrada de certificado de atributo. |
4 |
2 |
wRevision |
Contiene el número de versión del certificado. Para obtener más información, consulte el siguiente texto. |
6 |
2 |
wCertificateType |
Especifica el tipo de contenido de bCertificate. Para obtener más información, consulte el siguiente texto. |
8 |
Consulte |
bCertificate |
Contiene un certificado, como una firma Authenticode. Para obtener más información, consulte el siguiente texto. |
El valor de dirección virtual de la entrada de la tabla de certificados del directorio de datos de encabezado opcional es un desplazamiento de archivo respecto a la primera entrada del certificado de atributos. Se accede a las entradas posteriores avanzando los bytes dwLength de esa entrada, redondeados a un múltiplo de 8 bytes, desde el inicio de la entrada actual del certificado de atributo. Esto continúa hasta que la suma de los valores de dwLength redondeados es igual al valor de Tamaño de la entrada de la tabla de certificados en el directorio de datos de encabezado opcional. Si la suma de los valores dwLength redondeados no es igual al valor de Tamaño, significa que la tabla de certificados de atributos o el campo de Tamaño están dañados.
Por ejemplo, si la entrada de la tabla de certificados del directorio de datos de encabezado opcional contiene:
virtual address = 0x5000
size = 0x1000
El primer certificado comienza en el desplazamiento 0x5000 desde el inicio del archivo en el disco. Para avanzar a través de todas las entradas de certificado de atributo:
- Agregue el valor dwLength del primer certificado de atributo al desplazamiento inicial.
- Redondee el valor del paso 1 al múltiplo de 8 bytes más cercano para encontrar el desplazamiento de la segunda entrada de certificado de atributo.
- Agregue el valor de desplazamiento del paso 2 al valor dwLength de la segunda entrada de certificado de atributo y redondee al múltiplo de 8 bytes más cercano para determinar el desplazamiento de la tercera entrada de certificado de atributo.
- Repita el paso 3 para cada certificado sucesivo hasta que el desplazamiento calculado sea igual a 0x6000 (0x5000 inicio + 0x1000 tamaño total), lo que indica que ha recorrido toda la tabla.
También puede enumerar las entradas del certificado llamando a la función ImageEnumerateCertificates de Win32 en un bucle. Para obtener un enlace a la página de referencia de la función, consulte Referencias.
Las entradas de la tabla de certificados de atributos pueden contener cualquier tipo de certificado, siempre que la entrada tenga el valor dwLength correcto, un valor de wRevision único y un valor de wCertificateType único. El tipo más común de entrada de tabla de certificados es una estructura WIN_CERTIFICATE, que se documenta en Wintrust.h y que se describe en el resto de esta sección.
Las opciones para el miembro WIN_CERTIFICATE wRevision incluyen (pero no se limitan a) las siguientes.
Valor | Nombre | Notas |
---|---|---|
0x0100 |
WIN_CERT_REVISION_1_0 |
Versión 1, versión heredada de la estructura Win_Certificate. Solo se admite con el fin de verificar las firmas heredadas de Authenticode |
0x0200 |
WIN_CERT_REVISION_2_0 |
La versión 2 es la versión actual de la estructura Win_Certificate. |
Las opciones del miembro wCertificateType de WIN_CERTIFICATE incluyen (entre otros) los elementos de la tabla siguiente. Tenga en cuenta que, actualmente, algunos valores no se admiten.
Valor | Nombre | Notas |
---|---|---|
0x0001 |
WIN_CERT_TYPE_X509 |
bCertificate contiene un certificado X.509 No compatible |
0x0002 |
WIN_CERT_TYPE_PKCS_SIGNED_DATA |
bCertificate contiene una estructura PKCS#7 SignedData |
0x0003 |
WIN_CERT_TYPE_RESERVED_1 |
Reservado |
0x0004 |
WIN_CERT_TYPE_TS_STACK_SIGNED |
Firma de certificados de la pila de protocolos de Terminal Server No compatible |
El miembro bCertificate de la estructura WIN_CERTIFICATE contiene una matriz de bytes de longitud variable con el tipo de contenido especificado por wCertificateType. El tipo admitido por Authenticode es WIN_CERT_TYPE_PKCS_SIGNED_DATA, una estructura PKCS#7 SignedData. Para obtener más información sobre el formato de firma digital Authenticode, consulte Formato de firma ejecutable portátil de Windows Authenticode.
Si el contenido de bCertificate no termina en un límite de cuatro palabras, la entrada del certificado de atributos se rellena con ceros, desde el final de bCertificate hasta el siguiente límite de cuatro palabras.
El valor dwLength es la longitud de la estructura de WIN_CERTIFICATE finalizada y se calcula como:
dwLength = offsetof(WIN_CERTIFICATE, bCertificate) + (size of the variable-length binary array contained within bCertificate)
Esta longitud debe incluir el tamaño de cualquier relleno que se use para satisfacer el requisito de que cada estructura WIN_CERTIFICATE esté alineada por cuatro palabras:
dwLength += (8 - (dwLength & 7)) & 7;
El tamaño de la tabla de certificados especificado en la entrada de la Tabla de certificados en los Directorios de datos de encabezado opcional (solo imagen) incluye el relleno.
Para obtener más información sobre el uso de la API ImageHlp para enumerar, agregar y quitar certificados de archivos PE, consulte Funciones de ImageHlp.
Datos del certificado
Como se indicó en la sección anterior, los certificados de la tabla de certificados de atributos pueden contener cualquier tipo de certificado. Los certificados que garantizan la integridad de un archivo PE pueden incluir un hash de imagen PE.
Un hash de imagen PE (o hash de archivo) es parecido a una suma de comprobación de archivo en el sentido de que el algoritmo hash genera una síntesis de mensaje relacionada con la integridad de un archivo. Sin embargo, una suma de comprobación se genera mediante un algoritmo sencillo y se usa principalmente para detectar si un bloque de memoria en disco se ha estropeado y los valores almacenados en él se han dañado. Un hash de archivo es similar a una suma de comprobación en el sentido de que también detecta daños en los archivos. Sin embargo, a diferencia de la mayoría de los algoritmos de suma de comprobación, es muy difícil modificar un archivo sin cambiar el hash del archivo de su valor original sin modificar. Por lo tanto, un hash de archivo se puede usar para detectar modificaciones intencionales e incluso sutiles en un archivo, como las introducidas por virus, piratas informáticos o programas troyanos.
Cuando se incluye en un certificado, la síntesis de la imagen debe excluir determinados campos de la imagen PE, como la suma de comprobación y la entrada de la tabla de certificados en los directorios de datos de encabezado opcional. Esto se debe a que el acto de agregar un certificado cambia estos campos y haría que se calculara un valor hash diferente.
La función ImageGetDigestStream de Win32 proporciona un flujo de datos de un archivo PE de destino con el que se usan funciones hash. Esta transmisión de datos sigue siendo coherente cuando se agregan o quitan certificados de un archivo PE. En función de los parámetros que se transfieren a ImageGetDigestStream, se pueden omitir otros datos de la imagen PE del cálculo hash. Para obtener un enlace a la página de referencia de la función, consulte Referencias.
Tablas de importación de carga diferida (solo imagen)
Estas tablas se añadieron a la imagen para permitir un mecanismo uniforme para que las aplicaciones retrasen la carga de un archivo DLL hasta la primera llamada a ese archivo DLL. El diseño de las tablas coincide con el de las tablas de importación tradicionales que se describen en la sección 6.4, Sección .idata". Aquí solo se describen algunos detalles.
Tabla de directorio de carga retardada
La tabla de directorios de retraso de carga es el homólogo de la tabla de directorios de importación. Se puede recuperar a través de la entrada del descriptor de importación retrasada en la lista de directorios de datos de encabezado opcional (desplazamiento 200). La tabla está dispuesta de la siguiente manera:
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
4 |
Atributos |
Debe ser cero. |
4 |
4 |
Nombre |
El RVA del nombre del archivo DLL que se va a cargar. El nombre reside en la sección de datos de solo lectura de la imagen. |
8 |
4 |
Controlador de módulo |
RVA del controlador del módulo (en la sección de datos de la imagen) del archivo DLL que se va a cargar con retraso. Se usa para el almacenamiento mediante la rutina que se proporciona para administrar la carga retrasada. |
12 |
4 |
Tabla de direcciones de importación retrasada |
El RVA de la tabla de dirección de importación de carga retrasada. Para obtener más información, consulte Tabla de direcciones de importación retrasada (IAT). |
16 |
4 |
Tabla de nombres de importación retrasada |
El RVA de la tabla de nombre de carga retrasada, que contiene los nombres de las importaciones que podrían necesitar cargarse. Coincide con el diseño de la tabla de nombres de importación. Para obtener más información, consulte Tabla de sugerencias/nombres. |
20 |
4 |
Tabla de importación enlazada retrasada |
El RVA de la tabla de dirección de carga retardada enlazada, si existe. |
24 |
4 |
Tabla de importaciones de descarga retrasada |
RVA de la tabla de direcciones de carga-descarga retrasada, si existe. Se trata de una copia exacta de la tabla de direcciones de importación retrasada. Si el autor de la llamada descarga el archivo DLL, esta tabla se debe copiar de nuevo a través de la tabla de direcciones de importación retrasada para que las llamadas posteriores al archivo DLL sigan usando el mecanismo de aplicación de código thunk correctamente. |
28 |
4 |
Marca de tiempo |
Marca de tiempo del archivo DLL al que se ha enlazado esta imagen. |
Las tablas a las que se hace referencia en esta estructura de datos se organizan y ordenan de la misma manera que sus homólogas para las importaciones tradicionales. Para obtener más información, consulte la Sección .idata.
Atributos
Hasta el momento, no se ha definido ninguna marca de atributo. El vinculador establece este campo en cero en la imagen. Este campo se puede usar para extender el registro indicando la presencia de nuevos campos o bien se puede usar para indicar comportamientos a las funciones auxiliares de retraso o descarga.
Nombre
El nombre del archivo DLL que se va a cargar en diferido reside en la sección de datos de solo lectura de la imagen. Se hace referencia a él a través del campo szName.
Controlador de módulo
El controlador del archivo DLL que se va a cargar en diferido se encuentra en la sección de datos de la imagen. El campo phmod apunta al controlador. La aplicación auxiliar de carga retrasada suministrada usa esta ubicación para almacenar el controlador en el archivo DLL cargado.
Tabla de direcciones de importación retrasada
El descriptor de importación retrasada hace referencia a la tabla de dirección de importación retrasada (IAT) a través del campo pIAT. El asistente de carga retrasada actualiza estos punteros con los puntos de entrada reales para que los thunks ya no estén en el bucle de llamada. Se tiene acceso a los punteros de función mediante la expresión pINT->u1.Function
.
Tabla de nombres de importación retrasada
La tabla de nombre de importación retrasada (INT) contiene los nombres de las importaciones que pueden requerir carga. Se ordenan de la misma manera que los punteros de función en el IAT. Constan de las mismas estructuras que el INT estándar y se obtiene acceso a ellas mediante la expresión pINT->u1.AddressOfData->Name[0]
.
Tabla de direcciones de importación enlazada retrasada y marca de tiempo
La tabla de direcciones de importación enlazada retrasada (BIAT) es una tabla opcional de elementos IMAGE_THUNK_DATA que se usan junto con el campo de marca de tiempo de la tabla de directorios de carga retrasada mediante una fase de enlace posterior al proceso.
Tabla de direcciones de importación de descarga retrasada
La tabla de direcciones de importación de descarga retrasada (UIAT) es una tabla opcional de elementos IMAGE_THUNK_DATA que usa el código de descarga para controlar una solicitud de descarga explícita. Consta de datos inicializados en la sección de solo lectura que es una copia exacta de la IAT original que hizo referencia al código a los thunks de carga retrasada. En la solicitud de descarga, la biblioteca se puede liberar, el *phmod se puede borrar y la UIAT se puede escribir sobre la IAT puede restaurar todo a su estado anterior a la carga.
Secciones especiales
- La sección .debug
- La sección .drectve (solo objeto)
- La sección .edata (solo imagen)
- La sección .idata
- La sección .pdata
- La sección .reloc (solo imagen)
- La sección .tls
- La estructura de configuración de carga (solo imagen)
- La sección .rsrc
- La sección .cormeta (solo objeto)
- La sección .sxdata
Las secciones típicas de COFF contienen código o datos que los vinculadores y los cargadores de Microsoft Win32 procesan sin conocimientos especiales del contenido de la sección. El contenido es relevante solo para la aplicación que se está vinculando o ejecutando.
Sin embargo, algunas secciones COFF tienen significados especiales cuando se encuentran en archivos objeto o archivos de imagen. Las herramientas y los cargadores reconocen estas secciones porque tienen marcas especiales establecidas en el encabezado de sección, ya que las ubicaciones especiales del encabezado opcional de la imagen apuntan a ellas o porque el propio nombre de sección indica una función especial de la sección. (Incluso si el nombre de la sección en sí mismo no indica una función especial de la sección, el nombre de la sección está dictado por convención, por lo que los autores de esta especificación pueden hacer referencia a un nombre de sección en todos los casos).
Las secciones reservadas y sus atributos se describen en la tabla siguiente, seguidas de descripciones detalladas de los tipos de sección que se conservan en ejecutables y los tipos de sección que contienen metadatos para extensiones.
Nombre de sección | Contenido | Características |
---|---|---|
.bss |
Datos sin inicializar (formato libre) |
IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE |
.cormeta |
Metadatos de CLR que indican que el archivo de objeto contiene código administrado |
IMAGE_SCN_LNK_INFO |
.data |
Datos inicializados (formato libre) |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE |
.debug$F |
Información de depuración de FPO generada (solo para objetos, solo arquitectura x86 y ahora obsoleta) |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE |
.debug$P |
Tipos de depuración precompilados (solo objeto) |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE |
.debug$S |
Símbolos de depuración (solo objeto) |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE |
.debug$T |
Tipos de depuración (solo objeto) |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE |
.drective |
Opciones del enlazador |
IMAGE_SCN_LNK_INFO |
.edata |
Tablas de exportación |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ |
.idata |
Tablas de importación |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE |
.idlsym |
Incluye SEH registrado (solo imagen) para admitir atributos IDL. Para obtener información, consulte "Atributos IDL" en Referencias al final de este tema. |
IMAGE_SCN_LNK_INFO |
.pdata |
Información de excepción |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ |
.rdata |
Datos inicializados de solo lectura |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ |
.reloc |
Reubicaciones de imágenes |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE |
.rsrc |
Directorio de recursos |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ |
.sbss |
Datos no inicializados relativos a GP (formato libre) |
IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE _SCN_GPREL La marca IMAGE_SCN_GPREL debe establecerse solo para arquitecturas IA64; esta marca no es válida para otras arquitecturas. La marca IMAGE_SCN_GPREL es solo para los archivos de objeto; cuando este tipo de sección aparece en un archivo de imagen, no se debe establecer la marca IMAGE_SCN_GPREL. |
.sdata |
Datos inicializados relativos a GP (formato libre) |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE _SCN_GPREL La marca IMAGE_SCN_GPREL debe establecerse solo para arquitecturas IA64; esta marca no es válida para otras arquitecturas. La marca IMAGE_SCN_GPREL es solo para los archivos de objeto; cuando este tipo de sección aparece en un archivo de imagen, no se debe establecer la marca IMAGE_SCN_GPREL. |
.srdata |
Datos de solo lectura relativos a GP (formato libre) |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE _SCN_GPREL La marca IMAGE_SCN_GPREL debe establecerse solo para arquitecturas IA64; esta marca no es válida para otras arquitecturas. La marca IMAGE_SCN_GPREL es solo para los archivos de objeto; cuando este tipo de sección aparece en un archivo de imagen, no se debe establecer la marca IMAGE_SCN_GPREL. |
.sxdata |
Datos del controlador de excepciones registrados (formato libre y solo x86/objeto) |
IMAGE_SCN_LNK_INFO Contiene el índice de símbolos de cada uno de los controladores de excepciones a los que hace referencia el código de ese archivo objeto. El símbolo puede ser para un símbolo UNDEF o uno que esté definido en ese módulo. |
.text |
Código ejecutable (formato libre) |
IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IIMAGE_SCN_MEM_READ |
.tls |
Almacenamiento local de subprocesos (solo objeto) |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE |
.tls$ |
Almacenamiento local de subprocesos (solo objeto) |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE |
.vsdata |
Datos inicializados relativos a GP (formato libre y solo para arquitecturas ARM, SH4 y Thumb) |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE |
.xdata |
Información de excepción (formato libre) |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ |
Algunas de las secciones enumeradas aquí están marcadas como "solo objeto" o "solo imagen" para indicar que su semántica especial es relevante solo para archivos objeto o archivos de imagen, respectivamente. Una sección marcada como "solo imagen" puede seguir apareciendo en un archivo objeto como una forma de acceder al archivo de imagen, pero la sección no tiene ningún significado especial para el vinculador, solo para el cargador de archivos de imagen.
La sección .debug
La sección .debug se usa en los archivos objeto para contener información de depuración generada por el compilador y en los archivos de imagen para contener toda la información de depuración que se genera. En esta sección se describe el empaquetado de la información de depuración en archivos de objeto e imagen.
En la siguiente sección se describe el formato del directorio de depuración, que puede estar en cualquier parte de la imagen. En las secciones siguientes se describen los "grupos" de los archivos objeto que contienen información de depuración.
El valor predeterminado para el vinculador es que la información de depuración no se asigna al espacio de direcciones de la imagen. Una sección .debug solo existe cuando la información de depuración se asigna en el espacio de direcciones.
Directorio de depuración (solo imagen)
Los archivos de imagen contienen un directorio de depuración opcional que indica qué tipo de información de depuración está presente y dónde está. Este directorio consta de una matriz de entradas de directorio de depuración cuya ubicación y tamaño se indican en el encabezado opcional de la imagen.
El directorio de depuración puede estar en una sección .debug descartable (si existe alguna) o puede incluirse en cualquier otra sección del archivo de imagen o no estar en ninguna sección.
Cada entrada del directorio de depuración identifica la ubicación y el tamaño de un bloque de información de depuración. El RVA especificado puede ser cero si la información de depuración no está cubierta por un encabezado de sección (es decir, reside en el archivo de imagen y no está asignada al espacio de direcciones en tiempo de ejecución). Si está mapeado, el RVA es su dirección.
Una entrada de directorio de depuración tiene el siguiente formato:
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
4 |
Características |
Reservado, debe ser cero. |
4 |
4 |
TimeDateStamp |
La hora y la fecha en que se crearon los datos de depuración. |
8 |
2 |
MajorVersion |
Número de versión principal del formato de datos de depuración. |
10 |
2 |
MinorVersion |
Número de versión secundaria del formato de datos de depuración. |
12 |
4 |
Tipo |
El formato de la información de depuración. Este campo permite la compatibilidad con varios depuradores. Para más información, consulte Tipo de depuración. |
16 |
4 |
SizeOfData |
El tamaño de los datos de depuración (sin incluir el directorio de depuración en sí). |
20 |
4 |
AddressOfRawData |
La dirección de los datos de depuración cuando se cargan, en relación con la base de la imagen. |
24 |
4 |
PointerToRawData |
Puntero de archivo a los datos de depuración. |
Tipo de depuración
Se definen los siguientes valores para el campo Tipo de la entrada del directorio de depuración:
Constante | Value | Descripción |
---|---|---|
IMAGE_DEBUG_TYPE_UNKNOWN |
0 |
Un valor desconocido que todas las herramientas omiten. |
IMAGE_DEBUG_TYPE_COFF |
1 |
La información de depuración de COFF (números de línea, tabla de símbolos y tabla de cadenas). Los campos de los encabezados de archivo también señalan a este tipo de información de depuración. |
IMAGE_DEBUG_TYPE_CODEVIEW |
2 |
La información de depuración de Visual C++. |
IMAGE_DEBUG_TYPE_FPO |
3 |
La información de omisión del puntero de trama (FPO). Esta información indica al depurador cómo interpretar marcos de pila no estándar, que usan el registro EBP para un propósito distinto al de puntero de marco. |
IMAGE_DEBUG_TYPE_MISC |
4 |
La ubicación del archivo DBG. |
IMAGE_DEBUG_TYPE_EXCEPTION |
5 |
Una copia de la sección .pdata. |
IMAGE_DEBUG_TYPE_FIXUP |
6 |
Reservado. |
IMAGE_DEBUG_TYPE_OMAP_TO_SRC |
7 |
La asignación de un RVA en la imagen a un RVA en la imagen de origen. |
IMAGE_DEBUG_TYPE_OMAP_FROM_SRC |
8 |
Asignación de una RVA de la imagen de origen a una RVA de la imagen. |
IMAGE_DEBUG_TYPE_BORLAND |
9 |
Reservado para Borland. |
IMAGE_DEBUG_TYPE_RESERVED10 |
10 |
Reservado. |
IMAGE_DEBUG_TYPE_CLSID |
11 |
Reservado. |
IMAGE_DEBUG_TYPE_REPRO |
16 |
Determinismo o reproducibilidad de PE. |
Undefined |
17 |
La información de depuración se inserta en el archivo PE en la ubicación especificada por PointerToRawData. |
Undefined |
19 |
Almacena el hash criptográfico para el contenido del archivo de símbolos usado para generar el archivo PE/COFF. |
IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS | 20 | Bits de características de DLL extendidos. |
Si el campo Tipo se establece en IMAGE_DEBUG_TYPE_FPO, los datos sin procesar de depuración son una matriz en la que cada miembro describe el marco de pila de una función. No todas las funciones del archivo de imagen deben tener definida información de FPO, aunque el tipo de depuración sea FPO. Se supone que las funciones que no tienen información de FPO tienen marcos de pila normales. El formato de la información de FPO es el siguiente:
#define FRAME_FPO 0
#define FRAME_TRAP 1
#define FRAME_TSS 2
typedef struct _FPO_DATA {
DWORD ulOffStart; // offset 1st byte of function code
DWORD cbProcSize; // # bytes in function
DWORD cdwLocals; // # bytes in locals/4
WORD cdwParams; // # bytes in params/4
WORD cbProlog : 8; // # bytes in prolog
WORD cbRegs : 3; // # regs saved
WORD fHasSEH : 1; // TRUE if SEH in func
WORD fUseBP : 1; // TRUE if EBP has been allocated
WORD reserved : 1; // reserved for future use
WORD cbFrame : 2; // frame type
} FPO_DATA;
La presencia de una entrada de tipo IMAGE_DEBUG_TYPE_REPRO indica que el archivo PE está construido de forma que se consiga determinismo o reproducibilidad. Si la entrada no cambia, se garantiza que el archivo PE de salida será idéntico bit a bit independientemente de cuándo o dónde se produzca el PE. Varios campos de marca de fecha y hora del archivo PE se rellenan con parte o todos los bits de un valor hash calculado que usa el contenido del archivo PE como entrada y, por lo tanto, ya no representan la fecha y hora reales en que se produce un archivo PE o datos específicos relacionados dentro del PE. Los datos sin procesar de esta entrada de depuración pueden estar vacíos o pueden contener un valor hash calculado precedido por un valor de cuatro bytes que representa la longitud del valor hash.
Si el campo Tipo se establece en IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS, los datos sin procesar de depuración contienen bits de características de DLL extendidos, además de los que se pueden establecer en el encabezado opcional de la imagen. Consulte Características de DLL en la sección Campos específicos de Windows de encabezado opcional (solo imagen).
Características de DLL extendidas
Los siguientes valores están definidos para los bits de características de DLL extendidas.
Constante | Value | Descripción |
---|---|---|
IMAGE_DLLCHARACTERISTICS_EX_CET_COMPAT | 0x0001 | La imagen es compatible con la pila paralela de la tecnología de aplicación de flujos de control (CET). |
IMAGE_DLLCHARACTERISTICS_EX_FORWARD_CFI_COMPAT | 0x0040 | Todos los objetivos de rama en todas las secciones de código de imagen se anotan con instrucciones de protección de la integridad del flujo de control hacia delante, como las instrucciones x86 CET-Indirect Branch Tracking (IBT) o ARM Branch Target Identification (BTI). Windows no usa este bit. |
.debug$F (solo objeto)
Los datos de esta sección se han reemplazado en la versión 7.0 de Visual C++ y versiones posteriores mediante un conjunto más extenso de datos que se emiten en una subsección .debug$S.
Los archivos objeto pueden contener secciones .debug$F cuyo contenido es uno o más registros FPO_DATA (información de omisión del puntero de fotograma). Consulte "IMAGE_DEBUG_TYPE_FPO" en Tipo de depuración.
El enlazador reconoce estos registros .debug$F. Si se genera información de depuración, el vinculador ordena los registros de FPO_DATA por procedimiento RVA y genera una entrada de directorio de depuración para ellos.
El compilador no debe generar registros FPO para procedimientos que tengan un formato de marco estándar.
.debug$S (solo objeto)
Esta sección contiene información de depuración de Visual C++ (información simbólica).
.debug$P (solo objeto)
Esta sección contiene información de depuración de Visual C++ (información precompilada). Estos son tipos compartidos entre todos los objetos que se compilaron mediante el encabezado precompilado que se generó con este objeto.
.debug$T (solo objeto)
Esta sección contiene información de depuración de Visual C++ (información de tipo).
Compatibilidad del vinculador con la información de depuración de Microsoft
Para admitir la información de depuración, el vinculador:
Recopila todos los datos de depuración pertinentes de las secciones .debug$F, debug$S, .debug$P y .debug$T.
Procesa esos datos junto con la información de depuración generada por el enlazador en el archivo PDB y crea una entrada de directorio de depuración para hacer referencia a ellos.
La sección .drectve (solo objeto)
Una sección es una sección de directiva si tiene la marca IMAGE_SCN_LNK_INFO establecida en el encabezado de sección y tiene el nombre de la sección .drectve. El enlazador quita una sección .drectve después de procesar la información, por lo que la sección no aparece en el archivo de imagen que se está enlazando.
Una sección .drectve consta de una cadena de texto que se puede codificar como ANSI o UTF-8. Si el marcador de orden de bytes UTF-8 (BOM, un prefijo de tres bytes que consta de 0xEF, 0xBB y 0xBF) no está presente, la cadena de directiva se interpreta como ANSI. La cadena de directiva es una serie de opciones de enlazador que están separadas por espacios. Cada opción contiene un guion, el nombre de la opción y cualquier atributo apropiado. Si una opción contiene espacios, la opción debe ir entre comillas. La sección .drectve no debe tener reubicaciones ni números de línea.
La sección .edata (solo imagen)
La sección de exportación de datos, denominada .edata, contiene información sobre los símbolos a los que pueden acceder otras imágenes a través de enlaces dinámicos. Por lo general, los símbolos exportados se encuentran en archivos DLL, pero los archivos DLL también pueden importar símbolos.
A continuación se describe información general sobre la estructura de la sección de exportación. Las tablas descritas suelen ser contiguas en el archivo en el orden que se muestra (aunque esto no es obligatorio). Solo la tabla de directorios de exportación y la tabla de dirección de exportación son necesarias para exportar símbolos como ordinales. (Un ordinal es una exportación a la que accede directamente su índice de tabla de direcciones de exportación). La tabla de puntero de nombre, la tabla ordinal y la tabla de nombre de exportación existen para admitir el uso de nombres de exportación.
Nombre de la tabla | Descripción |
---|---|
Tabla de directorios de exportación |
Una tabla con una sola fila (a diferencia del directorio debug). Esta tabla indica las ubicaciones y tamaños de las otras tablas de exportación. |
Tabla de direcciones de exportación |
Matriz de RVA de símbolos exportados. Estas son las direcciones reales de las funciones exportadas y los datos dentro de las secciones de datos y código ejecutable. Otros archivos de imagen pueden importar un símbolo usando un índice para esta tabla (un ordinal) u, opcionalmente, usando el nombre público que corresponde al ordinal si se define un nombre público. |
Tabla de punteros de nombres |
Matriz de punteros a los nombres de exportación públicos, ordenados en orden ascendente. |
Tabla ordinal |
Matriz de los ordinales que corresponden a miembros de la tabla de punteros de nombres. La correspondencia es por posición; por lo tanto, la tabla de punteros de nombres y la tabla de ordinales deben tener el mismo número de miembros. Cada ordinal es un índice en la tabla de direcciones de exportación. |
Tabla de nombres de exportación |
Una serie de cadenas ASCII terminadas en null. Los miembros de la tabla de punteros de nombres apuntan a esta área. Estos nombres son los nombres públicos a través de los cuales se importan y exportan los símbolos; no son necesariamente los mismos que los nombres privados que se usan dentro del archivo de imagen. |
Cuando otro archivo de imagen importa un símbolo por nombre, el cargador win32 busca en la tabla de punteros de nombres una cadena coincidente. Si se encuentra una cadena coincidente, el ordinal asociado se identifica buscando el miembro correspondiente en la tabla de ordinales (es decir, el miembro de la tabla de ordinales con el mismo índice que el puntero de cadena encontrado en la tabla de punteros de nombres). El ordinal resultante es un índice de la tabla de direcciones de exportación, que proporciona la ubicación real del símbolo deseado. Un ordinal puede acceder a todos los símbolos de exportación.
Cuando otro archivo de imagen importa un símbolo por ordinal, no es necesario buscar en la tabla de punteros de nombres una cadena coincidente. Por lo tanto, el uso directo de un ordinal es más eficaz. Sin embargo, un nombre de exportación es más fácil de recordar y no requiere que el usuario conozca el índice de tabla del símbolo.
Tabla de directorios de exportación
La información del símbolo de exportación comienza con la tabla de directorios de exportación, que describe el resto de la información del símbolo de exportación. La tabla de directorios de exportación contiene información de dirección que se usa para resolver las importaciones en los puntos de entrada de esta imagen.
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
4 |
Marcas de exportación |
Reservado, debe ser 0. |
4 |
4 |
Marca de fecha/hora |
Fecha y hora en que se crearon los datos de exportación. |
8 |
2 |
Versión principal |
Número de versión principal. El usuario puede establecer los números de versión principal y secundaria. |
10 |
2 |
Versión secundaria |
Número de versión secundaria. |
12 |
4 |
RVA del nombre |
Dirección de la cadena ASCII que contiene el nombre del archivo DLL. Esta dirección es relativa a la base de la imagen. |
16 |
4 |
Base de ordinal |
Número ordinal inicial para las exportaciones de esta imagen. Este campo especifica el número ordinal inicial de la tabla de direcciones de exportación. Suele estar establecido en 1. |
20 |
4 |
Entradas de tabla de direcciones |
Número de entradas de la tabla de direcciones de exportación. |
24 |
4 |
Número de punteros de nombres |
Número de entradas en la tabla de punteros de nombres. También es el número de entradas de la tabla de ordinales. |
28 |
4 |
RVA de tabla de direcciones de exportación |
Dirección de la tabla de direcciones de exportación, relativa a la base de la imagen. |
32 |
4 |
RVA de puntero de nombre |
Dirección de la tabla de punteros del nombre de exportación, relativa a la base de la imagen. El tamaño de la tabla viene dado por el campo Número de punteros de nombres. |
36 |
4 |
RVA de tabla de ordinales |
La dirección de la tabla ordinal, relativa a la base de la imagen. |
Tabla de direcciones de exportación
La tabla de direcciones de exportación contiene la dirección de los puntos de entrada exportados y los datos y absolutos exportados. Un número ordinal se usa como índice en la tabla de direcciones de exportación.
Cada entrada de la tabla de direcciones de exportación es un campo que usa uno de los dos formatos de la siguiente tabla. Si la dirección especificada no está dentro de la sección de exportación (tal y como se define en la dirección y la longitud que se indican en el encabezado opcional), el campo es un RVA de exportación, que es una dirección real en código o datos. De lo contrario, el campo es una RVA de reenviador, que asigna un nombre a un símbolo en otro archivo DLL.
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
4 |
Export RVA |
La dirección del símbolo exportado cuando se carga en la memoria, en relación con la base de la imagen. Por ejemplo, la dirección de una función exportada. |
0 |
4 |
RVA de reenviador |
Puntero a una cadena ASCII terminada en null en la sección de exportación. Esta cadena debe estar dentro del intervalo dado por la entrada del directorio de datos de la tabla de exportación. Consulte Directorios de datos de encabezado opcionales (solo imagen). Esta cadena proporciona el nombre de DLL y el nombre de la exportación (por ejemplo, "MYDLL.expfunc") o el nombre de DLL y el número ordinal de la exportación (por ejemplo, "MYDLL.#27"). |
Un RVA de reenviador exporta una definición de otra imagen, haciendo que parezca que está exportando la imagen actual. De este manera, el símbolo se importa y exporta simultáneamente.
Por ejemplo, en Kernel32.dll de Windows XP, la exportación denominada "HeapAlloc" se reenvía a la cadena "NTDLL.RtlAllocateHeap". Esto permite a las aplicaciones usar el módulo específico de Windows XP Ntdll.dll sin contener realmente referencias de importación a él. La tabla de importaciones de la aplicación solo hace referencia a Kernel32.dll. Por lo tanto, la aplicación no es específica de Windows XP y se puede ejecutar en cualquier sistema Win32.
Tabla de punteros del nombre de exportación
La tabla de punteros del nombre de exportación es una matriz de direcciones (RVA) en la tabla de nombre de exportación. Los punteros son de 32 bits cada uno y son relativos a la base de la imagen. Los punteros están ordenados léxicamente para permitir búsquedas binarias.
Un nombre de exportación solo se define si la tabla de punteros del nombre de exportación contiene un puntero a él.
Tabla de ordinales de exportación
La tabla ordinal de exportación es una matriz de índices no sesgados de 16 bits en la tabla de direcciones de exportación. Los ordinales están sesgados por el campo Base ordinal de la tabla de directorios de exportación. En otras palabras, la base ordinal debe restarse de los ordinales para obtener índices verdaderos en la tabla de direcciones de exportación.
La tabla de punteros del nombre de exportación y la tabla ordinal de exportación forman dos matrices paralelas que están separadas para permitir la alineación de campo natural. Estas dos tablas, en efecto, funcionan como una sola tabla, en la que la columna Puntero de nombre de exportación apunta a un nombre público (exportado) y la columna Ordinal de exportación proporciona el ordinal correspondiente para ese nombre público. Un miembro de la tabla de punteros del nombre de exportación y un miembro de la tabla ordinal de exportación se asocian teniendo la misma posición (índice) en sus respectivas matrices.
De esta manera, cuando se busca la tabla de punteros del nombre de exportación y se encuentra una cadena coincidente en la posición i, el algoritmo para buscar la RVA del símbolo y el ordinal sesgado es:
i = Search_ExportNamePointerTable (name);
ordinal = ExportOrdinalTable [i];
rva = ExportAddressTable [ordinal];
biased_ordinal = ordinal + OrdinalBase;
Al buscar un símbolo por ordinal (sesgado), el algoritmo para buscar la RVA y el nombre del símbolo es:
ordinal = biased_ordinal - OrdinalBase;
i = Search_ExportOrdinalTable (ordinal);
rva = ExportAddressTable [ordinal];
name = ExportNameTable [i];
Tabla de nombres de exportación
La tabla de nombre de exportación contiene los datos de cadena reales a los que apuntó la tabla de punteros del nombre de exportación. Las cadenas de esta tabla son nombres públicos que otras imágenes pueden usar para importar los símbolos. Estos nombres públicos de exportación no son necesariamente los mismos que los nombres privados que tienen los símbolos en su propio archivo de imagen y código fuente, aunque pueden serlo.
Cada símbolo exportado tiene un valor ordinal, que es simplemente el índice en la tabla de direcciones de exportación. Sin embargo, el uso de nombres de exportación es opcional. Algunos, todos o ninguno de los símbolos exportados pueden tener nombres de exportación. En el caso de los símbolos exportados que sí tienen nombres de exportación, las entradas correspondientes de la tabla de punteros del nombre de exportación y de la tabla de ordinales de exportación funcionan conjuntamente para asociar cada nombre a un ordinal.
La estructura de la tabla de nombres de exportación es una serie de cadenas ASCII terminadas en null de longitud variable.
La sección .idata
Todos los archivos de imagen que importan símbolos, incluidos prácticamente todos los archivos ejecutables (EXE), tienen una sección .idata. A continuación se muestra un diseño de archivo típico para la información de importación:
Tabla de directorios
Entrada de directorio nula
Tabla de búsqueda de importación DLL1
Null
Tabla de búsqueda de importación DLL2
Null
Tabla de búsqueda de importación DLL3
Null
Tabla de sugerencias/nombres
Tabla de directorios de importación
La información de importación comienza con la tabla de directorio de importación, que describe el resto de la información de importación. La tabla del directorio de importación contiene información de dirección que se usa para resolver las referencias de corrección a los puntos de entrada dentro de una imagen DLL. La tabla de directorio de importación consta de una matriz de entradas de directorio de importación, una entrada para cada archivo DLL al que hace referencia la imagen. La última entrada de directorio está vacía (rellena con valores nulos), lo que indica el final de la tabla de directorio.
Cada entrada del directorio de importación tiene el siguiente formato:
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
4 |
Tabla de búsqueda de importación RVA (características) |
El RVA de la tabla de búsqueda de importación. Esta tabla contiene un nombre u ordinal para cada importación. (El nombre "Características" se usa en Winnt.h, pero ya no describe este campo). |
4 |
4 |
Marca de fecha/hora |
Marca que se establece en cero hasta que se enlaza la imagen. Una vez enlazada la imagen, este campo se establece en la marca de tiempo y datos del archivo DLL. |
8 |
4 |
Cadena de reenviador |
Índice de la primera referencia del reenviador. |
12 |
4 |
RVA del nombre |
Dirección de una cadena ASCII que contiene el nombre del archivo DLL. Esta dirección es relativa a la base de la imagen. |
16 |
4 |
RVA de tabla de direcciones de importación (tabla thunk) |
El RVA de la tabla de direcciones de importación. El contenido de esta tabla es idéntico al contenido de la tabla de búsqueda de importación hasta que la imagen esté enlazada. |
Tabla de búsqueda de importaciones
Una tabla de búsqueda de importación es una matriz de números de 32 bits para PE32 o una matriz de números de 64 bits para PE32+. Cada entrada usa el formato de campo de bits que se describe en la siguiente tabla. En este formato, el bit 31 es el bit más significativo para PE32 y el bit 63 es el bit más significativo para PE32+. La colección de estas entradas describe todas las importaciones desde un archivo DLL determinado. La última entrada se establece en cero (NULL) para indicar el final de la tabla.
Bit(s) | Size | Campo de bit | Descripción |
---|---|---|---|
31/63 |
1 |
Indicador ordinal/de nombre |
Si se establece este bit, se importa por ordinal. De lo contrario, se importa por nombre. El bit se enmascara como 0x80000000 para PE32, 0x8000000000000000 para PE32+. |
15-0 |
16 |
Número ordinal |
Número ordinal de 16 bits. Este campo solo se usa si el campo de bits Marca de ordinal/nombre es 1 (importar por ordinal). Los bits 30-15 o 62-15 deben ser 0. |
30-0 |
31 |
RVA de tabla de sugerencias/nombres |
RVA de 31 bits de una entrada de la tabla de sugerencias/nombres. Este campo solo se usa si el campo de bits Marca de ordinal/nombre es 0 (importar por nombre). Para PE32+, los bits 62-31 deben ser cero. |
Tabla de sugerencias/nombres
Una tabla de sugerencias/nombres basta para toda la sección de importación. Cada entrada de la tabla de sugerencias/nombres tiene el siguiente formato:
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
2 |
Sugerencia |
Índice en la tabla de punteros del de nombre de exportación. Primero se intenta una coincidencia con este valor. Si no es correcta, se realiza una búsqueda binaria en la tabla de punteros del nombre de exportación del archivo DLL. |
2 |
variable |
Nombre |
Cadena ASCII que contiene el nombre que se va a importar. Esta es la cadena que debe coincidir con el nombre público del archivo DLL. Esta cadena distingue entre mayúsculas y minúsculas y finaliza mediante un byte null. |
* |
0 o 1 |
Relleno |
Byte final de relleno cero que aparece después del byte nulo final, si es necesario, para alinear la siguiente entrada en un límite par. |
Tabla de direcciones de importación
La estructura y el contenido de la tabla de direcciones de importación son idénticos a los de la tabla de búsqueda de importaciones, hasta que se enlaza el archivo. Durante el enlace, las entradas de la tabla de direcciones de importación se sobrescriben con las direcciones de 32 bits (para PE32) o 64 bits (para PE32+) de los símbolos que se importan. Estas direcciones son las direcciones de memoria reales de los símbolos, aunque técnicamente todavía se denominan "direcciones virtuales". Normalmente, el cargador procesa el enlace.
La sección .pdata
La sección .pdata contiene una matriz de entradas de tabla de función que se usan para el control de excepciones. Apunta a la entrada de la tabla de excepciones en el directorio de datos de imagen. Las entradas deben ordenarse de acuerdo con las direcciones de las funciones (el primer campo de cada estructura) antes de emitirse en la imagen final. La plataforma de destino determina cuál de las tres variaciones de formato de entrada de la tabla de funciones que se describen a continuación se usa.
Para imágenes MIPS de 32 bits, las entradas de tabla de función tienen el siguiente formato:
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
4 |
Dirección inicial |
VA de la función correspondiente. |
4 |
4 |
Dirección final |
VA del final de la función. |
8 |
4 |
Controlador de excepciones |
Puntero al controlador de excepciones que se va a ejecutar. |
12 |
4 |
Datos del controlador |
Puntero a la información adicional que se va a pasar al controlador. |
16 |
4 |
Dirección final de Prolog |
La VA del final del prólogo de la función. |
Para las plataformas ARM, PowerPC, SH3 y SH4 Windows CE, las entradas de tabla de funciones tienen el siguiente formato:
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
4 |
Dirección inicial |
VA de la función correspondiente. |
4 |
8 bits |
Longitud del prólogo |
El número de instrucciones en el prólogo de la función. |
4 |
22 bits |
Longitud de la función |
El número de instrucciones de la función. |
4 |
1 bits |
Marca de 32 bits |
Si se establece, la función consta de instrucciones de 32 bits. Si se borra, la función consta de instrucciones de 16 bits. |
4 |
1 bits |
Marca de excepción |
Si se establece, existe un controlador de excepciones para la función. De lo contrario, no existe ningún controlador de excepciones. |
Para las plataformas x64 e Itanium, las entradas de la tabla de funciones tienen el siguiente formato:
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
4 |
Dirección inicial |
El RVA de la función correspondiente. |
4 |
4 |
Dirección final |
RVA del final de la función. |
8 |
4 |
Información de desenredado |
RVA de la información de desenredado. |
La sección .reloc (solo imagen)
La tabla de reubicación base contiene entradas para todas las reubicaciones base de la imagen. El campo Tabla de reubicaciones base en los directorios de datos de encabezado opcional proporciona el número de bytes en la tabla de reubicaciones base. Para obtener más información, consulte Directorios de datos de encabezado opcionales (solo imagen). La tabla de reubicación de la base está dividida en bloques. Cada bloque representa las reubicaciones base de una página 4K. Cada bloque debe comenzar en un límite de 32 bits.
El cargador no es necesario para procesar reubicaciones base resueltas por el enlazador, a menos que la imagen de carga no se pueda cargar en la base de imagen especificada en el encabezado PE.
Bloque de reubicación base
Cada bloque de reubicación base comienza con la siguiente estructura:
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
4 |
RVA de página |
La base de imagen más la RVA de la página se agregan a cada desplazamiento para crear la VA donde se debe aplicar la reubicación base. |
4 |
4 |
Tamaño del bloque |
Número total de bytes en el bloque de reubicación base, incluidos los campos RVA de página y Tamaño de bloque y los campos Tipo/Desplazamiento siguientes. |
A continuación, el campo Tamaño de bloque va seguido de cualquier número de entradas del campo Tipo o Desplazamiento. Cada entrada es WORD (2 bytes) y tiene la estructura siguiente:
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
4 bits |
Tipo |
Se almacena en los 4 bits altos de WORD, un valor que indica el tipo de reubicación base que se va a aplicar. Para obtener más información, consulte Tipos de reubicación base. |
0 |
12 bits |
Desplazamiento |
Se almacena en los 12 bits restantes de WORD, un desplazamiento de la dirección inicial que se especificó en el campo RVA de página del bloque. Este desplazamiento especifica dónde se va a aplicar la reubicación base. |
Para aplicar una reubicación base, se calcula la diferencia entre la dirección base preferida y la base en la que se carga realmente la imagen. Si la imagen se carga en su base preferida, la diferencia es cero y, por lo tanto, no es necesario aplicar las reubicaciones de base.
Tipos de reubicación base
Constante | Value | Descripción |
---|---|---|
IMAGE_REL_BASED_ABSOLUTE |
0 |
Se omite la reubicación de la base. Este tipo se puede usar para rellenar un bloque. |
IMAGE_REL_BASED_HIGH |
1 |
La reubicación base agrega los 16 bits altos de la diferencia al campo de 16 bits en el desplazamiento. El campo de 16 bits representa el valor alto de una palabra de 32 bits. |
IMAGE_REL_BASED_LOW |
2 |
La reubicación base agrega los 16 bits bajos de la diferencia al campo de 16 bits en el desplazamiento. El campo de 16 bits representa la mitad inferior de una palabra de 32 bits. |
IMAGE_REL_BASED_HIGHLOW |
3 |
La reubicación base aplica los 32 bits de la diferencia al campo de 32 bits en el desplazamiento. |
IMAGE_REL_BASED_HIGHADJ |
4 |
La reubicación base agrega los 16 bits altos de la diferencia al campo de 16 bits en el desplazamiento. El campo de 16 bits representa el valor alto de una palabra de 32 bits. Los 16 bits bajos del valor de 32 bits se almacenan en la palabra de 16 bits que sigue a esta reubicación base. Esto significa que esta reubicación base ocupa dos ranuras. |
IMAGE_REL_BASED_MIPS_JMPADDR |
5 |
La interpretación de la reubicación depende del tipo de máquina. Cuando el tipo de máquina es MIPS, la reubicación base se aplica a una instrucción de salto MIPS. |
IMAGE_REL_BASED_ARM_MOV32 |
5 |
Esta reubicación solo tiene sentido cuando el tipo de máquina es ARM o Thumb. La reubicación base aplica la dirección de 32 bits de un símbolo en un par consecutivo de instrucciones MOVW/MOVT. |
IMAGE_REL_BASED_RISCV_HIGH20 |
5 |
Esta reubicación solo tiene sentido cuando el tipo de máquina es RISC-V. La reubicación base se aplica a los 20 bits altos de una dirección absoluta de 32 bits. |
6 |
Reservado, debe ser cero. |
|
IMAGE_REL_BASED_THUMB_MOV32 |
7 |
Esta reubicación solo es significativa cuando el tipo de máquina es Thumb. La reubicación base aplica la dirección de 32 bits de un símbolo a un par consecutivo de instrucciones MOVW/MOVT. |
IMAGE_REL_BASED_RISCV_LOW12I |
7 |
Esta reubicación solo tiene sentido cuando el tipo de máquina es RISC-V. La reubicación base se aplica a los 12 bits bajos de una dirección absoluta de 32 bits formada con el formato de instrucción RISC-V de tipo I. |
IMAGE_REL_BASED_RISCV_LOW12S |
8 |
Esta reubicación solo tiene sentido cuando el tipo de máquina es RISC-V. La reubicación base se aplica a los 12 bits bajos de una dirección absoluta de 32 bits formada en formato de instrucción de tipo S RISC-V. |
IMAGE_REL_BASED_LOONGARCH32_MARK_LA |
8 |
Esta reubicación solo tiene sentido cuando el tipo de máquina es LoongArch de 32 bits. La reubicación base se aplica a una dirección absoluta de 32 bits formada en dos instrucciones consecutivas. |
IMAGE_REL_BASED_LOONGARCH64_MARK_LA |
8 |
Esta reubicación solo tiene sentido cuando el tipo de máquina es LoongArch de 64 bits. La reubicación base se aplica a una dirección absoluta de 64 bits formada en cuatro instrucciones consecutivas. |
IMAGE_REL_BASED_MIPS_JMPADDR16 |
9 |
La reubicación solo tiene sentido cuando el tipo de máquina es MIPS. La reubicación de la base se aplica a una instrucción de salto MIPS16. |
IMAGE_REL_BASED_DIR64 |
10 |
La reubicación base aplica la diferencia al campo de 64 bits en el desplazamiento. |
La sección .tls
La sección .tls proporciona compatibilidad directa con PE y COFF para el almacenamiento local de subprocesos estáticos (TLS). TLS es una clase de almacenamiento especial que admite Windows en la que un objeto de datos no es una variable automática (pila), sino que es local para cada subproceso individual que ejecuta el código. De esta manera, cada subproceso puede mantener un valor diferente para una variable declarada mediante TLS.
Tenga en cuenta que se puede admitir cualquier cantidad de datos TLS mediante las llamadas API TlsAlloc, TlsFree, TlsSetValue y TlsGetValue. La implementación de PE o COFF es un enfoque alternativo al uso de la API y tiene la ventaja de ser más simple desde el punto de vista del programador de lenguaje de alto nivel. Esta implementación permite que los datos TLS se definan e inicialicen de manera similar a las variables estáticas ordinarias de un programa. Por ejemplo, en Visual C++, se puede definir una variable TLS estática como se indica a continuación, sin usar la API de Windows:
__declspec (thread) int tlsFlag = 1;
Para admitir esta construcción de programación, la sección .tls de PE y COFF especifica la siguiente información: datos de inicialización, rutinas de devolución de llamada para la inicialización y terminación por subproceso, y el índice TLS, que se explica en el siguiente apartado.
Nota:
Antes de Windows Vista, los objetos de datos TLS declarados estáticamente solo se podían usar en archivos de imagen cargados estáticamente. Este hecho hace que no sea fiable usar datos TLS estáticos en un archivo DLL a menos que sepa que el archivo DLL, o cualquier elemento enlazado estáticamente con él, nunca se cargará dinámicamente con la función de la API loadLibrary. Sin embargo, a partir de Windows Vista, se realizaron mejoras en el cargador de Windows para admitir mejor la carga dinámica de archivos DLL con TLS estático. Este cambio significa que los archivos DLL con objetos de datos TLS declarados estáticamente ahora se pueden usar de forma más confiable, incluso si se cargan dinámicamente mediante LoadLibrary. El cargador es capaz de asignar ranuras TLS para estos archivos DLL en tiempo de carga, lo que mitiga las limitaciones presentes en versiones anteriores de Windows.
Nota:
Las referencias a desplazamientos de 32 bits y multiplicadores de índice de 4 se aplican a sistemas con arquitecturas de 32 bits. En un sistema basado en arquitecturas de 64 bits, ajústelas según sea necesario.
El código ejecutable accede a un objeto de datos TLS estático mediante los pasos siguientes:
En el momento del vínculo, el vinculador establece el campo Dirección de índice del directorio TLS. Este campo apunta a una ubicación en la que el programa espera recibir el índice TLS.
La biblioteca en tiempo de ejecución de Microsoft facilita este proceso definiendo una imagen de memoria del directorio TLS y asignándole el nombre especial "__tls_used" (plataformas Intel x86) o "_tls_used" (otras plataformas). El enlazador busca esta imagen de memoria y usa los datos para crear el directorio TLS. Otros compiladores que admiten TLS y funcionan con el enlazador de Microsoft deben usar esta misma técnica.
Cuando se crea un subproceso, el cargador comunica la dirección de la matriz TLS del subproceso colocando la dirección del bloque de entorno de subproceso (TEB) en el registro FS. Un puntero a la matriz TLS se encuentra en el desplazamiento de 0x2C desde el principio de TEB. Este comportamiento es específico de Intel x86.
El cargador asigna el valor del índice TLS al lugar indicado por el campo Dirección del índice.
El código ejecutable recupera el índice TLS y también la ubicación de la matriz TLS.
El código usa el índice TLS y la ubicación de la matriz TLS (multiplicando el índice por 4 y usándolo como un desplazamiento de la matriz) para obtener la dirección del área de datos TLS para el programa y el módulo dados. Cada subproceso tiene su propia área de datos TLS, pero esto es transparente para el programa, que no necesita saber cómo se asignan los datos para subprocesos individuales.
Se accede a un objeto de datos TLS individual como un desplazamiento fijo en el área de datos TLS.
La matriz TLS es una matriz de direcciones que el sistema mantiene en cada subproceso. Cada dirección de esta matriz proporciona la ubicación de los datos TLS para un módulo determinado (EXE o DLL) dentro del programa. El índice TLS indica qué miembro de la matriz se va a usar. El índice es un número (significativo solo para el sistema) que identifica el módulo.
El directorio TLS
El directorio TLS tiene el siguiente formato:
Desplazamiento (PE32/PE32+) | Tamaño (PE32/PE32+) | Campo | Descripción |
---|---|---|---|
0 |
4/8 |
VA de inicio de datos sin procesar |
La dirección de inicio de la plantilla TLS. La plantilla es un bloque de datos que se usa para inicializar los datos TLS. El sistema copia todos estos datos cada vez que se crea un subproceso, por lo que no debe estar dañado. Tenga en cuenta que esta dirección no es una RVA; es una dirección para la que debe haber una reubicación base en la sección .reloc. |
4/8 |
4/8 |
VA de fin de datos sin procesar |
Dirección del último byte de TLS, excepto el relleno cero. Al igual que con el campo VA de inicio de datos sin procesar, es una VA, no una RVA. |
8/16 |
4/8 |
Dirección del índice |
La ubicación para recibir el índice TLS, que asigna el cargador. Esta ubicación se encuentra en una sección de datos ordinaria, por lo que se le puede dar un nombre simbólico que sea accesible para el programa. |
12/24 |
4/8 |
Dirección de devoluciones de llamada |
Puntero a una matriz de funciones de devolución de llamada TLS. La matriz termina en null, por lo que si no se admite ninguna función de devolución de llamada, este campo apunta a 4 bytes establecidos en cero. Para obtener información sobre el prototipo de estas funciones, consulte Funciones de devolución de llamada TLS. |
16/32 |
4 |
Tamaño de relleno cero |
Tamaño en bytes de la plantilla, más allá de los datos inicializados delimitados por los campos VA de inicio de datos sin procesar y VA de finalización de datos sin procesar. El tamaño total de la plantilla debe ser el mismo que el tamaño total de los datos TLS en el archivo de imagen. El relleno cero es la cantidad de datos que viene después de los datos inicializados distintos de cero. |
20/36 |
4 |
Características |
Los cuatro bits [23:20] describen la información de alineación. Los valores posibles son los definidos como IMAGE_SCN_ALIGN_*, que también se usan para describir la alineación de la sección en los archivos de objeto. Los otros 28 bits están reservados para uso futuro. |
Funciones de devolución de llamada de TLS
El programa puede proporcionar una o más funciones de devolución de llamada TLS para admitir la inicialización y terminación adicionales para objetos de datos TLS. Un uso típico de una función de devolución de llamada sería llamar a los constructores y destructores de objetos.
Aunque normalmente no hay más de una función de devolución de llamada, se implementa una devolución de llamada como una matriz para que sea posible agregar funciones de devolución de llamada adicionales si lo desea. Si hay más de una función de devolución de llamada, se llama a cada función en el orden en que su dirección aparece en la matriz. Un puntero nulo finaliza la matriz. Es perfectamente válido tener una lista vacía (no se admite ninguna devolución de llamada), en cuyo caso la matriz de devolución de llamada tiene exactamente un miembro, un puntero nulo.
El prototipo de una función de devolución de llamada (a la que apunta un puntero de tipo PIMAGE_TLS_CALLBACK) tiene los mismos parámetros que una función de punto de entrada DLL:
typedef VOID
(NTAPI *PIMAGE_TLS_CALLBACK) (
PVOID DllHandle,
DWORD Reason,
PVOID Reserved
);
El parámetro Reservado debe establecerse en cero. El parámetro Reason puede tomar los siguientes valores:
Configuración | valor | Descripción |
---|---|---|
DLL_PROCESS_ATTACH |
1 |
Se ha iniciado un nuevo proceso, incluido el primer hilo. |
DLL_THREAD_ATTACH |
2 |
Se ha creado un nuevo hilo. Esta notificación se ha enviado para todos los subprocesos, menos para el primero. |
DLL_THREAD_DETACH |
3 |
Un hilo está a punto de terminarse. Esta notificación se ha enviado para todos los subprocesos, menos para el primero. |
DLL_PROCESS_DETACH |
0 |
Un proceso está a punto de finalizar, incluido el subproceso original. |
La estructura de configuración de carga (solo imagen)
La estructura de configuración de carga (IMAGE_LOAD_CONFIG_DIRECTORY) se usaba anteriormente en casos muy limitados en el propio sistema operativo Windows NT para describir varias características demasiado difíciles o demasiado grandes para describirlas en el encabezado del archivo o en el encabezado opcional de la imagen. Las versiones actuales del enlazador de Microsoft y Windows XP y versiones posteriores de Windows usan una nueva versión de esta estructura para sistemas basados en x86 de 32 bits que incluyen tecnología SEH reservada. Esto proporciona una lista de controladores de excepciones estructurados seguros que el sistema operativo usa durante la distribución de excepciones. Si la dirección del controlador reside en el intervalo de VA de una imagen y se marca como compatible con SEH reservado (es decir, IMAGE_DLLCHARACTERISTICS_NO_SEH está sin marcar en el campo DllCharacteristics del encabezado opcional, como se ha descrito anteriormente), el controlador debe estar en la lista de controladores seguros conocidos para esa imagen. De lo contrario, el sistema operativo finaliza la aplicación. Esto ayuda a evitar la vulnerabilidad de "secuestro del controlador de excepciones x86" que se ha usado en el pasado para tomar el control del sistema operativo.
El vinculador de Microsoft proporciona automáticamente una estructura de configuración de carga predeterminada para incluir los datos SEH reservados. Si el código del usuario ya proporciona una estructura de configuración de carga, debe incluir los nuevos campos SEH reservados. De lo contrario, el enlazador no puede incluir los datos de SEH reservado y la imagen no está marcada como contenedora de SEH reservado.
Directorio de configuración de carga
La entrada del directorio de datos para una estructura de configuración de carga de SEH reservado previamente debe especificar un tamaño determinado de la estructura de configuración de carga porque el cargador del sistema operativo siempre espera que sea un valor determinado. En ese sentido, el tamaño es realmente solo una verificación de versión. Para la compatibilidad con Windows XP y versiones anteriores de Windows, el tamaño debe ser 64 para las imágenes x86.
Diseño de configuración de carga
La estructura de configuración de carga tiene el siguiente diseño para archivos PE de 32 y 64 bits:
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
4 |
Características |
Marcas que indican los atributos del archivo, actualmente no se usa. |
4 |
4 |
TimeDateStamp |
Valor de marca de fecha y hora. El valor se representa en el número de segundos que han transcurrido desde la medianoche (00:00:00) del 1 de enero de 1970, Tiempo Universal Coordinado, según el reloj del sistema. La marca de tiempo se puede imprimir mediante la función de tiempo de ejecución de C (CRT). |
8 |
2 |
MajorVersion |
Número de versión principal. |
10 |
2 |
MinorVersion |
Número de versión secundaria. |
12 |
4 |
GlobalFlagsClear |
Las marcas del cargador global que se borrarán para este proceso a medida que el cargador inicia el proceso. |
16 |
4 |
GlobalFlagsSet |
Las marcas del cargador global que se definirán para este proceso a medida que el cargador inicia el proceso. |
20 |
4 |
CriticalSectionDefaultTimeout |
El valor de tiempo de espera predeterminado que se usará para las secciones críticas de este proceso que se abandonan. |
24 |
4/8 |
DeCommitFreeBlockThreshold |
Memoria que debe liberarse antes de devolverla al sistema, en bytes. |
28/32 |
4/8 |
DeCommitTotalFreeThreshold |
Cantidad total de memoria libre, en bytes. |
32/40 |
4/8 |
LockPrefixTable |
[solo x86] VA de una lista de direcciones donde se usa el prefijo LOCK para que se puedan reemplazar por NOP en máquinas de un único procesador. |
36/48 |
4/8 |
MaximumAllocationSize |
Tamaño máximo de asignación, en bytes. |
40/56 |
4/8 |
VirtualMemoryThreshold |
Tamaño máximo de memoria virtual, en bytes. |
44/64 |
4/8 |
ProcessAffinityMask |
Establecer este campo en un valor distinto de cero equivale a llamar a SetProcessAffinityMask con este valor durante el inicio del proceso (solo .exe) |
48/72 |
4 |
ProcessHeapFlags |
Marcas del montón de procesos que corresponden al primer argumento de la función HeapCreate. Estas marcas se aplican al montón de procesos que se crea durante el inicio del proceso. |
52/76 |
2 |
CSDVersion |
El identificador de versión del Service Pack. |
54/78 |
2 |
DependentLoadFlags |
Los indicadores de carga predeterminados que se utilizan cuando el sistema operativo resuelve las importaciones vinculadas estáticamente de un módulo. |
56/80 |
4/8 |
EditList |
Reservado para su uso por el sistema. |
60/88 |
4/8 |
SecurityCookie |
Puntero a una cookie que usa la implementación de Visual C++ o GS. |
64/96 |
4/8 |
SEHandlerTable |
[solo x86] VA de la tabla ordenada de RVA de cada controlador SE válido y único en la imagen. |
68/104 |
4/8 |
SEHandlerCount |
[solo x86] Recuento de controladores únicos de la tabla. |
72/112 |
4/8 |
GuardCFCheckFunctionPointer |
VA donde se almacena el puntero de la función de comprobación de protección de flujo de control. |
76/120 |
4/8 |
GuardCFDispatchFunctionPointer |
VA donde se almacena el puntero de la función de distribución de protección de flujo de control. |
80/128 |
4/8 |
GuardCFFunctionTable |
VA de la tabla ordenada de RVA de cada función de protección de flujo de control de la imagen. |
84/136 |
4/8 |
GuardCFFunctionCount |
El recuento de RVA únicos en la tabla anterior. |
88/144 |
4 |
GuardFlags |
Marcas relacionadas con la protección de flujo de control. |
92/148 |
12 |
CodeIntegrity |
Información de integridad del código. |
104/160 |
4/8 |
GuardAddressTakenIatEntryTable |
VA donde se almacena la dirección de protección de flujo de control tomada de la tabla IAT. |
108/168 |
4/8 |
GuardAddressTakenIatEntryCount |
El recuento de RVA únicos en la tabla anterior. |
112/176 |
4/8 |
GuardLongJumpTargetTable |
VA donde se almacena la tabla de destino de salto largo de protección de flujo de control. |
116/184 |
4/8 |
GuardLongJumpTargetCount |
El recuento de RVA únicos en la tabla anterior. |
El campo GuardFlags contiene una combinación de uno o varios de los siguientes indicadores y subcampos:
El módulo realiza comprobaciones de integridad de flujo de control mediante la compatibilidad proporcionada por el sistema.
#define IMAGE_GUARD_CF_INSTRUMENTED 0x00000100
El módulo realiza comprobaciones de integridad de escritura y flujo de control.
#define IMAGE_GUARD_CFW_INSTRUMENTED 0x00000200
El módulo contiene metadatos de destino de flujo de control válidos.
#define IMAGE_GUARD_CF_FUNCTION_TABLE_PRESENT 0x00000400
El módulo no usa la cookie de seguridad /GS.
#define IMAGE_GUARD_SECURITY_COOKIE_UNUSED 0x00000800
El módulo admite IAT de carga de retardo de solo lectura.
#define IMAGE_GUARD_PROTECT_DELAYLOAD_IAT 0x00001000
Tabla de importación con carga retrasada en su propia sección .didat (sin nada más) que se puede volver a proteger libremente.
#define IMAGE_GUARD_DELAYLOAD_IAT_IN_ITS_OWN_SECTION 0x00002000
El módulo contiene información de exportación suprimida. Esto también infiere que la tabla IAT de dirección tomada también está presente en la configuración de carga.
#define IMAGE_GUARD_CF_EXPORT_SUPPRESSION_INFO_PRESENT 0x00004000
El módulo permite la eliminación de las exportaciones.
#define IMAGE_GUARD_CF_ENABLE_EXPORT_SUPPRESSION 0x00008000
El módulo contiene información de destino de longjmp.
#define IMAGE_GUARD_CF_LONGJUMP_TABLE_PRESENT 0x00010000
Máscara para el subcampo que contiene el stride de las entradas de la tabla de funciones de protección de flujo de control (es decir, el recuento adicional de bytes por entrada de tabla).
#define IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_MASK 0xF0000000
Además, el encabezado winnt.h del SDK de Windows define esta macro para la cantidad de bits a desplazar a la derecha el valor de GuardFlags, para justificar a la derecha el stride de la tabla de funciones de protección de flujo de control:
#define IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_SHIFT 28
La sección .rsrc
Los recursos se indexan mediante una estructura de árbol ordenada binariamente de varios niveles. El diseño general puede incorporar niveles 2**31. Sin embargo, por convención, Windows usa tres niveles:
- Lenguaje de nombre de tipo
Una serie de tablas de directorios de recursos relaciona todos los niveles de la siguiente manera: cada tabla de directorios va seguida de una serie de entradas de directorio que proporcionan el nombre o el identificador (ID) para ese nivel (Tipo, Nombre o Nivel de lenguaje) y una dirección de una descripción de datos u otra tabla de directorios. Si la dirección apunta a una descripción de datos, entonces los datos son una hoja en el árbol. Si la dirección apunta a otra tabla de directorio, esa tabla enumera las entradas de directorio en el siguiente nivel hacia abajo.
Los ID de tipo, nombre y lenguaje de una hoja vienen determinados por la ruta de acceso que se toma a través de tablas de directorios para llegar a la hoja. La primera tabla determina el ID de tipo, la segunda tabla (señalada por la entrada de directorio en la primera tabla) determina el identificador de nombre y la tercera tabla determina el ID de lenguaje.
La estructura general de la sección .rsrc es:
Data | Descripción |
---|---|
Tablas de directorioa de recursos (y entradas de directorio de recursos) |
Una serie de tablas, una para cada grupo de nodos del árbol. Todos los nodos de nivel superior (tipo) se enumeran en la primera tabla. Las entradas de esta tabla apuntan a tablas de segundo nivel. Cada árbol de segundo nivel tiene el mismo ID de tipo pero diferentes ID de nombre. Los árboles de tercer nivel tienen los mismos ID de tipo y nombre, pero diferentes ID de lenguaje. Cada tabla individual es seguida inmediatamente por entradas de directorio, en las que cada entrada tiene un nombre o identificador numérico y un puntero a una descripción de datos o una tabla en el siguiente nivel inferior. |
Cadenas de directorio de recursos |
Cadenas Unicode alineadas con dos bytes, que sirven como datos de cadena a los que apuntan las entradas de directorio. |
Descripción de los datos de recursos |
Matriz de registros, a la que apuntan las tablas, que describen el tamaño real y la ubicación de los datos del recurso. Estos registros son las hojas del árbol de descripción de recursos. |
Datos de recursos |
Datos sin procesar de la sección de recursos. La información de tamaño y ubicación del campo Descripciones de datos de recursos delimita las regiones individuales de los datos de recursos. |
Tabla de directorios de recursos
Cada tabla de directorios de recursos tiene el siguiente formato. Esta estructura de datos debe considerarse el título de una tabla porque la tabla en realidad consta de entradas de directorio (descritas en la sección 6.9.2, "Entradas de directorio de recursos") y esta estructura:
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
4 |
Características |
Indicadores de recurso. Este campo está reservado para uso futuro. Actualmente está establecido en cero. |
4 |
4 |
Marca de fecha/hora |
Hora a la que el compilador de recursos creó los datos del recurso. |
8 |
2 |
Versión principal |
El número de versión principal, establecido por el usuario. |
10 |
2 |
Versión secundaria |
El número de versión secundaria, establecido por el usuario. |
12 |
2 |
Número de entradas de nombre |
Número de entradas de directorio inmediatamente después de la tabla que usan cadenas para identificar entradas de tipo, nombre o lenguaje (según el nivel de la tabla). |
14 |
2 |
Número de entradas de ID |
El número de entradas de directorio inmediatamente después de las entradas de nombre que usan ID numéricos para las entradas de tipo, nombre o lenguaje. |
Entradas de directorio de recursos
Las entradas de directorio forman las filas de una tabla. Cada entrada del directorio de recursos tiene el siguiente formato. Si la entrada es una entrada de nombre o de ID se indica mediante la tabla de directorios de recursos, que indica cuántas entradas de nombre e ID le siguen (recuerde que todas las entradas de nombre preceden a todas las entradas de ID de la tabla). Todas las entradas de la tabla se ordenan en orden ascendente: las entradas de Nombre por cadenas que distinguen entre mayúsculas y minúsculas, y las entradas de ID por valor numérico. Los desplazamientos son relativos a la dirección del directorio de datos IMAGE_DIRECTORY_ENTRY_RESOURCE. Consulte Emparejamiento en PE: un recorrido por el formato de archivo ejecutable portátil Win32 para obtener más información.
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
4 |
Desplazamiento de nombre |
El desplazamiento de una cadena que proporciona la entrada de tipo, nombre o ID de lenguaje, según el nivel de la tabla. |
0 |
4 |
ID de entero |
Entero de 32 bits que identifica la entrada de Tipo, Nombre o ID de lenguaje. |
4 |
4 |
Desplazamiento de entrada de datos |
Bit alto 0. Dirección de una entrada de datos de recurso (una hoja). |
4 |
4 |
Desplazamiento del subdirectorio |
Bit alto 1. Los 31 bits inferiores son la dirección de otra tabla de directorios de recursos (el siguiente nivel hacia abajo). |
Cadena de directorio de recursos
El área de cadena del directorio de recursos consta de cadenas Unicode, que están alineadas por palabras. Estas cadenas se almacenan juntas después de la última entrada de recurso de directorio y antes de la primera entrada de datos de recurso. Esto minimiza el impacto de estas cadenas de longitud variable en la alineación de las entradas de directorio de tamaño fijo. Cada cadena de directorio de recursos tiene el siguiente formato:
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
2 |
Length |
El tamaño de la cadena, sin incluir el campo de longitud en sí. |
2 |
variable |
Cadena Unicode |
Datos de cadena Unicode de longitud variable, alineados por palabras. |
Entrada de datos de recursos
Cada entrada de datos de recursos describe una unidad real de datos sin procesar en el área Datos de recursos. Una entrada de datos de recurso tiene el siguiente formato:
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
4 |
RVA de datos |
Dirección de una unidad de datos de recursos en el área Datos de recursos. |
4 |
4 |
Tamaño |
El tamaño, en bytes, de los datos de recurso a los que apunta el campo RVA de datos. |
8 |
4 |
Página de códigos |
La página de códigos que se usa descodificar los valores de puntos de código dentro de los datos de recursos. Normalmente, la página de códigos sería la página de códigos Unicode. |
12 |
4 |
Reservado, debe ser 0. |
La sección .cormeta (solo objeto)
Los metadatos de CLR se almacenan en esta sección. Se usa para indicar que el archivo objeto contiene código administrado. El formato de los metadatos no está documentado, pero se puede entregar a las interfaces CLR para controlar los metadatos.
La sección .sxdata
Los controladores de excepciones válidos de un objeto se enumeran en la sección .sxdata de ese objeto. La sección está marcada IMAGE_SCN_LNK_INFO. Contiene el índice de símbolos COFF de cada controlador válido, usando 4 bytes por índice.
Además, el compilador marca un objeto COFF como SEH registrado emitiendo el símbolo absoluto "@feat.00" con el LSB del campo de valor establecido en 1. Un objeto COFF sin controladores SEH registrados tendría el símbolo "@feat.00", pero ninguna sección .sxdata.
Formato de archivo de almacenamiento (biblioteca)
- Firma de archivo de almacenamiento
- Encabezados de miembro de archivo
- Primer miembro del enlazador
- Segundo miembro enlazador
- Miembro de Longnames
El formato de archivo COFF proporciona un mecanismo estándar para almacenar colecciones de archivos objeto. Estas colecciones se denominan comúnmente bibliotecas en la documentación de programación.
Los primeros 8 bytes de un archivo constan de la firma del archivo. El resto del archivo consta de una serie de miembros de archivo, como se indica a continuación:
El primer y segundo miembro son "miembros enlazadores". Cada uno de estos miembros tiene su propio formato, tal y como se describe en la sección Tipo de nombre de importación. Normalmente, un enlazador coloca información en estos miembros de archivo. Los miembros del enlazador contienen el directorio del archivo.
El tercer miembro es el miembro de "nombres largos". Este miembro opcional consta de una serie de cadenas ASCII terminadas en null en las que cada cadena es el nombre de otro miembro del archivo.
El resto del archivo consta de miembros estándar (archivo de objeto). Cada uno de estos miembros contiene el contenido de un archivo objeto en su totalidad.
Un encabezado de miembro de archivo precede a cada miembro. La siguiente lista muestra la estructura general de un archivo:
Firma :"!<arch>\n" |
---|
Encabezado |
---|
1er Miembro enlazador |
Encabezado |
---|
2º Miembro enlazador |
Encabezado |
---|
Miembro de Longnames |
Encabezado |
---|
Contenido del archivo OBJ 1 (Formato COFF) |
Encabezado |
---|
Contenido del archivo OBJ 2 (Formato COFF) |
...
Encabezado |
---|
Contenido del archivo OBJ N (Formato COFF) |
Firma de archivo de almacenamiento
La firma del archivo de almacenamiento identifica el tipo de archivo. Cualquier utilidad (por ejemplo, un enlazador) que tome un archivo de almacenamiento como entrada puede comprobar el tipo de archivo leyendo esta firma. La firma consta de los siguientes caracteres ASCII, en los que cada carácter a continuación se representa literalmente, excepto el carácter de nueva línea (\n):
!<arch>\n
El encabezado winnt.h de Windows SDK define las siguientes macros:
#define IMAGE_ARCHIVE_START_SIZE 8
#define IMAGE_ARCHIVE_START "!<arch>\n"
#define IMAGE_ARCHIVE_END "`\n"
#define IMAGE_ARCHIVE_PAD "\n"
#define IMAGE_ARCHIVE_LINKER_MEMBER "/ "
#define IMAGE_ARCHIVE_LONGNAMES_MEMBER "// "
#define IMAGE_ARCHIVE_HYBRIDMAP_MEMBER "/<HYBRIDMAP>/ "
Encabezados de miembro de archivo
Cada miembro (enlazador, longnames o miembro de archivo de objeto) está precedido por un encabezado. Un encabezado de miembro de archivo tiene el siguiente formato, en el que cada campo es una cadena de texto ASCII justificada a la izquierda y que se rellena con espacios al final del campo. No hay ningún carácter nulo de terminación en ninguno de estos campos.
Cada encabezado de miembro comienza en la primera dirección par después del final del miembro de archivo anterior, se puede insertar un byte '\n' (IMAGE_ARCHIVE_PAD) después de un miembro de archivo para que el siguiente miembro comience en una dirección par.
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
16 |
Nombre |
Nombre del miembro de archivo, con una barra diagonal (/) anexada para finalizar el nombre. Si el primer carácter es una barra, el nombre tiene una interpretación especial, como se describe en la siguiente tabla. |
16 |
12 |
Fecha. |
Fecha y hora en que se creó el miembro de archivo: esta es la representación decimal ASCII del número de segundos desde el 1/1/1970 UCT. |
28 |
6 |
ID de usuario |
Una representación decimal ASCII del ID de usuario. Este campo no contiene un valor significativo en las plataformas Windows porque las herramientas de Microsoft emiten todos los espacios en blanco. |
34 |
6 |
ID de grupo |
Una representación decimal ASCII del ID de grupo. Este campo no contiene un valor significativo en las plataformas Windows porque las herramientas de Microsoft emiten todos los espacios en blanco. |
40 |
8 |
Modo |
Una representación octal ASCII del modo de archivo del miembro. Este es el valor ST_MODE de la función en tiempo de ejecución de C _wstat. |
48 |
10 |
Tamaño |
Representación decimal ASCII del tamaño total del miembro del archivo, sin incluir el tamaño del encabezado. |
58 |
2 |
Fin del encabezado |
Los dos bytes (0x60 0x0A) en la cadena C "'\n" (IMAGE_ARCHIVE_END). |
El campo Nombre tiene uno de los formatos que se muestran en la siguiente tabla. Como se mencionó anteriormente, cada una de estas cadenas se justifica a la izquierda y se rellena con espacios finales dentro de un campo de 16 bytes:
Contenido del campo Nombre | Descripción |
---|---|
nombre/ |
El nombre del miembro del archivo. |
/ |
El miembro del archivo es uno de los dos miembros del vinculador. Ambos miembros del vinculador tienen este nombre. |
// |
El miembro de archivo es el miembro de longnames, que consiste en una serie de cadenas ASCII terminadas en null. El miembro de longnames es el tercer miembro del archivo y es opcional. |
/n |
El nombre del miembro del archivo se encuentra en el desplazamiento n dentro del miembro de longnames. El número n es la representación decimal del desplazamiento. Por ejemplo: "/26" indica que el nombre del miembro de archivo se encuentra 26 bytes más allá del principio del contenido del miembro de longnames. |
Primer miembro del enlazador
El nombre del primer miembro del enlazador es "/" (IMAGE_ARCHIVE_LINKER_MEMBER). El primer miembro del enlazador se incluye por motivos de compatibilidad con versiones anteriores. No lo usan los enlazadores actuales, pero su formato debe ser correcto. Este miembro del vinculador proporciona un directorio de nombres de símbolos, al igual que el segundo miembro enlazador. Para cada símbolo, la información indica dónde se puede encontrar el miembro de archivo que contiene el símbolo.
El primer miembro del vinculador tiene el siguiente formato. Esta información aparece después del encabezado:
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
4 |
Número de símbolos |
Largo sin signo que contiene el número de símbolos indexado. Este número se almacena en formato big-endian. Normalmente, cada miembro de archivo objeto define uno o varios símbolos externos. |
4 |
4 * n |
Desplazamientos |
Matriz de desplazamientos de archivo a encabezados de miembro de archivo, en los que n es igual al campo Número de símbolos. Cada número de la matriz es un long sin signo almacenado en formato big-endian. Para cada símbolo indicado en la tabla de cadenas, el elemento correspondiente de la matriz de desplazamientos proporciona la ubicación del miembro de archivo que contiene el símbolo. |
* |
* |
Tabla de cadenas |
Serie de cadenas terminadas en null que nombran todos los símbolos del directorio. Cada cadena comienza inmediatamente después del carácter nulo de la cadena anterior. El número de cadenas debe ser igual al valor del campo Número de símbolos. |
Los elementos de la matriz offsets deben organizarse en orden ascendente. Este hecho implica que los símbolos de la tabla de cadenas deben organizarse según el orden de los miembros de archivo. Por ejemplo, todos los símbolos del primer miembro del archivo de objeto tendrían que aparecer antes de los símbolos del segundo archivo de objeto.
Segundo miembro enlazador
Al igual que el primer miembro enlazador, el segundo miembro del enlazador tiene el nombre "/" (IMAGE_ARCHIVE_LINKER_MEMBER). Aunque ambos miembros del vinculador proporcionan un directorio de símbolos y miembros de archivo que los contienen, todos los vinculadores actuales utilizan el segundo miembro del vinculador con preferencia al primero. El segundo miembro vinculador incluye nombres de símbolos en orden léxico, lo que permite una búsqueda más rápida por nombre.
El segundo miembro tiene el siguiente formato. Esta información aparece después del encabezado:
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
4 |
Número de miembros |
Un long sin signo que contiene el número de miembros del archivo. |
4 |
4 * m |
Desplazamientos |
Matriz de desplazamientos de archivo para los encabezados de miembro de archivo, organizados por orden ascendente. Cada desplazamiento es un valor largo sin signo. El número m es igual al valor del campo Número de miembros. |
* |
4 |
Número de símbolos |
Un long sin signo que contiene el número de símbolos indexados. Normalmente, cada miembro de archivo objeto define uno o varios símbolos externos. |
* |
2 * n |
Índices |
Matriz de índices basados en 1 (corto sin signo) que asignan nombres de símbolos a desplazamientos de miembros de archivo. El número n es igual al campo Número de símbolos. Para cada símbolo que se nombra en la tabla de cadenas, el elemento correspondiente de la matriz Índices proporciona un índice en la matriz Desplazamientos. La matriz de desplazamientos, a su vez, proporciona la ubicación del miembro de archivo que contiene el símbolo. |
* |
* |
Tabla de cadenas |
Una serie de cadenas terminadas en null que nombran todos los símbolos del directorio. Cada cadena comienza inmediatamente después del byte nulo de la cadena anterior. El número de cadenas debe ser igual al valor del campo Número de símbolos. En esta tabla se enumeran todos los nombres de símbolos por orden léxico ascendente. |
Miembro de Longnames
El nombre del miembro longnames es "//" (IMAGE_ARCHIVE_LONGNAMES_MEMBER). El miembro de longnames es una serie de cadenas de nombres de miembros de archivo. Un nombre aparece aquí solamente cuando no hay suficiente espacio en el campo Nombre (16 bytes). El miembro de longnames es opcional. Puede estar vacío con solo un encabezado, o puede estar completamente ausente sin siquiera un encabezado.
Las cadenas están terminadas en null. Cada cadena comienza inmediatamente después del byte nulo de la cadena anterior.
Formato de biblioteca de importación
Las bibliotecas de importación tradicionales, es decir, las que describen las exportaciones de una imagen para usarlas en otra, normalmente siguen el diseño descrito en la sección 7, Formato de archivo de almacenamiento (biblioteca). La principal diferencia es que los miembros de la biblioteca de importación contienen archivos de pseudo-objetos en lugar de los reales, en los que cada miembro incluye las contribuciones de sección necesarias para compilar las tablas de importación que se describen en la sección 6.4, Sección .idata. El enlazador genera este archivo al compilar la aplicación de exportación.
Las contribuciones de las secciones para una importación se pueden inferir a partir de un pequeño conjunto de información. El enlazador puede generar la información completa detallada en la biblioteca de importación para cada miembro en el momento de la creación de la biblioteca o escribir solo la información canónica en la biblioteca y dejar que la aplicación que más adelante la use genere los datos necesarios sobre la marcha.
En una biblioteca de importación con el formato largo, un solo miembro contiene la siguiente información:
- Encabezado de miembro de archivo
- Encabezado de archivo
- Encabezados de sección
- Datos que corresponden a cada uno de los encabezados de sección
- Tabla de símbolos COFF
- Cadenas
Por el contrario, una biblioteca de importación corta se escribe de la siguiente manera:
- Encabezado de miembro de archivo
- Encabezado de importación
- Cadena de nombre de importación terminada en null
- Cadena de nombre DLL terminada en nulo
Esta es información suficiente para reconstruir con precisión todo el contenido del miembro en el momento de su uso.
Encabezado de importación
El encabezado de importación contiene los siguientes campos y desplazamientos:
Desplazamiento | Size | Campo | Descripción |
---|---|---|---|
0 |
2 |
Sig1 |
Debe ser IMAGE_FILE_MACHINE_UNKNOWN. Para obtener más información, consulte Tipos de máquinas. |
2 |
2 |
Sig2 |
Debe ser 0xFFFF. |
4 |
2 |
Versión |
La versión de la estructura. |
6 |
2 |
Máquina |
El número que identifica el tipo de máquina de destino. Para obtener más información, consulte Tipos de máquinas. |
8 |
4 |
Marca de fecha y hora |
La hora y la fecha en que se creó el archivo. |
12 |
4 |
Tamaño de los datos |
El tamaño de las cadenas que siguen al encabezado. |
16 |
2 |
Ordinal/Sugerencia |
Ordinal o sugerencia para la importación, determinado por el valor del campo Tipo de nombre. |
18 |
2 bits |
Tipo |
El tipo de importación. Para conocer los valores y descripciones específicos, consulte Tipo de importación. |
3 bits |
Tipo de nombre |
El tipo de nombre de importación. Para obtener más información, consulte Tipo de nombre de importación. |
|
11 bits |
Reservado |
Reservado, debe ser 0. |
Esta estructura va seguida de dos cadenas terminadas en null que describen el nombre del símbolo importado y el archivo DLL del que procede.
Tipo de importación
Se definen los siguientes valores para el campo Tipo en el encabezado de importación:
Constante | Value | Descripción |
---|---|---|
IMPORT_OBJECT_CODE |
0 |
Código ejecutable. |
IMPORT_OBJECT_DATA |
1 |
Datos. |
IMPORT_OBJECT_CONST |
2 |
Especificado como CONST en el archivo .def. |
Estos valores se utilizan para determinar qué contribuciones de sección debe generar la herramienta que utiliza la biblioteca si debe acceder a esos datos.
Tipo de nombre de importación
El nombre del símbolo de importación terminado en null sigue inmediatamente a su encabezado de importación asociado. Los siguientes valores están definidos para el campo Tipo de nombre en el encabezado de importación. Indican cómo se va a utilizar el nombre para generar los símbolos correctos que representan la importación:
Constante | Value | Descripción |
---|---|---|
IMPORT_OBJECT_ORDINAL | 0 | La importación es por ordinal. Esto indica que el valor del campo Ordinal/Sugerencia del encabezado de importación es el ordinal de la importación. Si no se especifica esta constante, el campo Ordinal/Sugerencia siempre debe interpretarse como sugerencia de importación. |
IMPORT_OBJECT_NAME | 1 | El nombre de importación es idéntico al nombre del símbolo público. |
IMPORT_OBJECT_NAME_NOPREFIX | 2 | El nombre de importación es el nombre del símbolo público, pero omitiendo el ?, @ u opcionalmente _ inicial. |
IMPORT_OBJECT_NAME_UNDECORATE | 3 | El nombre de importación es el nombre del símbolo público, pero omitiendo el ?, @ u opcionalmente _ inicial, y truncando en la primera @. |
Apéndice A: Cálculo del hash de imagen de PE de Authenticode
Se espera que se utilicen varios certificados de atributo para verificar la integridad de las imágenes. Sin embargo, la más común es la firma Authenticode. Se puede utilizar una firma Authenticode para verificar que las secciones relevantes de un archivo de imagen PE no se hayan alterado de ninguna manera con respecto a la forma original del archivo. Para llevar a cabo esta tarea, las firmas Authenticode contienen algo denominado hash de imagen PE
¿Qué es un hash de imagen Authenticode PE?
El hash de imagen Authenticode PE, o hash de archivo para abreviar, es similar a una suma de comprobación de archivo en el sentido de que produce un pequeño valor que se relaciona con la integridad de un archivo. Una suma de comprobación se produce mediante un algoritmo simple y se utiliza principalmente para detectar errores de memoria. Es decir, se utiliza para detectar si un bloque de memoria en disco se ha estropeado y los valores almacenados allí se han dañado. Un hash de archivo es similar a una suma de comprobación en el sentido de que también detecta daños en los archivos. Sin embargo, a diferencia de la mayoría de los algoritmos de suma de comprobación, es muy difícil modificar un archivo para que tenga el mismo hash de archivo que su forma original (sin modificar). Es decir, una suma de comprobación está pensada para detectar errores de memoria simples que conducen a la corrupción, pero un hash de archivo se puede utilizar para detectar modificaciones intencionadas e incluso sutiles en un archivo, como las introducidas por virus, piratas informáticos o programas troyanos.
En una firma Authenticode, el hash del archivo se firma digitalmente mediante una clave privada que solo conoce el firmante del archivo. Un consumidor de software puede verificar la integridad del archivo calculando el valor hash del archivo y comparándolo con el valor del hash firmado contenido en la firma digital Authenticode. Si los hashes del archivo no coinciden, se ha modificado parte del archivo cubierto por el hash de la imagen PE.
¿Qué cubre un hash de imagen Authenticode PE?
No es posible ni deseable incluir todos los datos del archivo de imagen en el cálculo del hash de imagen PE. A veces simplemente presenta características no deseadas (por ejemplo, la información de depuración no puede eliminarse de los archivos publicados públicamente); otras veces es sencillamente imposible. Por ejemplo, no es posible incluir toda la información de un archivo de imagen en una firma Authenticode y, a continuación, insertar la firma Authenticode que contiene ese hash de imagen PE en la imagen PE y, posteriormente, poder generar un hash de imagen PE idéntico incluyendo de nuevo todos los datos del archivo de imagen en el cálculo, ya que el archivo ahora contiene la firma Authenticode que no estaba allí originalmente.
Proceso para generar el hash de imagen Authenticode PE
En esta sección se describe cómo se calcula un hash de imagen PE y qué partes de la imagen PE se pueden modificar sin invalidar la firma Authenticode.
Nota:
El hash de imagen PE para un archivo específico se puede incluir en un archivo de catálogo independiente sin incluir un certificado de atributo dentro del archivo hash. Esto es relevante, ya que es posible invalidar el hash de imagen PE en un archivo de catálogo firmado por Authenticode modificando una imagen PE que en realidad no contiene una firma Authenticode.
A todos los datos de las secciones de la imagen PE que se especifican en la tabla de secciones se les aplica un hash en su totalidad, excepto los siguientes intervalos de exclusión:
El campo CheckSum de archivo de los campos específicos de Windows del encabezado opcional. Esta suma de comprobación incluye todo el archivo (incluidos los certificados de atributo del archivo). Con toda probabilidad, la suma de comprobación será diferente del valor original después de insertar la firma Authenticode.
Información relacionada con los certificados de atributos. Las áreas de la imagen PE que están relacionadas con la firma Authenticode no se incluyen en el cálculo del hash de imagen PE porque las firmas Authenticode se pueden agregar o quitar de una imagen sin afectar a la integridad general de la imagen. Esto no es un problema, ya que hay escenarios de usuario que dependen de volver a firmar imágenes de PE o agregar una marca de tiempo. Authenticode excluye la siguiente información del cálculo del hash:
Campo Tabla de certificados de los directorios de datos de encabezado opcional.
La tabla de certificados y los certificados correspondientes a los que apunta el campo Tabla de certificados que aparece inmediatamente encima.
Para calcular el hash de la imagen PE, Authenticode ordena las secciones especificadas en la tabla de secciones por intervalo de direcciones y, a continuación, aplica un hash a la secuencia de bytes resultante y transfiere los intervalos de exclusión.
Información transferida del final de la última sección. El área más allá de la última sección (definida por el desplazamiento más alto) no tiene hash. Esta área suele contener información de depuración. Por lo general, la información de depuración puede considerarse un asesoramiento para los depuradores; no afecta a la integridad real del programa ejecutable. Literalmente, es posible eliminar la información de depuración de una imagen después de que se haya entregado un producto y no afectar a la funcionalidad del programa. De hecho, esto a veces se hace como una medida para ahorrar espacio en el disco. Cabe destacar que la información de depuración contenida en las secciones especificadas de la imagen PE no se puede eliminar sin invalidar la firma de Authenticode.
Puede usar las herramientas makecert y signtool proporcionadas en el SDK de la plataforma Windows para experimentar con la creación y comprobación de firmas Authenticode. Para obtener más información, consulte Referencia, a continuación.
Referencias
Descargas y herramientas para Windows (incluye Windows SDK)
Creación, visualización y administración de certificados
Tutorial de firma de código en modo kernel (.doc)
Formato de firma ejecutable portátil de Windows Authenticode (.docx)