Formato PE

Esta especificación describe la estructura de archivos ejecutables (imagen) y archivos de objeto en la familia de sistemas operativos Windows. Estos archivos se conocen como archivos ejecutables portátiles (PE) y formato de archivo de objeto común (COFF), respectivamente.

Nota

Este documento se proporciona a fin de 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 del archivo ejecutable portátil y del 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 archivos ejecutables (imagen) y de archivos de objeto en la familia de sistemas operativos de Microsoft Windows. Estos archivos se conocen como archivos ejecutables portátiles (PE) y formato de archivo de objeto común (COFF), respectivamente. El nombre "Archivo ejecutable portátil" hace referencia 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 tabla siguiente:

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; una de los más útiles es una instrucción de un fabricante de software que indica cuál se prevé que sea el resumen de mensaje de la imagen. Un resumen de mensaje es similar a una suma de comprobación, salvo que es extremadamente difícil de falsificar. Por lo tanto, es muy difícil modificar un archivo para tener el mismo resumen de mensaje que el archivo original. La instrucción se puede comprobar como que la ha realizado el fabricante mediante esquemas de criptografía de clave pública o privada. En este documento se describen los detalles sobre los certificados de atributo distintos de los que se utilizan para permitir su inserción en archivos de imagen.
marca de fecha y hora
Marca que se utiliza con diferentes finalidades 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 que usan las funciones de tiempo en la biblioteca en tiempo de ejecución de C. Para obtener excepciones, vea 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
Ubicación de un elemento dentro del propio archivo, antes de que lo procese 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 a medida que se almacena en el disco.
vinculador
Referencia al enlazador que se proporciona con Microsoft Visual Studio.
objeto de archivo
Archivo que se proporciona como entrada al enlazador. El enlazador genera un archivo de imagen que, a su vez, lo usa como entrada el cargador. 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)
En un archivo de imagen, esta es la dirección de un elemento después de cargarlo en la memoria, a la que se le resta la dirección base del archivo de imagen. La RVA de un elemento casi siempre varía de su posición dentro del archivo en el 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. Por motivos de simplicidad, un compilador simplemente debe establecer la primera RVA en cada sección en cero.
section
Unidad básica de código o datos en un archivo PE o COFF. Por ejemplo, todo el código de un archivo de objeto se puede combinar en una sola sección o (según el 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 vincular en el 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 se deben cargar de forma contigua. Además, un archivo de imagen puede contener una serie de secciones, como .tls o .reloc, que tienen fines especiales.
Dirección virtual (VA)
Igual que la RVA, salvo que la dirección base del archivo de imagen no se resta. La dirección se denomina VA porque Windows crea un espacio VA distinto para cada proceso, independientemente de la memoria física. Para casi todas las finalidades, una VA debe considerarse tan 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 PE de Microsoft, con la base del encabezado de imagen en la parte superior. La sección del encabezado EXE compatible con MS-DOS 2.0 mediante la sección sin usar 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

  • unused

  • Identificador de OEM

    Información del OEM

    Desplazamiento al encabezado PE

  • Programa de código auxiliar y tabla de reubicación MS-DOS 2.0

  • unused

  • Encabezado PE (alineado en un límite de 8 bytes)

  • Encabezados de sección

  • Páginas de imagen:

    información de importación

    información de exportación

    reubicaciones base

    información de recursos

En la lista siguiente se describe el formato del módulo de objetos COFF de Microsoft:

  • Encabezado COFF de Microsoft

  • Encabezados de sección

  • Datos sin procesar:

    código

    datos

    información de depuración

    reubicaciones

Encabezados de archivo

El encabezado del archivo PE consta de un código auxiliar MS-DOS de Microsoft, la firma del PE, el encabezado del 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 por 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 delantera de la imagen EXE. El enlazador coloca un código auxiliar predeterminado aquí, 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 un código auxiliar diferente mediante la opción del enlazador /STUB.

En la ubicación 0x3c, el código auxiliar tiene el desplazamiento del archivo en la firma del PE. Esta información permite a Windows ejecutar correctamente el archivo de imagen, aunque tenga un código auxiliar de 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 de MS-DOS, en el desplazamiento del archivo especificado en el desplazamiento de 0x3c, es una firma de 4 bytes que identifica el archivo como un archivo de imagen de formato PE. Esta firma es "PE\0\0" (las letras "P" y "E" seguidas de dos bytes null).

Encabezado de archivo COFF (objeto e imagen)

Al principio de un archivo de objeto, o inmediatamente después de la firma de un archivo de imagen, es un encabezado de archivo COFF estándar en el formato siguiente. Tenga en cuenta que el cargador de Windows limita el número de secciones a 96.

Offset Size Campo Descripción
0
2
Máquina
Número que identifica el tipo de máquina de destino. Para obtener más información, vea Tipos de máquina.
2
2
NumberOfSections
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 inferiores 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. En el caso de una imagen, este valor debe ser cero porque la información de depuración de COFF está en desuso.
12
4
NumberOfSymbols
Número de entradas de 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. En el caso de una imagen, este valor debe ser cero porque la información de depuración de COFF está en desuso.
16
2
SizeOfOptionalHeader
Tamaño del encabezado opcional, que es necesario para los archivos ejecutables pero no para los archivos de objeto. Este valor debe ser cero para un archivo objeto. Para obtener una descripción del formato de encabezado, vea Encabezado opcional (solo imagen).
18
2
Características
Marcas que indican los atributos del archivo. Para obtener valores de marca específicos, vea Características.

Tipos de máquina

El campo Machine tiene uno de los valores siguientes, 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 Valor 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
Espacio de direcciones alfa AXP de 32 bits
IMAGE_FILE_MACHINE_ALPHA64
0x284
Espacio de direcciones alfa de 64, 64 bits
IMAGE_FILE_MACHINE_AM33
0x1d3
Matsushita AM33
IMAGE_FILE_MACHINE_AMD64
0x8664
x64
IMAGE_FILE_MACHINE_ARM
0x1c0
ARM en formato little endian
IMAGE_FILE_MACHINE_ARM64
0xaa64
ARM64 en formato little endian
IMAGE_FILE_MACHINE_ARMNT
0x1c4
ARM Thumb-2 en formato little endian
IMAGE_FILE_MACHINE_AXP64
0x284
AXP 64 (igual que Alfa 64)
IMAGE_FILE_MACHINE_EBC
0xebc
Código de bytes EFI
IMAGE_FILE_MACHINE_I386
0x14c
Procesadores Intel 386 o versiones 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 en formato 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 en formato 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 en formato little endian WCE v2

Características

El campo Characteristics contiene marcas que indican atributos del objeto o el archivo de imagen. Actualmente se definen las marcas siguientes:

Marca Value Descripción
IMAGE_FILE_RELOCS_STRIPPED
0x0001
Solo imagen, Windows CE, así como Microsoft Windows NT y versiones posteriores. Esto indica que el archivo no contiene reubicaciones base y, por tanto, debe cargarse en su dirección base preferida. Si la dirección base no está disponible, el cargador notifica un error. El comportamiento predeterminado del enlazador es quitar 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 esta marca no está establecida, indica un error del enlazador.
IMAGE_FILE_LINE_NUMS_STRIPPED
0x0004
Se han quitado los números de línea de COFF. Esta marca está en desuso y debe ser cero.
IMAGE_FILE_LOCAL_SYMS_STRIPPED
0x0008
Se han quitado las entradas de la tabla de símbolos de COFF para los símbolos locales. Esta marca está en desuso y debe ser cero.
IMAGE_FILE_AGGRESSIVE_WS_TRIM
0x0010
Obsoleto. Recorte agresivo del espacio 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 controlar direcciones > 2 GB.
0x0040
Esta marca se reserva para 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 quita del archivo de imagen.
IMAGE_FILE_REMOVABLE_RUN_ FROM_SWAP
0x0400
Si la imagen está en medios extraíbles, 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 en casi todos los propósitos, aunque no se pueden ejecutar directamente.
IMAGE_FILE_UP_SYSTEM_ONLY
0x4000
El archivo solo se debe ejecutar en una máquina con 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 (en concreto, los archivos de objeto) no lo tienen. En el caso de los archivos de imagen, se requiere este encabezado. Un archivo de objeto puede tener un encabezado opcional, pero generalmente este encabezado no tiene ninguna función en un archivo de objeto, excepto para 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 va más allá de SizeOfOptionalHeader. Para obtener más información, vea Encabezado de archivo COFF (objeto e imagen).

El campo NumberOfRvaAndSizes del encabezado opcional también debe usarse a fin de asegurarse de que ningún sondeo para una entrada de directorio de datos determinada va más allá del encabezado opcional. Además, es importante validar el número mágico del encabezado opcional para la compatibilidad del formato.

El número mágico del 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 limitar el tamaño de la imagen a 2 gigabytes. Otras modificaciones de PE32+ se tratan en sus respectivas secciones.

El propio encabezado opcional tiene tres partes principales.

Desplazamiento (PE32/PE32+) Tamaño (PE32/PE32+) Elemento 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 y tamaño de las tablas especiales que se encuentran en el archivo de imagen y se usan en 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 que se definen 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+.

Offset Size Campo Descripción
0
2
Instrucción mágica
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 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
Tamaño de la sección de código (texto), o bien la suma de todas las secciones de código si hay varias secciones.
8
4
SizeOfInitializedData
Tamaño de la sección de datos inicializados, o bien la suma de todas esas secciones si hay varias secciones de datos.
12
4
SizeOfUninitializedData
Tamaño de la sección de datos no inicializados (BSS), o bien la suma de todas esas secciones si hay varias secciones BSS.
16
4
AddressOfEntryPoint
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 inicial. En el caso de los controladores de dispositivos, esta es la dirección de la función de inicialización. El 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 la imagen de la sección de principio del código cuando se carga en la memoria.

PE32 contiene este campo adicional, que no está presente en PE32+, después de BaseOfCode.

Offset Size Campo Descripción
24
4
BaseOfData
Dirección relativa a la base de la imagen de la sección de principio de los datos cuando se carga en la memoria.

Campos de encabezado opcionales específicos de Windows (solo imagen)

Los 21 campos siguientes son una extensión para el formato de encabezado opcional COFF. Contienen información adicional que requiere el enlazador y el cargador en Windows.

Desplazamiento (PE32/PE32+) Tamaño (PE32/PE32+) Campo Descripción
28/24
4/8
ImageBase
La 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 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, 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 0.
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. Para obtener la validación en tiempo de carga se comprueba lo siguiente: todos los controladores, los archivos DLL cargados en tiempo de arranque y los archivos DLL cargados en un proceso crítico de Windows.
68/68
2
Subsystem
El subsistema necesario para ejecutar esta imagen. Para obtener más información, vea Subsistema de Windows.
70/70
2
DllCharacteristics
Para obtener más información, vea 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 una página a la vez hasta que se alcanza 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 una página a la vez hasta que se alcanza 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 0.
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 Subsystem del encabezado opcional determinan qué subsistema de Windows (si existe alguno) es necesario para ejecutar la imagen.

Constante Valor Descripción
IMAGE_SUBSYSTEM_UNKNOWN
0
Un 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
Una aplicación de Interfaz de firmware extensible (EFI)
IMAGE_SUBSYSTEM_EFI_BOOT_ SERVICE_DRIVER
11
Un controlador EFI con servicios de arranque
IMAGE_SUBSYSTEM_EFI_RUNTIME_ DRIVER
12
Un controlador EFI con servicios en tiempo de ejecución
IMAGE_SUBSYSTEM_EFI_ROM
13
Una imagen ROM de EFI
IMAGE_SUBSYSTEM_XBOX
14
XBOX
IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION
16
Aplicación de arranque de Windows.
Características de DLL

Los valores siguientes están definidos para el campo DllCharacteristics del encabezado opcional.

Constante Valor Descripción
0x0001
Reservado, debe ser 0.
0x0002
Reservado, debe ser 0.
0x0004
Reservado, debe ser 0.
0x0008
Reservado, debe ser 0.
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
Compatible con el 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 enlaza 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 admite Protección de flujo de control.
IMAGE_DLLCHARACTERISTICS_ TERMINAL_SERVER_AWARE
0x8000
Compatible con 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 Windows usa. Estas entradas del directorio de datos se cargan en la memoria para que el sistema pueda usarlas en tiempo de ejecución. Un directorio de datos es un campo de 8 bytes que tiene la declaración siguiente:

typedef struct _IMAGE_DATA_DIRECTORY {
    DWORD   VirtualAddress;
    DWORD   Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

El primer campo, VirtualAddress, es realmente la RVA de la tabla. La 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 proporciona el tamaño en bytes. Los directorios de datos, que forman la última parte del encabezado opcional, se muestran en la tabla siguiente.

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.

Además, no demos por hecho que las RVA de esta tabla apuntan al principio de una sección o que las secciones que contienen tablas específicas tienen nombres específicos.

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, vea Sección .edata (solo imagen).
104/120
8
Importación de la tabla
Dirección y tamaño de la tabla de importación. Para obtener más información, vea la Sección .idata.
112/128
8
Tabla del recurso
Dirección y tamaño de la tabla del recurso. Para obtener más información, vea la Sección .rsrc.
120/136
8
Tabla de excepciones
Dirección y tamaño de la tabla de excepciones. Para obtener más información, vea la Sección .pdata.
128/144
8
Tabla de certificados
Dirección y tamaño de la tabla de certificados del atributo. Para obtener más información, vea la Tabla de certificados de atributo (solo imagen).
136/152
8
Tabla de reubicación base
Dirección y tamaño de la tabla de reubicación base. Para obtener más información, vea la Sección .reloc (solo imagen).
144/160
8
Depuración
Dirección y tamaño del inicio de datos de depuración. Para obtener más información, vea la Sección .debug.
152/168
8
Arquitectura
Reservado, debe ser 0
160/176
8
Ptr global
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 0.
168/184
8
Tabla TLS
Dirección y tamaño de la tabla de almacenamiento local del subproceso (TLS). Para obtener más información, vea 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, vea 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, vea 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, vea Tablas de importación de carga retrasada (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, vea la Sección .cormeta (solo objeto).
216/232
8
Reservado, debe ser 0

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 lo tanto, el primer campo de esta entrada, que normalmente es una RVA, es un puntero de archivo en su lugar.

Tabla de secciones (encabezados de sección)

Cada fila de la tabla de secciones es, en efecto, un encabezado de sección. Esta tabla sigue inmediatamente el encabezado opcional, si existe. Este posicionamiento es necesario porque el encabezado de archivo no contiene un puntero directo a la tabla de secciones. En su lugar, la ubicación de la tabla de secciones se determina calculando la ubicación del primer byte que hay después de los encabezados. Asegúrese de usar el tamaño del encabezado opcional, tal como se especifica en el encabezado de archivo.

El campo NumberOfSections del encabezado de archivo determina el número de entradas de la tabla de secciones. Las entradas de la tabla de secciones se enumeran a partir de uno (1). Las entradas de sección de memoria de datos y código están en el orden que elige el enlazador.

En un archivo de imagen, el enlazador debe asignar las VA de las secciones para que estén en orden ascendente y adyacente, y deben ser un múltiplo del valor 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.

Offset Size Campo Descripción
0
8
Nombre
Cadena codificada en UTF-8 de 8 bytes y completada con valores null. Si la cadena tiene exactamente 8 caracteres, no hay ningún valor null 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 de objeto se truncan si se emiten en 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 completa con ceros. Este campo solo es válido para las imágenes ejecutables y debe establecerse en 0 para los archivos de objeto.
12
4
VirtualAddress
En el caso de las imágenes ejecutables, es 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 de objeto, este campo es la dirección del primer byte antes de aplicar la reubicación; por motivos de simplicidad, los compiladores deben establecer esto en 0. De lo contrario, es un valor arbitrario que se resta de desplazamientos durante la reubicación.
16
4
SizeOfRawData
Tamaño de la sección (para archivos de objeto) o tamaño de los datos inicializados en disco (para 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 completa 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 0.
20
4
PointerToRawData
Puntero de archivo a la primera página de la sección 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 de objeto, el valor debe alinearse 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 0.
24
4
PointerToRelocations
Puntero de archivo al principio de las entradas de reubicación de la sección. Esto se establece en 0 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. Esto se establece en 0 si no hay números de línea de COFF. En el caso de una imagen, este valor debe ser cero porque la información de depuración de COFF está en desuso.
32
2
NumberOfRelocations
Número de entradas de reubicación de la sección. Se establece en 0 para las imágenes ejecutables.
34
2
NumberOfLinenumbers
Número de entradas de número de línea de la sección. En el caso de una imagen, este valor debe ser cero porque la información de depuración de COFF está en desuso.
36
4
Características
Marcas que describen las características de la sección. Para obtener más información, vea Marcas de sección.

 

Marcas de sección

Las marcas de sección del campo Characteristics 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 se debe rellenar en el límite siguiente. Esta marca está obsoleta y reemplaza IMAGE_SCN_ALIGN_1BYTES. Esto solo es válido para archivos de 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 los archivos de objeto.
0x00000400
Reservado para uso futuro.
IMAGE_SCN_LNK_REMOVE
0x00000800
La sección no formará parte de la imagen. Esto solo es válido para archivos de objeto.
IMAGE_SCN_LNK_COMDAT
0x00001000
La sección contiene datos COMDAT. Para obtener más información, vea Secciones COMDAT (solo objeto). Esto solo es válido para archivos de objeto.
IMAGE_SCN_GPREL
0x00008000
La sección contiene datos a los que se hace referencia mediante el 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 los archivos de objeto.
IMAGE_SCN_ALIGN_2BYTES
0x00200000
Alinee los datos en un límite de 2 bytes. Válido solo para los archivos de objeto.
IMAGE_SCN_ALIGN_4BYTES
0x00300000
Alinee los datos en un límite de 4 bytes. Válido solo para los archivos de objeto.
IMAGE_SCN_ALIGN_8BYTES
0x00400000
Alinee los datos en un límite de 8 bytes. Válido solo para los archivos de objeto.
IMAGE_SCN_ALIGN_16BYTES
0x00500000
Alinee los datos en un límite de 16 bytes. Válido solo para los archivos de objeto.
IMAGE_SCN_ALIGN_32BYTES
0x00600000
Alinee los datos en un límite de 32 bytes. Válido solo para los archivos de objeto.
IMAGE_SCN_ALIGN_64BYTES
0x00700000
Alinee los datos en un límite de 64 bytes. Válido solo para los archivos de objeto.
IMAGE_SCN_ALIGN_128BYTES
0x00800000
Alinee los datos en un límite de 128 bytes. Válido solo para los archivos de objeto.
IMAGE_SCN_ALIGN_256BYTES
0x00900000
Alinee los datos en un límite de 256 bytes. Válido solo para los archivos de objeto.
IMAGE_SCN_ALIGN_512BYTES
0x00A00000
Alinee los datos en un límite de 512 bytes. Válido solo para los archivos de objeto.
IMAGE_SCN_ALIGN_1024BYTES
0x00B00000
Alinee los datos en un límite de 1024 bytes. Válido solo para los archivos de objeto.
IMAGE_SCN_ALIGN_2048BYTES
0x00C00000
Alinee los datos en un límite de 2048 bytes. Válido solo para los archivos de objeto.
IMAGE_SCN_ALIGN_4096BYTES
0x00D00000
Alinee los datos en un límite de 4096 bytes. Válido solo para los archivos de objeto.
IMAGE_SCN_ALIGN_8192BYTES
0x00E00000
Alinee los datos en un límite de 8192 bytes. Válido solo para los archivos de 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 caché.
IMAGE_SCN_MEM_NOT_PAGED
0x08000000
La sección no se puede paginar.
IMAGE_SCN_MEM_SHARED
0x10000000
La sección se puede compartir en la 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 reservados para ello en el encabezado de sección. Si se establece el bit y el campo NumberOfRelocations del encabezado de sección es 0xffff, el recuento de reubicación real 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 sección de los archivos de objeto.

Al determinar la sección de imagen que contendrá el contenido de una sección de objeto, el enlazador descarta los caracteres "$" y todos los caracteres que lo 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 contiguamente 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 de objeto con el nombre de sección .text$X termina junto, después de las contribuciones .text$W y antes de las contribuciones .text$Y.

El nombre de sección de un archivo de imagen nunca contiene un carácter "$".

Otros contenidos del archivo

Las estructuras de datos que se han descrito por el momento, hasta el encabezado opcional, se encuentran en un desplazamiento fijo 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 archivo de imagen u objeto COFF contiene bloques de datos que no tienen por qué estar en ningún desplazamiento de archivo específico. En su lugar, las ubicaciones se definen mediante punteros en el encabezado opcional o un encabezado de sección.

Una excepción es para las imágenes con un valor SectionAlignment menor que el tamaño de página de la arquitectura (4 K para Intel x86 y MIPS, y 8 K para Itanium). Para obtener una descripción de SectionAlignment, vea Encabezado opcional (solo imagen). En este caso, hay restricciones en el desplazamiento del archivo de los datos de sección, tal 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 atributo justo antes de la sección de depuración, porque el cargador no los asigna a la memoria. Pero la regla sobre el certificado de atributos y la información de depuración no se aplica a los archivos de objeto.

Datos de la sección

Los datos inicializados de una sección constan de bloques sencillos de bytes. Pero para las secciones que contienen todos los ceros, no es necesario incluir los datos de la 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 completa con ceros.

En un archivo de imagen, los datos de sección deben alinearse en un límite según lo que especifica el campo FileAlignment en el encabezado opcional. Los datos de la 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 la 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 la RVA.

Reubicaciones de COFF (solo objeto)

Los archivos de objeto contienen reubicaciones de COFF, que especifican cómo se deben modificar los datos de la sección cuando se colocan en el archivo de imagen y posteriormente se cargan en la memoria.

Los archivos de imagen no contienen reubicaciones de COFF, ya que todos los símbolos a los que se hace referencia ya se han asignado direcciones en un espacio de direcciones planas. 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, vea la Sección .reloc (solo imagen).

Para cada sección de un archivo de objeto, una matriz de registros de longitud fija contiene las reubicaciones de COFF de la sección. La posición y la longitud de la matriz se especifican en el encabezado de sección. Cada elemento de la matriz tiene el formato siguiente.

Offset Size Campo Descripción
0
4
VirtualAddress
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/Offset de la sección. Vea 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
Índice de base cero en la tabla de símbolos. Este símbolo proporciona la dirección que se va a 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. Vea 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 almacenamiento (biblioteca). En ese caso, la sección se puede encontrar en cualquier otro archivo de objeto del archivo que tenga el mismo nombre del miembro de archivo que el archivo del objeto actual. (La relación con el nombre del miembro de archivo se usa en la vinculación de las tablas de importación, es decir, la sección .idata).

Indicadores de tipo

El campo Type 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 indicadores de tipo de reubicación siguientes se definen para procesadores x64 y compatibles.

Constante Valor 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 la 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 1 del byte desde la reubicación.
IMAGE_REL_AMD64_REL32_2
0x0006
Dirección de 32 bits relativa a la distancia 2 del byte desde la reubicación.
IMAGE_REL_AMD64_REL32_3
0x0007
Dirección de 32 bits relativa a la distancia 3 del byte desde la reubicación.
IMAGE_REL_AMD64_REL32_4
0x0008
Dirección de 32 bits relativa a la distancia 4 del byte desde la reubicación.
IMAGE_REL_AMD64_REL32_5
0x0009
Dirección de 32 bits relativa a la distancia 5 del byte desde 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 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 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 CLR.
IMAGE_REL_AMD64_SREL32
0x000E
Valor que depende del intervalo con signo de 32 bits emitido en el objeto.
IMAGE_REL_AMD64_PAIR
0x000F
Un par que debe seguir inmediatamente cada valor que depende del intervalo.
IMAGE_REL_AMD64_SSPAN32
0x0010
Valor que depende del intervalo con signo de 32 bits que se aplica en tiempo de vínculo.

 

Procesadores ARM

Los indicadores de tipo de reubicación siguientes se definen para los procesadores ARM.

Constante Valor 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 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 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 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 mediante una instrucción MOVW para los 16 bits inferiores seguidos de una instrucción MOVT para los 16 bits superiores.
IMAGE_REL_THUMB_MOV32
0x0011
VA de 32 bits del destino. Esta reubicación se aplica mediante una instrucción MOVW para los 16 bits inferiores seguidos de una instrucción MOVT para los 16 bits superiores.
IMAGE_REL_THUMB_BRANCH20
0x0012
La instrucción se ha corregido con el desplazamiento relativo de 21 bits 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 de Thumb-2 de 32 bits.
No utilizado
0x0013
IMAGE_REL_THUMB_BRANCH24
0x0014
La instrucción se ha corregido 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 B de Thumb-2.
IMAGE_REL_THUMB_BLX23
0x0015
La instrucción se ha corregido con el desplazamiento relativo de 25 bits al destino alineado de 4 bytes. Los 2 bits inferiores 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 solo es válida cuando sigue inmediatamente un elemento ARM_REFHI o THUMB_REFHI. Su elemento SymbolTableIndex contiene un desplazamiento y no un índice en la tabla de símbolos.

 

Procesadores ARM64

Los indicadores de tipo de reubicación siguientes se definen para los procesadores ARM64.

Constante Valor 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
Desplazamiento relativo de 26 bits al destino, para instrucciones B y BL.
IMAGE_REL_ARM64_PAGEBASE_REL21
0x0004
Base de la página del destino, para la instrucción ADRP.
IMAGE_REL_ARM64_REL21
0x0005
Desplazamiento relativo de 12 bits al destino, para instrucciones ADR.
IMAGE_REL_ARM64_PAGEOFFSET_12A
0x0006
Desplazamiento de página de 12 bits del destino, para instrucciones ADD/ADDS (inmediato) con desplazamiento cero.
IMAGE_REL_ARM64_PAGEOFFSET_12L
0x0007
Desplazamiento de página de 12 bits del destino, para la instrucción LDR (indizada, 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 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 (inmediato) con desplazamiento cero.
IMAGE_REL_ARM64_SECREL_HIGH12A
0x000A
Bit 12:23 de desplazamiento de sección del destino, para instrucciones ADD/ADDS (inmediato) con desplazamiento cero.
IMAGE_REL_ARM64_SECREL_LOW12L
0x000B
Bit 0:11 de desplazamiento de sección del destino, para la instrucción LDR (indizada, sin signo inmediato).
IMAGE_REL_ARM64_TOKEN
0x000C
Token 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 información de depuración.
IMAGE_REL_ARM64_ADDR64
0x000E
VA de 64 bits del destino de reubicación.
IMAGE_REL_ARM64_BRANCH19
0x000F
Desplazamiento de 19 bits al destino de reubicación, para la instrucción B condicional.
IMAGE_REL_ARM64_BRANCH14
0x0010
Desplazamiento de 14 bits al destino de reubicación, para 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 indicadores de tipo de reubicación siguientes se definen para los procesadores SH3 y SH4. Las reubicaciones específicas de SH5 se indican como SHM (SH Media).

Constante Valor 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 la VA de 16 bits efectiva 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 inferiores 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 inferiores contienen la VA de 16 bits efectiva del símbolo de destino.
IMAGE_REL_SH3_DIRECT4_LONG
0x0008
Referencia a la instrucción de 8 bits cuyos 4 bits inferiores contienen la VA de 32 bits efectiva del símbolo de destino.
IMAGE_REL_SH3_PCREL8_WORD
0x0009
Referencia a la instrucción de 8 bits que contiene el desplazamiento relativo efectivo de 16 bits 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 inferiores contienen el desplazamiento relativo efectivo de 16 bits 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 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 información de depuración y el almacenamiento local de subprocesos estáticos.
IMAGE_REL_SH3_DIRECT32_NB
0x0010
RVA de 32 bits del símbolo de destino.
IMAGE_REL_SH3_GPREL4_LONG
0x0011
GP relativa.
IMAGE_REL_SH3_TOKEN
0x0012
Token CLR.
IMAGE_REL_SHM_PCRELPT
0x0013
Desplazamiento de la instrucción actual en palabras largas. Si no se establece el bit NOMODE, inserte el inverso del bit inferior en el bit 32 para seleccionar PTA o PTB.
IMAGE_REL_SHM_REFLO
0x0014
Los 16 bits inferiores de la dirección de 32 bits.
IMAGE_REL_SHM_REFHALF
0x0015
Los 16 bits superiores 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 superiores 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 omite el modo de sección.

 

Procesadores PowerPC de IBM

Los indicadores de tipo de reubicación siguientes se definen para procesadores PowerPC.

Constante Valor 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 inferiores de la VA del destino. Esto solo es válido cuando el símbolo de destino es absoluto y se puede producir una extensión de signo a su valor original.
IMAGE_REL_PPC_ADDR16
0x0004
Los 16 bits inferiores de la VA del destino.
IMAGE_REL_PPC_ADDR14
0x0005
Los 14 bits inferiores de la VA del destino. Esto solo es válido cuando el símbolo de destino es absoluto y se puede producir una extensión de signo a su valor original.
IMAGE_REL_PPC_REL24
0x0006
Desplazamiento relativo a PC de 24 bits a la ubicación del símbolo.
IMAGE_REL_PPC_REL14
0x0007
Desplazamiento relativo a PC de 14 bits 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 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 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 información de depuración y el almacenamiento local de subprocesos estáticos.
IMAGE_REL_PPC_REFHI
0x0010
Los 16 bits superiores 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 elemento SymbolTableIndex contenga un desplazamiento de 16 bits con signo que se agrega a los 16 bits superiores que se han tomado de la ubicación que se está reubicando.
IMAGE_REL_PPC_REFLO
0x0011
Los 16 bits inferiores de la VA del destino.
IMAGE_REL_PPC_PAIR
0x0012
Una reubicación válida solo cuando sigue inmediatamente a una reubicación REFHI o SECRELHI. Su elemento SymbolTableIndex contiene un desplazamiento y no un índice en la tabla de símbolos.
IMAGE_REL_PPC_SECRELLO
0x0013
Los 16 bits inferiores 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 CLR.

 

Procesadores Intel 386

Los indicadores de tipo de reubicación siguientes se definen para procesadores Intel 386 y compatibles.

Constante Valor Descripción
IMAGE_REL_I386_ABSOLUTE
0x0000
La reubicación se omite.
IMAGE_REL_I386_DIR16
0x0001
No compatible.
IMAGE_REL_I386_REL16
0x0002
No compatible.
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 compatible.
IMAGE_REL_I386_SECTION
0x000A
Índice de sección de 16 bits de la sección que contiene el destino. Se usa para admitir 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 información de depuración y el almacenamiento local de subprocesos estáticos.
IMAGE_REL_I386_TOKEN
0x000C
Token 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. Esto admite la rama relativa x86 y las instrucciones de llamada.

 

Familia de procesadores Intel Itanium (IPF)

Los indicadores de tipo de reubicación siguientes 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 conjunto y el número de espacio para el desplazamiento de reubicación.

Constante Valor 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 insertarla en el espacio especificado del conjunto IMM14. El destino de reubicación debe ser absoluto o bien la imagen debe ser fija.
IMAGE_REL_IA64_IMM22
0x0002
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 insertarla en el espacio especificado en el conjunto IMM22. El destino de reubicación debe ser absoluto o bien la imagen debe ser fija.
IMAGE_REL_IA64_IMM64
0x0003
El número de espacio 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 almacenarse en los tres espacios del conjunto IMM64.
IMAGE_REL_IA64_DIR32
0x0004
VA de 32 bits del destino. Esto solo se admite para imágenes /LARGEADDRESSAWARE:NO.
IMAGE_REL_IA64_DIR64
0x0005
VA de 64 bits del destino.
IMAGE_REL_IA64_PCREL21B
0x0006
La instrucción se ha corregido con el desplazamiento relativo de 25 bits al destino alineado de 16 bits. Los 4 bits inferiores del desplazamiento son 0 y no se almacenan.
IMAGE_REL_IA64_PCREL21M
0x0007
La instrucción se ha corregido con el desplazamiento relativo de 25 bits al destino alineado de 16 bits. Los 4 bits inferiores del desplazamiento, que son 0, no se almacenan.
IMAGE_REL_IA64_PCREL21F
0x0008
Los LSB del desplazamiento de esta reubicación deben contener el número de espacio, mientras que el resto es la dirección del conjunto. El conjunto se ha corregido con el desplazamiento relativo de 25 bits al destino alineado de 16 bits. Los 4 bits inferiores del desplazamiento son 0 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, después, un desplazamiento relativo de GP de 22 bits que se calcula y se aplica al conjunto GPREL22.
IMAGE_REL_IA64_LTOFF22
0x000A
La instrucción se ha corregido con el desplazamiento relativo de GP de 22 bits a la entrada de tabla literal del símbolo de destino. El enlazador crea esta entrada de tabla literal basada en esta reubicación y la reubicación ADDEND que puede ir después.
IMAGE_REL_IA64_SECTION
0x000B
Índice de sección de 16 bits de la sección contiene el destino. Se usa para admitir información de depuración.
IMAGE_REL_IA64_SECREL22
0x000C
La instrucción se ha corregido con el desplazamiento de 22 bits del destino desde el principio de su sección. A esta reubicación la puede seguir inmediatamente una reubicación ADDEND, cuyo campo Value 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 espacio para esta reubicación debe ser uno (1). La instrucción se ha corregido con el desplazamiento de 64 bits del destino desde el principio de su sección. A esta reubicación le puede seguir inmediatamente una reubicación ADDEND, cuyo campo Value 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 con signo que contiene la diferencia entre dos destinos que pueden reasignarse. 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 con signo que contiene la diferencia entre dos destinos que pueden reubicarse. 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 que pueden reubicarse. 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 que pueden reubicarse. 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 conjunto MLX.
IMAGE_REL_IA64_PCREL60B
0x0016
Corrección relativa a PC de 60 bits. Si el desplazamiento de destino encaja en un campo de 25 bits con signo, convierta todo el conjunto en uno MBB con NOP.B en el espacio 1 y una instrucción BR de 25 bits (con los 4 bits inferiores con valor 0 y descartados) en el espacio 2.
IMAGE_REL_IA64_PCREL60F
0x0017
Corrección relativa a PC de 60 bits. Si el desplazamiento de destino encaja en un campo de 25 bits con signo, convierta todo el conjunto en uno MFB con NOP.F en el espacio 1 y una instrucción BR de 25 bits (con los 4 bits inferiores con valor 0 y descartados) en el espacio 2.
IMAGE_REL_IA64_PCREL60I
0x0018
Corrección relativa a PC de 60 bits. Si el desplazamiento de destino encaja en un campo de 25 bits con signo, convierta todo el conjunto en uno MIB con NOP.I en el espacio 1 y una instrucción BR de 25 bits (con los 4 bits inferiores con valor 0 y descartados) en el espacio 2.
IMAGE_REL_IA64_PCREL60M
0x0019
Corrección relativa a PC de 60 bits. Si el desplazamiento de destino encaja en un campo de 25 bits con signo, convierta todo el conjunto en uno MMB con NOP.M en el espacio 1 y una instrucción BR de 25 bits (con los 4 bits inferiores con valor 0 y descartados) en el espacio 2.
IMAGE_REL_IA64_IMMGPREL64
0x001a
Corrección relativa a GP de 64 bits.
IMAGE_REL_IA64_TOKEN
0x001b
Un token CLR.
IMAGE_REL_IA64_GPREL32
0x001c
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 reubicaciones siguientes: IMM14, IMM22, IMM64, GPREL22, LTOFF22, LTOFF64, SECREL22, SECREL64I o SECREL32. Su valor contiene el anexo que se va a aplicar a las instrucciones de un conjunto, no a los datos.

 

Procesadores MIPS

Los indicadores de tipo de reubicación siguientes se definen para los procesadores MIPS.

Constante Valor Descripción
IMAGE_REL_MIPS_ABSOLUTE
0x0000
La reubicación se omite.
IMAGE_REL_MIPS_REFHALF
0x0001
Los 16 bits superiores 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 inferiores de la VA del destino. Esto admite las instrucciones J y JAL de MIPS.
IMAGE_REL_MIPS_REFHI
0x0004
Los 16 bits superiores 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 elemento SymbolTableIndex contenga un desplazamiento de 16 bits con signo que se agrega a los 16 bits superiores que se han tomado de la ubicación que se está reubicando.
IMAGE_REL_MIPS_REFLO
0x0005
Los 16 bits inferiores de la VA del destino.
IMAGE_REL_MIPS_GPREL
0x0006
Desplazamiento con signo de 16 bits del destino en relación con el registro de GP.
IMAGE_REL_MIPS_LITERAL
0x0007
Igual que IMAGE_REL_MIPS_GPREL.
IMAGE_REL_MIPS_SECTION
0x000A
Índice de sección de 16 bits de la sección contiene el destino. Se usa para admitir 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 información de depuración y el almacenamiento local de subprocesos estáticos.
IMAGE_REL_MIPS_SECRELLO
0x000C
Los 16 bits inferiores del desplazamiento de 32 bits del destino desde el principio de su sección.
IMAGE_REL_MIPS_SECRELHI
0x000D
Los 16 bits superiores 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 inferiores de la VA del destino. Esto admite la instrucción JAL de MIPS16.
IMAGE_REL_MIPS_REFWORDNB
0x0022
RVA de 32 bits del destino.
IMAGE_REL_MIPS_PAIR
0x0025
La reubicación solo es válida cuando inmediatamente sigue a una reubicación REFHI o SECRELHI. Su elemento SymbolTableIndex contiene un desplazamiento y no un índice en la tabla de símbolos.

 

Mitsubishi M32R

Los indicadores de tipo de reubicación siguientes se definen para los procesadores Mitsubishi M32R.

Constante Valor 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 del registro GP.
IMAGE_REL_M32R_PCREL24
0x0005
Desplazamiento de 24 bits del destino desde el contador de programa (PC), desplazado a la izquierda en 2 bits y con extensión de signo.
IMAGE_REL_M32R_PCREL16
0x0006
Desplazamiento de 16 bits del destino desde el PC, desplazado a la izquierda en 2 bits y con extensión de signo.
IMAGE_REL_M32R_PCREL8
0x0007
Desplazamiento de 8 bits del destino desde el PC, desplazado a la izquierda en 2 bits y con extensión de signo.
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. 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 elemento SymbolTableIndex contenga un desplazamiento de 16 bits con signo que se agrega a los 16 bits superiores que se han tomado 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 la reubicación REFHI. Su elemento 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 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 información de depuración y el almacenamiento local de subprocesos estáticos.
IMAGE_REL_M32R_TOKEN
0x000E
Token CLR.

 

Números de línea de COFF (en desuso)

Los números de línea de COFF ya no se producen y, en el futuro, no se consumirán.

Los números de línea de COFF indican la relación entre el código y los números de línea de los archivos de origen. El formato de Microsoft para los números de línea de COFF es similar al estándar COFF, pero se ha ampliado para permitir que una sola sección se relacione con los números de línea en varios archivos de origen.

Los números de línea de COFF constan de 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 sección. Cada registro de número de línea tiene el formato siguiente.

Offset Size Campo Descripción
0
4
Type (*)
Se trata de una unión de dos campos: SymbolTableIndex y VirtualAddress. En función del valor de Linenumber se usará SymbolTableIndex o RVA.
4
2
Linenumber
Cuando no es cero, este campo especifica un número de línea con base uno. Cuando es cero, el campo Type se interpreta como un índice de tabla de símbolos para una función.

 

El campo Type es una unión de dos campos de 4 bytes: SymbolTableIndex y VirtualAddress.

Offset Size Campo Descripción
0
4
SymbolTableIndex
Se usa cuando Linenumber es cero: índice para la entrada de tabla de símbolos de una función. Este formato se usa para indicar la función a la que hace referencia un grupo de registros de número de línea.
0
4
VirtualAddress
Se usa cuando Linenumber es distinto de cero: la RVA del código ejecutable que corresponde a la línea de origen indicada. En un archivo de objeto, contiene la VA 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 bien 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 del 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 de la función si se establece la marca COMDAT de la sección. Vea 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.

A un registro que identifica una función lo sigue 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 tienen base uno, en relación con el principio de la función, y representan todas las líneas de origen de la función, excepto la primera línea.

Por ejemplo, el primer registro de número de línea para el ejemplo siguiente especificaría la función ReverseSign (SymbolTableIndex de ReverseSign y Linenumber establecidos en cero). Después, seguirían los registros con valores Linenumber de 1, 2 y 3, correspondientes a las líneas de origen, tal 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 distinto 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 los nombres 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 ellos de 18 bytes de longitud. Cada registro es de tabla de símbolos estándar o auxiliar. Un registro estándar define un símbolo o nombre y tiene el formato siguiente.

Offset Size Campo Descripción
0
8
Name (*)
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, vea Representación del nombres de símbolo.
8
4
Valor
Valor asociado al símbolo. La interpretación de este campo depende de SectionNumber y StorageClass. Un significado típico es la dirección que puede reasignarse.
12
2
SectionNumber
Entero con signo que identifica la sección mediante un índice con base uno en la tabla de secciones. Algunos valores tienen un significado especial, tal 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, vea Representación de tipos.
16
1
StorageClass
Valor enumerado que representa la clase de almacenamiento. Para obtener más información, vea 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 que siguen inmediatamente a cada registro de tabla de símbolos estándar. Pero, normalmente, no más de un registro auxiliar de tabla de símbolos sigue a un registro de tabla de símbolos estándar (excepto los registros .file con nombres de archivo largos). Cada registro auxiliar tiene el mismo tamaño que un registro estándar de tabla de símbolos (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 los distintos formatos que se van a usar depende del campo StorageClass. Los formatos definidos actualmente para los registros de tabla de símbolos auxiliares se muestran en la sección 5.5, "Registros de símbolos auxiliares".

Las herramientas que leen tablas de símbolos COFF deben omitir los registros de símbolos auxiliares cuya interpretación sea desconocida. Esto permite extender el formato de tabla de símbolos para agregar nuevos registros auxiliares, sin interrumpir las herramientas existentes.

Representación del nombre de símbolos

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 bien 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.

Offset Size Campo Descripción
0
8
nombreCorto
Matriz de 8 bytes. Esta matriz se rellena con valores null a la derecha si el nombre tiene menos de 8 bytes de longitud.
0
4
Zeroes
Campo que se establece en todo ceros si el nombre tiene más de 8 bytes.
4
4
Offset
Desplazamiento en la tabla de cadenas.

 

Valores de número de sección

Normalmente, el campo Value de sección de una entrada de tabla de símbolos es un índice con base uno en la tabla de secciones. Pero este campo es un entero con signo y puede tomar valores negativos. Los valores siguientes, que sean menos de uno, tienen significados especiales.

Constante Valor Descripción
IMAGE_SYM_UNDEFINED
0
Todavía no se ha asignado una sección al registro de símbolos. Un valor de cero indica que una referencia a un símbolo externo se define en otro lugar. Un valor distinto de cero es un símbolo común con un tamaño que especifica el valor.
IMAGE_SYM_ABSOLUTE
-1
El símbolo tiene un valor absoluto (no reasignable) 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 Type de una entrada de tabla de símbolos contiene 2 bytes, donde cada byte representa información de tipos. 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 valores siguientes se definen para el tipo base, aunque las herramientas de Microsoft generalmente no usan este campo y establecen el LSB en 0. En su lugar, la información de depuración de Visual C++ se usa para indicar tipos. Pero los posibles valores de COFF se enumeran aquí a efectos de exhaustividad.

Constante Valor 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 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
Estructura
IMAGE_SYM_TYPE_UNION
9
Una unión.
IMAGE_SYM_TYPE_ENUM
10
Tipo enumerado.
IMAGE_SYM_TYPE_MOE
11
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
Entero sin signo de tamaño natural (normalmente, 4 bytes).
IMAGE_SYM_TYPE_DWORD
15
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 especificado 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 Type. Pero otras herramientas pueden usar este campo para comunicar más información.

Es muy importante especificar correctamente el atributo de función. Esta información es necesaria para que la vinculación incremental funcione correctamente. En algunas arquitecturas, la información puede resultar necesaria para otros fines.

Constante Valor Descripción
IMAGE_SYM_DTYPE_NULL
0
No es un 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é tipo de definición representa un símbolo. En la tabla siguiente se muestran los valores posibles. Tenga en cuenta que el campo StorageClass es un entero de 1 byte sin signo. Por lo tanto, se debe tomar el valor especial to mean -1 para referirse a 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ía de la información simbólica y, por lo general, usan solo cuatro valores de clase de almacenamiento: EXTERNAL (2), STATIC (3), FUNCTION (101) y FILE (103). Excepto en el segundo encabezado de columna de debajo, se debe tomar "Value" para hacer referencia al campo Value del registro de símbolos (cuya interpretación depende del número encontrado como clase de almacenamiento).

Constante Valor Descripción e interpretación del campo Value
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 Value especifica el desplazamiento del marco de pila.
IMAGE_SYM_CLASS_EXTERNAL
2
Valor que usan las herramientas de Microsoft para símbolos externos. El campo Value 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 Value especifica el desplazamiento dentro de la sección.
IMAGE_SYM_CLASS_STATIC
3
Desplazamiento del símbolo dentro de la sección. Si el campo Value es cero, el símbolo representa un nombre de sección.
IMAGE_SYM_CLASS_REGISTER
4
Variable de registro. El campo Value especifica el número de registro.
IMAGE_SYM_CLASS_EXTERNAL_DEF
5
Símbolo definido externamente.
IMAGE_SYM_CLASS_LABEL
6
Etiqueta de código que se define dentro del módulo. El campo Value 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 Value especifica el enésimo miembro.
IMAGE_SYM_CLASS_ARGUMENT
9
Argumento formal (parámetro) de una función. El campo Value especifica el enésimo argumento.
IMAGE_SYM_CLASS_STRUCT_TAG
10
Entrada de nombre de etiqueta de la estructura.
IMAGE_SYM_CLASS_MEMBER_OF_UNION
11
Un miembro de la unión. El campo Value especifica el enésimo miembro.
IMAGE_SYM_CLASS_UNION_TAG
12
Entrada de nombre de etiqueta de la unión.
IMAGE_SYM_CLASS_TYPE_DEFINITION
13
Una entrada Typedef.
IMAGE_SYM_CLASS_UNDEFINED_STATIC
14
Una declaración de datos estática.
IMAGE_SYM_CLASS_ENUM_TAG
15
Una entrada tagname de tipo enumerado.
IMAGE_SYM_CLASS_MEMBER_OF_ENUM
16
Un miembro de una enumeración. El campo Value especifica el enésimo miembro.
IMAGE_SYM_CLASS_REGISTER_PARAM
17
Un parámetro de registro.
IMAGE_SYM_CLASS_BIT_FIELD
18
Una referencia de campo de bits. El campo Value especifica el enésimo bit del campo de bits.
IMAGE_SYM_CLASS_BLOCK
100
Un registro .bb (principio del bloque) o .eb (final del bloque). El campo Value es la dirección que puede reasignarse 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: principio de la función (.bf), final de la función (.ef) y líneas en la función (.lf). Para los registros .lf, el campo Value proporciona el número de líneas de origen en la función. Para los registros .ef, el campo Value 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 usan las herramientas de Microsoft, así como el formato COFF tradicional, para el registro de símbolos del archivo de origen. El símbolo va seguido de registros auxiliares que asignan el nombre al archivo.
IMAGE_SYM_CLASS_SECTION
104
Una 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
Un externo débil. Para obtener más información, vea Formato auxiliar 3: externos débiles.
IMAGE_SYM_CLASS_CLR_TOKEN
107
Un símbolo de token CLR. El nombre es una cadena ASCII que consta del valor hexadecimal del token. Para obtener más información, vea Definición de token CLR (solo objeto).

 

Registros de símbolos auxiliares

Los registros de tabla de símbolos auxiliares siempre siguen a algunos registros de tabla de símbolos estándar, y se aplican a estos. Un registro auxiliar puede tener cualquier formato que las herramientas puedan reconocer, pero se deben asignar 18 bytes a ellos 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 función, símbolos de principio y final de función (.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 las usan, sino que colocan esa información simbólica en formato de depuración de Visual C++ en las secciones de depuración.

Formato auxiliar 1: definiciones de funciones

Un registro de tabla de símbolos marca el principio de una definición de función si incluye lo siguiente: una clase de almacenamiento EXTERNAL (2), un valor Type 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 tabla de símbolos que tenga un número de sección 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 descrito a continuación:

Offset Size Campo Descripción
0
4
TagIndex
Índice de la tabla de símbolos del registro de símbolos .bf (principio de la función) correspondiente.
4
4
TotalSize
Tamaño del código ejecutable de la propia función. Si la función está en su propia sección, el elemento SizeOfRawData en el encabezado de sección es mayor o igual que este campo, en función de las consideraciones sobre la 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 ninguna. Para obtener más información, vea Números de línea de COFF (en desuso).
12
4
PointerToNextFunction
Índice de la tabla de símbolos del registro para 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 utilizado

 

Formato auxiliar 2: símbolos .bf y .ef

Para cada definición de función de la tabla de símbolos, el principio, el final y el número de líneas lo definen tres elementos. Cada uno de estos símbolos tiene la clase de almacenamiento FUNCTION (101):

Un registro de símbolo denominado .bf (principio de la función). El campo Value no se usa.

Un registro de símbolo denominado .lf (líneas en la función). El campo Value proporciona el número de líneas de la función.

Registro de símbolos denominado .ef (final de la función). El campo Value tiene el mismo número que el campo Total Size en el registro de símbolos de definición de funciones.

Los registros de símbolos .bf y .ef (pero no los de tipo .lf) van seguidos de un registro auxiliar con el formato siguiente:

Offset Size Campo Descripción
0
4
No utilizado
4
2
Linenumber
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 utilizado
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 los registros .ef.
16
2
No utilizado

 

Formato auxiliar 3: externos débiles

Los "externos débiles" son un mecanismo para los archivos de objeto que permiten flexibilidad en tiempo de vínculo. 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 tiempo de vínculo, en su lugar se usa otro símbolo externo (sym2) para resolver las referencias.

Si se vincula una definición de sym1, se resuelve una referencia externa al símbolo con normalidad. Si una definición de sym1 no está vinculada, todas las referencias al externo débil para sym1 harán referencia a sym2. El símbolo externo, sym2, siempre debe estar vinculado; Normalmente, se define en el módulo que contiene la referencia débil a sym1.

Los externos débiles los representan un registro de 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ímbolos externos débiles va seguido de un registro auxiliar con el formato siguiente:

Offset Size Campo Descripción
0
4
TagIndex
Índice de tabla de símbolos de sym2, el símbolo que se va a 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 utilizado

 

Tenga en cuenta que el campo Characteristics no está definido en WINNT.H; en su lugar, se usa el campo Total Size.

Formato auxiliar 4: archivos

Este formato sigue un registro de tabla de símbolos con la clase de almacenamiento FILE (103). El propio nombre del símbolo debe ser .file y el registro auxiliar que sigue proporciona el nombre de un archivo de código fuente.

Offset Size Campo Descripción
0
18
Nombre de archivo
Cadena ANSI que proporciona el nombre del archivo de origen. Esto se completa con valores null si es menor que la longitud máxima.

 

Formato auxiliar 5: definiciones de secciones

Este formato sigue un registro de tabla de símbolos que define una sección. Este registro 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 hace referencia. Por lo tanto, duplica parte de la información del encabezado de sección.

Offset 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
Número de entradas de reubicación de la sección.
6
2
NumberOfLinenumbers
Número de entradas de número de línea de la sección.
8
4
CheckSum
Suma de comprobación de los datos comunes. Es aplicable si la marca IMAGE_SCN_LNK_COMDAT se establece en el encabezado de sección. Para obtener más información, vea Secciones COMDAT (solo objeto).
12
2
Number
Índice con base uno en la tabla de secciones de la sección asociada. Esto se usa cuando el valor de selección COMDAT es 5.
14
1
Número de selección
Número de selección COMDAT. Esto es aplicable si la sección es de tipo COMDAT.
15
3
No utilizado

 

Secciones COMDAT (solo objeto)

El campo Selection del formato auxiliar de definición de sección es aplicable si la sección es de tipo COMDAT. Una sección COMDAT es una sección que la puede definir más de un archivo de objeto. (La marca IMAGE_SCN_LNK_COMDAT se establece en el campo Section Flags del encabezado de sección). El campo Selection determina la forma en que el enlazador resuelve las múltiples definiciones de 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 Value igual a cero, el número de sección de la sección COMDAT concreta, el campo Type igual a IMAGE_SYM_TYPE_NULL, el campo Class 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 Selection.

A continuación se muestran los valores del campo Selection.

Constante Valor Descripción
IMAGE_COMDAT_SELECT_NODUPLICATES
1
Si este símbolo ya está definido, el enlazador emite un error que indica "símbolo definido por multiplicación".
IMAGE_COMDAT_SELECT_ANY
2
Cualquier sección que defina el mismo símbolo COMDAT se puede vincular; 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 las definiciones no tienen todas el mismo tamaño, se emite un error que indica "símbolo definido por multiplicación".
IMAGE_COMDAT_SELECT_EXACT_MATCH
4
El enlazador elige una sección arbitraria entre las definiciones de este símbolo. Si las definiciones no coinciden todas de forma exacta, se emite un error que indica "símbolo definido por multiplicación".
IMAGE_COMDAT_SELECT_ASSOCIATIVE
5
La sección está vinculada si otra sección COMDAT lo está también. Esta otra sección se indica mediante el campo Number 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 donde todas deben vincularse o descartarse como un conjunto. La otra sección a la que está asociada esta debe ser de tipo 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 tenga IMAGE_COMDAT_SELECT_ASSOCIATIVE establecido.
IMAGE_COMDAT_SELECT_LARGEST
6
El enlazador elige la definición más grande entre todas las definiciones de este símbolo. Si varias definiciones tienen este tamaño, la elección entre ellas es arbitraria.

 

Definición de token CLR (solo objeto)

Este símbolo auxiliar suele ir detrás de IMAGE_SYM_CLASS_CLR_TOKEN. Se usa para asociar un token con el espacio de nombres de la tabla de símbolos COFF.

Offset Size Campo Descripción
0
1
bAuxType
Debe ser IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF (1).
1
1
bReserved
Reservado, debe ser 0.
2
4
SymbolTableIndex
Índice de símbolo del símbolo COFF al que hace referencia esta definición de token CLR.
6
12
Reservado, debe ser 0.

 

Tabla de cadenas COFF

Inmediatamente después de la tabla de símbolos COFF se encuentra 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 van las cadenas terminadas en null a las que apuntan los símbolos de la tabla de símbolos COFF.

Tabla de certificados de atributo (solo imagen)

Los certificados de atributo se pueden asociar a una imagen agregando una tabla de certificados de atributo. La tabla de certificados de atributo se compone de un conjunto de entradas de certificado de atributo contiguas y alineadas con cuatro palabras. Para lograr esta alineación, se insertan ceros entre el final original del archivo y el principio de la tabla de certificados de atributo. Cada entrada del certificado de atributo contiene los campos siguientes.

Offset Size Campo Descripción
0
4
dwLength
Especifica la longitud de la entrada del certificado de atributo.
4
2
wRevision
Contiene el número de versión del certificado. Para obtener más información, vea el texto siguiente.
6
2
wCertificateType
Especifica el tipo de contenido en bCertificate. Para obtener más información, vea el texto siguiente.
8
Consulte
bCertificate
Contiene un certificado, como una firma Authenticode. Para obtener más información, vea el texto siguiente.

 

El valor de dirección virtual de la entrada Tabla de certificados en el Directorio de datos de encabezado opcional es un desplazamiento de archivo a la primera entrada del certificado de atributo. A las entradas posteriores se accede avanzando los bytes dwLength de esa entrada, redondeados hasta un múltiplo de 8 bytes, desde el principio de la entrada del certificado de atributo actual. Esto continúa hasta que la suma de los valores dwLength redondeados es igual al valor Size de la entrada Tabla de certificados en el directorio de datos del encabezado opcional. Si la suma de los valores dwLength redondeados no es igual al valor Size, la tabla de certificados del atributo o el campo Size está dañado.

Por ejemplo, si la entrada de la tabla de certificados del Directorio de datos de encabezado opcional contiene lo siguiente:

virtual address = 0x5000
size = 0x1000

El primer certificado comienza en el desplazamiento 0x5000 desde el inicio del archivo en el disco. Para avanzar por todas las entradas del certificado de atributo, haga lo siguiente:

  1. Agregue el primer valor dwLength del certificado de atributo al desplazamiento inicial.
  2. Redondea el valor del paso 1 hasta el múltiplo de 8 bytes más próximo para buscar el desplazamiento de la segunda entrada del certificado de atributo.
  3. Agregue el valor de desplazamiento del paso 2 al segundo valor dwLength de la entrada del certificado de atributo y redondee hasta el múltiplo de 8 bytes más cercano para determinar el desplazamiento de la tercera entrada de certificado de atributo.
  4. Repita el paso 3 para cada certificado sucesivo hasta que el desplazamiento calculado sea igual a 0x6000 (inicio de 0x5000 + tamaño total de 0x1000), 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 vínculo a la página de referencia de la función, vea Referencias.

Las entradas de la tabla de certificados de atributo pueden contener cualquier tipo de certificado, siempre que la entrada tenga el valor dwLength correcto, un valor wRevision único y un valor wCertificateType único. El tipo más común de entrada de la tabla de certificados es una estructura WIN_CERTIFICATE, que se documenta en Wintrust.h y se describe en el resto de esta sección.

Las opciones del miembro WIN_CERTIFICATE wRevision incluyen (sin limitación) lo siguiente.

Valor Nombre Notas
0x0100
WIN_CERT_REVISION_1_0
Versión 1, versión heredada de la estructura Win_Certificate. Solo se admite con fines de comprobación de firmas Authenticode heredadas.
0x0200
WIN_CERT_REVISION_2_0
La versión 2 es la versión actual de la estructura Win_Certificate.

 

Las opciones para el miembro wCertificateType de WIN_CERTIFICATE incluyen (sin limitación) los elementos de la tabla siguiente. Tenga en cuenta que algunos valores no se admiten actualmente.

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 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 que especifica wCertificateType. El tipo compatible con 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, vea Formato de firma ejecutable portátil Authenticode de Windows.

Si el contenido de bCertificate no termina en un límite de cuatro palabras, la entrada del certificado de atributo se completa con ceros, desde el final de bCertificate hasta el límite siguiente de cuatro palabras.

El valor dwLength es la longitud de la estructura WIN_CERTIFICATE finalizada y se calcula de la siguiente manera:

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 cumplir el requisito de que cada estructura WIN_CERTIFICATE esté alineada con cuatro palabras:

dwLength += (8 - (dwLength & 7)) & 7;

El tamaño de la tabla de certificados especificado en la entrada 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 ImageHlp API para enumerar, agregar y quitar certificados de archivos PE, vea Funciones ImageHlp.

Datos de certificado

Tal como se indicó en la sección anterior, los certificados de la tabla de certificados de atributo 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 similar a una suma de comprobación de archivo de tal forma que el algoritmo hash genera un resumen de mensaje relacionado con la integridad de un archivo. Pero una suma de comprobación la genera un algoritmo simple y se usa principalmente para detectar si un bloque de memoria en el disco ha ido mal y los valores almacenados allí se han dañado. Un hash de archivo es similar a una suma de comprobación de tal forma que también detecta daños en los archivos. Pero, 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 de archivo de su valor original sin modificar. Por lo tanto, se puede usar un hash de archivo para detectar modificaciones intencionadas e incluso sutiles en un archivo, como las que introducen virus, hackers o programas de caballo de Troya.

Cuando se incluye en un certificado, el resumen de imagen debe excluir determinados campos de la imagen PE, como la entrada Suma de comprobación y Tabla de certificados en los Directorios de datos de encabezado opcionales. Esto se debe a que el hecho de agregar un certificado cambia estos campos y provocaría que se calculara otro valor hash.

La función ImageGetDigestStream de Win32 proporciona un flujo de datos de un archivo PE de destino con el que se usan funciones hash. Este flujo de datos sigue siendo coherente cuando se agregan o quitan certificados de un archivo PE. En función de los parámetros que se pasan a ImageGetDigestStream, se pueden omitir otros datos de la imagen PE del cálculo hash. Para obtener un vínculo a la página de referencia de la función, vea Referencias.

Tablas de importación de carga retrasada (solo imagen)

Estas tablas se agregaron a la imagen a fin de admitir 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 directorios de carga retrasada

La tabla de directorios de carga retrasada es el homólogo de la tabla de directorios de importación. Se puede recuperar mediante la entrada Descriptor de importación retrasada en la lista opcional de directorios de datos de encabezado (desplazamiento 200). La tabla se organiza de la siguiente manera:

Offset Size Campo Descripción
0
4
Atributos
Debe ser cero.
4
4
Nombre
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
Module Handle
RVA del identificador del módulo (en la sección de datos de la imagen) del archivo DLL que se va a cargar con retraso. Lo usa la rutina que se proporciona a fin de administrar la carga diferida para el almacenamiento.
12
4
Delay Import Address Table
RVA de la tabla de direcciones de importación de carga retrasada. Para obtener más información, vea Tabla de direcciones de importación retrasada (IAT).
16
4
Delay Import Name Table
RVA de la tabla de nombres de carga retrasada, que contiene los nombres de las importaciones que podrían necesitar cargarse. Esto coincide con el diseño de la tabla de nombres de importación. Para obtener más información, vea Tabla Hint/Name.
20
4
Bound Delay Import Table
RVA de la tabla de direcciones de carga retrasada enlazada, si existe.
24
4
Unload Delay Import Table
RVA de la tabla de direcciones de carga retrasada de descarga, 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 volver a copiar en 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 igual que sus homólogos para las importaciones tradicionales. Para obtener más información, vea la Sección .idata.

Atributos

Por el momento, no se han definido marcas de atributo. El enlazador establece este campo en cero en la imagen. Este campo se puede usar para ampliar el registro indicando la presencia de nuevos campos, o bien se puede usar para indicar comportamientos en las funciones auxiliares de retraso o descarga.

Nombre

El nombre del archivo DLL que se va a cargar con retraso se encuentra en la sección de datos de solo lectura de la imagen. Se hace referencia a él mediante el campo szName.

Identificador de módulo

El identificador del archivo DLL que se va a cargar con retraso se encuentra en la sección de datos de la imagen. El campo phmod apunta al identificador. El asistente de carga retrasada proporcionado usa esta ubicación para almacenar el identificador en el archivo DLL cargado.

Tabla de direcciones de importación retrasada

El descriptor de importación retrasada hace referencia a la tabla de direcciones de importación retrasada (IAT) mediante el campo pIAT. El asistente de carga retrasada actualiza estos punteros con los puntos de entrada reales para que los códigos thunk ya no estén en el bucle de llamada. Se accede a los punteros de función mediante la expresión pINT->u1.Function.

Tabla de nombres de importación retrasada

La tabla de nombres de importación retrasada (INT) contiene los nombres de las importaciones que podrían requerir una carga. Se ordenan de la misma manera que los punteros de función en la IAT. Constan de las mismas estructuras que la INT estándar y se accede a ellas mediante la expresión pINT->u1.AddressOfData->Name[0].

Tabla de direcciones de importación enlazada retrasada y marca de tiempo

La de direcciones de importación enlazada retrasada (BIAT) es una tabla opcional de elementos IMAGE_THUNK_DATA que la usa, junto con el campo timestamp de la tabla de directorios de carga retrasada, 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 en 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 para restaurar todo a su estado de carga previa.

Secciones especiales

Las secciones típicas de COFF contienen código o datos que los enlazadores y los cargadores de Microsoft Win32 procesan sin conocimientos especiales sobre el contenido de la sección. El contenido solo es relevante para la aplicación que se está vinculando o ejecutando.

Pero algunas secciones de COFF tienen significados especiales cuando se encuentran en archivos de 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 propio nombre de sección no indica una función especial de la sección, el nombre de sección lo determina la 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 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 objeto, solo arquitectura x86 y obsoleta ahora)
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, vea "Atributos IDL" en Referencias al final de este tema.
IMAGE_SCN_LNK_INFO
.pdata
Información de la 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 del recurso
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 registrados del controlador de excepciones (solo formato libre y 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 de objeto. El símbolo puede ser para un símbolo UNDEF o para uno 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 excepciones (formato libre)
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ

 

Algunas de las secciones mostradas aquí se marcan como "solo objeto" o "solo imagen" para indicar que su semántica especial solo es relevante para archivos de objeto o archivos de imagen, respectivamente. Una sección marcada como "solo imagen" podría aparecer en un archivo de objeto como una forma de entrar en el archivo de imagen, pero la sección no tiene ningún significado especial para el enlazador, solo para el cargador de archivos de imagen.

Sección .debug

La sección .debug se usa en archivos de objeto para contener información de depuración generada por el compilador y en 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 sección siguiente se describe el formato del directorio de depuración, que puede estar en cualquier parte de la imagen. En las secciones posteriores se describen los "grupos" en los archivos de objeto que contienen información de depuración.

El valor predeterminado para el enlazador es que la información de depuración no está asignada 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é formato de información de depuración está presente y dónde se encuentra. 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), puede incluirse en cualquier otra sección del archivo de imagen o bien puede no estar en ninguna sección.

Cada entrada de directorio de depuración identifica la ubicación y el tamaño de un bloque de información de depuración. La RVA especificada puede ser cero si la información de depuración no la cubre un encabezado de sección (es decir, reside en el archivo de imagen y no se asigna al espacio de direcciones en tiempo de ejecución). Si se asigna, la RVA es su dirección.

Una entrada de directorio de depuración tiene el formato siguiente:

Offset Size Campo Descripción
0
4
Características
Reservado, debe ser 0.
4
4
TimeDateStamp
Hora y 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
Formato de la información de depuración. Este campo permite admitir varios depuradores. Para obtener más información, vea Tipo de depuración.
16
4
SizeOfData
Tamaño de los datos de depuración (sin incluir el propio directorio de depuración).
20
4
AddressOfRawData
Dirección de los datos de depuración cuando se cargan, relativa a la base de la imagen.
24
4
PointerToRawData
Puntero de archivo a los datos de depuración.

 

Tipo de depuración

Los valores siguientes se definen para el campo Type de la entrada del directorio de depuración:

Constante Valor Descripción
IMAGE_DEBUG_TYPE_UNKNOWN
0
Un valor desconocido que omiten todas las herramientas.
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
Información de depuración de Visual C++.
IMAGE_DEBUG_TYPE_FPO
3
Información de omisión del puntero de marco (FPO). Esta información indica al depurador cómo interpretar fotogramas de pila no estándar, que usan el registro EBP para un propósito distinto de un puntero de marco.
IMAGE_DEBUG_TYPE_MISC
4
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
Asignación de una RVA en la imagen a una RVA en la imagen de origen.
IMAGE_DEBUG_TYPE_OMAP_FROM_SRC
8
Asignación de una RVA en la imagen de origen a una RVA en 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 capacidad de reproducir de PE.
No definido
17
La información de depuración se inserta en el archivo PE en la ubicación especificada por PointerToRawData.
No definido
19
Almacena el hash criptográfico para el contenido del archivo de símbolos usado para compilar el archivo PE/COFF.
IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS 20 Bits de características de DLL extendidas.

 

Si el campo Type se establece en IMAGE_DEBUG_TYPE_FPO, los datos sin procesar de la 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 da por hecho 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á creado de forma que puede lograr el determinismo o la capacidad de reproducción. Si la entrada no cambia, se garantiza que el archivo PE de salida sea idéntico bit a bit, independientemente de cuándo o dónde se produzca. Se rellenan varios campos de marca de fecha y hora del archivo PE con algunos 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 los datos específicos relacionados dentro del PE. Los datos sin procesar de esta entrada de depuración pueden estar vacíos o contener un valor hash calculado precedido por un valor de cuatro bytes que representa la longitud del valor hash.

Si el campo Type se establece en IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS, los datos sin procesar de la depuración contienen bits de características de DLL extendidas, además de los que se podrían establecer en el encabezado opcional de la imagen. Vea Características de DLL en la sección Campos de encabezado opcionales específicos de Windows (solo imagen).

Características de DLL extendidas

Los valores siguientes se definen para los bits de características de DLL extendidas.

Constante Valor Descripción
IMAGE_DLLCHARACTERISTICS_EX_CET_COMPAT 0x0001 La imagen es compatible con la tecnología de cumplimiento de flujo de control (CET) Shadow Stack.
IMAGE_DLLCHARACTERISTICS_EX_FORWARD_CFI_COMPAT 0x0040 Todos los destinos de rama de todas las secciones de código de imagen se anotan con instrucciones de protección de integridad de flujo de control de reenvío hacia delante, como x86 CET-Indirect Branch Tracking (IBT) o las instrucciones de identificación de destino de rama de ARM (BTI). Windows no usa este bit.

.debug$F (solo objeto)

Los datos de esta sección las ha reemplazado en la versión 7.0 de Visual C++ y versiones posteriores un conjunto más amplio de datos que se emiten en una subsección de .debug$S.

Los archivos de objeto pueden contener secciones .debug$F cuyo contenido sea uno o varios registros FPO_DATA (información de omisión del puntero de marco). Vea "IMAGE_DEBUG_TYPE_FPO" en Tipo de depuración.

El enlazador reconoce estos registros de .debug$F. Si se genera información de depuración, el enlazador ordena los registros de FPO_DATA por RVA de procedimiento y genera una entrada de directorio de depuración para ellos.

El compilador no debe generar registros de 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 enlazador con la información de depuración de Microsoft

Para admitir la información de depuración, el enlazador realiza lo siguiente:

  • 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.

Sección .drectve (solo objeto)

Una sección es de directiva si tiene la marca IMAGE_SCN_LNK_INFO establecida en el encabezado de sección y tiene el nombre de 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á vinculando.

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 del enlazador separadas por espacios. Cada opción contiene un guion, el nombre de la opción y cualquier atributo adecuado. 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.

Sección .edata (solo imagen)

La sección exportación de datos, denominada .edata, contiene información sobre los símbolos a los que otras imágenes pueden acceder mediante la vinculación dinámica. Los símbolos exportados suelen encontrarse en archivos DLL, pero los archivos DLL también pueden importar símbolos.

A continuación se describe información general sobre la estructura general de la sección de exportación. Las tablas descritas suelen ser contiguas en el archivo en el orden mostrado (aunque esto no es necesario). Solo se requieren la tabla de directorios de exportación y la tabla de direcciones de exportación 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 nombres 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 de depuración). En esta tabla se indican las ubicaciones y tamaños de las demás 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 código y datos ejecutables. Otros archivos de imagen pueden importar un símbolo mediante un índice para esta tabla (un ordinal) o, de forma opcional, mediante el nombre público que se corresponde con el ordinal si se define un nombre público.
Tabla de punteros de nombre
Matriz de punteros a los nombres de exportación públicos, ordenados de forma ascendente.
Tabla de ordinales
Matriz de los ordinales que se corresponden con los miembros de la tabla de punteros de nombre. La correspondencia es por posición; por lo tanto, la tabla de punteros de nombre 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. Miembros del punto de la tabla de punteros de nombre en esta área. Estos son los nombres públicos mediante los cuales se importan y exportan los símbolos; no son necesariamente iguales que los nombres privados que se usan en el archivo de imagen.

 

Cuando otro archivo de imagen importa un símbolo por nombre, el cargador de Win32 busca una cadena coincidente en la tabla de punteros de nombre. 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 nombre). El ordinal resultante es un índice en 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 nombre una cadena coincidente. Por lo tanto, el uso directo de un ordinal es más eficaz. Pero un nombre de exportación es más fácil de recordar y no requiere que el usuario conozca el índice de tabla para el 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 direcciones que se usa para resolver las importaciones en los puntos de entrada de esta imagen.

Offset Size Campo Descripción
0
4
Export Flags
Reservado, debe ser 0.
4
4
Time/Date Stamp
Hora y fecha en que se crearon los datos de exportación.
8
2
Major Version
Número de versión principal. El usuario puede establecer los números de la versión principal y la secundaria.
10
2
Minor Version
Número de versión secundaria.
12
4
Name RVA
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
Ordinal Base
Número ordinal inicial de las exportaciones de esta imagen. Este campo especifica el número ordinal inicial de la tabla de direcciones de exportación. Normalmente se establece en 1.
20
4
Address Table Entries
Número de entradas de la tabla de direcciones de exportación.
24
4
Number of Name Pointers
Número de entradas de la tabla de punteros de nombre. También es el número de entradas de la tabla de ordinales.
28
4
Export Address Table RVA
Dirección de la tabla de direcciones de exportación, relativa a la base de la imagen.
32
4
Name Pointer RVA
Dirección de la tabla de punteros de nombre de exportación, relativa a la base de la imagen. El tamaño de la tabla lo asigna el campo Number of Name Pointers.
36
4
Ordinal Table RVA
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, así como los datos exportados y los absolutos. En esta tabla se usa como índice un número ordinal.

Cada entrada de la tabla de direcciones de exportación es un campo que usa uno de los dos formatos de la tabla siguiente. Si la dirección especificada no está en la sección de exportación (tal como se define en la dirección y la longitud indicadas en el encabezado opcional), el campo es una RVA de exportación, que es una dirección real en el código o los datos. De lo contrario, el campo es una RVA de reenviador, que asigna un nombre a un símbolo en otro archivo DLL.

Offset Size Campo Descripción
0
4
Export RVA
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
Forwarder RVA
Puntero a una cadena ASCII terminada en null en la sección de exportación. Esta cadena debe estar en el intervalo que proporciona la entrada del directorio de datos de la tabla de exportación. Vea Directorios de datos de encabezado opcionales (solo imagen). Esta cadena proporciona el nombre DLL y el nombre de la exportación (por ejemplo, "MYDLL.expfunc"), o el nombre DLL y el número ordinal de la exportación (por ejemplo, "MYDLL.#27").

 

Una RVA de reenviador exporta una definición de otra imagen, lo que hace que aparezca como si la exportara la imagen actual. Por lo tanto, el símbolo se importa y exporta simultáneamente.

Por ejemplo, en Kernel32.dll en 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 importación 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 de nombres de exportación

La tabla de punteros de nombres de exportación es una matriz de direcciones (RVA) en la tabla de nombres de exportación. Los punteros son de 32 bits cada uno y hacen referencia a la base de la imagen. Los punteros se ordenan léxicamente para permitir búsquedas binarias.

Un nombre de exportación solo se define si la tabla de punteros de nombres de exportación contiene un puntero a él.

Tabla de ordinales de exportación

La tabla de ordinales de exportación es una matriz de índices no sesgados de 16 bits en la tabla de direcciones de exportación. Los ordinales los sesga el campo Ordinal Base de la tabla de directorios de exportación. Es decir, la base ordinal debe restarse de los ordinales para obtener índices verdaderos en la tabla de direcciones de exportación.

La tabla de punteros de nombres de exportación y la tabla de ordinales de exportación forman dos matrices paralelas separadas para permitir la alineación natural de campos. Estas dos tablas, en efecto, funcionan como una tabla, en la que la columna Export Name Pointer apunta a un nombre público (exportado) y la columna Export Ordinal proporciona el ordinal correspondiente para ese nombre público. Un miembro de la tabla de punteros de nombres de exportación y un miembro de la tabla de ordinales de exportación están asociados al tener la misma posición (índice) en sus respectivas matrices.

Por lo tanto, cuando se busca en la tabla de punteros de nombres 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 el siguiente:

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 el siguiente:

ordinal = biased_ordinal - OrdinalBase;
i = Search_ExportOrdinalTable (ordinal);

rva = ExportAddressTable [ordinal];
name = ExportNameTable [i];

Tabla de nombres de exportación

La tabla de nombres de exportación contiene los datos de cadena reales a los que apunta la tabla de punteros de nombres 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 de símbolos privados que los símbolos tienen en su propio archivo de imágenes y código fuente, aunque podrían ser.

Cada símbolo exportado tiene un valor ordinal, que es solo el índice en la tabla de direcciones de exportación. Pero el uso de nombres de exportación es opcional. Algunos símbolos exportados, todos o ninguno de ellos, pueden tener nombres de exportación. En el caso de los símbolos exportados que tienen nombres de exportación, las entradas correspondientes de la tabla de punteros de nombres de exportación y 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.

Sección .idata

Todos los archivos de imágenes 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 null

  • Tabla de búsqueda de importación de DLL1

    Null

  • Tabla de búsqueda de importación de DLL2

    Null

  • Tabla de búsqueda de importación de DLL3

    Null

  • Tabla de sugerencias y nombres

Tabla de directorios de importación

La información de importación comienza con la tabla de directorios de importación, que describe el resto de la información de importación. La tabla de directorios de importación contiene información de direcciones que se usa para resolver las referencias de corrección a los puntos de entrada de una imagen DLL. La tabla de directorios de importación consta de una matriz de entradas de directorios de importación, una entrada por cada DLL a la que hace referencia la imagen. La última entrada del directorio está vacía (rellenada con valores null), que indica el final de la tabla de directorios.

Cada entrada de directorio de importación tiene el formato siguiente:

Offset Size Campo Descripción
0
4
Import Lookup Table RVA (Characteristics)
RVA de la tabla de búsquedas de importación. Esta tabla contiene un nombre u ordinal para cada importación. (El nombre "Characteristics" se usa en Winnt.h, pero ya no describe este campo).
4
4
Time/Date Stamp
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 o datos del archivo DLL.
8
4
Forwarder Chain
Índice de la primera referencia del reenviador.
12
4
Name RVA
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
Import Address Table RVA (Thunk Table)
RVA de la tabla de direcciones de importación. El contenido de esta tabla es idéntico al contenido de la tabla de búsquedas de importación hasta que se enlaza la imagen.

 

Tabla de búsquedas de importación

Una tabla de búsquedas 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 tabla siguiente. En este formato, el bit 31 es el más significativo para PE32 y el bit 63 es el más significativo para PE32+. La colección de estas entradas describe todas las importaciones de 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
Ordinal/Name Flag
Si se establece este bit, impórtelo por ordinales. De lo contrario, importe por nombres. El bit se enmascara como 0x80000000 para PE32, 0x8000000000000000 para PE32+.
15-0
16
Ordinal Number
Número ordinal de 16 bits. Este campo solo se usa si el campo de bits Ordinal/Name Flag es 1 (importar por ordinales). Los bits 30-15 o 62-15 deben ser 0.
30-0
31
Hint/Name Table RVA
RVA de 31 bits de una entrada de tabla de sugerencias o nombres. Este campo solo se usa si el campo de bits Ordinal/Name Flag es 0 (importar por nombres). Para PE32+, los bits 62-31 deben ser cero.

 

Tabla de sugerencias y nombres

Una tabla de sugerencias o nombres es suficiente para toda la sección de importación. Cada entrada de la tabla de sugerencias o nombres tiene el formato siguiente:

Offset Size Campo Descripción
0
2
Hint
Un índice en la tabla de punteros de nombres de exportación. Primero se intenta establecer una coincidencia con este valor. Si esto falla, se realiza una búsqueda binaria en la tabla de punteros de nombres de exportación del archivo DLL.
2
variable
Nombre
Una cadena ASCII que contiene el nombre que se va a importar. Esta es la cadena que debe coincidir con el nombre público en el archivo DLL. Esta cadena distingue mayúsculas de minúsculas y finaliza con un byte nulo.
*
0 o 1
Pad
Un byte final completado con ceros que aparece después del byte nulo final, en caso necesario, para alinear la entrada siguiente 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úsquedas de importación, 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 son las direcciones de memoria reales de los símbolos, aunque técnicamente todavía se denominan "direcciones virtuales". El cargador normalmente procesa el enlace.

Sección .pdata

La sección .pdata contiene una matriz de entradas de tabla de funciones que se usan para el control de excepciones. La entrada de la tabla de excepciones en el directorio de datos de imagen apunta a ella. Las entradas deben ordenarse según las direcciones de la función (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 las imágenes MIPS de 32 bits, las entradas de la tabla de funciones tienen el formato siguiente:

Offset Size Campo Descripción
0
4
Begin Address
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
Handler Data
Puntero a información adicional que se va a pasar al controlador.
16
4
Prolog End Address
VA del final del prólogo de la función.

 

Para las plataformas ARM, PowerPC, SH3 y SH4 de Windows CE, las entradas de la tabla de funciones tienen el formato siguiente:

Offset Size Campo Descripción
0
4
Begin Address
VA de la función correspondiente.
4
8 bits
Prolog Length
Número de instrucciones del prólogo de la función.
4
22 bits
Function Length
Número de instrucciones de la función.
4
1 bit
32-bit Flag
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 bit
Exception Flag
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 formato siguiente:

Offset Size Campo Descripción
0
4
Begin Address
RVA de la función correspondiente.
4
4
Dirección final
RVA del final de la función.
8
4
Unwind Information
RVA de la información de desenredado.

 

Sección .reloc (solo imagen)

La tabla de reubicaciones base contiene entradas para todas las reubicaciones base de la imagen. El campo Base Relocation Table en los directorios de datos de encabezado opcionales proporciona el número de bytes en la tabla de reubicaciones base. Para obtener más información, vea Directorios de datos de encabezado opcionales (solo imagen). La tabla de reubicaciones base se divide 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 las reubicaciones base que resuelva el enlazador, a menos que la imagen de carga no pueda cargarse en la base de la imagen especificada en el encabezado PE.

Bloque de reubicaciones base

Cada bloque de reubicaciones base comienza con la estructura siguiente:

Offset Size Campo Descripción
0
4
Page RVA
La base de la imagen más la RVA de página se agrega a cada desplazamiento para crear la VA donde se debe aplicar la reubicación base.
4
4
Tamaño de bloque
Número total de bytes del bloque de reubicación base, incluidos los campos Page RVA y Block Size y los campos Type/Offset siguientes.

 

Después, al campo Block Size lo sigue cualquier número de entradas de los campos Type u Offset. Cada entrada es un elemento WORD (2 bytes) y tiene la estructura siguiente:

Offset Size Campo Descripción
0
4 bits
Tipo
Almacenado en los 4 bits superiores de WORD, un valor que indica el tipo de reubicación base que se va a aplicar. Para obtener más información, vea Tipos de reubicación base.
0
12 bits
Offset
Almacenado en los 12 bits restantes de WORD, un desplazamiento de la dirección inicial que se especificó en el campo Page RVA del bloque. Este desplazamiento especifica dónde se va a aplicar la reubicación base.

 

Para aplicar una reubicación base, la diferencia se calcula entre la dirección base preferida y la base donde se carga realmente la imagen. Si la imagen se carga en su base preferida, la diferencia es cero y, por tanto, no es necesario aplicar las reubicaciones base.

Tipos de reubicación base

Constante Valor Descripción
IMAGE_REL_BASED_ABSOLUTE
0
Se omite la reubicación base. Este tipo se puede usar para rellenar un bloque.
IMAGE_REL_BASED_HIGH
1
La reubicación base agrega los 16 bits superiores de la diferencia al campo de 16 bits en el desplazamiento. El campo de 16 bits representa el valor superior de una palabra de 32 bits.
IMAGE_REL_BASED_LOW
2
La reubicación base agrega los 16 bits inferiores 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 superiores de la diferencia al campo de 16 bits en el desplazamiento. El campo de 16 bits representa el valor superior de una palabra de 32 bits. Los 16 bits inferiores 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 espacios.
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 es significativa 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 a un par consecutivo de instrucciones MOVW/MOVT.
IMAGE_REL_BASED_RISCV_HIGH20
5
Esta reubicación solo es significativa cuando el tipo de máquina es RISC-V. La reubicación base se aplica a los 20 bits superiores de una dirección absoluta de 32 bits.
6
Reservado, debe ser 0.
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 es significativa cuando el tipo de máquina es RISC-V. La reubicación base se aplica a los 12 bits inferiores de una dirección absoluta de 32 bits formada con el formato de instrucciones de tipo I de RISC-V.
IMAGE_REL_BASED_RISCV_LOW12S
8
Esta reubicación solo es significativa cuando el tipo de máquina es RISC-V. La reubicación base se aplica a los 12 bits inferiores de una dirección absoluta de 32 bits formada con el formato de instrucciones de tipo S de RISC-V.
IMAGE_REL_BASED_LOONGARCH32_MARK_LA
8
Esta reubicación solo es significativa 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 es significativa 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 es significativa cuando el tipo de máquina es MIPS. La reubicación base se aplica a una instrucción de salto MIPS16.
IMAGE_REL_BASED_DIR64
10
La reubicación base aplica la diferencia con el campo de 64 bits en el desplazamiento.

 

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 Windows admite 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. Por lo tanto, cada subproceso puede mantener un valor diferente para una variable declarada mediante TLS.

Tenga en cuenta que cualquier cantidad de datos TLS puede ser compatible mediante las llamadas API a TlsAlloc, TlsFree, TlsSetValue y TlsGetValue. La implementación de PE o COFF es un enfoque alternativo para usar la API y tiene la ventaja de ser más sencilla desde el punto de vista del programador de lenguaje de alto nivel. Esta implementación permite definir e inicializar datos TLS de forma similar a las variables estáticas normales de un programa. Por ejemplo, en Visual C++, se puede definir una variable TLS estática tal 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 finalización por subproceso, y el índice TLS, que se explica en la exposición siguiente.

Nota:

Los objetos de datos TLS declarados estáticamente solo se pueden 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 vinculado estáticamente con él, nunca se va a cargar dinámicamente con la función de la API LoadLibrary.

 

El código ejecutable accede a un objeto de datos TLS estático mediante los pasos siguientes:

  1. En tiempo de vínculo, el enlazador establece el campo Address of Index del directorio TLS. Este campo apunta a una ubicación donde el programa espera recibir el índice TLS.

    La biblioteca en tiempo de ejecución de Microsoft facilita este proceso al definir una imagen de memoria del directorio TLS y darle el nombre especial "__tls_used" (plataformas Intel x86) o "_tls_used" (otras plataformas). El enlazador busca esta imagen de memoria y usa los datos allí para crear el directorio TLS. Otros compiladores que admiten TLS y funcionan con el enlazador de Microsoft deben usar esta misma técnica.

  2. 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 subprocesos (TEB) en el registro de 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.

  3. El cargador asigna el valor del índice TLS al lugar que indica el campo Address of Index.

  4. El código ejecutable recupera el índice TLS y también la ubicación de la matriz TLS.

  5. El código usa el índice TLS y la ubicación de la matriz TLS (multiplicando el índice por 4 y usándolo como desplazamiento a la matriz) a fin de obtener la dirección del área de datos TLS para el programa y el módulo especificados. 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.

  6. 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) 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.

Directorio TLS

El directorio TLS tiene el formato siguiente:

Desplazamiento (PE32/PE32+) Tamaño (PE32/PE32+) Campo Descripción
0
4/8
Raw Data Start VA
Dirección inicial 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
Raw Data End VA
Dirección del último byte de TLS, excepto el completado con ceros. Al igual que con el campo Raw Data Start VA, se trata de una VA, no de una RVA.
8/16
4/8
Address of Index
Ubicación en la que se va a recibir el índice TLS, que asigna el cargador. Esta ubicación se encuentra en una sección de datos normal, por lo que se le puede asignar un nombre simbólico accesible para el programa.
12/24
4/8
Address of Callbacks
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 establecido en cero. Para obtener información sobre el prototipo de estas funciones, vea Funciones de devolución de llamada TLS.
16/32
4
Size of Zero Fill
Tamaño en bytes de la plantilla, más allá de los datos inicializados que delimitan los campos Raw Data Start VA y Raw Data End VA. 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 con ceros 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 se reservan para un uso futuro.

 

Funciones de devolución de llamada TLS

El programa puede proporcionar una o varias funciones de devolución de llamada TLS a fin de admitir la inicialización y terminación adicionales para los objetos de datos TLS. Un uso típico de esta función de devolución de llamada sería llamar a 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 se quiere. 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 Reserved debe establecerse en cero. El parámetro Reason puede aceptar los valores siguientes:

Parámetro Valor Descripción
DLL_PROCESS_ATTACH
1
Se ha iniciado un nuevo proceso, incluido el primer subproceso.
DLL_THREAD_ATTACH
2
Se ha creado un subproceso. Esta notificación se envió para todos los subprocesos menos el primero.
DLL_THREAD_DETACH
3
Un subproceso está a punto de finalizar. Esta notificación se envió para todos los subprocesos menos el primero.
DLL_PROCESS_DETACH
0
Un proceso está a punto de finalizar, incluido el subproceso original.

 

Estructura de configuración de carga (solo imagen)

La estructura de configuración de carga (IMAGE_LOAD_CONFIG_DIRECTORY) se usó anteriormente en casos muy limitados en el propio sistema operativo Windows NT para describir varias características demasiado difíciles o demasiado grandes de describir en el encabezado de 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 el envío de excepciones. Si la dirección del controlador reside en el intervalo de la VA de una imagen y se marca como compatible con SEH reservado (es decir, IMAGE_DLLCHARACTERISTICS_NO_SEH está borrado 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 "secuestro del controlador de excepciones x86" que se ha utilizado en el pasado para tomar el control del sistema operativo.

El enlazador de Microsoft proporciona automáticamente una estructura de configuración de carga predeterminada para incluir los datos SEH reservados. Si el código de 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 SEH reservados y la imagen no está marcada como que contiene datos SEH reservados.

Directorio de configuración de carga

La entrada del directorio de datos de una estructura de configuración de carga SEH reservada previamente debe especificar un tamaño determinado de la estructura de configuración de carga, ya que el cargador del sistema operativo siempre espera que sea un valor determinado. En este sentido, el tamaño tan solo es una comprobación de versión. Para la compatibilidad con Windows XP y versiones anteriores de Windows, el tamaño debe ser 64 para 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:

Offset Size Campo Descripción
0
4
Características
Marcas que indican los atributos del archivo, actualmente sin usar.
4
4
TimeDateStamp
Valor de marca de fecha y hora. El valor se representa en el número de segundos transcurridos desde la medianoche (00:00:00) del 1 de enero de 1970 en la hora universal coordinada, según el reloj del sistema. La marca de hora se puede imprimir mediante la función de hora en 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
Marcas del cargador global que se borrarán para este proceso a medida que el cargador inicia el proceso.
16
4
GlobalFlagsSet
Marcas del cargador global que se establecerán para este proceso a medida que el cargador inicia el proceso.
20
4
CriticalSectionDefaultTimeout
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 se debe liberar antes de que se devuelva 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 procesador único.
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
Identificador de versión del Service Pack.
54/78
2
Reservado
Debe ser cero.
56/80
4/8
EditList
Reservado para que lo use 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 envío 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
Recuento de RVA únicas en la tabla anterior.
88/144
4
GuardFlags
Control de marcas relacionadas con Protección de flujo.
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
Recuento de RVA únicas 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
Recuento de RVA únicas en la tabla anterior.

 

El campo GuardFlags contiene una combinación de una o varias de las marcas y subcampos siguientes:

  • 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 retrasada de solo lectura.

    #define IMAGE_GUARD_PROTECT_DELAYLOAD_IAT 0x00001000

  • Carga retrasada de la tabla de importación 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. De esto también se deduce que la dirección tomada de la tabla IAT está igualmente presente en la configuración de carga.

    #define IMAGE_GUARD_CF_EXPORT_SUPPRESSION_INFO_PRESENT 0x00004000

  • El módulo habilita la supresión de 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 intervalo de 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 de Windows SDK define esta macro para que la cantidad de bits cambie el valor GuardFlags a la derecha a fin de justificar el intervalo de la tabla de funciones de Protección de flujo de control:

#define IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_SHIFT 28

Sección .rsrc

Los recursos se indexan mediante una estructura de árbol ordenado binario de varios niveles. El diseño general puede incorporar 2**31 niveles. Pero, por convención, Windows usa tres niveles:

Lenguaje de nombre de tipo

Una serie de tablas de directorios del recurso 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 o de otra tabla de directorios. Si la dirección apunta a una descripción de datos, los datos son una hoja del árbol. Si la dirección apunta a otra tabla de directorios, esa tabla muestra una lista de las entradas de directorio en el siguiente nivel hacia abajo.

Los id. de tipo, nombre e idioma de una hoja los determina la ruta de acceso que se toma mediante las tablas de directorio para llegar a la hoja. La primera tabla determina el id. de tipo, la segunda tabla (a la que apunta la entrada de directorio de la primera tabla) determina el id. de nombre y, la tercera, el ID. de idioma.

La estructura general de la sección .rsrc es la siguiente:

data Descripción
Tablas de directorio del recurso (y Entradas de directorio del recurso)
Una serie de tablas, una para cada grupo de nodos del árbol. Todos los nodos de nivel superior (Tipo) se muestran 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 id. de nombre distintos. Los árboles de tercer nivel tienen los mismos id. de tipo y nombre, pero diferentes ID. de idioma.
Cada tabla individual va seguida inmediatamente de entradas de directorio, en las que cada entrada tiene un nombre o un identificador numérico y un puntero a una descripción de datos o a una tabla en el nivel inferior siguiente.
Cadenas de directorio del recurso
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 del recurso
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 del recurso.
Datos de recursos
Datos sin procesar de la sección del recurso. La información de tamaño y ubicación del campo Resource Data Descriptions delimita las regiones individuales de los datos del recurso.

 

Tabla de directorios del recurso

Cada tabla de directorios del recurso tiene el formato siguiente. Esta estructura de datos debe considerarse como el encabezado de una tabla porque la tabla está formada realmente por entradas de directorio (descritas en la sección 6.9.2, "Entradas de directorios del recurso") y esta estructura:

Offset Size Campo Descripción
0
4
Características
Marcas del recurso. Este campo está reservado para un uso futuro. Actualmente está establecido en cero.
4
4
Time/Date Stamp
Hora en que el compilador del recurso creó los datos del recurso.
8
2
Major Version
Número de versión principal, que establece el usuario.
10
2
Minor Version
Número de versión secundaria, que establece el usuario.
12
2
Number of Name Entries
Número de entradas del directorio inmediatamente después de la tabla que usan cadenas para identificar las entradas de Tipo, Nombre o Idioma (según el nivel de la tabla).
14
2
Number of ID Entries
Número de entradas del directorio inmediatamente después de las entradas de Nombre que usan id. numéricos para las entradas de Tipo, Nombre o Idioma.

 

Entradas de directorios del recurso

Las entradas de directorios componen las filas de una tabla. Cada entrada del directorio del recurso tiene el formato siguiente. La tabla del directorio del recurso determina si la entrada es un Nombre o un id., lo 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 de forma ascendente: las entradas de Nombre por cadena con distinción entre mayúsculas y minúsculas y las entradas de id. por valor numérico. Los desplazamientos son relativos a la dirección del DataDirectory IMAGE_DIRECTORY_ENTRY_RESOURCE. Vea Emparejamiento dentro del PE: un recorrido por el formato de archivo ejecutable portátil de Win32 para obtener más información.

Offset Size Campo Descripción
0
4
Name Offset
Desplazamiento de una cadena que proporciona la entrada de Tipo, Nombre o ID de idioma, según el nivel de tabla.
0
4
Identificador entero
Entero de 32 bits que identifica la entrada de Tipo, Nombre o ID de idioma.
4
4
Data Entry Offset
Bit superior 0. Dirección de una entrada de Datos del recurso (una hoja).
4
4
Subdirectory Offset
Bit superior 1. Los 31 bits inferiores son la dirección de otra tabla de directorios del recurso (el siguiente nivel inferior).

 

Cadena de directorios del recurso

El área de cadena del directorio del recurso consta de cadenas Unicode, que están alineadas con palabras. Estas cadenas se almacenan juntas después de la última entrada de Directorio del recurso y antes de la primera entrada de Datos del recurso. Esto minimiza el impacto de estas cadenas de longitud variable en la alineación de las entradas del directorio de tamaño fijo. Cada cadena del directorio del recurso tiene el formato siguiente:

Offset Size Campo Descripción
0
2
Length
Tamaño de la cadena, sin incluir el propio campo de longitud.
2
variable
Unicode String
Datos de la cadena Unicode de longitud variable, alineados con palabras.

 

Entrada de datos del recurso

Cada entrada de Datos del recurso describe una unidad real de datos sin procesar en el área Datos del recurso. Una entrada de Datos del recurso tiene el formato siguiente:

Offset Size Campo Descripción
0
4
Data RVA
Dirección de una unidad de datos del recurso en el área Datos del recurso.
4
4
Size
Tamaño, en bytes, de los datos del recurso a los que apunta el campo Data RVA.
8
4
codepage
Página de códigos que se usa para descodificar valores de punto de código dentro de los datos del recurso. Normalmente, la página de códigos sería la página de códigos Unicode.
12
4
Reservado, debe ser 0.

 

Sección .cormeta (solo objeto)

Los metadatos CLR se almacenan en esta sección. Se usa para indicar que el archivo de 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.

Sección .sxdata

Los controladores de excepciones válidos de un objeto se muestran en la sección .sxdata de ese objeto. La sección está marcada como IMAGE_SCN_LNK_INFO. Contiene el índice de símbolos COFF de cada controlador válido, utilizando 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)

El formato de archivo COFF proporciona un mecanismo estándar para almacenar colecciones de archivos de objetos. Estas colecciones normalmente se denominan bibliotecas en la documentación sobre programación.

Los primeros 8 bytes de un almacenamiento constan de la firma del archivo. El resto del almacenamiento consta de una serie de miembros de almacenamiento, tal como se indica a continuación:

  • Los miembros primero y segundo son "miembros del enlazador". Cada uno de estos miembros tiene su propio formato, tal como se describe en la sección Tipo de nombre de importación. Normalmente, un enlazador coloca información en estos miembros de almacenamiento. Los miembros del enlazador contienen el directorio del almacenamiento.

  • El tercero es el miembro "longnames". 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 almacenamiento.

  • El resto del almacenamiento consta de miembros estándar (archivo de objetos). Cada uno de estos miembros incluye el contenido de un archivo de objeto en su totalidad.

Un encabezado de miembro de almacenamiento precede a cada miembro. En la lista siguiente se muestra la estructura general de un archivo:

Firma :"!<arch>\n"
Encabezado
Primer miembro del enlazador
Encabezado
Segundo miembro del enlazador
Encabezado
Miembro longnames
Encabezado
Contenido del archivo 1 de OBJ
(Formato COFF)
Encabezado
Contenido del archivo 2 de OBJ
(Formato COFF)

...

Encabezado
Contenido del archivo N de OBJ
(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 toma 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 siguiente se representa literalmente, excepto el carácter de línea nueva (\n):

!<arch>\n

El encabezado winnt.h de Windows SDK define las macros siguientes:

#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 almacenamiento

Cada miembro (enlazador, longnames o miembro de archivo de objeto) viene precedido de un encabezado. Un encabezado de miembro de almacenamiento tiene el siguiente formato, en el que cada campo es una cadena de texto ASCII justificada a la izquierda y completada con espacios al final del campo. No hay ningún carácter null de finalización en ninguno de estos campos.

Cada encabezado de miembro se inicia 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 que un miembro de archivo haga que el siguiente miembro se inicie en una dirección par.

Offset Size Campo Descripción
0
16
Nombre
Nombre del miembro de almacenamiento, con una barra diagonal (/) anexada para finalizar el nombre. Si el primer carácter es una barra diagonal, el nombre tiene una interpretación especial, tal como se describe en la tabla siguiente.
16
12
Fecha
Fecha y hora en que se creó el miembro de almacenamiento: esta es la representación decimal ASCII del número de segundos desde el 1/1/1970 UCT.
28
6
Identificador de usuario
Representación decimal ASCII del id. de usuario. Este campo no contiene un valor significativo en plataformas Windows porque las herramientas de Microsoft emiten todos los espacios en blanco.
34
6
Identificador de grupo
Representación decimal ASCII del id. de grupo. Este campo no contiene un valor significativo en plataformas Windows porque las herramientas de Microsoft emiten todos los espacios en blanco.
40
8
Mode
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
Size
Representación decimal ASCII del tamaño total del miembro de almacenamiento, sin incluir el tamaño del encabezado.
58
2
End of Header
Los dos bytes (0x60 0x0A) de la cadena C "'\n" (IMAGE_ARCHIVE_END).

El campo Name tiene uno de los formatos que se muestran en la tabla siguiente. Tal como se ha mencionado anteriormente, cada una de estas cadenas está justificada a la izquierda y completada con espacios finales dentro de un campo de 16 bytes:

Contenido del campo Name Descripción
name/
Nombre del miembro de almacenamiento.
/
El miembro de almacenamiento es uno de los dos miembros del enlazador. Ambos miembros del enlazador tienen este nombre.
//
El miembro de almacenamiento es el miembro longnames, que consta de una serie de cadenas ASCII terminadas en null. El miembro longnames es el tercer miembro de almacenamiento y es opcional.
/n
El nombre del miembro de almacenamiento se encuentra en el desplazamiento n dentro del miembro longnames. El número n es la representación decimal del desplazamiento. Por ejemplo: "/26" indica que el nombre del miembro de almacenamiento se encuentra 26 bytes más allá del principio del contenido del miembro 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 enlazador proporciona un directorio de nombres de símbolos, al igual que el segundo miembro del enlazador. Para cada símbolo, la información indica dónde encontrar el miembro de almacenamiento que contiene el símbolo.

El primer miembro del enlazador tiene el formato siguiente. Esta información aparece después del encabezado:

Offset Size Campo Descripción
0
4
Number of Symbols
Tipo long sin signo que contiene el número de símbolos indizado. Este número se almacena en formato big-endian. Cada miembro de archivo de objeto normalmente define uno o varios símbolos externos.
4
4 * n
Offsets
Matriz de desplazamientos de archivo a encabezados de miembro de almacenamiento, en la que n es igual al campo Number of Symbols. Cada número de la matriz es de tipo long sin signo almacenado en formato big-endian. Para cada símbolo denominado en la tabla de cadenas, el elemento correspondiente de la matriz de desplazamientos proporciona la ubicación del miembro de almacenamiento que contiene el símbolo.
*
*
String Table
Serie de cadenas terminadas en null que asignan un nombre a todos los símbolos del directorio. Cada cadena comienza inmediatamente después del carácter null de la cadena anterior. El número de cadenas debe ser igual al valor del campo Number of Symbols.

 

Los elementos de la matriz de desplazamientos 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 almacenamiento. Por ejemplo, todos los símbolos del primer miembro de archivo de objeto tendrían que aparecer antes que los símbolos en el segundo archivo de objeto.

Segundo miembro del enlazador

Al igual que el primer miembro del enlazador, el segundo miembro del enlazador tiene el nombre "/" (IMAGE_ARCHIVE_LINKER_MEMBER). Aunque ambos miembros del enlazador proporcionan un directorio de símbolos y miembros de almacenamiento que los contienen, todos los enlazadores actuales priorizan el uso del segundo miembro del enlazador. El segundo miembro del enlazador incluye nombres de símbolos en orden léxico, lo que permite realizar búsquedas más rápidas por nombre.

El segundo miembro tiene el formato siguiente. Esta información aparece después del encabezado:

Offset Size Campo Descripción
0
4
Number of Members
Tipo long sin signo que contiene el número de miembros de almacenamiento.
4
4 * m
Offsets
Matriz de desplazamientos de archivo para los encabezados de miembro de almacenamiento, organizados en orden ascendente. Cada desplazamiento es de tipo long sin signo. El número m es igual al valor del campo Number of Members.
*
4
Number of Symbols
Tipo long sin signo que contiene el número de símbolos indizado. Cada miembro de archivo de objeto normalmente define uno o varios símbolos externos.
*
2 * n
Indices
Matriz de índices con base 1 (short sin signo) que asignan nombres de símbolos a desplazamientos de miembros de almacenamiento. El número n es igual al campo Number of Symbols. Para cada símbolo denominado en la tabla de cadenas, el elemento correspondiente de la matriz de Indices proporciona un índice a la matriz de desplazamientos. La matriz de desplazamientos, a su vez, proporciona la ubicación del miembro de almacenamiento que contiene el símbolo.
*
*
String Table
Serie de cadenas terminadas en null que asignan un nombre a todos los símbolos del directorio. Cada cadena comienza inmediatamente después del byte null de la cadena anterior. El número de cadenas debe ser igual al valor del campo Number of Symbols. En esta tabla se muestra una lista de todos los nombres de símbolos en orden léxico ascendente.

 

Miembro longnames

El nombre del miembro longnames es "//" (IMAGE_ARCHIVE_LONGNAMES_MEMBER). El miembro longnames es una serie de cadenas de nombres de miembros de almacenamiento. Aquí aparece un nombre solo cuando no hay espacio suficiente en el campo Name (16 bytes). El miembro longnames es opcional. Puede estar vacío e incluir solo un encabezado, o puede estar completamente ausente sin incluir ni siquiera un encabezado.

Las cadenas terminan en null. Cada cadena comienza inmediatamente después del byte null de la cadena anterior.

Formato de biblioteca de importación

Las bibliotecas de importación tradicionales, es decir, bibliotecas que describen las exportaciones de una imagen para que la use 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 seudobjetos 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 almacenamiento al compilar la aplicación de exportación.

Las contribuciones de sección para una importación se pueden deducir 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 permitir que la aplicación que lo use más adelante genere los datos necesarios sobre la marcha.

En una biblioteca de importación con el formato largo, un único miembro contiene la siguiente información:

  • Encabezado de miembro de almacenamiento
  • Encabezado de archivo
  • Encabezados de sección
  • Datos que se corresponden con cada uno de los encabezados de sección
  • Tabla de símbolos COFF
  • Cadenas

Por el contrario, se escribe una biblioteca de importación corta de la siguiente manera:

  • Encabezado de miembro de almacenamiento
  • Encabezado de importación
  • Cadena de nombre de importación terminada en null
  • Cadena de nombre DLL terminada en null

Esta información es 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:

Offset Size Campo Descripción
0
2
Sig1
Debe ser IMAGE_FILE_MACHINE_UNKNOWN. Para obtener más información, vea Tipos de máquina.
2
2
Sig2
Debe ser 0xFFFF.
4
2
Versión
Versión de la estructura.
6
2
Máquina
Número que identifica el tipo de máquina de destino. Para obtener más información, vea Tipos de máquina.
8
4
Time-Date Stamp
Hora y fecha en que se creó el archivo.
12
4
Size Of Data
Tamaño de las cadenas que siguen al encabezado.
16
2
Ordinal/Hint
El ordinal o la sugerencia para la importación, que lo determina el valor del campo Name Type.
18
2 bits
Tipo
Tipo de importación. Para obtener descripciones y valores específicos, vea Tipo de importación.
3 bits
Name Type
Tipo de nombre de la importación. Para obtener más información, vea Tipo de nombre de la 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

Los valores siguientes se definen para el campo Type en el encabezado de importación:

Constante Valor Descripción
IMPORT_OBJECT_CODE
0
Código ejecutable.
IMPORT_OBJECT_DATA
1
Datos
IMPORT_OBJECT_CONST
2
Se especifica como CONST en el archivo .def.

Estos valores se usan para determinar qué contribuciones de sección se deben generar mediante la herramienta que usa la biblioteca, en caso de que deba acceder a esos datos.

Tipo de nombre de importación

El nombre del símbolo de importación terminado en null va justo detrás de su encabezado de importación asociado. Los valores siguientes se definen para el campo Name Type en el encabezado de importación. Indican cómo se usará el nombre para generar los símbolos correctos que representan la importación:

Constante Valor Descripción
IMPORT_OBJECT_ORDINAL 0 La importación se realiza por ordinal. Esto indica que el valor del campo Ordinal/Hint del encabezado de importación es el ordinal de la importación. Si no se especifica esta constante, el campo Ordinal/Hint siempre debe interpretarse como la sugerencia de importación.
IMPORT_OBJECT_NAME 1 El nombre de importación es idéntico al nombre público del símbolo.
IMPORT_OBJECT_NAME_NOPREFIX 2 El nombre de importación es el nombre público del símbolo, pero omite los símbolos iniciales ?, @ u, opcionalmente, _.
IMPORT_OBJECT_NAME_UNDECORATE 3 El nombre de importación es el nombre público del símbolo, pero omite los símbolos iniciales ?, @ u, opcionalmente, _, y se trunca en el primer símbolo @.

Apéndice A: Cálculo del hash de imagen de PE de Authenticode

Se espera que se usen varios certificados de atributo para comprobar la integridad de las imágenes. Pero el más común es la firma Authenticode. Se puede usar una firma Authenticode para comprobar que las secciones pertinentes de un archivo de imagen de PE no se han modificado de ninguna manera del formato original del archivo. Para realizar esta tarea, las firmas Authenticode contienen algo denominado hash de imagen de PE.

¿Qué es un hash de imagen de PE de Authenticode?

El hash de imagen de PE de Authenticode, o hash de archivo en su denominación corta, es similar a una suma de comprobación de archivo en cuanto que genera un valor pequeño relacionado con la integridad de un archivo. Un algoritmo simple genera una suma de comprobación y se usa principalmente para detectar errores de memoria. Es decir, se usa para detectar si un bloque de memoria en el disco está defectuoso y los valores almacenados allí se han dañado. Un hash de archivo es similar a una suma de comprobación de tal forma que también detecta daños en los archivos. Pero a diferencia de la mayoría de los algoritmos de suma de comprobación, es muy difícil modificar un archivo de modo que tenga el mismo hash de archivo que su formato original (sin modificar). Es decir, el objetivo de una suma de comprobación es detectar errores de memoria simples que desembocan en daños, pero un hash de archivo se puede usar para detectar modificaciones intencionadas e incluso sutiles en un archivo, como las que introducen virus, hackers o programas de caballo de Troya.

En una firma Authenticode, el hash de archivo lo firma digitalmente una clave privada conocida solo para el firmante del archivo. Un consumidor de software puede comprobar 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 de archivo no coinciden, significa que se ha modificado parte del archivo que cubre el hash de imagen de PE.

¿Qué se trata en un hash de imagen de PE de Authenticode?

No es posible, ni deseable, incluir todos los datos del archivo de imagen en el cálculo del hash de imagen de PE. A veces tan solo presenta características no deseadas (por ejemplo, la información de depuración no se puede quitar de los archivos lanzados públicamente); a veces es simplemente imposible. Por ejemplo, no es posible incluir toda la información dentro de un archivo de imagen en una firma Authenticode y, después, insertar la firma Authenticode que contiene ese hash de imagen de PE en la imagen de PE y, posteriormente, poder generar un hash de imagen de PE idéntico incluyendo otra vez todos los datos de archivo de imagen en el cálculo, ya que el archivo ahora contiene la firma Authenticode que no estaba originalmente ahí.

Proceso para generar el hash de imagen de PE de Authenticode

En esta sección se describe cómo se calcula un hash de imagen de PE y qué partes de la imagen de PE se pueden modificar sin invalidar la firma Authenticode.

Nota:

El hash de imagen de PE de un archivo específico se puede incluir en un archivo de catálogo independiente sin incluir un certificado de atributo en el archivo hash. Esto es relevante, ya que se puede invalidar el hash de imagen de PE en un archivo de catálogo firmado por Authenticode modificando una imagen de PE que no contiene realmente una firma Authenticode.

A todos los datos de las secciones de la imagen de PE que se especifican en la tabla de secciones se les aplica un algoritmo hash en su totalidad, excepto en los siguientes intervalos de exclusión:

  • 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 atributo. Las áreas de la imagen de PE relacionadas con la firma Authenticode no se incluyen en el cálculo del hash de imagen de PE porque las firmas Authenticode se pueden agregar o quitar de una imagen sin que esto afecte a la integridad general de la imagen. Esto no supone un problema, ya que hay escenarios de usuario que dependen de volver a firmar imágenes de PE o de agregar una marca de tiempo. Authenticode excluye la siguiente información del cálculo de hash:

    • El campo Certificate Table de los directorios de datos de encabezado opcionales.

    • La tabla de certificados y los certificados correspondientes a los que apunta el campo Certificate Table que aparece inmediatamente arriba.

    Para calcular el hash de imagen de PE, Authenticode ordena las secciones especificadas en la tabla de secciones por intervalo de direcciones y, después, aplica un algoritmo hash a la secuencia de bytes resultante y pasa por alto los intervalos de exclusión.

  • Información más allá del final de la última sección. Al área situada más allá de la última sección (definida por el desplazamiento más alto) no se le aplica un algoritmo hash. Esta área suele contener información de depuración. Por lo general, la información de depuración se puede considerar como asesoramiento a los depuradores; no afecta a la integridad real del programa ejecutable. Es literalmente posible quitar la información de depuración de una imagen después de entregar un producto y que esto no afecte a la función del programa. De hecho, esto a veces se hace como una medida de ahorro de disco. Cabe destacar que la información de depuración contenida en las secciones especificadas de la imagen de PE no se puede quitar sin invalidar la firma Authenticode.

Puede usar las herramientas makecert y signtool proporcionadas en el SDK de la Plataforma de Windows para experimentar con la creación y comprobación de firmas Authenticode. Para obtener más información, vea la sección Referencias siguiente.

Referencias

Descargas y herramientas para Windows (incluye Windows SDK)

Creación, visualización y administración de certificados

Tutorial sobre la firma de código en modo Kernel (.doc)

SignTool

Formato de firma ejecutable portátil Authenticode de Windows (.docx)

Funciones ImageHlp