Formato PE

Esta especificação descreve a estrutura de arquivos executáveis (imagem) e arquivos de objeto na família de sistemas operacionais Windows. Esses arquivos são chamados de arquivos PE e em formato COFF (Common Object File Format), respectivamente.

Nota

Este documento é fornecido para auxiliar no desenvolvimento de ferramentas e aplicativos para Windows, mas não há garantias de que ele consista em uma especificação completa em todos os aspectos. A Microsoft reserva para si o direito de alterar este documento sem aviso prévio.

Esta revisão da Especificação de arquivo PE e em formato COFF da Microsoft substitui todas as revisões anteriores desta especificação.

Conceitos gerais

Este documento especifica a estrutura de arquivos executáveis (imagem) e arquivos de objeto na família de sistemas operacionais Microsoft Windows. Esses arquivos são chamados de arquivos PE e em formato COFF (Common Object File Format), respectivamente. O nome "PE (Portable Executable)" refere-se ao fato de que o formato não é específico da arquitetura.

Alguns conceitos que aparecem ao longo desta especificação são descritos na tabela a seguir:

Name Descrição
certificado de atributo
Um certificado usado para associar instruções verificáveis a uma imagem. Diversas instruções verificáveis podem ser associadas a um arquivo, sendo que uma das mais úteis consiste em uma instrução de um fabricante de software que indica qual deve ser o resumo da mensagem da imagem. Um resumo da mensagem é semelhante a uma soma de verificação, exceto pelo fato de ser extremamente difícil de falsificar. Portanto, é muito difícil modificar um arquivo para ter o mesmo resumo da mensagem que o arquivo original. A instrução pode ser verificada como sendo feita pelo fabricante usando esquemas de criptografia de chave pública ou privada. Este documento contém detalhes sobre certificados de atributo além de permitir sua inserção em arquivos de imagem.
carimbo de data e hora
Um carimbo é usado para diferentes propósitos em vários lugares em um arquivo PE ou COFF. Na maioria dos casos, o formato de cada carimbo é o mesmo usado pelas funções de tempo na biblioteca de tempo de execução C. Para exceções, veja a descrição de IMAGE_DEBUG_TYPE_REPRO em Tipo de depuração. Caso o valor do carimbo seja 0 ou 0xFFFFFFFF, significa que ele não representa um carimbo de data/hora real ou significativo.
ponteiro de arquivo
A localização de um item dentro do próprio arquivo antes de ser processado pelo vinculador (no caso de arquivos de objeto) ou pelo carregador (no caso de arquivos de imagem). Em outras palavras, trata-se de uma posição dentro do arquivo armazenada no disco.
vinculador
Uma referência ao vinculador fornecido com o Microsoft Visual Studio.
arquivo de objeto
Um arquivo que é fornecido como entrada para o vinculador. O vinculador produz um arquivo de imagem que, por sua vez, é usado como entrada pelo carregador. O termo "arquivo de objeto" não implica necessariamente uma conexão com a programação orientada a objetos.
reservado, deve ser 0
Uma descrição de um campo que indica que o valor do campo deve ser zero para geradores e que os consumidores devem ignorar o campo.
RVA (endereço virtual relativo)
Em um arquivo de imagem, esse é o endereço de um item depois que ele é carregado na memória, com o endereço base do arquivo de imagem subtraído dele. O RVA de um item quase sempre difere de sua posição dentro do arquivo no disco (ponteiro de arquivo).
Em um arquivo de objeto, um RVA é menos significativo porque os locais de memória não são atribuídos. Nesse caso, um RVA seria um endereço dentro de uma seção (descrita posteriormente nesta tabela) ao qual se aplica posteriormente uma realocação durante a vinculação. Para simplificar, um compilador deve apenas definir o primeiro RVA em cada seção como zero.
seção
A unidade básica de código ou dados em um arquivo PE ou COFF. Por exemplo, todo o código em um arquivo de objeto pode ser combinado em uma única seção ou (dependendo do comportamento do compilador) cada função pode ocupar sua própria seção. Com mais seções, há mais sobrecarga de arquivo, mas o vinculador pode vincular o código de forma mais seletiva. Uma seção é semelhante a um segmento na arquitetura Intel 8086. Todos os dados brutos em uma seção devem ser carregados de forma contígua. Além disso, um arquivo de imagem pode conter várias seções, como .tls ou .reloc, com propósitos especiais.
VA (endereço virtual)
O mesmo que RVA, exceto pelo fato de o endereço base do arquivo de imagem não ser subtraído. O endereço é chamado de VA porque Windows cria um espaço VA distinto para cada processo, independente da memória física. Para quase todas as finalidades, um VA deve ser considerado apenas um endereço. Um VA não é tão previsível quanto um RVA porque o carregador pode não carregar a imagem no respectivo local preferido.

Visão geral

A lista a seguir descreve o formato executável do PE da Microsoft, com a base do cabeçalho da imagem na parte superior. A seção do cabeçalho EXE compatível com MS-DOS 2.0 até a seção não utilizada logo antes do cabeçalho PE é a seção MS-DOS 2.0, sendo usada apenas para compatibilidade com o MS-DOS.

  • Cabeçalho EXE compatível com MS-DOS 2.0

  • não utilizado

  • Identificador do OEM

    Informações sobre OEM

    Deslocamento para cabeçalho PE

  • Programa de stub e tabela de realocação do MS-DOS 2.0

  • não utilizado

  • Cabeçalho do PE (alinhado no limite de 8 bytes)

  • Cabeçalhos da seção

  • Páginas de imagens:

    importar informações

    exportar informações

    realocações de base

    informações do recurso

A lista a seguir descreve o formato de módulo de objeto de COFF da Microsoft:

  • Cabeçalho do COFF da Microsoft

  • Cabeçalhos da seção

  • Dados brutos:

    código

    data

    informações de depuração

    realocações

Cabeçalhos de arquivo

O cabeçalho do arquivo PE consiste em um stub do Microsoft MS-DOS, a assinatura PE, o cabeçalho do arquivo COFF e um cabeçalho opcional. Um cabeçalho de arquivo de objeto COFF consiste em um cabeçalho de arquivo COFF e um cabeçalho opcional. Nos dois casos, os cabeçalhos dos arquivos são seguidos imediatamente pelos cabeçalhos das seções.

Stub do MS-DOS (somente imagem)

O stub do MS-DOS é um aplicativo válido executado no MS-DOS. Ele é colocado na frente da imagem EXE. O vinculador coloca um stub padrão aqui, que imprime a mensagem "Este programa não pode ser executado no modo DOS" quando a imagem é executada no MS-DOS. O usuário pode especificar um stub diferente usando a opção de vinculador /STUB.

No local 0x3c, o stub tem o deslocamento de arquivo para a assinatura PE. Com essas informações, o Windows pode executar corretamente o arquivo de imagem, mesmo que tenha um stub do MS-DOS. Esse deslocamento de arquivo é colocado no local 0x3c durante a vinculação.

Assinatura (somente imagem)

Após o stub do MS-DOS, no deslocamento de arquivo especificado no 0x3c de deslocamento, há uma assinatura de 4 bytes que identifica o arquivo como um arquivo de imagem no formato PE. Essa assinatura é "PE\0\0" (as letras "P" e "E" seguidas por dois bytes nulos).

Cabeçalho do arquivo COFF (objeto e imagem)

No início de um arquivo de objeto, ou imediatamente após a assinatura de um arquivo de imagem, há um cabeçalho de arquivo COFF padrão no formato a seguir. Observe que o carregador do Windows limita o número de seções a 96.

Deslocamento Tamanho Campo Descrição
0
2
Máquina
O número que identifica o tipo de computador de destino. Para obter mais informações, confira Tipos de computador.
2
2
NumberOfSections
O número de seções. Isso indica o tamanho da tabela da seção, que segue imediatamente os cabeçalhos.
4
4
TimeDateStamp
Os 32 bits inferiores do número de segundos das 00:00 de 1º de janeiro de 1970 (um valor de time_t de tempo de execução C), que indica quando o arquivo foi criado.
8
4
PointerToSymbolTable
O deslocamento do arquivo da tabela de símbolos COFF ou zero, caso nenhuma tabela de símbolos COFF esteja presente. Esse valor deve ser zero no caso de imagem, pois as informações de depuração COFF foram preteridas.
12
4
NumberOfSymbols
O número de entradas na tabela de símbolos. Esses dados podem ser usados para localizar a tabela de cadeia de caracteres, que segue imediatamente a tabela de símbolos. Esse valor deve ser zero no caso de imagem, pois as informações de depuração COFF foram preteridas.
16
2
SizeOfOptionalHeader
O tamanho do cabeçalho opcional, que é necessário para arquivos executáveis, mas não para arquivos-objeto. Esse valor deve ser zero para um arquivo-objeto. Para obter uma descrição do formato do cabeçalho, confira Cabeçalho opcional (somente imagem).
18
2
Características
Os sinalizadores que indicam os atributos do arquivo. Para valores de sinalizadores específicos, confira Características.

Tipos de máquina

O campo Computador tem um dos seguintes valores, que especificam o tipo de CPU. Um arquivo de imagem só pode ser executado no computador especificado ou em um sistema que emule o computador especificado.

Constante Valor Descrição
IMAGE_FILE_MACHINE_UNKNOWN
0x0
Presume-se que o conteúdo deste campo se aplique a qualquer tipo de máquina
IMAGE_FILE_MACHINE_ALPHA
0x184
Alpha AXP, espaço de endereço de 32 bits
IMAGE_FILE_MACHINE_ALPHA64
0x284
Alpha 64, espaço de endereço de 64 bits
IMAGE_FILE_MACHINE_AM33
0x1d3
Matsushita AM33
IMAGE_FILE_MACHINE_AMD64
0x8664
X64
IMAGE_FILE_MACHINE_ARM
0x1c0
ARM little endian
IMAGE_FILE_MACHINE_ARM64
0xaa64
ARM64 little endian
IMAGE_FILE_MACHINE_ARMNT
0x1c4
ARM Thumb-2 little endian
IMAGE_FILE_MACHINE_AXP64
0x284
AXP 64 (igual ao Alpha 64)
IMAGE_FILE_MACHINE_EBC
0xebc
EFI byte code
IMAGE_FILE_MACHINE_I386
0x14c
Processadores Intel 386 ou mais recentes e processadores compatíveis
IMAGE_FILE_MACHINE_IA64
0x200
Família de processadores Intel Itanium
IMAGE_FILE_MACHINE_LOONGARCH32
0x6232
Família de processadores LoongArch de 32 bits
IMAGE_FILE_MACHINE_LOONGARCH64
0x6264
Família de processadores LoongArch de 64 bits
IMAGE_FILE_MACHINE_M32R
0x9041
Mitsubishi M32R little endian
IMAGE_FILE_MACHINE_MIPS16
0x266
MIPS16
IMAGE_FILE_MACHINE_MIPSFPU
0x366
MIPS com FPU
IMAGE_FILE_MACHINE_MIPSFPU16
0x466
MIPS16 com FPU
IMAGE_FILE_MACHINE_POWERPC
0x1f0
Power PC little endian
IMAGE_FILE_MACHINE_POWERPCFP
0x1f1
Power PC com suporte para ponto flutuante
IMAGE_FILE_MACHINE_R4000
0x166
MIPS little endian
IMAGE_FILE_MACHINE_RISCV32
0x5032
Espaço de endereço RISC-V de 32 bits
IMAGE_FILE_MACHINE_RISCV64
0x5064
Espaço de endereço RISC-V de 64 bits
IMAGE_FILE_MACHINE_RISCV128
0x5128
Espaço de endereço 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
Elevador
IMAGE_FILE_MACHINE_WCEMIPSV2
0x169
MIPS little-endian WCE v2

Characteristics

O campo Characteristics contém sinalizadores que indicam os atributos do arquivo de imagem ou objeto. Os seguintes sinalizadores estão atualmente definidos:

Sinalizador Valor Descrição
IMAGE_FILE_RELOCS_STRIPPED
0x0001
Somente imagem, Windows CE e Microsoft Windows NT e posterior. Isso indica que o arquivo não contém realocações de base e, portanto, deve ser carregado no endereço base preferido. Se o endereço base não estiver disponível, o carregador relatará um erro. O comportamento padrão do vinculador é remover realocações de base de arquivos executáveis (EXE).
IMAGE_FILE_EXECUTABLE_IMAGE
0x0002
Somente imagem. Isso indica que o arquivo de imagem é válido e pode ser executado. Se esse sinalizador não estiver definido, ele indicará um erro de vinculador.
IMAGE_FILE_LINE_NUMS_STRIPPED
0x0004
Os números das linhas COFF foram removidos. Esse sinalizador está obsoleto e deve ser zero.
IMAGE_FILE_LOCAL_SYMS_STRIPPED
0x0008
As entradas da tabela de símbolos COFF para símbolos locais foram removidas. Esse sinalizador está obsoleto e deve ser zero.
IMAGE_FILE_AGGRESSIVE_WS_TRIM
0x0010
Obsoleto. Conjunto de trabalho com corte agressivo. Esse sinalizador foi preterido no Windows 2000 e posterior e deve ser zero.
IMAGE_FILE_LARGE_ADDRESS_ AWARE
0x0020
O aplicativo pode processar > endereços de 2 GB.
0x0040
O sinalizador é reservado para uso futuro.
IMAGE_FILE_BYTES_REVERSED_LO
0x0080
Little endian: o LSB (bit menos significativo) precede o MSB (bit mais significativo) na memória. Esse sinalizador está obsoleto e deve ser zero.
IMAGE_FILE_32BIT_MACHINE
0x0100
A máquina se baseia em uma arquitetura de palavra de 32 bits.
IMAGE_FILE_DEBUG_STRIPPED
0x0200
As informações de depuração são removidas do arquivo de imagem.
IMAGE_FILE_REMOVABLE_RUN_ FROM_SWAP
0x0400
Se a imagem estiver em mídia removível, carregue-a totalmente e copie-a para o arquivo de troca.
IMAGE_FILE_NET_RUN_FROM_SWAP
0x0800
Se a imagem estiver em mídia de rede, carregue-a totalmente e copie-a para o arquivo de troca.
IMAGE_FILE_SYSTEM
0x1000
O arquivo de imagem é um arquivo de sistema, não um programa de usuário.
IMAGE_FILE_DLL
0x2000
O arquivo de imagem é uma DLL (biblioteca de vínculo dinâmico). Esses arquivos são considerados arquivos executáveis para quase todos os fins, embora não possam ser executados diretamente.
IMAGE_FILE_UP_SYSTEM_ONLY
0x4000
O arquivo deve ser executado apenas em uma máquina com um único processador.
IMAGE_FILE_BYTES_REVERSED_HI
0x8000
Big endian: o MSB precede o LSB na memória. Esse sinalizador está obsoleto e deve ser zero.

Cabeçalho opcional (somente imagem)

Cada arquivo de imagem tem um cabeçalho opcional que fornece informações ao carregador. Esse cabeçalho é opcional no sentido de que alguns arquivos (especificamente, arquivos de objeto) não o contém. Para arquivos de imagem, esse cabeçalho é obrigatório. Um arquivo de objeto pode ter um cabeçalho opcional, mas geralmente esse cabeçalho não tem função em um arquivo de objeto, exceto aumentar seu tamanho.

Observe que o tamanho do cabeçalho opcional não é fixo. O campo SizeOfOptionalHeader no cabeçalho COFF deve ser usado para validar se uma investigação no arquivo para um diretório de dados específico não vai além de SizeOfOptionalHeader. Para obter mais informações, confira Cabeçalho do arquivo COFF (objeto e imagem).

O campo NumberOfRvaAndSizes do cabeçalho opcional também deve ser usado para garantir que nenhuma investigação para uma entrada de diretório de dados específica fique além do cabeçalho opcional. Além disso, é importante validar o número mágico do cabeçalho opcional para compatibilidade de formato.

O número mágico do cabeçalho opcional determina se uma imagem é um executável PE32 ou PE32+.

Número mágico Formato PE
0x10b
PE32
0x20b
PE32+

As imagens PE32+ permitem um espaço de endereço de 64 bits, limitando o tamanho da imagem a 2 gigabytes. Outras modificações do PE32+ são abordadas em suas respectivas seções.

O cabeçalho opcional em si tem três partes principais.

Deslocamento (PE32/PE32+) Tamanho (PE32/PE32+) Parte do cabeçalho Descrição
0
28/24
Campos padrão
Campos definidos para todas as implementações de COFF, incluindo UNIX.
28/24
68/88
Campos específicos do Windows
Campos adicionais para dar suporte a recursos específicos do Windows (por exemplo, subsistemas).
96/112
Variável
Diretórios de dados
Pares de endereço/tamanho para tabelas especiais que são encontradas no arquivo de imagem e são usadas pelo sistema operacional (por exemplo, as tabelas de importação e exportação).

Campos padrão de cabeçalho opcionais (somente imagem)

Os primeiros oito campos do cabeçalho opcional são campos padrão definidos para cada implementação de COFF. Esses campos contêm informações gerais úteis para carregar e executar um arquivo executável. Eles permanecem inalterados para o formato PE32+.

Deslocamento Tamanho Campo Descrição
0
2
Mágico
O inteiro sem sinal que identifica o estado do arquivo de imagem. O número mais comum é 0x10B, que o identifica como um arquivo executável normal. 0x107 o identifica como uma imagem ROM, e 0x20B, como um executável PE32+.
2
1
MajorLinkerVersion
O número da versão principal do vinculador.
3
1
MinorLinkerVersion
O número da versão secundária do vinculador.
4
4
SizeOfCode
O tamanho da seção de código (texto) ou a soma de todas as seções de código quando há várias seções.
8
4
SizeOfInitializedData
O tamanho da seção de dados inicializados ou a soma de todas essas seções quando há várias seções.
12
4
SizeOfUninitializedData
O tamanho da seção de dados não inicializados (BSS) ou a soma de todas essas seções quando há várias seções de BSS.
16
4
AddressOfEntryPoint
O endereço do ponto de entrada relativo à base de imagem quando o arquivo executável é carregado na memória. Para imagens de programa, este é o endereço inicial. Para drivers de dispositivo, esse é o endereço da função de inicialização. Um ponto de entrada é opcional para DLLs. Quando não houver ponto de entrada presente, esse campo deverá ser zero.
20
4
BaseOfCode
O endereço que é relativo à base de imagem da seção de início de código quando a imagem é carregada na memória.

O PE32 contém esse campo adicional, que está ausente no PE32+, seguindo BaseOfCode.

Deslocamento Tamanho Campo Descrição
24
4
BaseOfData
O endereço que é relativo à base de imagem da seção de início de dados quando a imagem é carregada na memória.

Campos específicos do Windows para cabeçalho opcional (somente imagem)

Os próximos 21 campos são uma extensão do formato de cabeçalho opcional COFF. Eles contêm informações adicionais exigidas pelo vinculador e pelo carregador no Windows.

Deslocamento (PE32/PE32+) Tamanho (PE32/PE32+) Campo Descrição
28/24
4/8
ImageBase
O endereço preferido do primeiro byte de imagem quando carregado na memória; deve ser um múltiplo de 64 K. O padrão para DLLs é 0x10000000. O padrão para EXEs do Windows CE é 0x00010000. O padrão para Windows NT, Windows 2000, Windows XP, Windows 95, Windows 98 e Windows ME é 0x00400000.
32/32
4
SectionAlignment
O alinhamento (em bytes) das seções quando elas são carregadas na memória. Ele deve ser maior ou igual a FileAlignment. O padrão é o tamanho da página para a arquitetura.
36/36
4
FileAlignment
O fator de alinhamento (em bytes) usado para alinhar os dados brutos das seções no arquivo de imagem. O valor deve ser uma potência de 2 entre 512 e 64 K, inclusive. O padrão é 512. Se SectionAlignment for menor que o tamanho da página da arquitetura, o FileAlignment deverá corresponder a SectionAlignment.
40/40
2
MajorOperatingSystemVersion
O número de versão principal do sistema operacional necessário.
42/42
2
MinorOperatingSystemVersion
O número de versão secundária do sistema operacional necessário.
44/44
2
MajorImageVersion
O número de versão principal da imagem.
46/46
2
MinorImageVersion
O número de versão secundária da imagem.
48/48
2
MajorSubsystemVersion
O número de versão principal do subsistema.
50/50
2
MinorSubsystemVersion
O número de secundária principal do subsistema.
52/52
4
Win32VersionValue
Reservado; deve ser zero
56/56
4
SizeOfImage
O tamanho (em bytes) da imagem, incluindo todos os cabeçalhos, pois a imagem é carregada na memória. Deve ser um múltiplo de SectionAlignment.
60/60
4
SizeOfHeaders
O tamanho combinado de um stub do MS-DOS, o cabeçalho do PE e os cabeçalhos de seção arredondados para um múltiplo de FileAlignment.
64/64
4
CheckSum
A soma de verificação do arquivo de imagem. O algoritmo para calcular a soma de verificação é incorporado a IMAGHELP.DLL. Estes são os elementos verificados quanto à validação no momento do carregamento: todos os drivers, qualquer DLL carregada no momento da inicialização e qualquer DLL carregada em um processo crítico do Windows.
68/68
2
Subsistema
O subsistema necessário para executar esta imagem. Para obter mais informações, confira Subsistema do Windows.
70/70
2
DllCharacteristics
Para obter mais informações, confira Características de DLL posteriormente nesta especificação.
72/72
4/8
SizeOfStackReserve
O tamanho da pilha a ser reservada. Somente SizeOfStackCommit é confirmado; o restante é disponibilizado uma página por vez até que o tamanho da reserva seja atingido.
76/80
4/8
SizeOfStackCommit
O tamanho da pilha a ser confirmada.
80/88
4/8
SizeOfHeapReserve
O tamanho do espaço de heap local a ser reservado. Somente SizeOfHeapCommit é confirmado; o restante é disponibilizado uma página por vez até que o tamanho da reserva seja atingido.
84/96
4/8
SizeOfHeapCommit
O tamanho do espaço de heap local a ser confirmado.
88/104
4
LoaderFlags
Reservado; deve ser zero
92/108
4
NumberOfRvaAndSizes
O número de entradas de diretório de dados no restante do cabeçalho opcional. Cada uma descreve uma localização e um tamanho.
Subsistema Windows

Os valores a seguir definidos para o campo Subsistema do cabeçalho opcional determinam qual subsistema do Windows (se houver) será necessário para executar a imagem.

Constante Valor Descrição
IMAGE_SUBSYSTEM_UNKNOWN
0
Um subsistema desconhecido
IMAGE_SUBSYSTEM_NATIVE
1
Drivers de dispositivo e processos nativos do Windows
IMAGE_SUBSYSTEM_WINDOWS_GUI
2
O subsistema de interface gráfica do usuário (GUI) do Windows
IMAGE_SUBSYSTEM_WINDOWS_CUI
3
O subsistema de caracteres do Windows
IMAGE_SUBSYSTEM_OS2_CUI
5
O subsistema de caracteres OS/2
IMAGE_SUBSYSTEM_POSIX_CUI
7
O subsistema de caracteres Posix
IMAGE_SUBSYSTEM_NATIVE_WINDOWS
8
Driver Win9x nativo
IMAGE_SUBSYSTEM_WINDOWS_CE_GUI
9
Windows CE
IMAGE_SUBSYSTEM_EFI_APPLICATION
10
Um aplicativo de EFI (Interface de Firmware Extensível)
IMAGE_SUBSYSTEM_EFI_BOOT_ SERVICE_DRIVER
11
Um driver EFI com serviços de inicialização
IMAGE_SUBSYSTEM_EFI_RUNTIME_ DRIVER
12
Um driver EFI com serviços de tempo de execução
IMAGE_SUBSYSTEM_EFI_ROM
13
Uma imagem ROM de EFI
IMAGE_SUBSYSTEM_XBOX
14
XBOX
IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION
16
Aplicativo de inicialização do Windows.
Características do DLL

Os valores a seguir são definidos para o campo DllCharacteristics do cabeçalho opcional.

Constante Valor Descrição
0x0001
Reservado; deve ser zero
0x0002
Reservado; deve ser zero
0x0004
Reservado; deve ser zero
0x0008
Reservado; deve ser zero
IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA
0x0020
A imagem pode processar um espaço de endereço virtual de alta entropia de 64 bits.
IMAGE_DLLCHARACTERISTICS_
DYNAMIC_BASE
0x0040
A DLL pode ser realocada no momento do carregamento.
IMAGE_DLLCHARACTERISTICS_
FORCE_INTEGRITY
0x0080
As verificações de integridade do código são impostas.
IMAGE_DLLCHARACTERISTICS_
NX_COMPAT
0x0100
A imagem é compatível com NX.
IMAGE_DLLCHARACTERISTICS_ NO_ISOLATION
0x0200
Reconhecimento de isolamento, mas sem isolar a imagem.
IMAGE_DLLCHARACTERISTICS_ NO_SEH
0x0400
Não usa o tratamento de SE (exceção estruturada). Nenhum manipulador SE pode ser chamado na imagem.
IMAGE_DLLCHARACTERISTICS_ NO_BIND
0x0800
Não associe a imagem.
IMAGE_DLLCHARACTERISTICS_APPCONTAINER
0x1000
A imagem deve ser executada em um AppContainer.
IMAGE_DLLCHARACTERISTICS_ WDM_DRIVER
0x2000
Um driver WDM.
IMAGE_DLLCHARACTERISTICS_GUARD_CF
0x4000
A imagem é compatível com o proteção de fluxo de controle.
IMAGE_DLLCHARACTERISTICS_ TERMINAL_SERVER_AWARE
0x8000
Reconhecimento de servidor de terminal.

Diretórios de dados de cabeçalho opcionais (somente imagem)

Cada diretório de dados fornece o endereço e o tamanho de uma tabela ou cadeia de caracteres que o Windows usa. Essas entradas de diretório de dados são todas carregadas na memória para que o sistema possa usá-las no tempo de execução. Um diretório de dados é um campo de 8 bytes que tem a seguinte declaração:

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

O primeiro campo, VirtualAddress, é, na verdade, o RVA da tabela. O RVA é o endereço da tabela em relação ao endereço base da imagem quando a tabela é carregada. O segundo campo fornece o tamanho em bytes. Os diretórios de dados, que formam a última parte do cabeçalho opcional, são listados na tabela a seguir.

Observe que o número de diretórios não é fixo. Antes de procurar um diretório específico, verifique o campo NumberOfRvaAndSizes no cabeçalho opcional.

Além disso, não suponha que os RVAs na tabela apontem para o início de uma seção ou que as seções que contêm tabelas específicas tenham nomes específicos.

Deslocamento (PE/PE32+) Tamanho Campo Descrição
96/112
8
Export Table
O endereço e o tamanho da tabela de exportação. Para obter mais informações, confira Seção .edata (somente imagem).
104/120
8
Import Table
O endereço e o tamanho da tabela de importação. Para obter mais informações, confira Seção .idata.
112/128
8
Resource Table
O endereço e o tamanho da tabela de recursos. Para obter mais informações, confira Seção .rsrc.
120/136
8
Exception Table
O endereço e o tamanho da tabela de exceções. Para obter mais informações, confira Seção .pdata.
128/144
8
Certificate Table
O endereço e o tamanho da tabela de certificados de atributos. Para obter mais informações, confira Tabela de certificados de atributos (somente imagem).
136/152
8
Base Relocation Table
O endereço e o tamanho da tabela de realocação de base. Para obter mais informações, confira Seção .reloc (somente imagem).
144/160
8
Debug
O endereço inicial e o tamanho dos dados de depuração. Para obter mais informações, confira Seção .debug.
152/168
8
Architecture
Reservado, deve ser 0
160/176
8
Global Ptr
O RVA do valor a ser armazenado no registro de ponteiro global. O membro de tamanho dessa estrutura deve ser definido como zero.
168/184
8
TLS Table
O endereço e o tamanho da tabela TLS (armazenamento local do thread). Para obter mais informações, confira Seção .tls.
176/192
8
Load Config Table
O endereço e o tamanho da tabela de configuração de carregamento. Para obter mais informações, confira Estrutura de configuração de carregamento (somente imagem).
184/200
8
Bound Import
O endereço e o tamanho da tabela de importação vinculada.
192/208
8
IAT
O endereço e o tamanho da tabela de endereços de importação. Para saber mais informações, confira Tabela de endereços de importação.
200/216
8
Delay Import Descriptor
O endereço e o tamanho do descritor de importação em atraso. Para obter mais informações, confira Tabelas de importação de carregamento em atraso (somente imagem).
208/224
8
CLR Runtime Header
O endereço e o tamanho do cabeçalho de tempo de execução de CLR. Para obter mais informações, confira Seção .cormeta (somente objeto).
216/232
8
Reserved, must be zero

A entrada da Tabela de certificados aponta para uma tabela de certificados de atributo. Esses certificados não são carregados na memória como parte da imagem. Dessa forma, o primeiro campo dessa entrada, que normalmente é um RVA, é um ponteiro de arquivo.

Tabela de seções (cabeçalhos de seção)

Cada linha da tabela de seção é, na verdade, um cabeçalho de seção. Essa tabela seguirá imediatamente o cabeçalho opcional, se houver. Esse posicionamento é necessário porque o cabeçalho do arquivo não contém um ponteiro direto para a tabela de seção. Em vez disso, a localização da tabela de seções é determinada calculando a localização do primeiro byte após os cabeçalhos. Certifique-se de usar o tamanho do cabeçalho opcional, conforme especificado no cabeçalho do arquivo.

O número de entradas na tabela de seções é dado pelo campo NumberOfSections no cabeçalho do arquivo. As entradas na tabela de seções são numeradas a partir de um (1). As entradas da seção de código e memória de dados estão na ordem escolhida pelo vinculador.

Em um arquivo de imagem, os VAs para seções devem ser atribuídos pelo vinculador para que estejam em ordem crescente e adjacente, além de precisar ser um múltiplo do valor de SectionAlignment no cabeçalho opcional.

Cada cabeçalho de seção (entrada da tabela de seção) tem o seguinte formato, para um total de 40 bytes por entrada.

Deslocamento Tamanho Campo Descrição
0
8
Name
Uma cadeia de caracteres codificada em UTF-8 de 8 bytes, preenchida com nulo. Se a cadeia de caracteres tiver exatamente 8 caracteres, não haverá nulo de terminação. Para nomes mais longos, esse campo contém uma barra (/) seguida por uma representação ASCII de um número decimal, que é um deslocamento na tabela de cadeias de caracteres. As imagens executáveis não usam uma tabela de cadeia de caracteres e não dão suporte a nomes de seção com mais de 8 caracteres. Nomes longos em arquivos de objeto ficarão truncados se forem emitidos para um arquivo executável.
8
4
VirtualSize
O tamanho total da seção quando carregada na memória. Se esse valor for maior que SizeOfRawData, a seção será preenchida com zero. Esse campo é válido apenas para imagens executáveis e deve ser definido como zero para arquivos de objeto.
12
4
VirtualAddress
Para imagens executáveis, o endereço do primeiro byte da seção em relação à base da imagem quando a seção é carregada na memória. Para arquivos de objeto, esse campo é o endereço do primeiro byte antes da aplicação da realocação; para simplificar, os compiladores devem defini-lo como zero. Caso contrário, trata-se de um valor arbitrário que é subtraído dos deslocamentos durante a realocação.
16
4
SizeOfRawData
O tamanho da seção (para arquivos de objeto) ou o tamanho dos dados inicializados em disco (para arquivos de imagem). Para imagens executáveis, deve ser um múltiplo de FileAlignment do cabeçalho opcional. Se for menor que VirtualSize, o restante da seção será preenchido com zero. Como o campo SizeOfRawData é arredondado, mas o campo VirtualSize não, é possível que SizeOfRawData também seja maior que VirtualSize. Quando uma seção contém apenas dados não inicializados, esse campo deverá ser zero.
20
4
PointerToRawData
O ponteiro do arquivo para a primeira página da seção dentro do arquivo COFF. Para imagens executáveis, deve ser um múltiplo de FileAlignment do cabeçalho opcional. Para arquivos de objeto, o valor deverá ser alinhado em um limite de 4 bytes para melhor desempenho. Quando uma seção contém apenas dados não inicializados, esse campo deverá ser zero.
24
4
PointerToRelocations
O ponteiro do arquivo para o início das entradas de realocação para a seção. Ele é definido como zero para imagens executáveis ou caso não haja realocações.
28
4
PointerToLinenumbers
O ponteiro do arquivo para o início das entradas de número de linha da seção. Ele será definido como zero se não houver números de linha COFF. Esse valor deve ser zero no caso de imagem, pois as informações de depuração COFF foram preteridas.
32
2
NumberOfRelocations
O número de entradas de realocação para a seção. Ele é definido como zero para imagens executáveis.
34
2
NumberOfLinenumbers
O número de entradas de número de linha para a seção. Esse valor deve ser zero no caso de imagem, pois as informações de depuração COFF foram preteridas.
36
4
Características
Os sinalizadores que descrevem as características da seção. Para obter mais informações, confira Sinalizadores de seção.

 

Sinalizadores de seção

Os sinalizadores de seção no campo Características do cabeçalho da seção indicam as características da seção.

Sinalizador Valor Descrição
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
A seção não deve ser preenchida para o próximo limite. Esse sinalizador está obsoleto e foi substituído por IMAGE_SCN_ALIGN_1BYTES. Isso só será válido para arquivos de objeto.
0x00000010
Reservado para uso futuro.
IMAGE_SCN_CNT_CODE
0x00000020
A seção contém código executável.
IMAGE_SCN_CNT_INITIALIZED_DATA
0x00000040
A seção contém dados inicializados.
IMAGE_SCN_CNT_UNINITIALIZED_ DATA
0x00000080
A seção contém dados não inicializados.
IMAGE_SCN_LNK_OTHER
0x00000100
Reservado para uso futuro.
IMAGE_SCN_LNK_INFO
0x00000200
A seção contém comentários ou outras informações. A seção .drectve tem esse tipo. Isso será válido apenas para arquivos de objeto.
0x00000400
Reservado para uso futuro.
IMAGE_SCN_LNK_REMOVE
0x00000800
A seção não se tornará parte da imagem. Isso só será válido para arquivos de objeto.
IMAGE_SCN_LNK_COMDAT
0x00001000
A seção contém dados COMDAT. Para obter mais informações, confira Seções COMDAT (somente objeto). Isso só será válido para arquivos de objeto.
IMAGE_SCN_GPREL
0x00008000
A seção contém dados referenciados por meio do GP (ponteiro global).
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
Alinhe os dados em um limite de 1 byte. Válido apenas para arquivos de objeto.
IMAGE_SCN_ALIGN_2BYTES
0x00200000
Alinhe os dados em um limite de 2 bytes. Válido apenas para arquivos de objeto.
IMAGE_SCN_ALIGN_4BYTES
0x00300000
Alinhe os dados em um limite de 4 bytes. Válido apenas para arquivos de objeto.
IMAGE_SCN_ALIGN_8BYTES
0x00400000
Alinhe os dados em um limite de 8 bytes. Válido apenas para arquivos de objeto.
IMAGE_SCN_ALIGN_16BYTES
0x00500000
Alinhe os dados em um limite de 16 bytes. Válido apenas para arquivos de objeto.
IMAGE_SCN_ALIGN_32BYTES
0x00600000
Alinhe os dados em um limite de 32 bytes. Válido apenas para arquivos de objeto.
IMAGE_SCN_ALIGN_64BYTES
0x00700000
Alinhe os dados em um limite de 64 bytes. Válido apenas para arquivos de objeto.
IMAGE_SCN_ALIGN_128BYTES
0x00800000
Alinhe os dados em um limite de 128 bytes. Válido apenas para arquivos de objeto.
IMAGE_SCN_ALIGN_256BYTES
0x00900000
Alinhe os dados em um limite de 256 bytes. Válido apenas para arquivos de objeto.
IMAGE_SCN_ALIGN_512BYTES
0x00A00000
Alinhe os dados em um limite de 512 bytes. Válido apenas para arquivos de objeto.
IMAGE_SCN_ALIGN_1024BYTES
0x00B00000
Alinhe os dados em um limite de 1024 bytes. Válido apenas para arquivos de objeto.
IMAGE_SCN_ALIGN_2048BYTES
0x00C00000
Alinhe os dados em um limite de 2048 bytes. Válido apenas para arquivos de objeto.
IMAGE_SCN_ALIGN_4096BYTES
0x00D00000
Alinhe os dados em um limite de 4096 bytes. Válido apenas para arquivos de objeto.
IMAGE_SCN_ALIGN_8192BYTES
0x00E00000
Alinhe os dados em um limite de 8192 bytes. Válido apenas para arquivos de objeto.
IMAGE_SCN_LNK_NRELOC_OVFL
0x01000000
A seção contém realocações estendidas.
IMAGE_SCN_MEM_DISCARDABLE
0x02000000
A seção pode ser descartada conforme necessário.
IMAGE_SCN_MEM_NOT_CACHED
0x04000000
A seção não pode ser armazenada em cache.
IMAGE_SCN_MEM_NOT_PAGED
0x08000000
A seção não é paginável.
IMAGE_SCN_MEM_SHARED
0x10000000
A seção pode ser compartilhada na memória.
IMAGE_SCN_MEM_EXECUTE
0x20000000
A seção pode ser executada como código.
IMAGE_SCN_MEM_READ
0x40000000
A seção pode ser lida.
IMAGE_SCN_MEM_WRITE
0x80000000
A seção pode ser escrita.

 

IMAGE_SCN_LNK_NRELOC_OVFL indica que a contagem de realocações para a seção excede os 16 bits reservados para ela no cabeçalho da seção. Se o bit estiver definido, e o campo NumberOfRelocations no cabeçalho da seção for 0xffff, a contagem real de realocação será armazenada no campo VirtualAddress de 32 bits da primeira realocação. Será um erro se IMAGE_SCN_LNK_NRELOC_OVFL estiver definido e houver menos de 0xffff realocações na seção.

Seções agrupadas (somente objeto)

O caractere "$" (cifrão) tem uma interpretação especial em nomes de seção em arquivos de objeto.

Ao determinar a seção de imagem com o conteúdo de uma seção de objeto, o vinculador descarta o "$" e todos os caracteres que o seguem. Assim, uma seção de objeto chamada .text$X realmente contribui para a seção .text na imagem.

No entanto, os caracteres após o "$" determinam a ordem das contribuições para a seção de imagens. Todas as contribuições com o mesmo nome de seção de objeto são alocadas de forma contígua na imagem, e os blocos de contribuições são classificados em ordem lexical pelo nome de seção de objeto. Portanto, tudo em arquivos de objeto com o nome da seção .text$X acaba junto após as contribuições de .text$W e antes das contribuições de .text$Y.

O nome da seção em um arquivo de imagem nunca contém um caractere "$".

Outro conteúdos de um arquivo

As estruturas de dados descritas até agora, inclusive o cabeçalho opcional, estão todas localizadas em um deslocamento fixo desde o início do arquivo (ou do cabeçalho PE, se o arquivo for uma imagem que contém um stub do MS-DOS).

O restante de um objeto COFF ou arquivo de imagem contendo blocos de dados que não estão necessariamente em nenhum deslocamento de arquivo específico. Em vez disso, os locais são definidos por ponteiros no cabeçalho opcional ou em um cabeçalho de seção.

Uma exceção ocorre para imagens com um valor SectionAlignment menor que o tamanho da página da arquitetura (4 K para Intel x86 e para MIPS e 8 K para Itanium). Para obter uma descrição de SectionAlignment, confira Cabeçalho opcional (somente imagem). Nesse caso, existem restrições no deslocamento do arquivo dos dados da seção, conforme descrito na seção 5.1, "Dados de seção". Outra exceção é que o certificado de atributo e as informações de depuração devem ser colocados no final de um arquivo de imagem, com a tabela de certificados de atributo imediatamente anterior à seção de depuração, pois o carregador não os mapeia na memória. No entanto, a regra sobre certificado de atributo e informações de depuração não se aplica a arquivos de objeto.

Dados de seção

Os dados inicializados de uma seção consistem em blocos simples de bytes. No entanto, para seções contendo todos os zeros, os dados de seção não precisam ser incluídos.

Os dados de cada seção estão localizados no deslocamento de arquivo fornecido pelo campo PointerToRawData no cabeçalho da seção. O tamanho desses dados no arquivo é indicado pelo campo SizeOfRawData. Se SizeOfRawData for menor que VirtualSize, o restante será preenchido com zeros.

Em um arquivo de imagem, os dados da seção devem ser alinhados em um limite, conforme especificado pelo campo FileAlignment no cabeçalho opcional. Os dados da seção devem aparecer na ordem dos valores RVA para as seções correspondentes (assim como os cabeçalhos de seção individuais na tabela de seção).

Há restrições adicionais em arquivos de imagem caso o valor SectionAlignment no cabeçalho opcional seja menor que o tamanho da página da arquitetura. Para esses arquivos, a localização dos dados de seção no arquivo deve corresponder à localização na memória quando a imagem é carregada, de modo que o deslocamento físico dos dados de seção seja o mesmo que o RVA.

Realocações de COFF (somente objeto)

Os arquivos de objeto contêm realocações COFF, que especificam como os dados da seção devem ser modificados quando colocados no arquivo de imagem e, posteriormente, carregados na memória.

Os arquivos de imagem não contêm realocações COFF, pois todos os símbolos referenciados já receberam endereços em um espaço de endereçamento simples. Uma imagem contém informações de realocação na forma de realocações de base na seção .reloc (a menos que a imagem tenha o atributo IMAGE_FILE_RELOCS_STRIPPED). Para obter mais informações, confira Seção .reloc (somente imagem).

Para cada seção em um arquivo de objeto, uma matriz de registros de tamanho fixo contém as realocações COFF da seção. A posição e o tamanho da matriz são especificados no cabeçalho da seção. Cada elemento da matriz tem o seguinte formato.

Deslocamento Tamanho Campo Descrição
0
4
VirtualAddress
O endereço do item ao qual a realocação é aplicada. Este é o deslocamento do início da seção, mais o valor do campo RVA/Deslocamento da seção. Consulte Tabela de seção (cabeçalhos de seção). Por exemplo, se o primeiro byte da seção tiver um endereço de 0x10, o terceiro byte terá um endereço de 0x12.
4
4
SymbolTableIndex
Um índice baseado em zero na tabela de símbolos. Este símbolo fornece o endereço que deve ser usado para a realocação. Se o símbolo especificado tiver uma classe de armazenamento de seção, o endereço do símbolo será o endereço com a primeira seção com o mesmo nome.
8
2
Tipo
Um valor que indica o tipo de realocação que deve ser executada. Os tipos de realocação válidos dependem do tipo de máquina. Confira Indicadores de tipo.

 

Se o símbolo mencionado pelo campo SymbolTableIndex tiver a classe de armazenamento IMAGE_SYM_CLASS_SECTION, o endereço do símbolo será o início da seção. A seção geralmente está no mesmo arquivo, exceto quando o arquivo de objeto faz parte de um arquivo (biblioteca). Nesse caso, a seção pode ser encontrada em qualquer outro arquivo de objeto no arquivo com o mesmo nome de membro do arquivo que o arquivo de objeto atual. (O relacionamento com o nome do membro do arquivo é usado na vinculação de tabelas de importação, ou seja, a seção .idata.)

Indicadores de tipo

O campo Tipo do registro de realocação indica que tipo de realocação deve ser executada. Diferentes tipos de realocação são definidos para cada tipo de máquina.

Processadores x64

Os indicadores de tipo de realocação a seguir são definidos para processadores x64 e compatíveis.

Constante Valor Descrição
IMAGE_REL_AMD64_ABSOLUTE
0x0000
A realocação é ignorada.
IMAGE_REL_AMD64_ADDR64
0x0001
O VA de 64 bits do destino de realocação.
IMAGE_REL_AMD64_ADDR32
0x0002
O VA de 32 bits do destino de realocação.
IMAGE_REL_AMD64_ADDR32NB
0x0003
O endereço de 32 bits sem uma base de imagem (RVA).
IMAGE_REL_AMD64_REL32
0x0004
O endereço relativo de 32 bits do byte após a realocação.
IMAGE_REL_AMD64_REL32_1
0x0005
O endereço de 32 bits relativo à distância 1 de bytes da realocação.
IMAGE_REL_AMD64_REL32_2
0x0006
O endereço de 32 bits relativo à distância 2 de bytes da realocação.
IMAGE_REL_AMD64_REL32_3
0x0007
O endereço de 32 bits relativo à distância 3 de bytes da realocação.
IMAGE_REL_AMD64_REL32_4
0x0008
O endereço de 32 bits relativo à distância 4 de bytes da realocação.
IMAGE_REL_AMD64_REL32_5
0x0009
O endereço de 32 bits relativo à distância 5 de bytes da realocação.
IMAGE_REL_AMD64_SECTION
0x000A
O índice de seção de 16 bits da seção que contém o destino. Usado para dar suporte a informações de depuração.
IMAGE_REL_AMD64_SECREL
0x000B
O deslocamento de 32 bits do destino desde o início de sua seção. Usado para dar suporte a informações de depuração e armazenamento local de thread estático.
IMAGE_REL_AMD64_SECREL7
0x000C
Um deslocamento sem sinal de 7 bits da base da seção que contém o destino.
IMAGE_REL_AMD64_TOKEN
0x000D
Tokens de CLR.
IMAGE_REL_AMD64_SREL32
0x000E
Um valor dependente de span assinado de 32 bits emitido para o objeto.
IMAGE_REL_AMD64_PAIR
0x000F
Um par que deve seguir imediatamente cada valor dependente de span.
IMAGE_REL_AMD64_SSPAN32
0x0010
Um valor dependente de span assinado de 32 bits que é aplicado no momento da vinculação.

 

Processadores ARM

Os indicadores de tipo de realocação a seguir são definidos para processadores ARM.

Constante Valor Descrição
IMAGE_REL_ARM_ABSOLUTE
0x0000
A realocação é ignorada.
IMAGE_REL_ARM_ADDR32
0x0001
O VA de 32 bits do destino.
IMAGE_REL_ARM_ADDR32NB
0x0002
O RVA de 32 bits do destino.
IMAGE_REL_ARM_BRANCH24
0x0003
O deslocamento relativo de 24 bits para o destino.
IMAGE_REL_ARM_BRANCH11
0x0004
A referência a uma chamada de sub-rotina. A referência consiste em duas instruções de 16 bits com deslocamentos de 11 bits.
IMAGE_REL_ARM_REL32
0x000A
O endereço relativo de 32 bits do byte após a realocação.
IMAGE_REL_ARM_SECTION
0x000E
O índice de seção de 16 bits da seção que contém o destino. Usado para dar suporte a informações de depuração.
IMAGE_REL_ARM_SECREL
0x000F
O deslocamento de 32 bits do destino desde o início de sua seção. Usado para dar suporte a informações de depuração e armazenamento local de thread estático.
IMAGE_REL_ARM_MOV32
0x0010
O VA de 32 bits do destino. Essa realocação é aplicada usando uma instrução MOVW para os 16 bits baixos, seguida por um MOVT para os 16 bits altos.
IMAGE_REL_THUMB_MOV32
0x0011
O VA de 32 bits do destino. Essa realocação é aplicada usando uma instrução MOVW para os 16 bits baixos, seguida por um MOVT para os 16 bits altos.
IMAGE_REL_THUMB_BRANCH20
0x0012
A instrução é corrigida com o deslocamento relativo de 21 bits para o destino alinhado de 2 bytes. A parte menos significativa do deslocamento é sempre zero e não é armazenada. Essa realocação corresponde a uma instrução B condicional de 32 bits do Thumb-2.
Não utilizado
0x0013
IMAGE_REL_THUMB_BRANCH24
0x0014
A instrução é corrigida com o deslocamento relativo de 25 bits para o destino alinhado de 2 bytes. A parte menos significativa do deslocamento é zero e não é armazenada. Essa realocação corresponde a uma instrução Thumb-2 B.
IMAGE_REL_THUMB_BLX23
0x0015
A instrução é corrigida com o deslocamento relativo de 25 bits para o destino alinhado de 4 bytes. Os 2 bits baixos do deslocamento são zero e não são armazenados.
Essa realocação corresponde a uma instrução Thumb-2 BLX.
IMAGE_REL_ARM_PAIR
0x0016
A realocação é válida apenas quando segue imediatamente uma ARM_REFHI ou THUMB_REFHI. O respectivo SymbolTableIndex contém um deslocamento e não um índice na tabela de símbolos.

 

Processadores ARM64

Os indicadores de tipo de realocação a seguir são definidos para processadores ARM64.

Constante Valor Descrição
IMAGE_REL_ARM64_ABSOLUTE
0x0000
A realocação é ignorada.
IMAGE_REL_ARM64_ADDR32
0x0001
O VA de 32 bits do destino.
IMAGE_REL_ARM64_ADDR32NB
0x0002
O RVA de 32 bits do destino.
IMAGE_REL_ARM64_BRANCH26
0x0003
O deslocamento relativo de 26 bits para o destino, para instruções B e BL.
IMAGE_REL_ARM64_PAGEBASE_REL21
0x0004
A base da página do destino, para instrução ADRP.
IMAGE_REL_ARM64_REL21
0x0005
O deslocamento relativo de 12 bits para o destino, para instrução ADR
IMAGE_REL_ARM64_PAGEOFFSET_12A
0x0006
O deslocamento de página de 12 bits do destino, para instruções ADD/ADDS (imediato) com deslocamento zero.
IMAGE_REL_ARM64_PAGEOFFSET_12L
0x0007
O deslocamento de página de 12 bits do destino, para instrução LDR (indexado, sem sinal imediato).
IMAGE_REL_ARM64_SECREL
0x0008
O deslocamento de 32 bits do destino desde o início de sua seção. Usado para dar suporte a informações de depuração e armazenamento local de thread estático.
IMAGE_REL_ARM64_SECREL_LOW12A
0x0009
Bit 0:11 do deslocamento da seção do alvo, para instruções ADD/ADDS (imediatas) com deslocamento zero.
IMAGE_REL_ARM64_SECREL_HIGH12A
0x000A
Bit 12:23 do deslocamento da seção do alvo, para instruções ADD/ADDS (imediatas) com deslocamento zero.
IMAGE_REL_ARM64_SECREL_LOW12L
0x000B
Bit 0:11 do deslocamento da seção do destino, para instrução LDR (indexado, sem sinal imediato).
IMAGE_REL_ARM64_TOKEN
0x000C
Token da CLR.
IMAGE_REL_ARM64_SECTION
0x000D
O índice de seção de 16 bits da seção que contém o destino. Usado para dar suporte a informações de depuração.
IMAGE_REL_ARM64_ADDR64
0x000E
O VA de 64 bits do destino de realocação.
IMAGE_REL_ARM64_BRANCH19
0x000F
O deslocamento de 19 bits para o destino de realocação, para instrução B condicional.
IMAGE_REL_ARM64_BRANCH14
0x0010
O deslocamento de 14 bits para o destino de realocação, para instruções TBZ e TBNZ.
IMAGE_REL_ARM64_REL32
0x0011
O endereço relativo de 32 bits do byte após a realocação.
Processadores Hitachi SuperH

Os indicadores de tipo de realocação a seguir são definidos para processadores SH3 e SH4. As realocações específicas do SH5 são anotadas como SHM (SH Media).

Constante Valor Descrição
IMAGE_REL_SH3_ABSOLUTE
0x0000
A realocação é ignorada.
IMAGE_REL_SH3_DIRECT16
0x0001
Uma referência ao local de 16 bits que contém o VA do símbolo de destino.
IMAGE_REL_SH3_DIRECT32
0x0002
O VA de 32 bits do símbolo de destino.
IMAGE_REL_SH3_DIRECT8
0x0003
Uma referência ao local de 8 bits que contém o VA do símbolo de destino.
IMAGE_REL_SH3_DIRECT8_WORD
0x0004
Uma referência à instrução de 8 bits que contém o VA efetivo de 16 bits do símbolo de destino.
IMAGE_REL_SH3_DIRECT8_LONG
0x0005
Uma referência à instrução de 8 bits que contém o VA efetivo de 32 bits do símbolo de destino.
IMAGE_REL_SH3_DIRECT4
0x0006
Uma referência ao local de 8 bits cujos 4 bits baixos contêm o VA do símbolo de destino.
IMAGE_REL_SH3_DIRECT4_WORD
0x0007
Uma referência à instrução de 8 bits cujos 4 bits baixos contêm o VA efetivo de 16 bits do símbolo de destino.
IMAGE_REL_SH3_DIRECT4_LONG
0x0008
Uma referência à instrução de 8 bits cujos 4 bits baixos contêm o VA efetivo de 32 bits do símbolo de destino.
IMAGE_REL_SH3_PCREL8_WORD
0x0009
Uma referência à instrução de 8 bits que contém o deslocamento relativo efetivo de 16 bits do símbolo de destino.
IMAGE_REL_SH3_PCREL8_LONG
0x000A
Uma referência à instrução de 8 bits que contém o deslocamento relativo efetivo de 32 bits do símbolo de destino.
IMAGE_REL_SH3_PCREL12_WORD
0x000B
Uma referência à instrução de 16 bits cujos 12 bits baixos contêm o deslocamento relativo efetivo de 16 bits do símbolo de destino.
IMAGE_REL_SH3_STARTOF_SECTION
0x000C
Uma referência a um local de 32 bits que é o VA da seção que contém o símbolo de destino.
IMAGE_REL_SH3_SIZEOF_SECTION
0x000D
Uma referência ao local de 32 bits que é o tamanho da seção que contém o símbolo de destino.
IMAGE_REL_SH3_SECTION
0x000E
O índice de seção de 16 bits da seção que contém o destino. Usado para dar suporte a informações de depuração.
IMAGE_REL_SH3_SECREL
0x000F
O deslocamento de 32 bits do destino desde o início de sua seção. Usado para dar suporte a informações de depuração e armazenamento local de thread estático.
IMAGE_REL_SH3_DIRECT32_NB
0x0010
O RVA de 32 bits do símbolo de destino.
IMAGE_REL_SH3_GPREL4_LONG
0x0011
GP relativo.
IMAGE_REL_SH3_TOKEN
0x0012
Token da CLR.
IMAGE_REL_SHM_PCRELPT
0x0013
O deslocamento da instrução atual em palavras longas. Se o bit NOMODE não estiver definido, insira o inverso do bit baixo no bit 32 para selecionar PTA ou PTB.
IMAGE_REL_SHM_REFLO
0x0014
Os 16 bits baixos do endereço de 32 bits.
IMAGE_REL_SHM_REFHALF
0x0015
Os 16 bits altos do endereço de 32 bits.
IMAGE_REL_SHM_RELLO
0x0016
Os 16 bits baixos do endereço relativo.
IMAGE_REL_SHM_RELHALF
0x0017
Os 16 bits altos do endereço relativo.
IMAGE_REL_SHM_PAIR
0x0018
A realocação é válida somente quando segue imediatamente uma realocação REFHALF, RELHALF ou RELLO. O campo SymbolTableIndex da realocação contém um deslocamento e não um índice na tabela de símbolos.
IMAGE_REL_SHM_NOMODE
0x8000
A realocação ignora o modo de seção.

 

Processadores IBM PowerPC

Os indicadores de tipo de realocação a seguir são definidos para processadores PowerPC.

Constante Valor Descrição
IMAGE_REL_PPC_ABSOLUTE
0x0000
A realocação é ignorada.
IMAGE_REL_PPC_ADDR64
0x0001
O VA de 64 bits do destino.
IMAGE_REL_PPC_ADDR32
0x0002
O VA de 32 bits do destino.
IMAGE_REL_PPC_ADDR24
0x0003
Os 24 bits baixos do VA do destino. Isso será válido somente quando o símbolo de destino for absoluto e puder ser estendido por sinal para o valor original.
IMAGE_REL_PPC_ADDR16
0x0004
Os 16 bits baixos do VA do destino.
IMAGE_REL_PPC_ADDR14
0x0005
Os 14 bits baixos do VA do destino. Isso será válido somente quando o símbolo de destino for absoluto e puder ser estendido por sinal para o valor original.
IMAGE_REL_PPC_REL24
0x0006
Um deslocamento relativo ao PC de 24 bits para o local do símbolo.
IMAGE_REL_PPC_REL14
0x0007
Um deslocamento relativo ao PC de 14 bits para o local do símbolo.
IMAGE_REL_PPC_ADDR32NB
0x000A
O RVA de 32 bits do destino.
IMAGE_REL_PPC_SECREL
0x000B
O deslocamento de 32 bits do destino desde o início de sua seção. Usado para dar suporte a informações de depuração e armazenamento local de thread estático.
IMAGE_REL_PPC_SECTION
0x000C
O índice de seção de 16 bits da seção que contém o destino. Usado para dar suporte a informações de depuração.
IMAGE_REL_PPC_SECREL16
0x000F
O deslocamento de 16 bits do destino desde o início de sua seção. Usado para dar suporte a informações de depuração e armazenamento local de thread estático.
IMAGE_REL_PPC_REFHI
0x0010
Os 16 bits altos do VA de 32 bits do destino. Usado para a primeira instrução em uma sequência de duas instruções que carrega um endereço completo. Essa realocação deve ser imediatamente seguida por uma realocação PAIR cujo SymbolTableIndex contém um deslocamento de 16 bits assinado que é adicionado aos 16 bits superiores que foram retirados do local que está sendo realocado.
IMAGE_REL_PPC_REFLO
0x0011
Os 16 bits baixos do VA do destino.
IMAGE_REL_PPC_PAIR
0x0012
Uma realocação que é válida somente quando segue imediatamente uma realocação REFHI ou SECRELHI. O respectivo SymbolTableIndex contém um deslocamento e não um índice na tabela de símbolos.
IMAGE_REL_PPC_SECRELLO
0x0013
Os 16 bits baixos do deslocamento de 32 bits do destino desde o início de sua seção.
IMAGE_REL_PPC_GPREL
0x0015
O deslocamento assinado de 16 bits do destino em relação ao registro GP.
IMAGE_REL_PPC_TOKEN
0x0016
O token CLR.

 

Processadores Intel 386

Os indicadores de tipo de realocação a seguir são definidos para processadores Intel 386 e compatíveis.

Constante Valor Descrição
IMAGE_REL_I386_ABSOLUTE
0x0000
A realocação é ignorada.
IMAGE_REL_I386_DIR16
0x0001
Não há suporte.
IMAGE_REL_I386_REL16
0x0002
Não há suporte.
IMAGE_REL_I386_DIR32
0x0006
O VA de 32 bits do destino.
IMAGE_REL_I386_DIR32NB
0x0007
O RVA de 32 bits do destino.
IMAGE_REL_I386_SEG12
0x0009
Não há suporte.
IMAGE_REL_I386_SECTION
0x000A
O índice de seção de 16 bits da seção que contém o destino. Usado para dar suporte a informações de depuração.
IMAGE_REL_I386_SECREL
0x000B
O deslocamento de 32 bits do destino desde o início de sua seção. Usado para dar suporte a informações de depuração e armazenamento local de thread estático.
IMAGE_REL_I386_TOKEN
0x000C
O token CLR.
IMAGE_REL_I386_SECREL7
0x000D
Um deslocamento de 7 bits da base da seção que contém o destino.
IMAGE_REL_I386_REL32
0x0014
O deslocamento relativo de 32 bits para o destino. Isso dá suporte às instruções de ramificação e chamada relativas de x86.

 

Família de processadores Intel Itanium (IPF)

Os seguintes indicadores de tipo de realocação são definidos para a família de processadores Intel Itanium e processadores compatíveis. As realocações nas instruções usam o deslocamento do pacote e o número do slot para o deslocamento de realocação.

Constante Valor Descrição
IMAGE_REL_IA64_ABSOLUTE
0x0000
A realocação é ignorada.
IMAGE_REL_IA64_IMM14
0x0001
A realocação de instrução pode ser seguida por uma realocação ADDEND cujo valor é adicionado ao endereço de destino antes de ser inserido no slot especificado no pacote IMM14. O destino de realocação deve ser absoluto ou a imagem deve ser fixa.
IMAGE_REL_IA64_IMM22
0x0002
A realocação de instrução pode ser seguida por uma realocação ADDEND cujo valor é adicionado ao endereço de destino antes de ser inserido no slot especificado no pacote IMM22. O destino de realocação deve ser absoluto ou a imagem deve ser fixa.
IMAGE_REL_IA64_IMM64
0x0003
O número do slot dessa realocação deve ser um (1). A realocação pode ser seguida por uma realocação ADDEND cujo valor é adicionado ao endereço de destino antes de ser armazenado nos três slots do pacote IMM64.
IMAGE_REL_IA64_DIR32
0x0004
O VA de 32 bits do destino. Há suporte apenas para imagens /LARGEADDRESSAWARE:NO.
IMAGE_REL_IA64_DIR64
0x0005
O VA de 64 bits do destino.
IMAGE_REL_IA64_PCREL21B
0x0006
A instrução é corrigida com o deslocamento relativo de 25 bits para o destino alinhado de 16 bits. Os 4 bits baixos do deslocamento são zero e não são armazenados.
IMAGE_REL_IA64_PCREL21M
0x0007
A instrução é corrigida com o deslocamento relativo de 25 bits para o destino alinhado de 16 bits. Os 4 bits baixos do deslocamento, que são zero e não são armazenados.
IMAGE_REL_IA64_PCREL21F
0x0008
Os LSBs do deslocamento dessa realocação devem conter o número do slot, enquanto o restante é o endereço do pacote. O pacote é corrigido com o deslocamento relativo de 25 bits para o destino alinhado de 16 bits. Os 4 bits baixos do deslocamento são zero e não são armazenados.
IMAGE_REL_IA64_GPREL22
0x0009
A realocação de instrução pode ser seguida por uma realocação ADDEND cujo valor é adicionado ao endereço de destino e, em seguida, um deslocamento relativo à GP de 22 bits que é calculado e aplicado ao pacote GPREL22.
IMAGE_REL_IA64_LTOFF22
0x000A
A instrução é corrigida com o deslocamento relativo à GP de 22 bits para a entrada literal da tabela do símbolo de destino. O vinculador cria essa entrada de tabela literal com base nessa realocação e na realocação ADDEND que pode ser subsequente.
IMAGE_REL_IA64_SECTION
0x000B
O índice de seção de 16 bits da seção contém o destino. Usado para dar suporte a informações de depuração.
IMAGE_REL_IA64_SECREL22
0x000C
A instrução é corrigida com o deslocamento de 22 bits do destino desde o início da seção. Essa realocação pode ser seguida imediatamente por uma realocação ADDEND, cujo campo Value contém o deslocamento sem sinal de 32 bits do destino desde o início da seção.
IMAGE_REL_IA64_SECREL64I
0x000D
O número do slot relativo a essa realocação deve ser um (1). A instrução é corrigida com o deslocamento de 64 bits do destino desde o início da seção. Essa realocação pode ser seguida imediatamente por uma realocação ADDEND cujo campo Value contém o deslocamento sem sinal de 32 bits do destino desde o início da seção.
IMAGE_REL_IA64_SECREL32
0x000E
O endereço dos dados a serem corrigidos com o deslocamento de 32 bits do destino desde o início de sua seção.
IMAGE_REL_IA64_DIR32NB
0x0010
O RVA de 32 bits do destino.
IMAGE_REL_IA64_SREL14
0x0011
Isso se aplica a um imediato de 14 bits assinado que contém a diferença entre dois destinos relocáveis. Esse é um campo declarativo para o vinculador que indica que o compilador já emitiu esse valor.
IMAGE_REL_IA64_SREL22
0x0012
Isso se aplica a um imediato de 22 bits assinado que contém a diferença entre dois destinos relocáveis. Esse é um campo declarativo para o vinculador que indica que o compilador já emitiu esse valor.
IMAGE_REL_IA64_SREL32
0x0013
Isso se aplica a um imediato de 32 bits assinado que contém a diferença entre dois valores relocáveis. Esse é um campo declarativo para o vinculador que indica que o compilador já emitiu esse valor.
IMAGE_REL_IA64_UREL32
0x0014
Isso se aplica a um imediato de 32 bits sem sinal que contém a diferença entre dois valores relocáveis. Esse é um campo declarativo para o vinculador que indica que o compilador já emitiu esse valor.
IMAGE_REL_IA64_PCREL60X
0x0015
Uma correção relativa ao PC de 60 bits que sempre permanece como uma instrução BRL de um pacote MLX.
IMAGE_REL_IA64_PCREL60B
0x0016
Uma correção relativa ao PC de 60 bits. Se o deslocamento de destino se enquadrar em um campo de 25 bits assinado, converta todo o pacote em um pacote MBB com NOP.B no slot 1 e uma instrução BR de 25 bits (com os 4 bits mais baixos zerados e descartados) no slot 2.
IMAGE_REL_IA64_PCREL60F
0x0017
Uma correção relativa ao PC de 60 bits. Se o deslocamento de destino se enquadrar em um campo de 25 bits assinado, converta todo o pacote em um pacote MFB com NOP.F no slot 1 e uma instrução BR de 25 bits (com os 4 bits mais baixos zerados e descartados) no slot 2.
IMAGE_REL_IA64_PCREL60I
0x0018
Uma correção relativa ao PC de 60 bits. Se o deslocamento de destino se enquadrar em um campo de 25 bits assinado, converta todo o pacote em um pacote MIB com NOP.I no slot 1 e uma instrução BR de 25 bits (com os 4 bits mais baixos zerados e descartados) no slot 2.
IMAGE_REL_IA64_PCREL60M
0x0019
Uma correção relativa ao PC de 60 bits. Se o deslocamento de destino se enquadrar em um campo de 25 bits assinado, converta todo o pacote em um pacote MMB com NOP.M no slot 1 e uma instrução BR de 25 bits (com os 4 bits mais baixos zerados e descartados) no slot 2.
IMAGE_REL_IA64_IMMGPREL64
0x001a
Uma correção relativa à GP de 64 bits.
IMAGE_REL_IA64_TOKEN
0x001b
Um token CLR.
IMAGE_REL_IA64_GPREL32
0x001c
Uma correção relativa à GP de 32 bits.
IMAGE_REL_IA64_ADDEND
0x001F
A realocação é válida somente quando segue imediatamente uma das seguintes realocações: IMM14, IMM22, IMM64, GPREL22, LTOFF22, LTOFF64, SECREL22, SECREL64I ou SECREL32. O respectivo valor contém o adendo a ser aplicado a instruções dentro de um pacote, não para dados.

 

Processadores MIPS

Os indicadores de tipo de realocação a seguir são definidos para processadores MIPS.

Constante Valor Descrição
IMAGE_REL_MIPS_ABSOLUTE
0x0000
A realocação é ignorada.
IMAGE_REL_MIPS_REFHALF
0x0001
Os 16 bits altos do VA de 32 bits do destino.
IMAGE_REL_MIPS_REFWORD
0x0002
O VA de 32 bits do destino.
IMAGE_REL_MIPS_JMPADDR
0x0003
Os 26 bits baixos do VA do destino. Isso suporta as instruções MIPS J e JAL.
IMAGE_REL_MIPS_REFHI
0x0004
Os 16 bits altos do VA de 32 bits do destino. Usado para a primeira instrução em uma sequência de duas instruções que carrega um endereço completo. Essa realocação deve ser imediatamente seguida por uma realocação PAIR cujo SymbolTableIndex contém um deslocamento de 16 bits assinado que é adicionado aos 16 bits superiores que são retirados do local que está sendo realocado.
IMAGE_REL_MIPS_REFLO
0x0005
Os 16 bits baixos do VA do destino.
IMAGE_REL_MIPS_GPREL
0x0006
Um deslocamento assinado de 16 bits do destino em relação ao registro GP.
IMAGE_REL_MIPS_LITERAL
0x0007
O mesmo que IMAGE_REL_MIPS_GPREL.
IMAGE_REL_MIPS_SECTION
0x000A
O índice de seção de 16 bits da seção contém o destino. Usado para dar suporte a informações de depuração.
IMAGE_REL_MIPS_SECREL
0x000B
O deslocamento de 32 bits do destino desde o início de sua seção. Usado para dar suporte a informações de depuração e armazenamento local de thread estático.
IMAGE_REL_MIPS_SECRELLO
0x000C
Os 16 bits baixos do deslocamento de 32 bits do destino desde o início de sua seção.
IMAGE_REL_MIPS_SECRELHI
0x000D
Os 16 bits altos do deslocamento de 32 bits do destino desde o início de sua seção. Uma realocação IMAGE_REL_MIPS_PAIR deve seguir imediatamente esta. O SymbolTableIndex da realocação de PAIR contém um deslocamento de 16 bits assinado que é adicionado aos 16 bits superiores que são retirados do local que está sendo realocado.
IMAGE_REL_MIPS_JMPADDR16
0x0010
Os 26 bits baixos do VA do destino. Isso dá suporte à instrução MIPS16 JAL.
IMAGE_REL_MIPS_REFWORDNB
0x0022
O RVA de 32 bits do destino.
IMAGE_REL_MIPS_PAIR
0x0025
A realocação é válida somente quando segue imediatamente uma realocação REFHI ou SECRELHI. O respectivo SymbolTableIndex contém um deslocamento e não um índice na tabela de símbolos.

 

Mitsubishi M32R

Os seguintes indicadores de tipo de realocação são definidos para os processadores Mitsubishi M32R.

Constante Valor Descrição
IMAGE_REL_M32R_ABSOLUTE
0x0000
A realocação é ignorada.
IMAGE_REL_M32R_ADDR32
0x0001
O VA de 32 bits do destino.
IMAGE_REL_M32R_ADDR32NB
0x0002
O RVA de 32 bits do destino.
IMAGE_REL_M32R_ADDR24
0x0003
O VA de 24 bits do destino.
IMAGE_REL_M32R_GPREL16
0x0004
O deslocamento de 16 bits do destino do registro GP.
IMAGE_REL_M32R_PCREL24
0x0005
O deslocamento de 24 bits do destino do contador de programas (PC), deslocado para a esquerda por 2 bits e com sinal estendido
IMAGE_REL_M32R_PCREL16
0x0006
O deslocamento de 16 bits do destino do PC, deslocado para a esquerda por 2 bits e com sinal estendido
IMAGE_REL_M32R_PCREL8
0x0007
O deslocamento de 8 bits do destino do PC, deslocado para a esquerda por 2 bits e com sinal estendido
IMAGE_REL_M32R_REFHALF
0x0008
Os 16 MSBs do VA de destino.
IMAGE_REL_M32R_REFHI
0x0009
Os 16 MSBs do VA alvo, ajustados para extensão de sinal LSB. Usado para a primeira instrução em uma sequência de duas instruções que carrega um endereço completo de 32 bits. Essa realocação deve ser imediatamente seguida por uma realocação PAIR cujo SymbolTableIndex contém um deslocamento de 16 bits assinado que é adicionado aos 16 bits superiores que são retirados do local que está sendo realocado.
IMAGE_REL_M32R_REFLO
0x000A
Os 16 LSBs do VA de destino.
IMAGE_REL_M32R_PAIR
0x000B
A realocação deve seguir a realocação do REFHI. O respectivo SymbolTableIndex contém um deslocamento e não um índice na tabela de símbolos.
IMAGE_REL_M32R_SECTION
0x000C
O índice de seção de 16 bits da seção que contém o destino. Usado para dar suporte a informações de depuração.
IMAGE_REL_M32R_SECREL
0x000D
O deslocamento de 32 bits do destino desde o início de sua seção. Usado para dar suporte a informações de depuração e armazenamento local de thread estático.
IMAGE_REL_M32R_TOKEN
0x000E
O token CLR.

 

Números de linha COFF (preterido)

Os números de linha COFF não são mais produzidos e, no futuro, não serão consumidos.

Os números de linha COFF indicam a relação entre o código e os números de linha nos arquivos de origem. O formato da Microsoft para números de linha COFF é semelhante ao COFF padrão, mas foi estendido para permitir que uma única seção se relacione com números de linha em vários arquivos de origem.

Os números de linha COFF consistem em uma matriz de registros de tamanho fixo. O local (deslocamento do arquivo) e o tamanho da matriz são especificados no cabeçalho da seção. Cada registro de número de linha tem o seguinte formato.

Deslocamento Tamanho Campo Descrição
0
4
Tipo (*)
Esta é uma união de dois campos: SymbolTableIndex e VirtualAddress. O uso de SymbolTableIndex ou RVA depende do valor de Linenumber.
4
2
Linenumber
Quando diferente de zero, esse campo especifica um número de linha baseado em um. Quando zero, o campo Type é interpretado como um índice de tabela de símbolos para uma função.

 

O campo Type é uma união de dois campos de 4 bytes: SymbolTableIndex e VirtualAddress.

Deslocamento Tamanho Campo Descrição
0
4
SymbolTableIndex
Usado quando Linenumber é zero: índice para entrada de tabela de símbolos para uma função. Esse formato é usado para indicar a função à qual um grupo de registros de número de linha se refere.
0
4
VirtualAddress
Usado quando Linenumber é diferente de zero: o RVA do código executável que corresponde à linha de origem indicada. Em um arquivo de objeto, ele contém o VA dentro da seção.

 

Um registro de número de linha pode definir o campo Linenumber como zero e apontar para uma definição de função na tabela de símbolos ou pode funcionar como uma entrada de número de linha padrão, fornecendo um número inteiro positivo (número de linha) e o endereço correspondente no código de objeto.

Um grupo de entradas de número de linha sempre começa com o primeiro formato: o índice de um símbolo de função. Se esse for o primeiro registro de número de linha na seção, também será o nome do símbolo COMDAT para a função se o sinalizador COMDAT da seção estiver definido. Confira Seções COMDAT (somente objeto). O registro auxiliar da função na tabela de símbolos tem um ponteiro para o campo Linenumber que aponta para esse mesmo registro de número de linha.

Um registro que identifica uma função é seguido por qualquer número de entradas de número de linha que fornecem informações reais de número de linha (ou seja, entradas com Linenumber maior que zero). Essas entradas se baseiam em um, em relação ao início da função, e representam todas as linhas de origem na função, exceto a primeira linha.

Por exemplo, o primeiro registro de número de linha para o exemplo a seguir especificaria a função ReverseSign (SymbolTableIndex de ReverseSign e Linenumber definido como zero). Em seguida, os registros com valores de número de linha de 1, 2 e 3 seguiriam, correspondendo às linhas de origem, conforme mostrado:

// some code precedes ReverseSign function
int ReverseSign(int i)
1: {
2:  return -1 * i;
3: }

Tabela de símbolos COFF

A tabela de símbolos nesta seção é herdada do formato COFF tradicional. É diferente das informações de depuração do Microsoft Visual C++. Um arquivo pode conter uma tabela de símbolos COFF e informações de depuração do Visual C++, e os dois são mantidos separados. Algumas ferramentas da Microsoft usam a tabela de símbolos para fins limitados, mas importantes, como comunicar informações COMDAT ao vinculador. Nomes de seção e nomes de arquivo, bem como símbolos de código e dados, são listados na tabela de símbolos.

A localização da tabela de símbolos é indicada no cabeçalho COFF.

A tabela de símbolos é uma matriz de registros, cada uma com 18 bytes de tamanho. Cada registro é um registro padrão ou auxiliar da tabela de símbolos. Um registro padrão define um símbolo ou nome e tem o seguinte formato.

Deslocamento Tamanho Campo Descrição
0
8
Name (*)
O nome do símbolo, representado por uma união de três estruturas. Uma matriz de 8 bytes será usada se o nome não tiver mais de 8 bytes. Para obter mais informações, confira Representação de nome de símbolo.
8
4
Value
O valor associado ao símbolo. A interpretação desse campo depende de SectionNumber e StorageClass. Um significado típico é o endereço relocável.
12
2
SectionNumber
O inteiro assinado que identifica a seção, usando um índice baseado em um na tabela de seções. Alguns valores têm um significado especial, conforme definido na seção 5.4.2, "Valores do número da seção".
14
2
Type
Um número que representa o tipo. As ferramentas da Microsoft definem esse campo como 0x20 (função) ou 0x0 (não uma função). Para saber mais, confira Representação de tipo.
16
1
StorageClass
Um valor enumerado que representa a classe de armazenamento. Para obter mais informações, confira Classe de armazenamento.
17
1
NumberOfAuxSymbols
O número de entradas da tabela de símbolos auxiliares que seguem esse registro.

 

Zero ou mais registros auxiliares da tabela de símbolos seguem imediatamente cada registro padrão da tabela de símbolos. No entanto, normalmente não mais do que um registro de tabela de símbolos auxiliares segue um registro de tabela de símbolos padrão (exceto para registros .file com nomes de arquivo longos). Cada registro auxiliar tem o mesmo tamanho de um registro de tabela de símbolos padrão (18 bytes), mas, em vez de definir um novo símbolo, o registro auxiliar fornece informações adicionais sobre o último símbolo definido. A escolha de qual dos vários formatos usar depende do campo StorageClass. Os formatos atualmente definidos para registros de tabela de símbolos auxiliares são mostrados na seção 5.5, "Registros de símbolos auxiliares".

As ferramentas que leem tabelas de símbolos COFF devem ignorar registros de símbolos auxiliares cuja interpretação é desconhecida. Isso permite que o formato da tabela de símbolos seja estendido para adicionar novos registros auxiliares, sem quebrar as ferramentas existentes.

Representação do nome do símbolo

O campo ShortName em uma tabela de símbolos consiste em 8 bytes que contêm o próprio nome, caso não tenha mais de 8 bytes de tamanho, ou o campo ShortName fornece um deslocamento para a tabela de cadeias de caracteres. Para determinar se o nome em si ou um deslocamento é fornecido, teste os primeiros 4 bytes para ser igual a zero.

Por convenção, os nomes são tratados como cadeias de caracteres codificadas em UTF-8 terminadas em zero.

Deslocamento Tamanho Campo Descrição
0
8
ShortName
Uma matriz de 8 bytes. Essa matriz será preenchida com nulos à direita se o nome tiver menos de 8 bytes de tamanho.
0
4
Zeroes
Um campo definido somente com zeros se o nome tiver mais de 8 bytes.
4
4
Offset
Um deslocamento na tabela de cadeias de caracteres.

 

Valores de número de seção

Normalmente, o campo Section Value em uma entrada da tabela de símbolos é um índice baseado em um na tabela de seção. No entanto, esse campo é um inteiro com sinal e pode assumir valores negativos. Os valores a seguir, menores que um, têm significados especiais.

Constante Valor Descrição
IMAGE_SYM_UNDEFINED
0
O registro de símbolo ainda não foi atribuído a uma seção. Um valor zero indica que uma referência a um símbolo externo está definida em outro lugar. Um valor diferente de zero é um símbolo comum com um tamanho especificado pelo valor.
IMAGE_SYM_ABSOLUTE
1-
O símbolo tem um valor absoluto (não relocável) e não é um endereço.
IMAGE_SYM_DEBUG
2-
O símbolo fornece informações gerais de tipo ou depuração, mas não corresponde a uma seção. As ferramentas da Microsoft usam essa configuração junto com os registros .file (classe de armazenamento FILE).

 

Representação de tipo

O campo Type de uma entrada de tabela de símbolos contém 2 bytes, em que cada byte representa informações de tipo. O LSB representa o tipo de dados simples (base) e o MSB representa o tipo complexo, se houver:

MSB LSB
Tipo complexo: nenhum, ponteiro, função, matriz.
Tipo base: inteiro, ponto flutuante e assim por diante.

 

Os valores a seguir são definidos para o tipo base, embora as ferramentas da Microsoft geralmente não usem esse campo e definam o LSB como 0. Em vez disso, as informações de depuração do Visual C++ são usadas para indicar tipos. No entanto, os possíveis valores de COFF estão listados aqui para fins de integridade.

Constante Valor Descrição
IMAGE_SYM_TYPE_NULL
0
Nenhuma informação de tipo ou tipo base desconhecido. As ferramentas da Microsoft usam essa configuração
IMAGE_SYM_TYPE_VOID
1
Nenhum tipo válido; usado com ponteiros e funções void
IMAGE_SYM_TYPE_CHAR
2
Um caractere (byte assinado)
IMAGE_SYM_TYPE_SHORT
3
Um inteiro de dois bytes com sinal
IMAGE_SYM_TYPE_INT
4
Um tipo inteiro natural (normalmente 4 bytes no Windows)
IMAGE_SYM_TYPE_LONG
5
Um inteiro de quatro bytes com sinal
IMAGE_SYM_TYPE_FLOAT
6
Um número de ponto flutuante de quatro bytes
IMAGE_SYM_TYPE_DOUBLE
7
Um número de ponto flutuante de oito bytes
IMAGE_SYM_TYPE_STRUCT
8
Uma estrutura
IMAGE_SYM_TYPE_UNION
9
Uma união
IMAGE_SYM_TYPE_ENUM
10
Um tipo enumerado
IMAGE_SYM_TYPE_MOE
11
Um membro da enumeração (um valor específico)
IMAGE_SYM_TYPE_BYTE
12
Um byte; inteiro de 1 byte sem sinal
IMAGE_SYM_TYPE_WORD
13
Uma palavra; inteiro de 2 bytes sem sinal
IMAGE_SYM_TYPE_UINT
14
Um inteiro sem sinal de tamanho natural (normalmente, 4 bytes)
IMAGE_SYM_TYPE_DWORD
15
Um inteiro de 4 bytes sem sinal

 

O byte mais significativo especifica se o símbolo é um ponteiro para, retorno de função ou matriz do tipo base especificado no LSB. As ferramentas da Microsoft usam esse campo apenas para indicar se o símbolo é uma função, de modo que os dois únicos valores resultantes sejam 0x0 e 0x20 para o campo Type. No entanto, outras ferramentas podem usar esse campo para comunicar mais informações.

É muito importante especificar o atributo de função corretamente. Essas informações são necessárias para que a vinculação incremental funcione corretamente. Para algumas arquiteturas, as informações podem ser necessárias para outros fins.

Constante Valor Descrição
IMAGE_SYM_DTYPE_NULL
0
Nenhum tipo derivado; o símbolo é uma variável escalar simples.
IMAGE_SYM_DTYPE_POINTER
1
O símbolo é um ponteiro para o tipo base.
IMAGE_SYM_DTYPE_FUNCTION
2
O símbolo é uma função que retorna um tipo base.
IMAGE_SYM_DTYPE_ARRAY
3
O símbolo é uma matriz do tipo base.

 

Classe de armazenamento

O campo StorageClass da tabela de símbolos indica que tipo de definição um símbolo representa. A tabela a seguir mostra os valores possíveis. Observe que o campo StorageClass é um inteiro de 1 byte sem sinal. O valor especial -1 deve, portanto, ser entendido como seu equivalente sem sinal, 0xFF.

Embora o formato COFF tradicional use muitos valores de classe de armazenamento, as ferramentas da Microsoft dependem do formato de depuração do Visual C++ para a maioria das informações simbólicas e geralmente usam apenas quatro valores de classe de armazenamento: EXTERNAL (2), STATIC (3), FUNCTION (101) e FILE (103). Exceto no cabeçalho da segunda coluna abaixo, "Value" deve ser entendido como o campo de valor do registro do símbolo (cuja interpretação depende do número encontrado como a classe de armazenamento).

Constante Valor Descrição/interpretação do campo Value
IMAGE_SYM_CLASS_END_OF_FUNCTION
-1 (0xFF)
Um símbolo especial que representa o fim da função, para fins de depuração.
IMAGE_SYM_CLASS_NULL
0
Nenhuma classe de armazenamento atribuída.
IMAGE_SYM_CLASS_AUTOMATIC
1
A variável automática (pilha). O campo Value especifica o deslocamento do quadro de pilha.
IMAGE_SYM_CLASS_EXTERNAL
2
Um valor que as ferramentas da Microsoft usam para símbolos externos. O campo Value indicará o tamanho se o número da seção for IMAGE_SYM_UNDEFINED (0). Se o número da seção não for zero, o campo Value especificará o deslocamento dentro da seção.
IMAGE_SYM_CLASS_STATIC
3
O deslocamento do símbolo na seção. Se o campo Value for zero, o símbolo representará um nome de seção.
IMAGE_SYM_CLASS_REGISTER
4
Uma variável de registro. O campo Value especifica o número do registro.
IMAGE_SYM_CLASS_EXTERNAL_DEF
5
Um símbolo definido externamente.
IMAGE_SYM_CLASS_LABEL
6
Um rótulo de código definido no módulo. O campo Value especifica o deslocamento do símbolo dentro da seção.
IMAGE_SYM_CLASS_UNDEFINED_LABEL
7
Uma referência a um rótulo de código que não está definido.
IMAGE_SYM_CLASS_MEMBER_OF_STRUCT
8
O membro da estrutura. O campo Value especifica o enésimo membro.
IMAGE_SYM_CLASS_ARGUMENT
9
Um argumento formal (parâmetro) de uma função. O campo Value especifica o enésimo argumento.
IMAGE_SYM_CLASS_STRUCT_TAG
10
A entrada de nome da tag de estrutura.
IMAGE_SYM_CLASS_MEMBER_OF_UNION
11
Um membro de união. O campo Value especifica o enésimo membro.
IMAGE_SYM_CLASS_UNION_TAG
12
A entrada de nome de tag da união.
IMAGE_SYM_CLASS_TYPE_DEFINITION
13
Uma entrada Typedef.
IMAGE_SYM_CLASS_UNDEFINED_STATIC
14
Uma declaração de dados estáticos.
IMAGE_SYM_CLASS_ENUM_TAG
15
Uma entrada de nome de marca de tipo enumerado.
IMAGE_SYM_CLASS_MEMBER_OF_ENUM
16
Um membro de uma enumeração. O campo Value especifica o enésimo membro.
IMAGE_SYM_CLASS_REGISTER_PARAM
17
Um parâmetro de registro.
IMAGE_SYM_CLASS_BIT_FIELD
18
Uma referência de campo de bits. O campo Value especifica o enésimo bit no campo de bits.
IMAGE_SYM_CLASS_BLOCK
100
Um registro .bb (início do bloco) ou .eb (fim do bloco). O campo Value é o endereço relocável do local do código.
IMAGE_SYM_CLASS_FUNCTION
101
Um valor que as ferramentas da Microsoft usam para registros de símbolo que definem a extensão de uma função: função begin (.bf), função end (.ef) e linhas na função (.lf). Para registros .lf, o campo Value fornece o número de linhas de origem na função. Para registros .ef, o campo Value fornece o tamanho do código da função.
IMAGE_SYM_CLASS_END_OF_STRUCT
102
Uma entrada de fim de estrutura.
IMAGE_SYM_CLASS_FILE
103
Um valor que as ferramentas da Microsoft, bem como o formato COFF tradicional, usam para o registro de símbolo do arquivo de origem. O símbolo é seguido por registros auxiliares que nomeiam o arquivo.
IMAGE_SYM_CLASS_SECTION
104
Uma definição de uma seção (as ferramentas da Microsoft usam a classe de armazenamento STAT).
IMAGE_SYM_CLASS_WEAK_EXTERNAL
105
Um externo fraco. Para obter mais informações, confira Formato auxiliar 3: externos fracos.
IMAGE_SYM_CLASS_CLR_TOKEN
107
Um símbolo de token CLR. O nome é uma cadeia de caracteres ASCII que consiste no valor hexadecimal do token. Para obter mais informações, confira Definição de token CLR (somente objeto).

 

Registros de símbolos auxiliares

Os registros de tabela de símbolos auxiliares sempre seguem e se aplicam a algum registro de tabela de símbolos padrão. Um registro auxiliar pode ter qualquer formato que as ferramentas possam reconhecer, mas 18 bytes devem ser alocados para eles para que a tabela de símbolos seja mantida como uma matriz de tamanho regular. Atualmente, as ferramentas da Microsoft reconhecem formatos auxiliares para os seguintes tipos de registro: definições de função, símbolos de início e término de função (.bf e .ef), externos fracos, nomes de arquivo e definições de seção.

O design tradicional do COFF também inclui formatos de registro auxiliar para matrizes e estruturas. As ferramentas da Microsoft não os usam, mas colocam essas informações simbólicas no formato de depuração do Visual C++ nas seções de depuração.

Formato auxiliar 1: definições de função

Um registro de tabela de símbolos marcará o início de uma definição de função se tiver todos estes itens: uma classe de armazenamento de EXTERNAL (2), um valor Type que indica que é uma função (0x20) e um número de seção maior que zero. Observe que um registro de tabela de símbolos que tem um número de seção UNDEFINED (0) não define a função e não tem um registro auxiliar. Os registros de símbolo de definição de função são seguidos por um registro auxiliar no formato descrito abaixo:

Deslocamento Tamanho Campo Descrição
0
4
TagIndex
O índice da tabela de símbolos do registro de símbolo .bf (função begin) correspondente.
4
4
TotalSize
O tamanho do código executável para a função em si. Se a função estiver na sua própria seção, o SizeOfRawData no cabeçalho da seção será maior ou igual a esse campo, dependendo das considerações de alinhamento.
8
4
PointerToLinenumber
O deslocamento de arquivo da primeira entrada de número de linha COFF para a função ou zero, se não houver nenhum. Para obter mais informações, confira Números de linha COFF (preteridos).
12
4
PointerToNextFunction
O índice da tabela de símbolos do registro para a próxima função. Se a função for a última na tabela de símbolos, esse campo será definido como zero.
16
2
Não utilizado

 

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

Para cada definição de função na tabela de símbolos, três itens descrevem o início, o fim e o número de linhas. Cada um desses símbolos tem a classe de armazenamento FUNCTION (101):

Um registro de símbolo chamado .bf (função begin). O campo Value não é usado.

Um registro de símbolo chamado .lf (linhas na função). O campo Valor fornece o número de linhas na função.

Um registro de símbolo chamado .ef (fim da função). O campo Value tem o mesmo número que o campo Total Size no registro do símbolo de definição de função.

Os registros de símbolo .bf e .ef (mas não os registros .lf) são seguidos por um registro auxiliar com o seguinte formato:

Deslocamento Tamanho Campo Descrição
0
4
Não utilizado
4
2
Linenumber
O número de linha ordinal real (1, 2, 3 e assim por diante) dentro do arquivo de origem, correspondente ao registro .bf ou .ef.
6
6
Não utilizado
12
4
PointerToNextFunction (somente .bf)
O índice da tabela de símbolos do próximo registro de símbolo .bf. Se a função for a última na tabela de símbolos, esse campo será definido como zero. Ele não é usado para registros .ef.
16
2
Não utilizado

 

Formato auxiliar 3: externos fracos

"Externos fracos" são um mecanismo para arquivos de objeto que permite flexibilidade no tempo de vinculação. Um módulo pode conter um símbolo externo não resolvido (sym1), mas também incluir um registro auxiliar que indica que, se sym1 não estiver presente no momento do link, outro símbolo externo (sym2) será usado para resolver referências.

Se uma definição de sym1 estiver vinculada, uma referência externa ao símbolo será resolvida normalmente. Se uma definição de sym1 não estiver vinculada, todas as referências ao externo fraco para sym1 se referem a sym2. O símbolo externo, sym2, deve estar sempre vinculado; normalmente, ele é definido no módulo que contém a referência fraca ao SYM1.

Os externos fracos são representados por um registro de tabela de símbolos com a classe de armazenamento EXTERNAL, o número da seção UNDEF e um valor zero. O registro de símbolo externo fraco é seguido por um registro auxiliar com o seguinte formato:

Deslocamento Tamanho Campo Descrição
0
4
TagIndex
O índice da tabela de símbolos de sym2, o símbolo a ser vinculado se sym1 não for encontrado.
4
4
Características
Um valor de IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY indica que nenhuma pesquisa de biblioteca para sym1 deve ser executada.
Um valor de IMAGE_WEAK_EXTERN_SEARCH_LIBRARY indica que uma pesquisa de biblioteca para sym1 deve ser executada.
Um valor de IMAGE_WEAK_EXTERN_SEARCH_ALIAS indica que sym1 é um alias para sym2.
8
10
Não utilizado

 

Observe que o campo Characteristics não está definido no WINNT.H; em vez disso, o campo Total Size é usado.

Formato auxiliar 4: arquivos

Esse formato segue um registro de tabela de símbolos com a classe de armazenamento FILE (103). O nome do símbolo em si deve ser .file, e o registro auxiliar que o segue fornece o nome de um arquivo de código-fonte.

Deslocamento Tamanho Campo Descrição
0
18
Nome do arquivo
Uma cadeia de caracteres ANSI que fornece o nome do arquivo de origem. Ele será preenchido com nulos se for menor que o tamanho máximo.

 

Formato auxiliar 5: definições de seção

Esse formato segue um registro de tabela de símbolos que define uma seção. Esse registro tem um nome de símbolo que é o nome de uma seção (como .text ou .drectve) e tem a classe de armazenamento STATIC (3). O registro auxiliar fornece informações sobre a seção a que se refere. Assim, ele duplica algumas das informações no cabeçalho da seção.

Deslocamento Tamanho Campo Descrição
0
4
Length
O tamanho dos dados da seção; o mesmo que SizeOfRawData no cabeçalho da seção.
4
2
NumberOfRelocations
O número de entradas de realocação para a seção.
6
2
NumberOfLinenumbers
O número de entradas de número de linha para a seção.
8
4
CheckSum
A soma de verificação dos dados comuns. Será aplicável se o sinalizador IMAGE_SCN_LNK_COMDAT estiver definido no cabeçalho da seção. Para obter mais informações, confira Seções COMDAT (somente objeto).
12
2
Número
Índice baseado em um na tabela de seção para a seção associada. Usado quando a configuração de seleção COMDAT é 5.
14
1
Seleção
O número de seleção COMDAT. Será aplicável se a seção for uma seção COMDAT.
15
3
Não utilizado

 

Seções COMDAT (somente objeto)

O campo Selection do formato auxiliar de definição de seção será aplicável se a seção for uma seção COMDAT. Uma seção COMDAT é uma seção que pode ser definida por mais de um arquivo de objeto. (O IMAGE_SCN_LNK_COMDAT de sinalizadores é definido no campo Section Flags do cabeçalho da seção.) O campo Selection determina a maneira pela qual o vinculador resolve as várias definições de seções COMDAT.

O primeiro símbolo que tem o valor da seção COMDAT deve ser o símbolo de seção. Esse símbolo tem o nome da seção, o campo Value igual a zero, o número da seção COMDAT em questão, o campo Type igual a IMAGE_SYM_TYPE_NULL, o campo Class igual a IMAGE_SYM_CLASS_STATIC e um registro auxiliar. O segundo símbolo é chamado de "símbolo COMDAT" e é usado pelo vinculador em conjunto com o campo Selection.

Os valores do campo Selection são mostrados abaixo.

Constante Valor Descrição
IMAGE_COMDAT_SELECT_NODUPLICATES
1
Se esse símbolo já estiver definido, o vinculador emitirá um erro de "símbolo definido por multiplicação".
IMAGE_COMDAT_SELECT_ANY
2
Qualquer seção que defina o mesmo símbolo COMDAT pode ser vinculada, e o resto é removido.
IMAGE_COMDAT_SELECT_SAME_SIZE
3
O vinculador escolhe uma seção arbitrária entre as definições desse símbolo. Se todas as definições não forem do mesmo tamanho, um erro "multiplicar símbolo definido" será emitido.
IMAGE_COMDAT_SELECT_EXACT_MATCH
4
O vinculador escolhe uma seção arbitrária entre as definições desse símbolo. Se todas as definições não corresponderem exatamente, um erro "multiplicar símbolo definido" será emitido.
IMAGE_COMDAT_SELECT_ASSOCIATIVE
5
A seção estará vinculada se uma determinada outra seção COMDAT estiver vinculada. Essa outra seção é indicada pelo campo Number do registro de símbolo auxiliar para a definição da seção. Essa configuração será útil para definições que têm componentes em várias seções (por exemplo, código em uma e dados em outra), mas em que todos devem ser vinculados ou descartados como um conjunto. A outra seção à qual esta seção está associada deve ser uma seção COMDAT, que pode ser outra seção COMDAT associativa. A cadeia de associação de uma seção COMDAT associativa não pode formar um loop. A cadeia de associação de seção deve eventualmente chegar a uma seção COMDAT que não tenha IMAGE_COMDAT_SELECT_ASSOCIATIVE definido.
IMAGE_COMDAT_SELECT_LARGEST
6
O vinculador escolhe a maior definição entre todas as definições desse símbolo. Se várias definições tiverem esse tamanho, a escolha entre elas será arbitrária.

 

Definição de token CLR (somente objeto)

Esse símbolo auxiliar geralmente segue o IMAGE_SYM_CLASS_CLR_TOKEN. Ele será usado para associar um token ao namespace da tabela de símbolos COFF.

Deslocamento Tamanho Campo Descrição
0
1
bAuxType
Deve ser IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF (1).
1
1
bReserved
Reservado; deve ser zero
2
4
SymbolTableIndex
O índice do símbolo COFF ao qual essa definição de token CLR se refere.
6
12
Reservado; deve ser zero

 

Tabela de cadeira de caracteres do COFF

Imediatamente após a tabela de símbolos COFF está a tabela de cadeia de caracteres COFF. A posição dessa tabela é encontrada tomando o endereço da tabela de símbolos no cabeçalho COFF e adicionando o número de símbolos multiplicado pelo tamanho de um símbolo.

No início da tabela de cadeias de caracteres COFF há 4 bytes que contêm o tamanho total (em bytes) do restante da tabela de cadeias de caracteres. Esse tamanho inclui o próprio campo de tamanho, de modo que o valor nesse local seria 4 se nenhuma cadeia de caracteres estivesse presente.

Após o tamanho, há cadeias de caracteres terminadas em nulo que são apontadas por símbolos na tabela de símbolos COFF.

Tabela de certificados de atributo (somente imagem)

Os certificados de atributo podem ser associados a uma imagem adicionando uma tabela de certificados de atributo. A tabela de certificados de atributo é composta por um conjunto de entradas de certificado de atributo contíguas e alinhadas a palavras quádruplas. O preenchimento zero é inserido entre o final original do arquivo e o início da tabela de certificados de atributo para obter esse alinhamento. Cada entrada de certificado de atributo contém os campos a seguir.

Deslocamento Tamanho Campo Descrição
0
4
dwLength
Especifica o tamanho da entrada do certificado de atributo.
4
2
wRevision
Contém o número da versão do certificado. Para obter detalhes, confira o texto a seguir.
6
2
wCertificateType
Especifica o tipo de conteúdo em bCertificate. Para obter detalhes, confira o texto a seguir.
8
Consulte o seguinte
bCertificate
Contém um certificado, como uma assinatura Authenticode. Para obter detalhes, confira o texto a seguir.

 

O valor do endereço virtual da entrada da Tabela de certificados no Diretório de dados de cabeçalho opcional é um deslocamento de arquivo para a primeira entrada de certificado de atributo. As entradas subsequentes são acessadas avançando os bytes dwLength dessa entrada, arredondados para um múltiplo de 8 bytes, desde o início da entrada do certificado de atributo atual. Isso continua até que a soma dos valores arredondados de dwLength seja igual ao valor de trabalho da entrada Tabela de certificados no Diretório de dados de cabeçalho opcional. Se a soma dos valores arredondados de dwLength não for igual ao valor de tamanho, a tabela de certificado de atributo ou o campo Size estará corrompido.

Por exemplo, se a Entrada da tabela de certificados do Diretório de dados de cabeçalho opcional contiver:

virtual address = 0x5000
size = 0x1000

O primeiro certificado começa no deslocamento 0x5000 desde o início do arquivo no disco. Para avançar por todas as entradas de certificado de atributo:

  1. Adicione o valor dwLength do primeiro certificado de atributo ao deslocamento inicial.
  2. Arredonde o valor da etapa 1 para o múltiplo de 8 bytes mais próximo para localizar o deslocamento da segunda entrada de certificado de atributo.
  3. Adicione o valor de deslocamento da etapa 2 ao valor dwLength da segunda entrada de certificado de atributo e arredonde para o múltiplo de 8 bytes mais próximo para determinar o deslocamento da terceira entrada de certificado de atributo.
  4. Repita a etapa 3 para cada certificado sucessivo até que o deslocamento calculado seja igual a 0x6000 (início 0x5000 + tamanho total de 0x1000), o que indica que você percorreu a tabela inteira.

Como alternativa, você pode enumerar as entradas de certificado chamando a função ImageEnumerateCertificates Win32 em um loop. Para obter um link para a página de referência da função, confira Referências.

As entradas da tabela de certificados de atributo podem conter qualquer tipo de certificado, desde que a entrada tenha o valor dwLength correto, um valor wRevision exclusivo e um valor wCertificateType exclusivo. O tipo mais comum de entrada de tabela de certificado é uma estrutura WIN_CERTIFICATE, que está documentada em Wintrust.h e será discutida no restante desta seção.

As opções para o membro WIN_CERTIFICATE wRevision incluem (sem limitação) o seguinte.

Valor Name Observações
0x0100
WIN_CERT_REVISION_1_0
Versão 1, versão herdada da estrutura Win_Certificate. Ele é suportado apenas para fins de verificação de assinaturas Authenticode herdadas
0x0200
WIN_CERT_REVISION_2_0
A versão 2 é a versão atual da estrutura Win_Certificate.

 

As opções para o membro WIN_CERTIFICATE wCertificateType incluem (sem limitação) os itens na tabela a seguir. Observe que atualmente, não há suporte para alguns valores.

Valor Name Observações
0x0001
WIN_CERT_TYPE_X509
bCertificate contém um certificado X.509
Sem suporte
0x0002
WIN_CERT_TYPE_PKCS_SIGNED_DATA
bCertificate contém uma estrutura SignedData PKCS#7
0x0003
WIN_CERT_TYPE_RESERVED_1
Reservado
0x0004
WIN_CERT_TYPE_TS_STACK_SIGNED
Assinatura de certificado de pilha de protocolo do Terminal Server
Sem suporte

 

O membro bCertificate da estrutura WIN_CERTIFICATE contém uma matriz de bytes de tamanho variável com o tipo de conteúdo especificado por wCertificateType. O tipo suportado pelo Authenticode é WIN_CERT_TYPE_PKCS_SIGNED_DATA, uma estrutura SignedData de PKCS#7. Para obter detalhes sobre o formato de assinatura digital Authenticode, confira Formato de assinatura executável portátil do Windows Authenticode.

Se o conteúdo de bCertificate não terminar em um limite de palavras quádruplas, a entrada do certificado de atributo será preenchida com zeros, do final de bCertificate até o limite seguinte de palavras quádruplas.

O valor dwLength é o tamanho da estrutura WIN_CERTIFICATE finalizada e é calculado como:

dwLength = offsetof(WIN_CERTIFICATE, bCertificate) + (size of the variable-length binary array contained within bCertificate)

Esse tamanho deve incluir o tamanho de qualquer preenchimento usado para atender ao requisito de que cada estrutura WIN_CERTIFICATE seja alinhada a palavras quádruplas:

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

O tamanho da Tabela de certificados especificado na entrada Tabela de certificados nos Diretórios de dados de cabeçalho opcionais (somente imagem) inclui o preenchimento.

Para obter mais informações sobre como usar a API ImageHlp para enumerar, adicionar e remover certificados de arquivos PE, confira Funções ImageHlp.

Dados do certificado

Conforme indicado na seção anterior, os certificados na tabela de certificados de atributo podem conter qualquer tipo de certificado. Os certificados que garantem a integridade de um arquivo PE podem incluir um hash de imagem PE.

Um hash de imagem PE (ou hash de arquivo) é semelhante a uma soma de verificação de arquivo, pois o algoritmo de hash produz um resumo de mensagem relacionado à integridade de um arquivo. No entanto, uma soma de verificação é produzida por um algoritmo simples e é usada principalmente para detectar se um bloco de memória no disco falhou e os valores armazenados nele foram corrompidos. Um hash de arquivo é semelhante a uma soma de verificação, pois também detecta corrupção de arquivo. No entanto, ao contrário da maioria dos algoritmos de soma de verificação, é muito difícil modificar um arquivo sem alterar o hash do arquivo de seu valor original não modificado. Um hash de arquivo pode, portanto, ser usado para detectar modificações intencionais e até sutis em um arquivo, como as introduzidas por vírus, hackers ou programas de cavalos de Tróia.

Quando incluído em um certificado, o resumo da imagem deve excluir determinados campos na imagem PE, como a entrada de soma de verificação e tabela de certificados nos Diretórios de dados de cabeçalho opcionais. Isso ocorre porque o ato de adicionar um certificado altera esses campos e faria com que um valor de hash diferente fosse calculado.

A função Win32 ImageGetDigestStream fornece um fluxo de dados de um arquivo PE de destino com o qual é feito hash nas funções. Esse fluxo de dados permanece consistente quando os certificados são adicionados ou removidos de um arquivo PE. Com base nos parâmetros que são passados para ImageGetDigestStream, outros dados da imagem PE podem ser omitidos da computação de hash. Para obter um link para a página de referência da função, confira Referências.

Tabelas de importação de carregamento em atraso (somente imagem)

Essas tabelas foram adicionadas à imagem para dar suporte a um mecanismo uniforme para que os aplicativos atrasem o carregamento de uma DLL até a primeira chamada para essa DLL. O layout das tabelas corresponde ao das tabelas de importação tradicionais descritas na seção 6.4, Seção .idata". Apenas alguns detalhes são discutidos aqui.

Tabela de diretórios de carregamento em atraso

A tabela de diretórios de carregamento em atraso é a contrapartida da tabela de diretórios de importação. Ela pode ser recuperada por meio da entrada Descritor de importação de atraso na lista de diretórios de dados de cabeçalho opcionais (deslocamento 200). A tabela está organizada da seguinte forma:

Deslocamento Tamanho Campo Descrição
0
4
Attributes
Deve ser zero.
4
4
Name
O RVA do nome do DLL a ser carregado. O nome reside na seção de dados somente leitura da imagem.
8
4
Module Handle
O RVA do identificador do módulo (na seção de dados da imagem) da DLL a ser carregada com atraso. Ele é usado para armazenamento pela rotina fornecida para gerenciar o carregamento em atraso.
12
4
Delay Import Address Table
O RVA da tabela de endereços de importação de carga em atraso. Para obter mais informações, confira IAT (Tabela de endereços de importação em atraso).
16
4
Delay Import Name Table
O RVA da tabela de nomes de carregamento em atraso, que contém os nomes das importações que podem precisar ser carregadas. Isso corresponde ao layout da tabela de nomes de importação. Para obter mais informações, confira Tabela de dicas/nomes.
20
4
Bound Delay Import Table
O RVA da tabela de endereços de carga em atraso associada, se existir.
24
4
Unload Delay Import Table
O RVA da tabela de endereços de descarregamento em atraso associada, se existir. Esta é uma cópia exata da tabela de endereços de importação em atraso. Se o chamador descarregar a DLL, essa tabela deverá ser copiada de volta sobre a tabela de endereços de importação em atraso para que as chamadas subsequentes para a DLL continuem usando o mecanismo de conversão corretamente.
28
4
Time Stamp
O carimbo de data/hora da DLL à qual essa imagem foi associada.

 

As tabelas referenciadas nessa estrutura de dados são organizadas e classificadas da mesma forma que suas contrapartes para importações tradicionais. Para obter mais informações, confira Seção .idata.

Atributos

Até o momento, nenhum sinalizador de atributo está definido. O vinculador define esse campo como zero na imagem. Esse campo pode ser usado para estender o registro indicando a presença de novos campos ou pode ser usado para indicar comportamentos para as funções auxiliares de descarregamento ou atraso.

Name

O nome da DLL a ser carregada com atraso reside na seção de dados somente leitura da imagem. Ele é referenciado por meio do campo szName.

Identificador do módulo

O identificador da DLL a ser carregada em atraso está na seção de dados da imagem. O campo phmod aponta para o identificador. O auxiliar de carregamento em atraso fornecido usa esse local para armazenar o identificador na DLL carregada.

Tabela de endereços de importação em atraso

A tabela de endereços de importação em atraso (IAT) é referenciada pelo descritor de importação em atraso por meio do campo pIAT. O auxiliar de carregamento em atraso atualiza esses ponteiros com os pontos de entrada reais para que as conversões não estejam mais no loop de chamada. Os ponteiros de função são acessados usando a expressão pINT->u1.Function.

Tabela de nomes de importação em atraso

A tabela de nomes de importação em atraso (INT) contém os nomes das importações que podem exigir carregamento. Eles são ordenados da mesma forma que os ponteiros de função no IAT. Eles consistem nas mesmas estruturas que o INT padrão e são acessados usando a expressão pINT->u1.AddressOfData->Name[0].

Tabela e carimbo de data/hora de endereços de importação associada em atraso

A BIAT (tabela de endereços de importação associada em atraso) é uma tabela opcional de itens IMAGE_THUNK_DATA que é usada junto com o campo de registro de data e hora da tabela de diretório de carregamento em atraso por uma fase de associação pós-processo.

Tabela de endereços de importação de descarregamento em atraso

A UIAT (tabela de endereços de importação de descarregamento em atraso) é uma tabela opcional de itens de IMAGE_THUNK_DATA que o código de descarregamento usa para lidar com uma solicitação de descarregamento explícita. Ele consiste em dados inicializados na seção somente leitura que é uma cópia exata do IAT original que encaminhou o código para as conversões de carregamento em atraso. Na solicitação de descarregamento, a biblioteca pode ser liberada, o *phmod limpo e o UIAT gravado no IAT para restaurar tudo ao estado de pré-carregamento.

Seções especiais

As seções COFF típicas contêm código ou dados que os vinculadores e os carregadores do Microsoft Win32 processam sem conhecimento especial do conteúdo da seção. O conteúdo é relevante apenas para o aplicativo que está sendo vinculado ou executado.

No entanto, algumas seções COFF têm significados especiais quando encontradas em arquivos de objeto ou arquivos de imagem. Ferramentas e carregadores reconhecem essas seções porque elas têm sinalizadores especiais definidos no cabeçalho da seção, porque locais especiais no cabeçalho opcional da imagem apontam para elas ou porque o próprio nome da seção indica uma função especial da seção. (Mesmo que o nome da seção em si não indique uma função especial da seção, o nome da seção é ditado por convenção, portanto, os autores da especificação podem se referir a um nome de seção em todos os casos.)

As seções reservadas e os atributos são descritos na tabela abaixo, seguidos por descrições detalhadas para os tipos de seção que são persistidos em executáveis e os tipos de seção que contêm metadados para extensões.

Nome da Seção Sumário Características
.bss
Dados não inicializados (formato livre)
IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
.cormeta
Metadados CLR que indicam que o arquivo de objeto contém código gerenciado
IMAGE_SCN_LNK_INFO
.data
Dados inicializados (formato livre)
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
.debug$F
Informações de depuração FPO geradas (somente objeto, somente arquitetura x86 e agora obsoletas)
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
.debug$P
Tipos de depuração pré-compilados (somente objeto)
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
.debug$S
Símbolos de depuração (somente objeto)
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
.debug$T
Tipos de depuração (somente objeto)
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
.drective
Opções de vinculador
IMAGE_SCN_LNK_INFO
.edata
Tabelas de exportação
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
.idata
Tabelas de importação
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
.idlsym
Inclui SEH registrado (somente imagem) para dar suporte a atributos IDL. Para obter informações, confira "Atributos IDL" em Referências no final deste tópico.
IMAGE_SCN_LNK_INFO
.pdata
Informações da exceção
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
.rdata
Dados inicializados somente leitura
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
.reloc
Realocações de imagem
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
.rsrc
Diretório de recursos
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
.sbss
Dados não inicializados relativos à GP (formato livre)
IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE _SCN_GPREL O sinalizador IMAGE_SCN_GPREL deve ser definido apenas para arquiteturas IA64; esse sinalizador não é válido para outras arquiteturas. O sinalizador IMAGE_SCN_GPREL é apenas para arquivos de objeto; quando esse tipo de seção aparece em um arquivo de imagem, o sinalizador IMAGE_SCN_GPREL não deve ser definido.
.sdata
Dados inicializados relativos à GP (formato livre)
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE _SCN_GPREL O sinalizador IMAGE_SCN_GPREL deve ser definido apenas para arquiteturas IA64; esse sinalizador não é válido para outras arquiteturas. O sinalizador IMAGE_SCN_GPREL é apenas para arquivos de objeto; quando esse tipo de seção aparece em um arquivo de imagem, o sinalizador IMAGE_SCN_GPREL não deve ser definido.
.srdata
Dados somente leitura relativos à GP (formato livre)
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE _SCN_GPREL O sinalizador IMAGE_SCN_GPREL deve ser definido apenas para arquiteturas IA64; esse sinalizador não é válido para outras arquiteturas. O sinalizador IMAGE_SCN_GPREL é apenas para arquivos de objeto; quando esse tipo de seção aparece em um arquivo de imagem, o sinalizador IMAGE_SCN_GPREL não deve ser definido.
.sxdata
Dados do manipulador de exceção registrados (formato livre e somente x86/objeto)
IMAGE_SCN_LNK_INFO Contém o índice de símbolo de cada um dos manipuladores de exceção que estão sendo referenciados pelo código nesse arquivo de objeto. O símbolo pode ser para um símbolo UNDEF ou um que esteja definido nesse módulo.
.text
Código executável (formato livre)
IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IIMAGE_SCN_MEM_READ
.tls
Armazenamento local de thread (somente objeto)
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
.tls$
Armazenamento local de thread (somente objeto)
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
.vsdata
Dados inicializados relativos à GP (formato livre e somente para arquiteturas ARM, SH4 e Thumb)
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
.xdata
Informações de exceção (formato livre)
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ

 

Algumas seções listadas aqui são marcadas como "somente objeto" ou "somente imagem" para indicar que sua semântica especial é relevante apenas para arquivos de objeto ou arquivos de imagem, respectivamente. Uma seção marcada como "somente imagem" ainda pode aparecer em um arquivo de objeto como uma maneira de entrar no arquivo de imagem, mas a seção não tem nenhum significado especial para o vinculador, apenas para o carregador de arquivo de imagem.

Seção .debug

A seção .debug é usada em arquivos de objeto para conter informações de depuração geradas pelo compilador e em arquivos de imagem para conter todas as informações de depuração geradas. Essa seção descreve o empacotamento de informações de depuração em arquivos de objeto e imagem.

A próxima seção descreve o formato do diretório de depuração, que pode estar em qualquer lugar na imagem. As seções subsequentes descrevem os "grupos" em arquivos de objeto que contêm informações de depuração.

O padrão para o vinculador é que as informações de depuração não sejam mapeadas no espaço de endereço da imagem. Uma seção .debug existe somente quando as informações de depuração são mapeadas no espaço de endereço.

Diretório de depuração (somente imagem)

Os arquivos de imagem contêm um diretório de depuração opcional que indica qual forma de informação de depuração está presente e onde ela está. Esse diretório consiste em uma matriz de entradas de diretório de depuração cujo local e tamanho são indicados no cabeçalho opcional da imagem.

O diretório de depuração pode estar em uma seção .debug descartável (se houver) ou pode ser incluído em qualquer outra seção no arquivo de imagem ou não estar em uma seção.

Cada entrada do diretório de depuração identifica o local e o tamanho de um bloco de informações de depuração. O RVA especificado poderá ser zero se as informações de depuração não forem cobertas por um cabeçalho de seção (ou seja, residir no arquivo de imagem e não ser mapeado no espaço de endereço de tempo de execução). Se for mapeado, o RVA será seu endereço.

Uma entrada de diretório de depuração tem o seguinte formato:

Deslocamento Tamanho Campo Descrição
0
4
Características
Reservado; deve ser zero
4
4
TimeDateStamp
A hora e a data em que os dados de depuração foram criados.
8
2
MajorVersion
O número de versão principal do formato de dados de depuração.
10
2
MinorVersion
O número de versão secundária do formato de dados de depuração.
12
4
Tipo
O formato das informações de depuração. Esse campo permite o suporte a vários depuradores. Para obter mais informações, confira Tipo de depuração.
16
4
SizeOfData
O tamanho dos dados de depuração (não incluindo o próprio diretório de depuração).
20
4
AddressOfRawData
O endereço dos dados de depuração quando carregados, em relação à base da imagem.
24
4
PointerToRawData
O ponteiro de arquivo para os dados de depuração.

 

Tipo de depuração

Os seguintes valores são definidos para o campo Type da entrada do diretório de depuração:

Constante Valor Descrição
IMAGE_DEBUG_TYPE_UNKNOWN
0
Um valor desconhecido é ignorado por todas as ferramentas.
IMAGE_DEBUG_TYPE_COFF
1
As informações de depuração do COFF (números de linha, tabela de símbolos e tabela de cadeia de caracteres). Esse tipo de informação de depuração também é apontado por campos nos cabeçalhos de arquivo.
IMAGE_DEBUG_TYPE_CODEVIEW
2
As informações de depuração do Visual C++.
IMAGE_DEBUG_TYPE_FPO
3
As informações de FPO (omissão do ponteiro do quadro). Essas informações informam ao depurador como interpretar quadros de pilha não padrão, que usam o registro EBP para uma finalidade diferente de um ponteiro de quadro.
IMAGE_DEBUG_TYPE_MISC
4
O local do arquivo DBG.
IMAGE_DEBUG_TYPE_EXCEPTION
5
Uma cópia da seção .pdata.
IMAGE_DEBUG_TYPE_FIXUP
6
Reservado.
IMAGE_DEBUG_TYPE_OMAP_TO_SRC
7
O mapeamento de um RVA na imagem para um RVA na imagem de origem.
IMAGE_DEBUG_TYPE_OMAP_FROM_SRC
8
O mapeamento de um RVA na imagem de origem para um RVA na imagem.
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 ou reprodutibilidade de PE.
Indefinido
17
As informações de depuração são integradas no arquivo PE no local especificado por PointerToRawData.
Indefinido
19
Armazena o hash de criptografia para o conteúdo do arquivo de símbolo usado para criar o arquivo PE/COFF.
IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS 20 Bits de características DLL estendidos.

 

Se o campo Type estiver definido como IMAGE_DEBUG_TYPE_FPO, os dados brutos de depuração serão uma matriz na qual cada membro descreve o quadro de pilha de uma função. Nem todas as funções no arquivo de imagem devem ter informações FPO definidas, mesmo que o tipo de depuração seja FPO. Presume-se que as funções que não têm informações de FPO tenham quadros de pilha normais. O formato das informações FPO é o seguinte:

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

A presença de uma entrada do tipo IMAGE_DEBUG_TYPE_REPRO indica que o arquivo PE é criado de forma a obter determinismo ou reprodutibilidade. Se a entrada não for alterada, o arquivo PE de saída terá a garantia de ser idêntico em cada bit, independentemente de quando ou onde o PE é produzido. Vários campos de carimbo de data/hora no arquivo PE são preenchidos com parte ou todos os bits de um valor de hash calculado que usa o conteúdo do arquivo PE como entrada e, portanto, não representam mais a data e hora reais em que um arquivo PE ou dados específicos relacionados dentro do PE são produzidos. Os dados brutos dessa entrada de depuração podem estar vazios ou podem conter um valor de hash calculado precedido por um valor de quatro bytes que representa o tamanho do valor de hash.

Se o campo Type estiver definido como IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS, os dados brutos de depuração conterão bits de características de DLL estendidos, além daqueles que podem ser definidos no cabeçalho opcional da imagem. Confira Características de DLL na seção Campos específicos do Windows para cabeçalho opcional (somente imagem).

Características de DLL estendidas

Os valores a seguir são definidos para os bits de características de DLL estendidas.

Constante Valor Descrição
IMAGE_DLLCHARACTERISTICS_EX_CET_COMPAT 0x0001 A imagem é compatível com a pilha de sombra CET (tecnologia de imposição de fluxo de controle).
IMAGE_DLLCHARACTERISTICS_EX_FORWARD_CFI_COMPAT 0x0040 Todos os destinos de ramificação em todas as seções de código de imagem são anotados com instruções de proteção de integridade de fluxo de controle de borda frontal, como instruções x86 IBT (CET-Indirect Branch Tracking) ou BTI (ARM Branch Target Identification). Esse bit não é usado pelo Windows.

.debug$F (somente objeto)

Os dados nesta seção foram substituídos no Visual C++ versão 7.0 e posterior por um conjunto mais extenso de dados que é emitido em uma subseção .debug$S.

Os arquivos de objeto podem conter seções .debug$F cujo conteúdo é um ou mais registros FPO_DATA (informações de omissão de ponteiro de quadro). Confira "IMAGE_DEBUG_TYPE_FPO" em Tipo de depuração.

O vinculador reconhece esses registros .debug$F. Se as informações de depuração estiverem sendo geradas, o vinculador classificará os registros FPO_DATA por RVA de procedimento e gerará uma entrada de diretório de depuração para eles.

O compilador não deve gerar registros FPO para procedimentos com um formato de quadro padrão.

.debug$S (somente objeto)

Esta seção contém informações de depuração do Visual C++ (informações simbólicas).

.debug$P (somente objeto)

Esta seção contém informações de depuração do Visual C++ (informações pré-compiladas). Esses são tipos compartilhados entre todos os objetos que foram compilados usando o cabeçalho pré-compilado que foi gerado com esse objeto.

.debug$T (somente objeto)

Esta seção contém informações de depuração do Visual C++ (informações de tipo).

Suporte ao vinculador para informações de depuração da Microsoft

Para dar suporte a informações de depuração, o vinculador:

  • Reúne todos os dados de depuração relevantes das seções .debug$F, debug$S, .debug$P e .debug$T.

  • Processa esses dados junto com as informações de depuração geradas pelo vinculador no arquivo PDB e cria uma entrada de diretório de depuração para se referir a ele.

Seção .drectve (somente objeto)

Uma seção é uma seção de diretiva caso tenha o sinalizador IMAGE_SCN_LNK_INFO definido no cabeçalho da seção e o nome da seção .drectve. O vinculador remove uma seção .drectve após processar as informações para que a seção não apareça no arquivo de imagem que está sendo vinculado.

Uma seção .drectve consiste em uma sequência de texto que pode ser codificada como ANSI ou UTF-8. Se o marcador de ordem de bytes UTF-8 (BOM, um prefixo de três bytes que consiste em 0xEF, 0xBB e 0xBF) não estiver presente, a cadeia de caracteres de diretiva será interpretada como ANSI. A cadeia de caracteres diretiva é uma série de opções de vinculador separadas por espaços. Cada opção contém um hífen, o nome da opção e qualquer atributo apropriado. Se uma opção contiver espaços, a opção deverá ser colocada entre aspas. A seção .drectve não deve ter realocações ou números de linha.

Seção .edata (somente imagem)

A seção de dados de exportação, chamada .edata, contém informações sobre símbolos que outras imagens podem acessar por meio de vinculação dinâmica. Os símbolos exportados geralmente são encontrados em DLLs, mas as DLLs também podem importar símbolos.

Uma visão geral da estrutura geral da seção de exportação é descrita abaixo. As tabelas descritas são geralmente contíguas no arquivo na ordem mostrada (embora isso não seja obrigatório). Somente a tabela de diretórios de exportação e a tabela de endereços de exportação são necessárias para exportar símbolos como ordinais. (Um ordinal é uma exportação que é acessada diretamente por seu índice de tabela de endereços de exportação.) A tabela de ponteiro de nome, a tabela ordinal e a tabela de nomes de exportação existem para dar suporte ao uso de nomes de exportação.

Nome da tabela Descrição
Tabela de diretórios de exportação
Uma tabela com apenas uma linha (ao contrário do diretório de depuração). Essa tabela indica os locais e tamanhos das outras tabelas de exportação.
Tabela de endereços de exportação
Uma matriz de RVAs de símbolos exportados. Esses são os endereços reais das funções e dados exportados nas seções de código executável e dados. Outros arquivos de imagem podem importar um símbolo usando um índice para essa tabela (um ordinal) ou, opcionalmente, usando o nome público que corresponderá ao ordinal se um nome público for definido.
Tabela de ponteiro de nome
Uma matriz de ponteiros para os nomes de exportação públicos, classificados em ordem crescente.
Tabela de ordinais
Uma matriz de ordinais que correspondem aos membros da tabela de ponteiro de nome. A correspondência é por posição. Sendo assim, a tabela de ponteiro de nome e a tabela de ordinais devem ter o mesmo número de membros. Cada ordinal é um índice na tabela de endereços de exportação.
Tabela de nomes de exportação
Uma série de cadeias de caracteres ASCII terminadas em nulo. Os membros da tabela de ponteiro de nome apontam para essa área. Esses nomes são os nomes públicos por meio dos quais os símbolos são importados e exportados; eles não são necessariamente os mesmos que os nomes privados usados no arquivo de imagem.

 

Quando outro arquivo de imagem importa um símbolo por nome, o carregador Win32 pesquisa a tabela de ponteiro de nome em busca de uma cadeia de caracteres correspondente. Se uma cadeia de caracteres correspondente for encontrada, o ordinal associado será identificado pesquisando o membro correspondente na tabela ordinal (ou seja, o membro da tabela ordinal com o mesmo índice que o ponteiro de cadeia de caracteres encontrado na tabela de ponteiro de nome). O ordinal resultante é um índice na tabela de endereços de exportação, que fornece a localização real do símbolo desejado. Cada símbolo de exportação pode ser acessado por um ordinal.

Quando outro arquivo de imagem importa um símbolo por ordinal, não é necessário pesquisar na tabela de ponteiro de nome uma cadeia de caracteres correspondente. O uso direto de um ordinal é, portanto, mais eficiente. No entanto, um nome de exportação é mais fácil de lembrar e não exige que o usuário saiba o índice da tabela para o símbolo.

Tabela de diretórios de exportação

As informações do símbolo de exportação começam com a tabela de diretórios de exportação, que descreve o restante das informações do símbolo de exportação. A Tabela de diretórios de exportação contém informações de endereço que são usadas para resolver importações para os pontos de entrada nesta imagem.

Deslocamento Tamanho Campo Descrição
0
4
Sinalizadores de exportação
Reservado, deve ser 0.
4
4
Carimbo de data/hora
A hora e a data em que os dados de exportação foram criados.
8
2
Versão principal
O número da versão principal. Os números de versão principal e secundária podem ser definidos pelo usuário.
10
2
Versão secundária
O número da versão secundária.
12
4
RVA de nome
O endereço da cadeia de caracteres ASCII que contém o nome da DLL. O endereço é relativo à base da imagem.
16
4
Base do ordinal
O número ordinal inicial para exportações nesta imagem. O campo especifica o número ordinal inicial para a tabela de endereços de exportação. Geralmente é definido como 1.
20
4
Entradas da tabela de endereços
O número de entradas na tabela de endereços de exportação.
24
4
Número de ponteiros de nome
O número de entradas na tabela de ponteiros de nome. Também é o número de entradas na tabela ordinal.
28
4
RVA da tabela de endereços de exportação
O endereço da tabela de endereços de exportação em relação à base da imagem.
32
4
RVA do ponteiro de nome
O endereço da tabela de ponteiro de nome de exportação, em relação à base da imagem. O tamanho da tabela é dado pelo campo Número de ponteiros de nome.
36
4
RVA da tabela de ordinais
O endereço da tabela ordinal, em relação à base da imagem.

 

Tabela de endereços de exportação

A tabela de endereços de exportação contém o endereço dos pontos de entrada exportados e dados e absolutos exportados. Um número ordinal é usado como um índice na tabela de endereços de exportação.

Cada entrada na tabela de endereços de exportação é um campo que usa um dos dois formatos na tabela a seguir. Se o endereço especificado não estiver na seção de exportação (conforme definido pelo endereço e tamanho indicados no cabeçalho opcional), o campo será um RVA de exportação, que é um endereço real no código ou nos dados. Caso contrário, o campo será um RVA de encaminhador, que nomeia um símbolo em outra DLL.

Deslocamento Tamanho Campo Descrição
0
4
Exportar RVA
O endereço do símbolo exportado quando carregado na memória, em relação à base da imagem. Por exemplo, o endereço de uma função exportada.
0
4
RVA de encaminhador
O ponteiro para uma cadeia de caracteres ASCII terminada em nulo na seção de exportação. Essa cadeia de caracteres deve estar dentro do intervalo fornecido pela entrada do diretório de dados da tabela de exportação. Confira Diretórios de dados de cabeçalho opcionais (somente imagem). Essa cadeia de caracteres fornece o nome da DLL e o nome da exportação (por exemplo, "MYDLL.expfunc") ou o nome da DLL e o número ordinal da exportação (por exemplo, "MYDLL.#27").

 

Um encaminhador RVA exporta uma definição de alguma outra imagem, fazendo com que pareça que ela está sendo exportada pela imagem atual. Assim, o símbolo é importado e exportado simultaneamente.

Por exemplo, no Kernel32.dll no Windows XP, a exportação chamada "HeapAlloc" é encaminhada para a cadeia de caracteres "NTDLL.RtlAllocateHeap". Isso permite que os aplicativos usem o módulo específico do Windows XP Ntdll.dll sem realmente conter referências de importação para ele. A tabela de importação do aplicativo refere-se apenas a Kernel32.dll. Portanto, o aplicativo não é específico do Windows XP e pode ser executado em qualquer sistema Win32.

Tabela de ponteiros de nome de exportação

A tabela de ponteiro de nome de exportação é uma matriz de endereços (RVAs) na tabela de nomes de exportação. Os ponteiros são de 32 bits cada e são relativos à base da imagem. Os ponteiros são ordenados de modo lexical para permitir pesquisas binárias.

Um nome de exportação será definido somente se a tabela de ponteiro de nome de exportação contiver um ponteiro para ele.

Tabela de ordinais de exportação

A tabela de ordinais de exportação é uma matriz de índices imparciais de 16 bits na tabela de endereços de exportação. Os ordinais são influenciados pelo campo Ordinal Base da tabela de diretórios de exportação. Em outras palavras, a base ordinal deverá ser subtraída dos ordinais para obter índices verdadeiros na tabela de endereços de exportação.

A tabela de ponteiro de nome de exportação e a tabela ordinal de exportação formam duas matrizes paralelas que são separadas para permitir o alinhamento natural do campo. Essas duas tabelas, na verdade, operam como uma tabela, na qual a coluna Ponteiro de nome de exportação aponta para um nome público (exportado) e a coluna Ordinal de exportação fornece o ordinal correspondente para esse nome público. Um membro da tabela de ponteiro de nome de exportação e um membro da tabela de ordinais de exportação são associados por terem a mesma posição (índice) em suas respectivas matrizes.

Assim, quando a tabela de ponteiros de nome de exportação é pesquisada e uma cadeia de caracteres correspondente é encontrada na posição i, o algoritmo para encontrar o RVA do símbolo e o ordinal tendencioso é:

i = Search_ExportNamePointerTable (name);
ordinal = ExportOrdinalTable [i];

rva = ExportAddressTable [ordinal];
biased_ordinal = ordinal + OrdinalBase;

Ao pesquisar um símbolo por ordinal (tendencioso), o algoritmo para encontrar o RVA e o nome do símbolo é:

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

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

Tabela de nomes de exportação

A tabela de nomes de exportação contém os dados de cadeia de caracteres reais que foram apontados pela tabela de ponteiro de nome de exportação. As cadeias de caracteres nesta tabela são nomes públicos que outras imagens podem usar para importar os símbolos. Esses nomes de exportação públicos não são necessariamente os mesmos que os nomes dos símbolos privados que têm em seu próprio arquivo de imagem e código-fonte, embora possam ser.

Cada símbolo exportado tem um valor ordinal, que é apenas o índice na tabela de endereços de exportação. O uso de nomes de exportação, no entanto, é opcional. Alguns, todos ou nenhum dos símbolos exportados podem ter nomes de exportação. Para símbolos exportados que têm nomes de exportação, as entradas correspondentes na tabela de ponteiro de nome de exportação e na tabela ordinal de exportação trabalham juntas para associar cada nome a um ordinal.

A estrutura da tabela de nomes de exportação é uma série de cadeias de caracteres ASCII terminadas em nulo de tamanho variável.

Seção .idata

Todos os arquivos de imagem que importam símbolos, inclusive praticamente todos os arquivos executáveis (EXE), têm uma seção .idata. Um layout de arquivo típico para as informações de importação é o seguinte:

  • Tabela de diretórios

    Entrada de diretório nula

  • Tabela de pesquisa de importação DLL1

    Nulo

  • Tabela de pesquisa de importação DLL2

    Nulo

  • Tabela de pesquisa de importação DLL3

    Nulo

  • Tabela de dicas-nomes

Tabela de diretórios de importação

As informações de importação começam com a tabela de diretórios de importação, que descreve o restante das informações de importação. A tabela de diretórios de importação contém informações de endereço que são usadas para resolver referências de correção aos pontos de entrada em uma imagem DLL. A tabela de diretórios de importação consiste em uma matriz de entradas de diretório de importação, uma entrada para cada DLL à qual a imagem se refere. A última entrada de diretório está vazia (preenchida com valores nulos), o que indica o fim da tabela de diretórios.

Cada entrada de diretório de importação tem o seguinte formato:

Deslocamento Tamanho Campo Descrição
0
4
RVA da tabela de pesquisa de importação (características)
O RVA da tabela de pesquisa de importação. A tabela contém um nome ou ordinal para cada importação. (O nome "Características" é usado em Winnt.h, mas não descreve mais esse campo.)
4
4
Carimbo de data/hora
O carimbo definido como zero até que a imagem seja acoplada. Depois que a imagem é associada, esse campo é definido como o carimbo de data/hora da DLL.
8
4
Corrente de encaminhador
O índice da primeira referência de encaminhador.
12
4
RVA de nome
O endereço de uma cadeia de caracteres ASCII que contém o nome da DLL. O endereço é relativo à base da imagem.
16
4
RVA da tabela de endereços de importação (tabela de conversão)
O RVA da tabela de endereços de importação. O conteúdo da tabela é idêntico ao conteúdo da tabela de pesquisa de importação até que a imagem seja associada.

 

Tabela de pesquisa de importação

Uma tabela de pesquisa de importação é uma matriz de números de 32 bits para PE32 ou uma matriz de números de 64 bits para PE32+. Cada entrada usa o formato de campos de bits descrito na tabela a seguir. Nesse formato, o bit 31 é o bit mais significativo para PE32, e o bit 63 é o bit mais significativo para PE32+. A coleção dessas entradas descreve todas as importações de uma determinada DLL. A última entrada é definida como zero (NULL) para indicar o final da tabela.

Bit(s) Tamanho Campo de bits Descrição
31/63
1
Sinalizador de ordinal/nome
Se esse bit estiver definido, importe por ordinal. Caso contrário, importe por nome. O bit é mascarado como 0x80000000 para PE32 0x8000000000000000 para PE32+.
15-0
16
Número ordinal
Um número ordinal de 16 bits. Esse campo será usado somente se o campo de bit Ordinal/Name Flag for 1 (importação por ordinal). Os bits 30-15 ou 62-15 devem ser 0.
30-0
31
RVA de tabela de dicas/nomes
Um RVA de 31 bits de uma entrada de tabela de dicas/nomes. Esse campo será usado somente se o campo de bit Ordinal/Name Flag for 0 (importação por nome). Para os bits PE32+, 62-31 deve ser zero.

 

Tabela de dicas/nomes

Uma tabela de dicas/nomes é suficiente para toda a seção de importação. Cada entrada na tabela de dicas/nomes tem o seguinte formato:

Deslocamento Tamanho Campo Descrição
0
2
Dica
Um índice na tabela de ponteiro de nome de exportação. Uma correspondência é tentada primeiro com esse valor. Se falhar, uma pesquisa binária será executada na tabela de ponteiro de nome de exportação da DLL.
2
variável
Name
Uma cadeia de caracteres ASCII que contém o nome a ser importado. Essa é a cadeia de caracteres que deve corresponder ao nome público na DLL. Essa cadeia de caracteres diferencia maiúsculas de minúsculas e é encerrada por um byte nulo.
*
0 ou 1
Pad
Um byte de bloco zero à direita que aparece após o byte nulo à direita, se necessário, para alinhar a próxima entrada em um limite par.

 

Tabela de endereços de importação

A estrutura e o conteúdo da tabela de endereços de importação são idênticos aos da tabela de pesquisa de importação, até que o arquivo seja vinculado. Durante a vinculação, as entradas na tabela de endereços de importação são substituídas pelos endereços de 32 bits (para PE32) ou 64 bits (para PE32+) dos símbolos que estão sendo importados. Esses endereços são os endereços de memória reais dos símbolos, embora tecnicamente ainda sejam chamados de "endereços virtuais". O carregador normalmente processa a associação.

Seção .pdata

A seção .pdata contém uma matriz de entradas de tabela de funções que são usadas para tratamento de exceções. Ele é apontado pela entrada da tabela de exceção no diretório de dados da imagem. As entradas devem ser classificadas de acordo com os endereços de função (o primeiro campo em cada estrutura) antes de serem emitidas para a imagem final. A plataforma de destino determina qual das três variações de formato de entrada da tabela de funções descritas abaixo é usada.

Para imagens MIPS de 32 bits, as entradas da tabela de funções têm o seguinte formato:

Deslocamento Tamanho Campo Descrição
0
4
Endereço de início
O VA da função correspondente.
4
4
Endereço final
O VA do fim da função.
8
4
Manipulador de exceção
O ponteiro para o manipulador de exceção a ser executado.
12
4
Dados do manipulador
O ponteiro para informações adicionais a serem passadas para o manipulador.
16
4
Endereço final do prólogo
[O VA do final do prólogo da função.

 

Para as plataformas ARM, PowerPC, SH3 e SH4 Windows CE, as entradas da tabela de funções têm o seguinte formato:

Deslocamento Tamanho Campo Descrição
0
4
Endereço de início
O VA da função correspondente.
4
8 bits
Tamanho do prólogo
O número de instruções no prólogo da função.
4
22 bits
Tamanho da função
O número de instruções na função.
4
1 bits
Sinalizador de 32 bits
Se definida, a função consiste em instruções de 32 bits. Se estiver limpa, a função consistirá em instruções de 16 bits.
4
1 bits
Sinalizador de exceções
Se definido, existe um manipulador de exceções para a função. Caso contrário, não existe manipulador de exceção.

 

Para plataformas x64 e Itanium, as entradas da tabela de funções têm o seguinte formato:

Deslocamento Tamanho Campo Descrição
0
4
Endereço de início
O RVA da função correspondente.
4
4
Endereço final
O RVA do fim da função.
8
4
Informações de desenrolamento
O RVA das informações de desenrolamento.

 

Seção .reloc (somente imagem)

A tabela de realocação de base contém entradas para todas as realocações de base na imagem. O campo da tabela de realocação de base nos diretórios de dados de cabeçalho opcionais fornece o número de bytes na tabela de realocação base. Para obter mais informações, confira Diretórios de dados de cabeçalho opcionais (somente imagem). A tabela de realocação de base é dividida em blocos. Cada bloco representa as realocações de base de uma página 4K. Cada bloco deve começar em um limite de 32 bits.

O carregador não é necessário para processar realocações de base resolvidas pelo vinculador, a menos que a imagem de carregamento não possa ser carregada na base de imagem especificada no cabeçalho PE.

Bloco de realocação de base

Cada bloco de realocação de base começa com a seguinte estrutura:

Deslocamento Tamanho Campo Descrição
0
4
RVA da página
A base da imagem mais o RVA da página são adicionados a cada deslocamento para criar o VA em que a realocação da base deve ser aplicada.
4
4
Tamanho do bloco
O número total de bytes no bloco de realocação de base, incluindo os campos Page RVA e Block Size e os campos Type/Offset a seguir.

 

O campo Block Size é seguido por qualquer número de entradas de campo Type ou Offset. Cada entrada é uma WORD (2 bytes) e tem a seguinte estrutura:

Deslocamento Tamanho Campo Descrição
0
4 bits
Tipo
Armazenado nos 4 bits altos do WORD, um valor que indica o tipo de realocação de base a ser aplicada. Para obter mais informações, confira Tipos de realocação de base.
0
12 bits
Offset
Armazenado nos 12 bits restantes do WORD, um deslocamento do endereço inicial especificado no campo Page RVA para o bloco. Esse deslocamento especifica onde a realocação de base deve ser aplicada.

 

Para aplicar uma realocação de base, a diferença é calculada entre o endereço de base preferencial e a base onde a imagem é realmente carregada. Se a imagem for carregada em sua base preferida, a diferença será zero e, portanto, as realocações de base não precisarão ser aplicadas.

Tipos de realocação de base

Constante Valor Descrição
IMAGE_REL_BASED_ABSOLUTE
0
A realocação de base é ignorada. Esse tipo pode ser usado para preencher um bloco.
IMAGE_REL_BASED_HIGH
1
A realocação de base adiciona os 16 bits altos da diferença ao campo de 16 bits no deslocamento. O campo de 16 bits representa o alto valor de uma palavra de 32 bits.
IMAGE_REL_BASED_LOW
2
A realocação de base adiciona os 16 bits baixos da diferença ao campo de 16 bits no deslocamento. O campo de 16 bits representa a metade inferior de uma palavra de 32 bits.
IMAGE_REL_BASED_HIGHLOW
3
A realocação de base aplica todos os 32 bits baixos da diferença ao campo de 32 bits no deslocamento.
IMAGE_REL_BASED_HIGHADJ
4
A realocação de base adiciona os 16 bits altos da diferença ao campo de 16 bits no deslocamento. O campo de 16 bits representa o alto valor de uma palavra de 32 bits. Os 16 bits baixos do valor de 32 bits são armazenados na palavra de 16 bits que segue essa realocação de base. Isso significa que essa realocação de base ocupa dois slots.
IMAGE_REL_BASED_MIPS_JMPADDR
5
A interpretação de realocação depende do tipo de máquina.
Quando o tipo de máquina é MIPS, a realocação de base se aplica a uma instrução de salto MIPS.
IMAGE_REL_BASED_ARM_MOV32
5
Essa realocação só será significativa quando o tipo de máquina for ARM ou Thumb. A realocação de base aplica o endereço de 32 bits de um símbolo em um par de instruções MOVW/MOVT consecutivo.
IMAGE_REL_BASED_RISCV_HIGH20
5
Essa realocação só será significativa quando o tipo de máquina for RISC-V. A realocação de base se aplica aos 20 bits altos de um endereço absoluto de 32 bits.
6
Reservado; deve ser zero
IMAGE_REL_BASED_THUMB_MOV32
7
Essa realocação só será significativa quando o tipo de máquina for Thumb. A realocação de base aplica o endereço de 32 bits de um símbolo para um par de instruções MOVW/MOVT consecutivo.
IMAGE_REL_BASED_RISCV_LOW12I
7
Essa realocação só será significativa quando o tipo de máquina for RISC-V. A realocação de base se aplica aos 12 bits baixos de um endereço absoluto de 32 bits formado no formato de instrução do tipo RISC-V I.
IMAGE_REL_BASED_RISCV_LOW12S
8
Essa realocação só será significativa quando o tipo de máquina for RISC-V. A realocação de base se aplica aos 12 bits baixos de um endereço absoluto de 32 bits formado no formato de instrução do tipo RISC-V S.
IMAGE_REL_BASED_LOONGARCH32_MARK_LA
8
Essa realocação só será significativa quando o tipo de máquina for LoongArch de 32 bits. A realocação de base se aplica a um endereço absoluto de 32 bits formado em duas instruções consecutivas.
IMAGE_REL_BASED_LOONGARCH64_MARK_LA
8
Essa realocação só será significativa quando o tipo de máquina for LoongArch de 64 bits. A realocação de base se aplica a um endereço absoluto de 64 bits formado em quatro instruções consecutivas.
IMAGE_REL_BASED_MIPS_JMPADDR16
9
A realocação só será significativa quando o tipo de máquina for MIPS. A realocação de base se aplica a uma instrução de salto MIPS16.
IMAGE_REL_BASED_DIR64
10
A realocação de base aplica a diferença ao campo de 64 bits no deslocamento.

 

Seção .tls

A seção .tls fornece suporte direto a PE e COFF para TLS (armazenamento local de thread estático). O TLS é uma classe de armazenamento especial compatível com Windows em que um objeto de dados não é uma variável automática (pilha), mas é local para cada thread individual que executa o código. Assim, cada thread pode manter um valor diferente para uma variável declarada usando TLS.

Observe que qualquer quantidade de dados TLS pode ser suportada usando as chamadas de API TlsAlloc, TlsFree, TlsSetValue e TlsGetValue. A implementação PE ou COFF é uma abordagem alternativa ao uso da API e tem a vantagem de ser mais simples do ponto de vista do programador de linguagem de alto nível. Essa implementação permite que os dados TLS sejam definidos e inicializados de modo semelhante às variáveis estáticas comuns em um programa. Por exemplo, no Visual C++, uma variável TLS estática pode ser definida da seguinte maneira, sem usar a API do Windows:

__declspec (thread) int tlsFlag = 1;

Para dar suporte a esse construtor de programação, a seção .tls PE e COFF especifica as seguintes informações: dados de inicialização, rotinas de retorno de chamada para inicialização e encerramento por thread e índice TLS, que são explicados na discussão a seguir.

Nota

Antes do Windows Vista, os objetos de dados TLS declarados estaticamente só podem ser usados em arquivos de imagem carregados estaticamente. Esse fato torna não confiável o uso de dados TLS estáticos em uma DLL, a menos que você saiba que a DLL, ou qualquer item vinculado estaticamente a ela, nunca será carregada dinamicamente com a função de API LoadLibrary. No entanto, do Windows Vista em diante, foram feitas melhorias no carregador do Windows para oferecer melhor suporte ao carregamento dinâmico de DLLs com TLS estático. Essa alteração significa que as DLLs com objetos de dados TLS declarados estaticamente agora podem ser usadas de forma mais confiável, mesmo que sejam carregadas dinamicamente usando LoadLibrary. O carregador é capaz de alocar slots TLS para essas DLLs no tempo de carregamento, atenuando as limitações presentes em versões anteriores do Windows.

 

Nota

Referências a deslocamentos de 32 bits e multiplicadores de índice de 4 se aplicam a sistemas com arquiteturas de 32 bits. Em um sistema baseado em arquiteturas de 64 bits, ajuste-as conforme necessário.

O código executável acessa um objeto de dados TLS estático por meio das seguintes etapas:

  1. No momento da vinculação, o vinculador define o campo Address of Index do diretório TLS. Esse campo aponta para um local onde o programa espera receber o índice TLS.

    A biblioteca de tempo de execução da Microsoft facilita esse processo definindo uma imagem de memória do diretório TLS e dando a ela o nome especial "__tls_used" (plataformas Intel x86) ou "_tls_used" (outras plataformas). O vinculador procura essa imagem de memória e usa os dados para criar o diretório TLS. Outros compiladores que dão suporte ao TLS e trabalham com o vinculador da Microsoft devem usar essa mesma técnica.

  2. Quando um thread é criado, o carregador comunica o endereço da matriz TLS do thread colocando o endereço do TEB (bloco de ambiente de thread) no registro FS. Um ponteiro para a matriz TLS está no deslocamento de 0x2C desde o início do TEB. Esse comportamento é específico do Intel x86.

  3. O carregador atribui o valor do índice TLS ao local indicado pelo campo Address of Index.

  4. O código executável recupera o índice TLS e também o local da matriz TLS.

  5. O código usa o índice TLS e o local da matriz TLS (multiplicando o índice por 4 e usando-o como um deslocamento para a matriz) para obter o endereço da área de dados TLS para o programa e módulo fornecidos. Cada thread tem sua própria área de dados TLS, mas isso é transparente para o programa, que não precisa saber como os dados são alocados para threads individuais.

  6. Um objeto de dados TLS individual é acessado como um deslocamento fixo na área de dados TLS.

A matriz TLS é uma matriz de endereços que o sistema mantém para cada thread. Cada endereço na matriz fornece a localização dos dados TLS para um determinado módulo (EXE ou DLL) dentro do programa. O índice TLS indica qual membro da matriz usar. O índice é um número (significativo apenas para o sistema) que identifica o módulo.

Diretório TLS

O diretório TLS tem o seguinte formato:

Deslocamento (PE32/PE32+) Tamanho (PE32/PE32+) Campo Descrição
0
4/8
VA inicial de dados brutos
O endereço inicial do modelo TLS. O modelo é um bloco de dados usado para inicializar dados TLS. O sistema copia todos esses dados sempre que um thread é criado, portanto, ele não deve ser corrompido. Observe que esse endereço não é um RVA; é um endereço para o qual deve haver uma realocação de base na seção .reloc.
4/8
4/8
VA final de dados brutos
O endereço do último byte do TLS, exceto para o preenchimento zero. Assim como acontece com o campo VA de início de dados brutos, este é um VA, não um RVA.
8/16
4/8
Endereço do índice
O local para receber o índice TLS, que o carregador atribui. Esse local está em uma seção de dados comum, portanto, pode receber um nome simbólico acessível ao programa.
12/24
4/8
Endereço dos retornos de chamada
O ponteiro para uma matriz de funções de retorno de chamada TLS. A matriz é terminada em nulo, portanto, se nenhuma função de retorno de chamada for suportada, esse campo apontará para 4 bytes definidos como zero. Para obter informações sobre o protótipo dessas funções, confira Funções de retorno de chamada TLS.
16/32
4
Tamanho do preenchimento zero
O tamanho em bytes do modelo, além dos dados inicializados delimitados pelos campos de VA inicial de dados brutos e VA final de dados brutos. O tamanho total do modelo deve ser igual ao tamanho total dos dados TLS no arquivo de imagem. O preenchimento zero é a quantidade de dados que vem após os dados diferentes de zero inicializados.
20/36
4
Características
Os quatro bits [23:20] descrevem informações de alinhamento. Os valores possíveis são aqueles definidos como IMAGE_SCN_ALIGN_*, que também são usados para descrever o alinhamento da seção em arquivos de objeto. Os outros 28 bits são reservados para uso futuro.

 

Funções de retorno de chamada de TLS

O programa pode fornecer uma ou mais funções de retorno de chamada TLS para dar suporte à inicialização e ao encerramento adicionais para objetos de dados TLS. Um uso típico para essa função de retorno de chamada seria chamar construtores e destruidores para objetos.

Embora normalmente não haja mais de uma função de retorno de chamada, um retorno de chamada é implementado como uma matriz para possibilitar a inclusão de funções de retorno de chamada adicionais, se desejado. Se houver mais de uma função de retorno de chamada, cada função será chamada na ordem em que seu endereço aparece na matriz. Um ponteiro nulo encerra a matriz. É perfeitamente válido ter uma lista vazia (sem suporte para retorno de chamada), caso em que a matriz de retorno de chamada tem exatamente um membro: um ponteiro nulo.

O protótipo de uma função de retorno de chamada (apontado por um ponteiro do tipo PIMAGE_TLS_CALLBACK) tem os mesmos parâmetros que uma função de ponto de entrada DLL:

typedef VOID
(NTAPI *PIMAGE_TLS_CALLBACK) (
    PVOID DllHandle,
    DWORD Reason,
    PVOID Reserved
    );

O parâmetro Reserved deve ser definido como zero. Esse parâmetro Reason pode usar os seguintes valores:

Configuração Valor Descrição
DLL_PROCESS_ATTACH
1
Um novo processo foi iniciado, incluindo o primeiro thread.
DLL_THREAD_ATTACH
2
Um thread foi criado. Essa notificação foi enviada para todos, exceto o primeiro thread.
DLL_THREAD_DETACH
3
Um thread está prestes a ser encerrado. Essa notificação foi enviada para todos, exceto o primeiro thread.
DLL_PROCESS_DETACH
0
Um processo está prestes a ser encerrado, incluindo o thread original.

 

Estrutura de configuração de carregamento (somente imagem)

A estrutura de configuração de carga (IMAGE_LOAD_CONFIG_DIRECTORY) era usada anteriormente em casos muito limitados no próprio sistema operacional Windows NT para descrever vários recursos muito difíceis ou muito grandes para descrever no cabeçalho do arquivo ou no cabeçalho opcional da imagem. As versões atuais do vinculador da Microsoft e do Windows XP e versões posteriores do Windows usam uma nova versão dessa estrutura para sistemas baseados em x86 de 32 bits que incluem a tecnologia SEH reservada. Isso fornece uma lista de manipuladores de exceção estruturados seguros que o sistema operacional usa durante a expedição de exceção. Se o endereço do manipulador residir no intervalo VA de uma imagem e estiver marcado com reconhecimento de SEH reservado (ou seja, IMAGE_DLLCHARACTERISTICS_NO_SEH estiver claro no campo DllCharacteristics do cabeçalho opcional, conforme descrito anteriormente), o manipulador deverá estar na lista de manipuladores seguros conhecidos para essa imagem. Caso contrário, o sistema operacional encerra o aplicativo. Isso ajuda a evitar o exploit "x86 exception handler hijacking" que foi usado no passado para assumir o controle do sistema operacional.

O vinculador da Microsoft fornece automaticamente uma estrutura de configuração de carga padrão para incluir os dados SEH reservados. Se o código do usuário já fornecer uma estrutura de configuração de carga, ele deverá incluir os novos campos SEH reservados. Caso contrário, o vinculador não poderá incluir os dados SEH reservados, e a imagem não será marcada como contendo SEH reservada.

Diretório de configuração de carregamento

A entrada do diretório de dados para uma estrutura de configuração de carga SEH pré-reservada deve especificar um tamanho específico da estrutura de configuração de carga, pois o carregador do sistema operacional sempre espera que seja um determinado valor. Nesse sentido, o tamanho é realmente apenas uma verificação de versão. Para compatibilidade com o Windows XP e versões anteriores do Windows, o tamanho deve ser 64 para imagens x86.

Layout de configuração de carregamento

A estrutura de configuração de carga tem o seguinte layout para arquivos PE de 32 bits e 64 bits:

Deslocamento Tamanho Campo Descrição
0
4
Características
Sinalizadores que indicam atributos do arquivo, atualmente não utilizados.
4
4
TimeDateStamp
Valor de carimbo de data e hora. O valor é representado no número de segundos decorridos desde a meia-noite (00:00:00), 1º de janeiro de 1970, UTC (Tempo Universal Coordenado), de acordo com o relógio do sistema. O carimbo de data/hora pode ser impresso usando a função de tempo CRT (tempo de execução C).
8
2
MajorVersion
Número de versão principal.
10
2
MinorVersion
Número de versão secundária.
12
4
GlobalFlagsClear
O carregador global sinaliza para limpar esse processo à medida que o carregador inicia o processo.
16
4
GlobalFlagsSet
O carregador global sinaliza para definir esse processo à medida que o carregador inicia o processo.
20
4
CriticalSectionDefaultTimeout
O valor de tempo limite padrão a ser usado para as seções críticas desse processo que são abandonadas.
24
4/8
DeCommitFreeBlockThreshold
Memória que deve ser liberada antes de ser devolvida ao sistema, em bytes.
28/32
4/8
DeCommitTotalFreeThreshold
Quantidade total de memória livre, em bytes.
32/40
4/8
LockPrefixTable
[Somente x86] O VA de uma lista de endereços em que o prefixo LOCK é usado para que eles possam ser substituídos por NOP em máquinas com um único processador.
36/48
4/8
MaximumAllocationSize
Tamanho máximo de alocação, em bytes.
40/56
4/8
VirtualMemoryThreshold
Tamanho máximo da memória virtual, em bytes.
44/64
4/8
ProcessAffinityMask
Definir esse campo como um valor diferente de zero é equivalente a chamar SetProcessAffinityMask com esse valor durante a inicialização do processo (somente .exe)
48/72
4
ProcessHeapFlags
Sinalizadores de heap de processo que correspondem ao primeiro argumento da função HeapCreate. Esses sinalizadores se aplicam ao heap do processo criado durante a inicialização do processo.
52/76
2
CSDVersion
O identificador de versão do service pack.
54/78
2
DependentLoadFlags
Os sinalizadores de carregamento padrão usados quando o sistema operacional resolve as importações vinculadas estaticamente de um módulo.
56/80
4/8
EditList
Reservado para uso pelo sistema.
60/88
4/8
SecurityCookie
Um ponteiro para um cookie usado pela implementação do Visual C++ ou GS.
64/96
4/8
SEHandlerTable
[Somente x86] O VA da tabela classificada de RVAs de cada manipulador SE válido e exclusivo na imagem.
68/104
4/8
SEHandlerCount
[Somente x86] A contagem de manipuladores exclusivos na tabela.
72/112
4/8
GuardCFCheckFunctionPointer
O VA onde o ponteiro da função de verificação da proteção de fluxo de controle está armazenado.
76/120
4/8
GuardCFDispatchFunctionPointer
O VA onde o ponteiro da função de despacho da proteção de fluxo de controle está armazenado.
80/128
4/8
GuardCFFunctionTable
O VA da tabela classificada de RVAs de cada função de proteção de fluxo de controle na imagem.
84/136
4/8
GuardCFFunctionCount
A contagem de RVAs exclusivos na tabela acima.
88/144
4
GuardFlags
Sinalizadores relacionados à proteção de fluxo de controle.
92/148
12
CodeIntegrity
Informações de integridade do código.
104/160
4/8
GuardAddressTakenIatEntryTable
O VA em que o endereço da proteção de fluxo de controle obtido na tabela IAT é armazenado.
108/168
4/8
GuardAddressTakenIatEntryCount
A contagem de RVAs exclusivos na tabela acima.
112/176
4/8
GuardLongJumpTargetTable
O VA em que a tabela de destino de salto em distância da proteção de fluxo de controle está armazenada.
116/184
4/8
GuardLongJumpTargetCount
A contagem de RVAs exclusivos na tabela acima.

 

O campo GuardFlags contém uma combinação de um ou mais dos seguintes sinalizadores e subcampos:

  • O módulo executa verificações de integridade do fluxo de controle usando o suporte fornecido pelo sistema.

    #define IMAGE_GUARD_CF_INSTRUMENTED 0x00000100

  • O módulo executa verificações de fluxo de controle e integridade de gravação.

    #define IMAGE_GUARD_CFW_INSTRUMENTED 0x00000200

  • O módulo contém metadados de destino de fluxo de controle válidos.

    #define IMAGE_GUARD_CF_FUNCTION_TABLE_PRESENT 0x00000400

  • O módulo não faz uso do cookie de segurança /GS.

    #define IMAGE_GUARD_SECURITY_COOKIE_UNUSED 0x00000800

  • O módulo suporta IAT de carregamento de atraso somente leitura.

    #define IMAGE_GUARD_PROTECT_DELAYLOAD_IAT 0x00001000

  • Delayload em sua própria seção .didat (sem mais nada nela) que pode ser protegida novamente.

    #define IMAGE_GUARD_DELAYLOAD_IAT_IN_ITS_OWN_SECTION 0x00002000

  • O módulo contém informações de exportação suprimidas. Isso também infere que a tabela IAT de endereço obtido também está presente na configuração de carregamento.

    #define IMAGE_GUARD_CF_EXPORT_SUPPRESSION_INFO_PRESENT 0x00004000

  • Módulo permite a supressão de exportações.

    #define IMAGE_GUARD_CF_ENABLE_EXPORT_SUPPRESSION 0x00008000

  • O módulo contém informações de destino longjmp.

    #define IMAGE_GUARD_CF_LONGJUMP_TABLE_PRESENT 0x00010000

  • Máscara para o subcampo que contém o passo de entradas da tabela de funções da proteção de fluxo de controle (ou seja, a contagem adicional de bytes por entrada da tabela).

    #define IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_MASK 0xF0000000

Além disso, o cabeçalho winnt.h do SDK do Windows define essa macro para a quantidade de bits para deslocar para a direita o valor GuardFlags e justificar à direita a etapa da tabela de funções da proteção de fluxo de controle:

#define IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_SHIFT 28

Seção .rsrc

Os recursos são indexados por uma estrutura de árvore classificada por binários de vários níveis. O design geral pode incorporar 2**31 níveis. Por convenção, no entanto, o Windows usa três níveis:

Tipo, nome e idioma

Uma série de tabelas de diretório de recursos relaciona todos os níveis da seguinte maneira: cada tabela de diretório é seguida por uma série de entradas de diretório que fornecem o nome ou identificador (ID) para esse nível (nível de tipo, nome ou idioma) e um endereço de uma descrição de dados ou outra tabela de diretório. Se o endereço apontar para uma descrição de dados, os dados serão uma folha na árvore. Se o endereço apontar para outra tabela de diretórios, essa tabela listará as entradas de diretório no próximo nível abaixo.

As IDs de tipo, nome e idioma de uma folha são determinadas pelo caminho percorrido pelas tabelas de diretório para chegar à folha. A primeira tabela determina a ID do tipo, a segunda tabela (apontada pela entrada do diretório na primeira tabela) determina a ID do nome e a terceira tabela determina a ID do idioma.

A estrutura geral da seção .rsrc é:

Dados Descrição
Tabelas de diretório de recursos (e entradas de diretório de recursos)
Uma série de tabelas, uma para cada grupo de nós na árvore. Todos os nós de nível superior (Tipo) são listados na primeira tabela. As entradas nesta tabela apontam para tabelas de segundo nível. Cada árvore de segundo nível tem a mesma ID de tipo, mas IDs de nome diferentes. As árvores de terceiro nível têm as mesmas IDs de tipo e nome, mas IDs de idioma diferentes.
Cada tabela individual é imediatamente seguida por entradas de diretório, nas quais cada entrada tem um nome ou identificador numérico e um ponteiro para uma descrição de dados ou uma tabela no próximo nível inferior.
Cadeias de caracteres do diretório de recursos
Cadeias de caracteres Unicode alinhadas a dois bytes, que servem como dados de cadeia de caracteres apontados por entradas de diretório.
Descrição de dados de recursos
Uma matriz de registros, apontada por tabelas, que descreve o tamanho real e a localização dos dados do recurso. Esses registros são as folhas na árvore de descrição do recurso.
Dados do recurso
Dados brutos da seção de recursos. As informações de tamanho e localização no campo de descrições de dados de recursos delimitam as regiões individuais dos dados de recursos.

 

Tabela de diretório de recursos

Cada tabela de diretório de recursos tem o seguinte formato. Essa estrutura de dados deve ser considerada o cabeçalho de uma tabela, pois a tabela na verdade consiste em entradas de diretório (descritas na seção 6.9.2, "Entradas de diretório de recursos") e esta estrutura:

Deslocamento Tamanho Campo Descrição
0
4
Características
Sinalizadores de recursos. Este campo é reservado para uso futuro. No momento, está definido como zero.
4
4
Carimbo de data/hora
A hora em que os dados do recurso foram criados pelo compilador de recursos.
8
2
Versão principal
O número da versão principal, definido pelo usuário.
10
2
Versão secundária
O número da versão secundária, definido pelo usuário.
12
2
Número de entradas de nome
O número de entradas de diretório imediatamente após a tabela que usam cadeias de caracteres para identificar entradas de Tipo, Nome ou Idioma (dependendo do nível da tabela).
14
2
Número de entradas de ID
O número de entradas de diretório imediatamente após as entradas de Nome que usam IDs numéricas para entradas de Tipo, Nome ou Idioma.

 

Entradas de diretório de recursos

As entradas de diretório compõem as linhas de uma tabela. Cada entrada de diretório de recursos tem o seguinte formato. Se a entrada é de Nome ou ID e é indicada pela tabela de diretório de recursos, que indica quantas entradas de Nome e ID a seguem (lembre-se de que todas as entradas de Nome precedem todas as entradas de ID da tabela). Todas as entradas da tabela são classificadas em ordem crescente: as entradas Nome por cadeia de caracteres que diferencia maiúsculas de minúsculas e as entradas de ID por valor numérico. Os deslocamentos são relativos ao endereço no IMAGE_DIRECTORY_ENTRY_RESOURCE DataDirectory. Confira Emparelhamento dentro do PE: um tour pelo formato de arquivo executável portátil Win32 para obter mais informações.

Deslocamento Tamanho Campo Descrição
0
4
Deslocamento de nome
O deslocamento de uma cadeia de caracteres que fornece a entrada Tipo, Nome ou ID de idioma, dependendo do nível da tabela.
0
4
ID de inteiro
Um inteiro de 32 bits que identifica a entrada Tipo, Nome ou ID de idioma.
4
4
Deslocamento de entrada de dados
0 bits altos. Endereço de uma entrada de dados de recurso (uma folha).
4
4
Deslocamento de subdiretório
1 bit alto. Os 31 bits inferiores são o endereço de outra tabela de diretório de recursos (o próximo nível abaixo).

 

Cadeia de caracteres do diretório de recursos

A área de cadeia de caracteres do diretório de recursos consiste em cadeias de caracteres Unicode, que são alinhadas a palavras. Essas cadeias de caracteres são armazenadas juntas após a última entrada do Diretório de recursos e antes da primeira entrada de Dados do recurso. Isso minimiza o impacto dessas cadeias de caracteres de tamanho variável no alinhamento das entradas de diretório de tamanho fixo. Cada cadeia de caracteres de diretório de recursos tem o seguinte formato:

Deslocamento Tamanho Campo Descrição
0
2
Comprimento
O tamanho da cadeia de caracteres, sem incluir o campo de tamanho em si.
2
variável
Cadeia de caracteres Unicode
Os dados de cadeia de caracteres Unicode de tamanho variável, alinhados a palavras.

 

Entrada de dados de recurso

Cada entrada de dados do recurso descreve uma unidade real de dados brutos na área de dados do recurso. Uma entrada de dados do recurso tem o seguinte formato:

Deslocamento Tamanho Campo Descrição
0
4
RVA de dados
O endereço de uma unidade de dados de recurso na área de dados do recurso.
4
4
Tamanho
O tamanho, em bytes, dos dados do recurso apontados pelo campo RVA de dados.
8
4
Codepage
A página de código usada para decodificar valores de ponto de código nos dados do recurso. Normalmente, a página de código seria a página de código Unicode.
12
4
Reservado, deve ser 0.

 

Seção .cormeta (somente objeto)

Os metadados CLR são armazenados nesta seção. Ele é usado para indicar que o arquivo de objeto contém código gerenciado. O formato dos metadados não está documentado, mas pode ser entregue às interfaces CLR para manipulação de metadados.

Seção .sxdata

Os manipuladores de exceção válidos de um objeto são listados na seção .sxdata desse objeto. A seção está marcada como IMAGE_SCN_LNK_INFO. Ele contém o índice de símbolo COFF de cada manipulador válido, usando 4 bytes por índice.

Além disso, o compilador marca um objeto COFF como SEH registrado emitindo o símbolo absoluto "@feat.00" com o LSB do campo de valor definido como 1. Um objeto COFF sem manipuladores SEH registrados teria o símbolo "@feat.00", mas nenhuma seção .sxdata.

Formato de arquivo (biblioteca)

O formato de arquivo COFF fornece um mecanismo padrão para armazenar coleções de arquivos de objeto. Essas coleções são comumente chamadas de bibliotecas na documentação de programação.

Os primeiros 8 bytes de um arquivo compactado consistem na assinatura do arquivo. O restante do arquivo consiste em uma série de membros do arquivo, como segue:

  • O primeiro e o segundo membros são "membros vinculadores". Cada um desses membros tem seu próprio formato, conforme descrito na seção Tipo de nome de importação. Normalmente, um vinculador coloca informações nesses membros do arquivo. Os membros do vinculador contêm o diretório do arquivo.

  • O terceiro membro é o membro "longnames". Esse membro opcional consiste em uma série de cadeias de caracteres ASCII terminadas em nulo, nas quais cada cadeia de caracteres é o nome de outro membro do arquivo.

  • O restante do arquivo consiste em membros padrão (arquivo-objeto). Cada um desses membros contém o conteúdo de um arquivo de objeto em sua totalidade.

Um cabeçalho de membro de arquivo precede cada membro. A lista a seguir mostra a estrutura geral de um arquivo:

Assinatura :"!<arch>\n"
Cabeçalho
1º membro do vinculador
Cabeçalho
2º membro do vinculador
Cabeçalho
Membro longnames
Cabeçalho
Conteúdo do arquivo OBJ 1
(Formato COFF)
Cabeçalho
Conteúdo do arquivo OBJ 2
(Formato COFF)

...

Cabeçalho
Conteúdo do arquivo OBJ N
(Formato COFF)

Assinatura de arquivo

A assinatura do arquivo identifica o tipo de arquivo. Qualquer utilitário (por exemplo, um vinculador) que usa um arquivo como entrada pode verificar o tipo de arquivo lendo essa assinatura. A assinatura consiste nos seguintes caracteres ASCII, nos quais cada caractere abaixo é representado literalmente, exceto o caractere de nova linha (\n):

!<arch>\n

O cabeçalho winnt.h do SDK do Windows define as seguintes macros:

#define IMAGE_ARCHIVE_START_SIZE             8
#define IMAGE_ARCHIVE_START                  "!<arch>\n"
#define IMAGE_ARCHIVE_END                    "`\n"
#define IMAGE_ARCHIVE_PAD                    "\n"
#define IMAGE_ARCHIVE_LINKER_MEMBER          "/               "
#define IMAGE_ARCHIVE_LONGNAMES_MEMBER       "//              "
#define IMAGE_ARCHIVE_HYBRIDMAP_MEMBER       "/<HYBRIDMAP>/   "

Cabeçalhos de membro de arquivo

Cada membro (vinculador, longnames ou membro do arquivo de objeto) é precedido por um cabeçalho. Um cabeçalho de membro de arquivo tem o seguinte formato, no qual cada campo é uma cadeia de caracteres de texto ASCII que é justificada à esquerda e preenchida com espaços no final do campo. Não há nenhum caractere nulo de terminação em nenhum desses campos.

Each member header starts on the first even address after the end of the previous archive member, one byte '\n' (IMAGE_ARCHIVE_PAD) may be inserted after an archive member to make the following member start on an even address.

Deslocamento Tamanho Campo Descrição
0
16
Name
O nome do membro do arquivo, com uma barra (/) anexada para terminar o nome. Se o primeiro caractere for uma barra, o nome terá uma interpretação especial, conforme descrito na tabela a seguir.
16
12
Data
A data e a hora em que o membro do arquivo foi criado: esta é a representação decimal ASCII do número de segundos desde 1/1/1970 UCT.
28
6
ID do usuário
Uma representação decimal ASCII do ID do usuário. Esse campo não contém um valor significativo em plataformas Windows porque as ferramentas da Microsoft emitem todos os espaços em branco.
34
6
ID do grupo
Uma representação decimal ASCII do ID do grupo. Esse campo não contém um valor significativo em plataformas Windows porque as ferramentas da Microsoft emitem todos os espaços em branco.
40
8
Modo
Uma representação octal ASCII do modo de arquivo do membro. Esse é o valor ST_MODE da função de tempo de execução C _wstat.
48
10
Tamanho
Uma representação decimal ASCII do tamanho total do membro do arquivo, não incluindo o tamanho do cabeçalho.
58
2
Fim do cabeçalho
Os dois bytes (0x60 0x0A) na cadeia de caracteres C "'\n" (IMAGE_ARCHIVE_END).

O campo Name tem um dos formatos mostrados na tabela a seguir. Como mencionado anteriormente, cada uma dessas cadeias de caracteres é justificada à esquerda e preenchida com espaços à direita dentro de um campo de 16 bytes:

Conteúdo do campo Name Descrição
name/
O nome do membro de arquivo.
/
O membro do arquivo é um dos dois membros do vinculador. Ambos os membros do vinculador têm esse nome.
//
O membro do arquivo é o membro longnames, que consiste em uma série de cadeias de caracteres ASCII terminadas em nulo. O membro longnames é o terceiro membro do arquivo e é opcional.
/n
O nome do membro do arquivo está localizado no deslocamento n dentro do membro longnames. O número n é a representação decimal do deslocamento. Por exemplo: "/26" indica que o nome do membro do arquivo está localizado 26 bytes além do início do conteúdo do membro longnames.

 

Primeiro membro do vinculador

O nome do primeiro membro do vinculador é "/" (IMAGE_ARCHIVE_LINKER_MEMBER). O primeiro membro do vinculador é incluído para compatibilidade com versões anteriores. Não é usado por vinculadores atuais, mas seu formato deve estar correto. Esse membro do vinculador fornece um diretório de nomes de símbolos, assim como o segundo membro do vinculador. Para cada símbolo, as informações indicam onde localizar o membro do arquivo que contém o símbolo.

O primeiro membro do vinculador tem o formato a seguir. Essas informações aparecem após o cabeçalho:

Deslocamento Tamanho Campo Descrição
0
4
Número de símbolos
Tipo longo sem sinal, que contém o número de símbolos indexados. Esse número é armazenado no formato big-endian. Cada membro do arquivo de objeto normalmente define um ou mais símbolos externos.
4
4 * n
Deslocamentos
Uma matriz de deslocamentos de arquivo para arquivar cabeçalhos de membros, em que n é igual ao campo de número de símbolos. Cada número na matriz é um tipo longo sem sinal armazenado no formato big-endian. Para cada símbolo nomeado na tabela de sequências, o elemento correspondente na matriz de deslocamentos fornece o local do membro do arquivo que contém o símbolo.
*
*
Tabela de cadeira de caracteres
Uma série de cadeias de caracteres terminadas em nulo que nomeiam todos os símbolos no diretório. Cada cadeia de caracteres começa imediatamente após o caractere nulo na cadeia de caracteres anterior. O número de cadeias de caracteres deve ser igual ao valor do campo de número de símbolos.

 

Os elementos na matriz de deslocamentos devem ser organizados em ordem crescente. Esse fato implica que os símbolos na tabela de cadeias de caracteres devem ser organizados de acordo com a ordem dos membros do arquivo. Por exemplo, todos os símbolos no primeiro membro do arquivo de objeto teriam que ser listados antes dos símbolos no segundo arquivo de objeto.

Segundo membro do vinculador

Como o primeiro membro do vinculador, o segundo membro do vinculador tem o nome "/" (IMAGE_ARCHIVE_LINKER_MEMBER). Embora ambos os membros do vinculador forneçam um diretório de símbolos e membros de arquivo que os contêm, o segundo membro do vinculador é usado preferencialmente ao primeiro por todos os vinculadores atuais. O segundo membro do vinculador inclui nomes de símbolos em ordem lexical, o que permite uma pesquisa mais rápida por nome.

O segundo membro tem o seguinte formato. Essas informações aparecem após o cabeçalho:

Deslocamento Tamanho Campo Descrição
0
4
Número de membros
Um tipo longo não assinado que contém o número de membros do arquivo.
4
4 * m
Deslocamentos
Uma matriz de deslocamentos de arquivo para arquivar cabeçalhos de membros, organizados em ordem crescente. Cada deslocamento é um tipo longo sem sinal. O número m é igual ao valor do campo de número de membros.
*
4
Número de símbolos
Um tipo longo sem sinal, que contém o número de símbolos indexados. Cada membro do arquivo de objeto normalmente define um ou mais símbolos externos.
*
2 * n
Índices
Uma matriz de índices baseados em 1 (abreviado sem sinal) que mapeia nomes de símbolos para deslocamentos de membros de arquivo. O número n é igual ao campo de número de símbolos. Para cada símbolo nomeado na tabela de strings, o elemento correspondente na matriz de Índices fornece um índice na matriz de deslocamentos. A matriz de deslocamentos, por sua vez, fornece o local do membro do arquivo que contém o símbolo.
*
*
Tabela de cadeira de caracteres
Uma série de cadeias de caracteres terminadas em nulo que nomeiam todos os símbolos no diretório. Cada cadeia de caracteres começa imediatamente após o byte nulo na cadeia de caracteres anterior. O número de cadeias de caracteres deve ser igual ao valor do campo de número de símbolos. Esta tabela lista todos os nomes de símbolos em ordem lexical crescente.

 

Membro longnames

O nome do membro longnames é "//" (IMAGE_ARCHIVE_LONGNAMES_MEMBER). O membro longnames é uma série de sequências de nomes de membros do arquivo. Um nome aparece aqui somente quando não há espaço suficiente no campo Name (16 bytes). O membro longnames é opcional. Ele pode estar vazio com apenas um cabeçalho ou pode estar completamente ausente, sem nem mesmo um cabeçalho.

As cadeias de caracteres são terminadas em nulo. Cada cadeia de caracteres começa imediatamente após o byte nulo na cadeia de caracteres anterior.

Formato de biblioteca de importação

As bibliotecas de importação tradicionais, ou seja, as bibliotecas que descrevem as exportações de uma imagem para uso por outra, normalmente seguem o layout descrito na seção 7, Formato Formato de arquivo (biblioteca). A principal diferença é que os membros da biblioteca de importação contêm arquivos de pseudo-objeto em vez de arquivos reais, em que cada membro inclui as contribuições de seção necessárias para criar as tabelas de importação descritas na seção 6.4, Seção .idata O vinculador gera esse arquivo durante a criação do aplicativo de exportação.

As contribuições de seção para uma importação podem ser inferidas a partir de um pequeno conjunto de informações. O vinculador pode gerar as informações completas e detalhadas na biblioteca de importação para cada membro no momento da criação da biblioteca ou gravar apenas as informações canônicas na biblioteca e permitir que o aplicativo que as usa posteriormente gere os dados necessários em tempo real.

Em uma biblioteca de importação com o formato longo, um único membro contém as seguintes informações:

  • Cabeçalho do membro do arquivo
  • Cabeçalho do arquivo
  • Cabeçalhos da seção
  • Dados que correspondem a cada um dos cabeçalhos de seção
  • Tabela de símbolos COFF
  • Cadeias de caracteres

Em contraposição, uma biblioteca de importação curta é escrita da seguinte maneira:

  • Cabeçalho do membro do arquivo
  • Cabeçalho de importação
  • Cadeia de caracteres de nome de importação terminada em nulo
  • Cadeia de caracteres de nome DLL terminada em nulo

Essa informação é suficiente para reconstruir com precisão todo o conteúdo do membro no momento de seu uso.

Cabeçalho de importação

O cabeçalho de importação contém os seguintes campos e deslocamentos:

Deslocamento Tamanho Campo Descrição
0
2
Sig1
Deve ser IMAGE_FILE_MACHINE_UNKNOWN. Para obter mais informações, confira Tipos de computador.
2
2
Sig2
Deve ser 0xFFFF.
4
2
Versão
A versão da estrutura.
6
2
Máquina
O número que identifica o tipo de computador de destino. Para obter mais informações, confira Tipos de computador.
8
4
Carimbo de data e hora
A hora e a data em que o arquivo foi criado.
12
4
Tamanho dos dados
O tamanho das cadeias de caracteres que seguem o cabeçalho.
16
2
Ordinal/Dica
O ordinal ou a dica para a importação, determinado pelo valor no campo Name Type.
18
2 bits
Tipo
O tipo de importação. Para obter valores e descrições específicos, consulte Tipo de importação.
3 bits
Tipo de nome
O tipo de nome de importação Para obter mais informações, confira Tipo de nome de importação.
11 bits
Reservado
Reservado, deve ser 0.

 

Essa estrutura é seguida por duas cadeias de caracteres terminadas em nulo que descrevem o nome do símbolo importado e a DLL da qual ele veio.

Tipo de importação

Os valores a seguir são definidos para o campo Type no cabeçalho de importação:

Constante Valor Descrição
IMPORT_OBJECT_CODE
0
Código executável.
IMPORT_OBJECT_DATA
1
Dados.
IMPORT_OBJECT_CONST
2
Especificado como CONST no arquivo .def.

Esses valores são usados para determinar quais contribuições de seção deverão ser geradas pela ferramenta que usa a biblioteca se ela precisar acessar esses dados.

Tipo de nome de importação

O nome do símbolo de importação terminado em nulo segue imediatamente o cabeçalho de importação associado. Os valores a seguir são definidos para o campo Name Type no cabeçalho de importação. Eles indicam como o nome deve ser usado para gerar os símbolos corretos que representam a importação:

Constante Valor Descrição
IMPORT_OBJECT_ORDINAL 0 A importação é por ordinal. Isso indica que o valor no campo Ordinal/Hint do cabeçalho de importação é o ordinal da importação. Se essa constante não for especificada, o campo Ordinal/Hint sempre deverá ser interpretado como a dica da importação.
IMPORT_OBJECT_NAME 1 O nome de importação é idêntico ao nome do símbolo público.
IMPORT_OBJECT_NAME_NOPREFIX 2 O nome de importação é o nome do símbolo público, mas ignorando o ?, @ ou, opcionalmente, _.
IMPORT_OBJECT_NAME_UNDECORATE 3 O nome de importação é o nome do símbolo público, mas ignorando o ?, @ ou, opcionalmente, _, à esquerda e truncando no primeiro @.

Apêndice A: calcular o hash de imagem PE do Authenticode

Espera-se que vários certificados de atributo sejam usados para verificar a integridade das imagens. No entanto, o mais comum é a assinatura Authenticode. Uma assinatura Authenticode pode ser usada para verificar se as seções relevantes de um arquivo de imagem PE não foram alteradas de forma alguma em relação à forma original do arquivo. Para realizar essa tarefa, as assinaturas de Authenticode contêm um elemento chamado hash de imagem PE

O que é um hash de imagem PE do Authenticode?

O hash de imagem PE do Authenticode, ou simplesmente hash de arquivo, é semelhante a uma soma de verificação de arquivo, pois produz um pequeno valor relacionado à integridade de um arquivo. Uma soma de verificação é produzida por um algoritmo simples e é usada principalmente para detectar falhas de memória. Ou seja, é usada para detectar se um bloco de memória no disco falhou e se os valores armazenados nele foram corrompidos. Um hash de arquivo é semelhante a uma soma de verificação, pois também detecta corrupção de arquivo. No entanto, ao contrário da maioria dos algoritmos de soma de verificação, é muito difícil modificar um arquivo para que ele tenha o mesmo hash de arquivo da forma original (não modificada). Ou seja, uma soma de verificação destina-se a detectar falhas simples de memória que levam à corrupção, mas um hash de arquivo pode ser usado para detectar modificações intencionais e até sutis em um arquivo, como aquelas introduzidas por vírus, hackers ou programas de cavalo de Tróia.

Em uma assinatura Authenticode, o hash do arquivo é assinado digitalmente usando uma chave privada conhecida apenas pelo signatário do arquivo. Um consumidor de software pode verificar a integridade do arquivo calculando o valor de hash do arquivo e comparando-o com o valor do hash assinado contido na assinatura digital Authenticode. Caso os hashes do arquivo não correspondam, significa que parte do arquivo coberto pelo hash da imagem PE foi modificada.

O que é coberto em um hash de imagem PE do Authenticode?

Não é possível ou desejável incluir todos os dados do arquivo de imagem no cálculo do hash da imagem PE. Às vezes, ele simplesmente apresenta características indesejáveis (por exemplo, as informações de depuração não podem ser removidas de arquivos divulgados publicamente); às vezes, é simplesmente impossível. Por exemplo, não é possível incluir todas as informações em um arquivo de imagem em uma assinatura Authenticode, inserir a assinatura Authenticode que contém esse hash de imagem PE na imagem PE e, posteriormente, gerar um hash de imagem PE idêntico incluindo todos os dados do arquivo de imagem no cálculo novamente. Isso porque o arquivo agora contém a assinatura Authenticode que não estava originalmente presente.

Processo para gerar o hash de imagem PE do Authenticode

Esta seção descreve como um hash de imagem PE é calculado e quais partes da imagem PE podem ser modificadas sem invalidar a assinatura Authenticode.

Nota

O hash de imagem PE para um arquivo específico pode ser incluído em um arquivo de catálogo separado sem incluir um certificado de atributo no arquivo com hash. Isso é relevante, pois torna-se possível invalidar o hash da imagem PE em um arquivo de catálogo assinado por Authenticode modificando uma imagem PE que na verdade não contém uma assinatura do Authenticode.

Todos os dados nas seções da imagem PE especificadas na tabela de seções são hash em sua totalidade, exceto nos seguintes intervalos de exclusão:

  • O campo CheckSum do arquivo dos campos específicos do Windows do cabeçalho opcional. Essa soma de verificação inclui todo o arquivo (incluindo certificados de atributo no arquivo). Em todos os casos prováveis, a soma de verificação será diferente do valor original após inserir a assinatura Authenticode.

  • Informações relacionadas a certificados de atributo. As áreas da imagem PE relacionadas à assinatura do Authenticode não são incluídas no cálculo do hash da imagem PE, pois as assinaturas do Authenticode podem ser adicionadas ou removidas de uma imagem sem afetar a integridade geral da imagem. Isso não é um problema, pois há cenários de usuário que dependem de uma nova assinatura de imagens PE ou da adição de um carimbo de data/hora. O Authenticode exclui as seguintes informações do cálculo de hash:

    • O campo Certificate Table dos diretórios de dados de cabeçalho opcionais.

    • A tabela de certificados e os certificados correspondentes que são apontados pelo campo Certificate Table listado imediatamente acima.

    Para calcular o hash da imagem PE, o Authenticode ordena as seções especificadas na tabela de seções por intervalo de endereços e faz o hash da sequência resultante de bytes, passando pelos intervalos de exclusão.

  • Informações passadas do final da última seção. A área após a última seção (definida pelo deslocamento mais alto) não é hash. Essa área geralmente contém informações de depuração. As informações de depuração geralmente podem ser consideradas consultivas para depuradores; isso não afeta a integridade real do programa executável. É literalmente possível remover informações de depuração de uma imagem após a entrega de um produto e não afetar a funcionalidade do programa. Na verdade, isso às vezes é feito como uma medida de economia de disco. Vale a pena observar que as informações de depuração contidas nas seções especificadas da imagem PE não podem ser removidas sem invalidar a assinatura do Authenticode.

Você pode usar as ferramentas makecert e signtool fornecidas no SDK da Plataforma Windows para experimentar a criação e a verificação de assinaturas Authenticode. Para obter mais informações, confira Referências abaixo.

Referências

Downloads e ferramentas para Windows (inclui o SDK do Windows)

Criar, exibir e gerenciar certificados

Passo a passo da assinatura de código no modo kernel (.doc)

SignTool

Formato de assinatura executável portátil da tecnologia Windows Authenticode (.docx)

Funções de ImageHlp