Formato PE

Esta especificação descreve a estrutura de arquivos executáveis (imagem) e arquivos de objeto sob a família Windows de sistemas operacionais. Esses arquivos são referidos como arquivos executáveis portáteis (PE) e COFF (Common Object File Format), respectivamente.

Observação

Este documento é fornecido para ajudar no desenvolvimento de ferramentas e aplicativos para Windows, mas não é garantido que seja uma especificação completa em todos os aspectos. A Microsoft reserva-se o direito de alterar este documento sem aviso prévio.

Esta revisão da especificação Microsoft Portable Executable and Common Object File Format 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 referidos como arquivos executáveis portáteis (PE) e COFF (Common Object File Format), respectivamente. O nome "Portable Executable" refere-se ao fato de que o formato não é específico da arquitetura.

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

Nome Descrição
certificado de atributo
Um certificado usado para associar instruções verificáveis a uma imagem. Várias declarações verificáveis diferentes podem ser associadas a um arquivo; Um dos mais úteis é uma declaração de um fabricante de software que indica qual deve ser o resumo da mensagem da imagem. Um resumo de mensagem é semelhante a uma soma de verificação, exceto que é extremamente difícil de falsificar. Portanto, é muito difícil modificar um arquivo para ter o mesmo resumo de mensagem que o arquivo original. A declaração pode ser verificada como sendo feita pelo fabricante usando esquemas de criptografia de chave pública ou privada. Este documento descreve detalhes sobre certificados de atributo que não permitam sua inserção em arquivos de imagem.
carimbo de data/hora
Um carimbo que é usado para diferentes finalidades 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, consulte a descrição de IMAGE_DEBUG_TYPE_REPRO em Debug Type. Se o valor do carimbo for 0 ou 0xFFFFFFFF, ele não representará 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, esta é uma posição dentro do arquivo como armazenado no disco.
Vinculador
Uma referência ao vinculador fornecido com o Microsoft Visual Studio.
arquivo de objeto
Um arquivo que é dado 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 qualquer 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 os consumidores devem ignorar o campo.
Endereço virtual relativo (RVA)
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 do 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 uma realocação é aplicada posteriormente durante a vinculação. Para simplificar, um compilador deve apenas definir o primeiro RVA em cada seção como zero.
de seção
A unidade básica de código ou dados dentro de um arquivo PE ou COFF. Por exemplo, todo o código em um arquivo de objeto pode ser combinado dentro de 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 arquivos, mas o vinculador é capaz de 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 contíguamente. Além disso, um arquivo de imagem pode conter várias seções, como .tls ou .reloc , que têm finalidades especiais.
Endereço Virtual (VA)
O mesmo que RVA, exceto que o endereço base do arquivo de imagem não é subtraído. O endereço é chamado de VA porque o Windows cria um espaço VA distinto para cada processo, independente da memória física. Para quase todos os efeitos, um AV 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 em seu local preferido.

Visão geral

A lista a seguir descreve o formato executável do Microsoft PE, 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 pouco antes do cabeçalho PE é a seção MS-DOS 2.0 e é usada apenas para compatibilidade com MS-DOS.

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

  • unused

  • Identificador OEM

    Informações do OEM

    Deslocamento para cabeçalho PE

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

  • unused

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

  • Cabeçalhos de seção

  • Páginas de Imagens:

    Informações de importação

    Informações de exportação

    Remanejamentos de base

    informações do recurso

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

  • Cabeçalho COFF da Microsoft

  • Cabeçalhos de seção

  • Dados brutos:

    código

    data

    informações de depuração

    Deslocalizaçõ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. Em ambos os casos, os cabeçalhos de arquivo são seguidos imediatamente por cabeçalhos de seção.

Stub do MS-DOS (somente imagem)

O stub do MS-DOS é um aplicativo válido que é executado em 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 arquivo deslocado para a assinatura PE. Essas informações permitem que o Windows execute corretamente o arquivo de imagem, mesmo que ele 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 deslocamento 0x3c, é uma assinatura de 4 bytes que identifica o arquivo como um arquivo de imagem de 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 seguinte formato. Observe que o carregador do Windows limita o número de seções a 96.

Compensação Tamanho Campo Descrição
0
2
Máquina
O número que identifica o tipo de máquina de destino. Para obter mais informações, consulte Tipos de máquina.
2
2
Número deSeções
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 baixos do número de segundos desde 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 se nenhuma tabela de símbolos COFF estiver presente. Esse valor deve ser zero para uma imagem porque as informações de depuração COFF foram preteridas.
12
4
NúmeroDeSímbolos
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 para uma imagem porque 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 de objeto. Esse valor deve ser zero para um arquivo-objeto. Para obter uma descrição do formato de cabeçalho, consulte Cabeçalho opcional (somente imagem).
18
2
Características
Os sinalizadores que indicam os atributos do arquivo. Para obter valores de sinalizador específicos, consulte Características.

Tipos de Máquinas

O campo Computador tem um dos seguintes valores, que especificam o tipo de CPU. Um arquivo de imagem pode ser executado somente na máquina especificada ou em um sistema que emula a máquina especificada.

Constante Valor Descrição
IMAGE_FILE_MACHINE_UNKNOWN
0x0
Presume-se que o conteúdo deste campo seja aplicável 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
BRAÇO pequeno endian
IMAGE_FILE_MACHINE_ARM64
0xaa64
ARM64 pequeno endian
IMAGE_FILE_MACHINE_ARMNT
0x1c4
ARM Polegar-2 pequeno endian
IMAGE_FILE_MACHINE_AXP64
0x284
AXP 64 (O mesmo que Alpha 64)
IMAGE_FILE_MACHINE_EBC
0xebc
Código de byte EFI
IMAGE_FILE_MACHINE_I386
0x14c
Processadores Intel 386 ou posteriores 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 pequeno 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 pequeno endian
IMAGE_FILE_MACHINE_POWERPCFP
0x1f1
Power PC com suporte a ponto flutuante
IMAGE_FILE_MACHINE_R4000
0x166
MIPS pequeno endian
IMAGE_FILE_MACHINE_RISCV32
0x5032
Espaço de endereçamento RISC-V de 32 bits
IMAGE_FILE_MACHINE_RISCV64
0x5064
Espaço de endereçamento 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
Polegar
IMAGE_FILE_MACHINE_WCEMIPSV2
0x169
MIPS little-endian WCE v2

Características

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

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 em seu endereço base preferencial. 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
Apenas 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 de linha COFF foram removidos. Esse sinalizador foi preterido 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 foi preterido e deve ser zero.
IMAGE_FILE_AGGRESSIVE_WS_TRIM
0x0010
Obsoleto. Aparar agressivamente o conjunto de trabalho. Esse sinalizador foi preterido para o Windows 2000 e posterior e deve ser zero.
IMAGE_FILE_LARGE_ADDRESS_ CIENTE
0x0020
O aplicativo pode lidar com > endereços de 2 GB.
0x0040
Este sinalizador é reservado para uso futuro.
IMAGE_FILE_BYTES_REVERSED_LO
0x0080
Pequeno endian: o bit menos significativo (LSB) precede o bit mais significativo (MSB) na memória. Esse sinalizador foi preterido e deve ser zero.
IMAGE_FILE_32BIT_MACHINE
0x0100
A máquina é baseada em uma arquitetura de palavras 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 permuta.
IMAGE_FILE_NET_RUN_FROM_SWAP
0x0800
Se a imagem estiver na mídia de rede, carregue-a totalmente e copie-a para o arquivo de permuta.
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 biblioteca de vínculo dinâmico (DLL). Esses arquivos são considerados arquivos executáveis para quase todos os fins, embora eles não podem ser executados diretamente.
IMAGE_FILE_UP_SYSTEM_ONLY
0x4000
O arquivo deve ser executado somente em uma máquina uniprocessadora.
IMAGE_FILE_BYTES_REVERSED_HI
0x8000
Big endian: o MSB precede o LSB na memória. Esse sinalizador foi preterido 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 possuem. Para arquivos de imagem, esse cabeçalho é necessá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 para 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 um teste no arquivo para um diretório de dados específico não vai além de SizeOfOptionalHeader. Para obter mais informações, consulte Cabeçalho do arquivo COFF (objeto e imagem).

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

O número mágico de 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çamento de 64 bits enquanto limitam o tamanho da imagem a 2 gigabytes. Outras modificações do PE32+ são abordadas em suas respectivas seções.

O próprio cabeçalho opcional 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 do COFF, incluindo UNIX.
28/24
68/88
Campos específicos do Windows
Campos adicionais para oferecer 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, a tabela de importação e a tabela de exportação).

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

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

Compensação Tamanho Campo Descrição
0
2
Magia
O inteiro não assinado que identifica o estado do arquivo de imagem. O número mais comum é 0x10B, que o identifica como um arquivo executável normal. 0x107 identifica-o como uma imagem ROM e 0x20B identifica-o 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, se houver várias seções.
8
4
SizeOfInitializedData
O tamanho da seção de dados inicializada ou a soma de todas essas seções se houver várias seções de dados.
12
4
SizeOfUninitializedData
O tamanho da seção de dados não inicializados (BSS) ou a soma de todas essas seções se houver várias seções BSS.
16
4
AddressOfEntryPoint
O endereço do ponto de entrada relativo à base da imagem quando o arquivo executável é carregado na memória. Para imagens de programas, 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 nenhum ponto de entrada estiver presente, esse campo deve ser zero.
20
4
BaseOfCode
O endereço que é relativo à base de imagem da seção de início de código quando ele é carregado na memória.

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

Compensação Tamanho Campo Descrição
24
4
BaseOfData
O endereço relativo à base de imagens da seção de início de dados quando ele é carregado na memória.

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

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

Deslocamento (PE32/ PE32+) Tamanho (PE32/ PE32+) Campo Descrição
28/24
4/8
Base de imagens
O endereço preferencial 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 o SectionAlignment for menor que o tamanho da página da arquitetura, 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, à medida que 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, cabeçalho PE e 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 ao IMAGHELP.DLL. Os seguintes itens são verificados para validação no momento do carregamento: todos os drivers, qualquer DLL carregada no momento da inicialização e qualquer DLL que é 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, consulte Subsistema Windows.
70/70
2
DllCaracterísticas
Para obter mais informações, consulte Características da DLL mais adiante nesta especificação.
72/72
4/8
SizeOfStackReserve
O tamanho da pilha a ser reservada. Somente SizeOfStackCommit é confirmado; o restante é disponibilizado uma página de cada 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 de cada 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
CarregadeirasBandeiras
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) é 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
Janelas CE
IMAGE_SUBSYSTEM_EFI_APPLICATION
10
Um aplicativo EFI (Extensible Firmware Interface)
IMAGE_SUBSYSTEM_EFI_BOOT_ SERVICE_DRIVER
11
Um driver EFI com serviços de inicialização
IMAGE_SUBSYSTEM_EFI_RUNTIME_ MOTORISTA
12
Um driver EFI com serviços de tempo de execução
IMAGE_SUBSYSTEM_EFI_ROM
13
Uma imagem de ROM EFI
IMAGE_SUBSYSTEM_XBOX
14
XBOX
IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION
16
Aplicativo de inicialização do Windows.
Características da 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 lidar com um espaço de endereço virtual de 64 bits de alta entropia.
IMAGE_DLLCHARACTERISTICS_
DYNAMIC_BASE
0x0040
DLL pode ser realocado 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
Isole consciente, mas não isole a imagem.
IMAGE_DLLCHARACTERISTICS_ NO_SEH
0x0400
Não utiliza tratamento de exceção estruturada (SE). Nenhum manipulador SE pode ser chamado nesta imagem.
IMAGE_DLLCHARACTERISTICS_ NO_BIND
0x0800
Não vincule 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 suporta o Control Flow Guard.
IMAGE_DLLCHARACTERISTICS_ TERMINAL_SERVER_AWARE
0x8000
Reconhecimento do Terminal Server.

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 em 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, estã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 assuma que os RVAs nesta tabela apontam para o início de uma seção ou que as seções que contêm tabelas específicas têm nomes específicos.

Deslocamento (PE/PE32+) Tamanho Campo Descrição
96/112
8
Tabela de Exportação
O endereço e o tamanho da tabela de exportação. Para obter mais informações, consulte a seção .edata (somente imagem).
104/120
8
Tabela de Importação
O endereço e o tamanho da tabela de importação. Para obter mais informações, consulte A seção .idata.
112/128
8
Tabela de Recursos
O endereço e o tamanho da tabela de recursos. Para obter mais informações, consulte A seção .rsrc.
120/136
8
Tabela de Exceções
O endereço e o tamanho da tabela de exceções. Para obter mais informações, consulte A seção .pdata.
128/144
8
Tabela de Certificados
O endereço e o tamanho da tabela de certificado de atributo. Para obter mais informações, consulte A tabela de certificado de atributo (somente imagem).
136/152
8
Tabela de Realocação de Base
O endereço e o tamanho da tabela de realocação base. Para obter mais informações, consulte A seção .reloc (somente imagem).
144/160
8
Depurar
O endereço e o tamanho iniciais dos dados de depuração. Para obter mais informações, consulte A seção .debug.
152/168
8
Arquitetura
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
Tabela TLS
O endereço e o tamanho da tabela de armazenamento local de thread (TLS). Para obter mais informações, consulte A seção .tls.
176/192
8
Carregar tabela de configuração
O endereço e o tamanho da tabela de configuração de carga. Para obter mais informações, consulte A estrutura de configuração de carga (somente imagem).
184/200
8
Importação Vinculada
O endereço e o tamanho da tabela de importação acoplada.
192/208
8
IAT
O endereço e o tamanho da tabela de endereços de importação. Para obter mais informações, consulte Importar tabela de endereços.
200/216
8
Descritor de importação de atraso
O endereço e o tamanho do descritor de importação de atraso. Para obter mais informações, consulte Tabelas de importação de carga atrasada (somente imagem).
208/224
8
Cabeçalho de tempo de execução CLR
O endereço e o tamanho do cabeçalho de tempo de execução do CLR. Para obter mais informações, consulte A seção .cormeta (somente objeto).
216/232
8
Reservado, deve ser zero

A entrada 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. Como tal, o primeiro campo desta 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. Esta tabela segue 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, o local da tabela de seção é determinado calculando o local 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ção é 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 adjacentes, e devem ser um múltiplo do valor SectionAlignment no cabeçalho opcional.

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

Compensação Tamanho Campo Descrição
0
8
Nome
Uma cadeia de caracteres codificada UTF-8 de 8 bytes, acolchoada em nulo. Se a cadeia de caracteres tiver exatamente 8 caracteres, não haverá terminação nula. Para nomes mais longos, esse campo contém uma barra (/) que é seguida por uma representação ASCII de um número decimal que é um deslocamento na tabela de cadeia de caracteres. As imagens executáveis não usam uma tabela de cadeia de caracteres e não oferecem suporte a nomes de seção com mais de 8 caracteres. Nomes longos em arquivos de objeto são truncados se forem emitidos para um arquivo executável.
8
4
Tamanho Virtual:
O tamanho total da seção quando carregada na memória. Se esse valor for maior que SizeOfRawData, a seção será zero-padded. Esse campo é válido apenas para imagens executáveis e deve ser definido como zero para arquivos de objeto.
12
4
Endereço Virtual
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 que a realocação seja aplicada; Para simplificar, os compiladores devem definir isso como zero. Caso contrário, é 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 no disco (para arquivos de imagem). Para imagens executáveis, isso deve ser um múltiplo de FileAlignment do cabeçalho opcional. Se isso 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 deve 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, isso deve ser um múltiplo de FileAlignment do cabeçalho opcional. Para arquivos de objeto, o valor deve ser alinhado em um limite de 4 bytes para melhor desempenho. Quando uma seção contém apenas dados não inicializados, esse campo deve ser zero.
24
4
PointerToRelocações
O ponteiro do arquivo para o início das entradas de realocação para a seção. Isso é definido como zero para imagens executáveis ou se não houver realocações.
28
4
PointerToLinenumbers
O ponteiro do arquivo para o início das entradas de número de linha para a seção. Isso é definido como zero se não houver números de linha COFF. Esse valor deve ser zero para uma imagem porque as informações de depuração COFF foram preteridas.
32
2
NúmeroDerealocações
O número de entradas de realocação para a seção. Isso é 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 para uma imagem porque as informações de depuração COFF foram preteridas.
36
4
Características
As bandeiras que descrevem as características da seção. Para obter mais informações, consulte Sinalizadores de seção.

 

Bandeiras de seção

Os sinalizadores de seção no campo Características do cabeçalho da seção indicam 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 é obsoleto e é substituído por IMAGE_SCN_ALIGN_1BYTES. Isso é válido apenas 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_ DADOS
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 é 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 é válido apenas para arquivos de objeto.
IMAGE_SCN_LNK_COMDAT
0x00001000
A seção contém dados COMDAT. Para obter mais informações, consulte Seções COMDAT (somente objeto). Isso é válido apenas para arquivos de objeto.
IMAGE_SCN_GPREL
0x00008000
A seção contém dados referenciados por meio do ponteiro global (GP).
IMAGE_SCN_MEM_PURGEABLE
0x00020000
Reservado para uso futuro.
IMAGE_SCN_MEM_16BIT
0x00020000
Reservado para uso futuro.
IMAGE_SCN_MEM_LOCKED
0x00040000
Reservado para uso futuro.
IMAGE_SCN_MEM_PRELOAD
0x00080000
Reservado para uso futuro.
IMAGE_SCN_ALIGN_1BYTES
0x00100000
Alinhe os dados em um limite de 1 byte. Válido somente para arquivos de objeto.
IMAGE_SCN_ALIGN_2BYTES
0x00200000
Alinhe os dados em um limite de 2 bytes. Válido somente para arquivos de objeto.
IMAGE_SCN_ALIGN_4BYTES
0x00300000
Alinhe os dados em um limite de 4 bytes. Válido somente para arquivos de objeto.
IMAGE_SCN_ALIGN_8BYTES
0x00400000
Alinhe os dados em um limite de 8 bytes. Válido somente para arquivos de objeto.
IMAGE_SCN_ALIGN_16BYTES
0x00500000
Alinhe os dados em um limite de 16 bytes. Válido somente para arquivos de objeto.
IMAGE_SCN_ALIGN_32BYTES
0x00600000
Alinhe os dados em um limite de 32 bytes. Válido somente para arquivos de objeto.
IMAGE_SCN_ALIGN_64BYTES
0x00700000
Alinhe os dados em um limite de 64 bytes. Válido somente para arquivos de objeto.
IMAGE_SCN_ALIGN_128BYTES
0x00800000
Alinhe os dados em um limite de 128 bytes. Válido somente para arquivos de objeto.
IMAGE_SCN_ALIGN_256BYTES
0x00900000
Alinhe os dados em um limite de 256 bytes. Válido somente para arquivos de objeto.
IMAGE_SCN_ALIGN_512BYTES
0x00A00000
Alinhe os dados em um limite de 512 bytes. Válido somente para arquivos de objeto.
IMAGE_SCN_ALIGN_1024BYTES
0x00B00000
Alinhe os dados em um limite de 1024 bytes. Válido somente para arquivos de objeto.
IMAGE_SCN_ALIGN_2048BYTES
0x00C00000
Alinhe os dados em um limite de 2048 bytes. Válido somente para arquivos de objeto.
IMAGE_SCN_ALIGN_4096BYTES
0x00D00000
Alinhe os dados em um limite de 4096 bytes. Válido somente para arquivos de objeto.
IMAGE_SCN_ALIGN_8192BYTES
0x00E00000
Alinhe os dados em um limite de 8192 bytes. Válido somente 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 para.

 

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 estiver 0xffff, a contagem real de realocação será armazenada no campo VirtualAddress de 32 bits da primeira realocação. É 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 que conterá 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 imagem. 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 por nome de seção de objeto. Portanto, tudo em arquivos de objeto com nome de seção .text$X acaba junto, após as contribuições .text$W e antes das contribuições .text$Y .

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

Outro conteúdo do arquivo

As estruturas de dados que foram descritas até agora, até e incluindo o cabeçalho opcional, estão todas localizadas em um deslocamento fixo do 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 contém blocos de dados que não estão necessariamente em qualquer 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 é para imagens com um valor SectionAlignment menor que o tamanho da página da arquitetura (4 K para Intel x86 e MIPS e 8 K para Itanium). Para obter uma descrição de SectionAlignment, consulte Cabeçalho opcional (somente imagem). Nesse caso, há restrições no deslocamento de arquivo dos dados da seção, conforme descrito na seção 5.1, "Dados da 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 certificado de atributo imediatamente anterior à seção de depuração, porque 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 da Seção

Os dados inicializados para uma seção consistem em blocos simples de bytes. No entanto, para seções que contêm todos os zeros, os dados da 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ções).

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

Remanejamentos 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, porque todos os símbolos referenciados já receberam endereços em um espaço de endereço 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, consulte A seção .reloc (somente imagem).

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

Compensação Tamanho Campo Descrição
0
4
Endereço Virtual
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/Offset 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 classe de armazenamento de seção, o endereço do símbolo será o endereço com a primeira seção do mesmo nome.
8
2
Digite
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. Consulte Indicadores de tipo.

 

Se o símbolo referido 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 que tenha o mesmo nome de membro do arquivo que o arquivo de objeto atual. (A relação com o nome do membro do arquivo é usada na vinculação de tabelas de importação, ou seja, na 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 de byte 1 da realocação.
IMAGE_REL_AMD64_REL32_2
0x0006
O endereço de 32 bits relativo à distância de byte 2 da realocação.
IMAGE_REL_AMD64_REL32_3
0x0007
O endereço de 32 bits relativo à distância de byte 3 da realocação.
IMAGE_REL_AMD64_REL32_4
0x0008
O endereço de 32 bits relativo à distância de byte 4 da realocação.
IMAGE_REL_AMD64_REL32_5
0x0009
O endereço de 32 bits relativo à distância de byte 5 da realocação.
IMAGE_REL_AMD64_SECTION
0x000A
O índice de seção de 16 bits da seção que contém o destino. Isso é 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. Isso é usado para oferecer suporte a informações de depuração e armazenamento local de thread estático.
IMAGE_REL_AMD64_SECREL7
0x000C
Um deslocamento não assinado de 7 bits da base da seção que contém o destino.
IMAGE_REL_AMD64_TOKEN
0x000D
Tokens CLR.
IMAGE_REL_AMD64_SREL32
0x000E
Um valor dependente de extensão assinado de 32 bits emitido no objeto.
IMAGE_REL_AMD64_PAIR
0x000F
Um par que deve seguir imediatamente cada valor dependente da extensão.
IMAGE_REL_AMD64_SSPAN32
0x0010
Um valor dependente de extensão assinado de 32 bits que é aplicado no momento do link.

 

Processadores ARM

Os seguintes indicadores de tipo de realocação 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 alvo.
IMAGE_REL_ARM_ADDR32NB
0x0002
O RVA de 32 bits do alvo.
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. Isso é 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. Isso é usado para oferecer 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 alvo. 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 alvo. 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.
Utilizadas
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 somente quando se segue imediatamente a um ARM_REFHI ou THUMB_REFHI. Seu SymbolTableIndex contém um deslocamento e não um índice na tabela de símbolos.

 

Processadores ARM64

Os seguintes indicadores de tipo de realocação 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 alvo.
IMAGE_REL_ARM64_ADDR32NB
0x0002
O RVA de 32 bits do alvo.
IMAGE_REL_ARM64_BRANCH26
0x0003
O deslocamento relativo de 26 bits para o alvo, para instruções B e BL.
IMAGE_REL_ARM64_PAGEBASE_REL21
0x0004
A base de 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 (imediata) com zero shift.
IMAGE_REL_ARM64_PAGEOFFSET_12L
0x0007
O deslocamento de página de 12 bits do destino, para instrução LDR (indexado, não assinado imediato).
IMAGE_REL_ARM64_SECREL
0x0008
O deslocamento de 32 bits do destino desde o início de sua seção. Isso é usado para oferecer suporte a informações de depuração e armazenamento local de thread estático.
IMAGE_REL_ARM64_SECREL_LOW12A
0x0009
Bit 0:11 de deslocamento de seção do destino, para instruções ADD/ADDS (imediata) com deslocamento zero.
IMAGE_REL_ARM64_SECREL_HIGH12A
0x000A
Bit 12:23 de deslocamento de seção do destino, para instruções ADD/ADDS (imediato) com deslocamento zero.
IMAGE_REL_ARM64_SECREL_LOW12L
0x000B
Bit 0:11 de deslocamento de seção do destino, para instrução LDR (indexado, não assinado imediato).
IMAGE_REL_ARM64_TOKEN
0x000C
Token CLR.
IMAGE_REL_ARM64_SECTION
0x000D
O índice de seção de 16 bits da seção que contém o destino. Isso é 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 seguintes indicadores de tipo de realocação são definidos para processadores SH3 e SH4. As realocações específicas do SH5 são observadas 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 a VA do símbolo de destino.
IMAGE_REL_SH3_DIRECT8_WORD
0x0004
Uma referência à instrução de 8 bits que contém a VA efetiva 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 a VA efetiva 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 é a 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. Isso é 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. Isso é usado para oferecer 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 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 baixos 16 bits do endereço de 32 bits.
IMAGE_REL_SHM_REFHALF
0x0015
Os 16 bits mais altos do endereço de 32 bits.
IMAGE_REL_SHM_RELLO
0x0016
Os baixos 16 bits 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 ocorre imediatamente após 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 seguintes indicadores de tipo de realocação 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 alvo.
IMAGE_REL_PPC_ADDR32
0x0002
O VA de 32 bits do alvo.
IMAGE_REL_PPC_ADDR24
0x0003
Os 24 bits baixos do VA do alvo. Isso é válido somente quando o símbolo de destino é absoluto e pode ser estendido para seu valor original.
IMAGE_REL_PPC_ADDR16
0x0004
Os baixos 16 bits do VA do alvo.
IMAGE_REL_PPC_ADDR14
0x0005
Os baixos 14 bits do VA do alvo. Isso é válido somente quando o símbolo de destino é absoluto e pode ser estendido para seu 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 alvo.
IMAGE_REL_PPC_SECREL
0x000B
O deslocamento de 32 bits do destino desde o início de sua seção. Isso é usado para oferecer 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. Isso é 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. Isso é usado para oferecer 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 alvo. Isso é 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 baixos 16 bits do VA do alvo.
IMAGE_REL_PPC_PAIR
0x0012
Uma realocação que é válida somente quando segue imediatamente uma realocação REFHI ou SECRELHI. Seu SymbolTableIndex contém um deslocamento e não um índice na tabela de símbolos.
IMAGE_REL_PPC_SECRELLO
0x0013
Os baixos 16 bits 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 seguintes indicadores de tipo de realocação são definidos para Intel 386 e processadores 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 alvo.
IMAGE_REL_I386_DIR32NB
0x0007
O RVA de 32 bits do alvo.
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. Isso é 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. Isso é usado para oferecer 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 oferece suporte à ramificação relativa x86 e instruções de chamada.

 

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. Observe que as realocações nas instruções usam o deslocamento e o número do slot do pacote 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ções 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ções 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 em todos os três slots do pacote IMM64.
IMAGE_REL_IA64_DIR32
0x0004
O VA de 32 bits do alvo. Isso é suportado apenas para imagens /LARGEADDRESSAWARE:NO.
IMAGE_REL_IA64_DIR64
0x0005
O VA de 64 bits do alvo.
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, 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 configurável é 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ções pode ser seguida por uma realocação ADDEND cujo valor é adicionado ao endereço de destino e, em seguida, um deslocamento relativo de GP de 22 bits que é calculado e aplicado ao pacote GPREL22.
IMAGE_REL_IA64_LTOFF22
0x000A
A instrução é corrigida com o deslocamento relativo do 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 vir a seguir.
IMAGE_REL_IA64_SECTION
0x000B
O índice de seção de 16 bits da seção contém o destino. Isso é 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 de sua seção. Essa realocação pode ser seguida imediatamente por uma realocação ADDEND, cujo campo Valor contém o deslocamento não assinado de 32 bits do destino do início da seção.
IMAGE_REL_IA64_SECREL64I
0x000D
O número do slot para essa realocação deve ser um (1). A instrução é corrigida com o deslocamento de 64 bits do destino desde o início de sua seção. Essa realocação pode ser seguida imediatamente por uma realocação ADDEND cujo campo Valor contém o deslocamento não assinado de 32 bits do destino do início da seção.
IMAGE_REL_IA64_SECREL32
0x000E
O endereço de dados a ser corrigido 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 alvo.
IMAGE_REL_IA64_SREL14
0x0011
Isso é aplicado a um imediato de 14 bits assinado que contém a diferença entre dois destinos relocáveis. Este é um campo declarativo para o vinculador que indica que o compilador já emitiu esse valor.
IMAGE_REL_IA64_SREL22
0x0012
Isso é aplicado a um imediato de 22 bits assinado que contém a diferença entre dois destinos relocáveis. Este é um campo declarativo para o vinculador que indica que o compilador já emitiu esse valor.
IMAGE_REL_IA64_SREL32
0x0013
Isso é aplicado a um imediato de 32 bits assinado que contém a diferença entre dois valores relocáveis. Este é um campo declarativo para o vinculador que indica que o compilador já emitiu esse valor.
IMAGE_REL_IA64_UREL32
0x0014
Isso é aplicado a um imediato de 32 bits não assinado que contém a diferença entre dois valores relocáveis. Este é 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 couber 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 todos 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 couber em um campo de 25 bits assinado, converta o pacote inteiro em um pacote MFB com NOP. F no slot 1 e uma instrução BR de 25 bits (4 bits mais baixos todos zero e caídos) no slot 2.
IMAGE_REL_IA64_PCREL60I
0x0018
Uma correção relativa ao PC de 60 bits. Se o deslocamento de destino couber em um campo de 25 bits assinado, converta todo o pacote em um pacote MIB com NOP. Eu no slot 1 e um 25-bit (4 bits mais baixos todos zero e caiu) instrução BR no slot 2.
IMAGE_REL_IA64_PCREL60M
0x0019
Uma correção relativa ao PC de 60 bits. Se o deslocamento de destino couber em um campo de 25 bits assinado, converta o pacote inteiro em um pacote MMB com NOP. M no slot 1 e uma instrução BR de 25 bits (4 bits mais baixos todos zero e caídos) no slot 2.
IMAGE_REL_IA64_IMMGPREL64
0x001a
Uma correção relativa ao GP de 64 bits.
IMAGE_REL_IA64_TOKEN
0x001b
Um token CLR.
IMAGE_REL_IA64_GPREL32
0x001c
Uma correção relativa ao 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. Seu valor contém o complemento a ser aplicado a instruções dentro de um pacote, não para dados.

 

Processadores MIPS

Os seguintes indicadores de tipo de realocação 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 alvo.
IMAGE_REL_MIPS_REFWORD
0x0002
O VA de 32 bits do alvo.
IMAGE_REL_MIPS_JMPADDR
0x0003
Os baixos 26 bits do VA do alvo. Isso suporta as instruções MIPS J e JAL.
IMAGE_REL_MIPS_REFHI
0x0004
Os 16 bits altos do VA de 32 bits do alvo. Isso é 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 assinado de 16 bits que é adicionado aos 16 bits superiores que são retirados do local que está sendo realocado.
IMAGE_REL_MIPS_REFLO
0x0005
Os baixos 16 bits do VA do alvo.
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. Isso é 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. Isso é usado para oferecer suporte a informações de depuração e armazenamento local de thread estático.
IMAGE_REL_MIPS_SECRELLO
0x000C
Os baixos 16 bits 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 alvo desde o início de sua seção. Uma IMAGE_REL_MIPS_PAIR realocação deve seguir imediatamente esta. O SymbolTableIndex da realocação PAIR contém um deslocamento assinado de 16 bits que é adicionado aos 16 bits superiores que são retirados do local que está sendo realocado.
IMAGE_REL_MIPS_JMPADDR16
0x0010
Os baixos 26 bits do VA do alvo. Isso suporta a instrução MIPS16 JAL.
IMAGE_REL_MIPS_REFWORDNB
0x0022
O RVA de 32 bits do alvo.
IMAGE_REL_MIPS_PAIR
0x0025
A realocação é válida somente quando se segue imediatamente a uma realocação REFHI ou SECRELHI. Seu 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 alvo.
IMAGE_REL_M32R_ADDR32NB
0x0002
O RVA de 32 bits do alvo.
IMAGE_REL_M32R_ADDR24
0x0003
O VA de 24 bits do alvo.
IMAGE_REL_M32R_GPREL16
0x0004
O deslocamento de 16 bits do alvo do registro GP.
IMAGE_REL_M32R_PCREL24
0x0005
O deslocamento de 24 bits do alvo do contador de programas (PC), deslocado para a esquerda por 2 bits e sinal estendido
IMAGE_REL_M32R_PCREL16
0x0006
O deslocamento de 16 bits do alvo do PC, deslocado para a esquerda por 2 bits e sinal estendido
IMAGE_REL_M32R_PCREL8
0x0007
O deslocamento de 8 bits do alvo do PC, deslocado para a esquerda por 2 bits e sinal estendido
IMAGE_REL_M32R_REFHALF
0x0008
Os 16 MSBs do VA alvo.
IMAGE_REL_M32R_REFHI
0x0009
Os 16 MSBs do VA de destino, ajustados para extensão de sinal LSB. Isso é 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 assinado de 16 bits 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 alvo.
IMAGE_REL_M32R_PAIR
0x000B
A realocação deve seguir a realocação REFHI. Seu 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. Isso é 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. Isso é usado para oferecer 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 (preteridos)

Os números da 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 a números de linha em vários arquivos de origem.

Os números de linha COFF consistem em uma matriz de registros de comprimento 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.

Compensação Tamanho Campo Descrição
0
4
Tipo (*)
Esta é uma união de dois campos: SymbolTableIndex e VirtualAddress. Se SymbolTableIndex ou RVA é usado 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 Tipo é interpretado como um índice de tabela de símbolos para uma função.

 

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

Compensação 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
Endereço Virtual
Usado quando Linenumber é diferente de zero: o RVA do código executável que corresponde à linha de origem indicada. Em um arquivo de objeto, isso contém o VA dentro da seção .

 

Um registro de número de linha pode definir o campo Número de linha 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 inteiro positivo (número de linha) e o endereço correspondente no código do 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 este 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. Consulte Seções COMDAT (somente objeto). O registro auxiliar da função na tabela de símbolos tem um ponteiro para o campo Número de linha 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 número de linha maior que zero). Essas entradas são baseadas em um, relativas 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 Linenumber de 1, 2 e 3 seriam seguidos, 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. Ele é 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.

O local da tabela de símbolos é indicado no cabeçalho COFF.

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

Compensação Tamanho Campo Descrição
0
8
Nome (*)
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, consulte Representação de nome de símbolo.
8
4
Valor
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
Número da Seção
O inteiro assinado que identifica a seção, usando um índice baseado em um na tabela de seção. Alguns valores têm significado especial, conforme definido na seção 5.4.2, "Valores do número da seção".
14
2
Digite
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 obter mais informações, consulte Representação de tipo.
16
1
Classe de armazenamento
Um valor enumerado que representa a classe de armazenamento. Para obter mais informações, consulte Classe de armazenamento.
17
1
NumberOfAuxSymbols
O número de entradas de tabela de símbolos auxiliares que seguem esse registro.

 

Zero ou mais registros de tabela de símbolos auxiliares seguem imediatamente cada registro de tabela de símbolos padrão. 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 que 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, se ele não tiver mais de 8 bytes de comprimento, ou o campo ShortName fornecerá um deslocamento na tabela de cadeia de caracteres. Para determinar se o próprio nome ou um deslocamento é dado, teste os primeiros 4 bytes para igualdade a zero.

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

Compensação Tamanho Campo Descrição
0
8
Nome curto
Uma matriz de 8 bytes. Essa matriz é preenchida com nulos à direita se o nome tiver menos de 8 bytes.
0
4
Zeros
Um campo definido como todos os zeros se o nome tiver mais de 8 bytes.
4
4
Offset
Um deslocamento na tabela de cadeia de caracteres.

 

Valores do número da seção

Normalmente, o campo Valor da Seção em uma entrada de tabela de símbolos é um índice baseado em um na tabela de seção. No entanto, esse campo é um inteiro assinado e pode ter valores negativos. Os valores a seguir, menos de um, têm significados especiais.

Constante Valor Descrição
IMAGE_SYM_UNDEFINED
0
O registro de símbolo ainda não recebeu uma seção. Um valor de zero indica que uma referência a um símbolo externo é 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 registros .file (classe de armazenamento FILE).

 

Representação de tipo

O campo Tipo de uma entrada de tabela de símbolos contém 2 bytes, onde 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 de 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 completude.

Constante Valor Descrição
IMAGE_SYM_TYPE_NULL
0
Nenhuma informação de tipo ou tipo de 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 vazias
IMAGE_SYM_TYPE_CHAR
2
Um caractere (byte assinado)
IMAGE_SYM_TYPE_SHORT
3
Um inteiro assinado de 2 bytes
IMAGE_SYM_TYPE_INT
4
Um tipo inteiro natural (normalmente 4 bytes no Windows)
IMAGE_SYM_TYPE_LONG
5
Um inteiro assinado de 4 bytes
IMAGE_SYM_TYPE_FLOAT
6
Um número de ponto flutuante de 4 bytes
IMAGE_SYM_TYPE_DOUBLE
7
Um número de ponto flutuante de 8 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 não assinado
IMAGE_SYM_TYPE_WORD
13
Uma palavra; inteiro de 2 bytes não assinado
IMAGE_SYM_TYPE_UINT
14
Um inteiro não assinado de tamanho natural (normalmente, 4 bytes)
IMAGE_SYM_TYPE_DWORD
15
Um inteiro de 4 bytes não assinado

 

O byte mais significativo especifica se o símbolo é um ponteiro para, função retornando 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 Tipo. No entanto, outras ferramentas podem usar esse campo para comunicar mais informações.

É muito importante especificar o atributo function 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 não assinado. O valor especial -1 deve, portanto, ser entendido como seu equivalente não assinado, 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 título da segunda coluna abaixo, "Valor" deve ser entendido como o campo Valor do registro de símbolo (cuja interpretação depende do número encontrado como a classe de armazenamento).

Constante Valor Descrição/interpretação do campo Valor
IMAGE_SYM_CLASS_END_OF_FUNCTION
-1 (0xFF)
Um símbolo especial que representa o final 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 Valor 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 Valor indica 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 Valor especificará o deslocamento dentro da seção.
IMAGE_SYM_CLASS_STATIC
3
O deslocamento do símbolo dentro da seção. Se o campo Valor for zero, o símbolo representará um nome de seção.
IMAGE_SYM_CLASS_REGISTER
4
Uma variável de registro. O campo Valor especifica o número de registro.
IMAGE_SYM_CLASS_EXTERNAL_DEF
5
Um símbolo que é definido externamente.
IMAGE_SYM_CLASS_LABEL
6
Um rótulo de código que é definido dentro do módulo. O campo Valor 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 Valor especifica o n-ésimo membro.
IMAGE_SYM_CLASS_ARGUMENT
9
Um argumento formal (parâmetro) de uma função. O campo Valor especifica o n ésimo argumento.
IMAGE_SYM_CLASS_STRUCT_TAG
10
A entrada de nome de marca de estrutura.
IMAGE_SYM_CLASS_MEMBER_OF_UNION
11
Um membro do sindicato. O campo Valor especifica o n-ésimo membro.
IMAGE_SYM_CLASS_UNION_TAG
12
A entrada do nome da marca 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 Valor especifica o n-é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 Valor especifica o n é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 Valor é 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 Valor fornece o número de linhas de origem na função. Para registros .ef, o campo Valor 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 STSTATIC em vez disso).
IMAGE_SYM_CLASS_WEAK_EXTERNAL
105
Um externo fraco. Para obter mais informações, consulte 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, consulte 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 registros: definições de função, símbolos de início e fim de função (.bf e .ef), externos fracos, nomes de arquivo e definições de seção.

O projeto COFF tradicional também inclui formatos de registro auxiliares para arrays e estruturas. As ferramentas da Microsoft não usam isso, 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 marca o início de uma definição de função se tiver todos os itens a seguir: uma classe de armazenamento 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:

Compensação Tamanho Campo Descrição
0
4
TagIndex
O índice da tabela de símbolos do registro de símbolo .bf (função inicial) correspondente.
4
4
Tamanho Total
O tamanho do código executável para a função em si. Se a função estiver em sua própria seçã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 do arquivo da primeira entrada de número de linha COFF para a função ou zero se nenhum existir. Para obter mais informações, consulte Números de linha COFF (preterido).
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
Utilizadas

 

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 start). O campo Valor não é utilizado.

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 Valor tem o mesmo número que o campo Tamanho Total no registro de 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:

Compensação Tamanho Campo Descrição
0
4
Utilizadas
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
Utilizadas
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
Utilizadas

 

Formato Auxiliar 3: Externos fracos

"Externals fracos" são um mecanismo para arquivos de objeto que permite flexibilidade no tempo do link. Um módulo pode conter um símbolo externo não resolvido (sym1), mas também pode 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 está ligada, então todas as referências ao externo fraco para sym1 referem-se a sym2 em vez disso. O símbolo externo, sym2, deve estar sempre ligado; Normalmente, ele é definido no módulo que contém a referência fraca a SYM1.

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

Compensação 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
Utilizadas

 

Observe que o campo Características não está definido no WINNT. H; em vez disso, o campo Tamanho Total é usado.

Formato auxiliar 4: Arquivos

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

Compensação Tamanho Campo Descrição
0
18
Nome do arquivo
Uma cadeia de caracteres ANSI que fornece o nome do arquivo de origem. Isso é preenchido com nulos se for menor que o comprimento 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.

Compensação Tamanho Campo Descrição
0
4
Comprimento
O tamanho dos dados da seção; o mesmo que SizeOfRawData no cabeçalho da seção.
4
2
NúmeroDerealocações
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 para dados comunitários. É aplicável se o sinalizador IMAGE_SCN_LNK_COMDAT estiver definido no cabeçalho da seção. Para obter mais informações, consulte Seções COMDAT (somente objeto).
12
2
Número
Índice baseado em um na tabela de seção da seção associada. Isso é usado quando a configuração de seleção COMDAT é 5.
14
1
Seleção
O número de seleção COMDAT. Isso é aplicável se a seção for uma seção COMDAT.
15
3
Utilizadas

 

Seções COMDAT (somente objeto)

O campo Seleção do formato auxiliar de definição de seção é 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 sinalizador é definido no campo Sinalizadores de Seção do cabeçalho da seção.) O campo Seleção determina a maneira como o vinculador resolve as várias definições de seções COMDAT.

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

Os valores para o campo Seleção 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 "multiplicar símbolo definido".
IMAGE_COMDAT_SELECT_ANY
2
Qualquer seção que defina o mesmo símbolo COMDAT pode ser vinculada; o resto é removido.
IMAGE_COMDAT_SELECT_SAME_SIZE
3
O vinculador escolhe uma seção arbitrária entre as definições para esse 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 para esse 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 é vinculada se uma determinada outra seção COMDAT estiver vinculada. Essa outra seção é indicada pelo campo Número do registro de símbolo auxiliar para a definição da seção. Essa configuração é útil para definições que têm componentes em várias seções (por exemplo, código em uma e dados em outra), mas onde 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 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 tem IMAGE_COMDAT_SELECT_ASSOCIATIVE definido.
IMAGE_COMDAT_SELECT_LARGEST
6
O vinculador escolhe a maior definição entre todas as definições para esse símbolo. Se várias definições tiverem esse tamanho, a escolha entre elas é arbitrária.

 

Definição de token CLR (somente objeto)

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

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

 

Tabela de cadeias de caracteres COFF

Imediatamente após a tabela de símbolos COFF está a tabela de cadeias 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 cadeia de caracteres COFF são 4 bytes que contêm o tamanho total (em bytes) do restante da tabela de cadeia 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 estão cadeias de caracteres terminadas em nulo que são apontadas por símbolos na tabela de símbolos COFF.

A tabela de certificado 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, alinhadas a quadword. O preenchimento zero é inserido entre a extremidade original do arquivo e o início da tabela de certificado de atributo para obter esse alinhamento. Cada entrada de certificado de atributo contém os seguintes campos.

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

 

O valor de endereço virtual da entrada 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, a partir do início da entrada de certificado de atributo atual. Isso continua até que a soma dos valores arredondados dwLength seja igual ao valor Tamanho da entrada Tabela de Certificados no Diretório de Dados de Cabeçalho Opcional. Se a soma dos valores arredondados dwLength não for igual ao valor Size, a tabela de certificado de atributo ou o campo Size estarão corrompidos.

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 0x5000 de deslocamento a partir do 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. Arredondar 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 arredondar para cima 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 + 0x1000 tamanho total), o que indica que você percorreu a tabela inteira.

Como alternativa, você pode enumerar as entradas de certificado chamando a função Win32 ImageEnumerateCertificates em um loop. Para obter um link para a página de referência da função, consulte 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 é documentada em Wintrust.h e discutida no restante desta seção.

As opções para o membro wRevision WIN_CERTIFICATE incluem (mas não estão limitadas a) o seguinte.

Valor Nome 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 wCertificateType WIN_CERTIFICATE incluem (mas não estão limitadas a) os itens na tabela a seguir. Observe que alguns valores não são suportados no momento.

Valor Nome 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 PKCS#7 SignedData
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 comprimento variável com o tipo de conteúdo especificado por wCertificateType. O tipo suportado pelo Authenticode é WIN_CERT_TYPE_PKCS_SIGNED_DATA, uma estrutura PKCS#7 SignedData . Para obter detalhes sobre o formato de assinatura digital Authenticode, consulte Formato de assinatura executável portátil do Windows Authenticode.

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

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

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

Esse comprimento deve incluir o tamanho de qualquer preenchimento usado para satisfazer o requisito de que cada estrutura WIN_CERTIFICATE esteja alinhada com quadword:

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, consulte Funções do 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 ficou ruim e os valores armazenados lá ficaram 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 aquelas introduzidas por vírus, hackers ou programas de cavalo de Tróia.

Quando incluído em um certificado, o resumo da imagem deve excluir determinados campos na Imagem PE, como a entrada Soma de verificação e Tabela de certificados em 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 hash funções. Esse fluxo de dados permanece consistente quando 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 do cálculo de hash. Para obter um link para a página de referência da função, consulte Referências.

Tabelas de importação de carregamento atrasado (somente imagem)

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

A tabela de diretórios de carregamento de atraso

A tabela de diretório de carregamento de atraso é a contraparte da tabela de diretório de importação. Ele pode ser recuperado por meio da entrada Descritor de Importação de Atraso na lista de diretórios de dados de cabeçalho opcional (deslocamento 200). A tabela está organizada da seguinte forma:

Compensação Tamanho Campo Descrição
0
4
Atributos
Deve ser zero.
4
4
Nome
O RVA do nome da DLL a ser carregada. O nome reside na seção de dados somente leitura da imagem.
8
4
Alça do módulo
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 que é fornecida para gerenciar o carregamento atrasado.
12
4
Tabela de endereços de importação de atraso
O RVA da tabela de endereços de importação de carga de atraso. Para obter mais informações, consulte Atrasar tabela de endereços de importação (IAT).
16
4
Tabela de nomes de importação de atraso
O RVA da tabela de nomes de carregamento de atraso, que contém os nomes das importações que talvez precisem ser carregadas. Isso corresponde ao layout da tabela de nomes de importação. Para obter mais informações, consulte Tabela de dicas/nomes.
20
4
Tabela de importação de atraso vinculado
O RVA da tabela de endereços de carga de atraso vinculada, se existir.
24
4
Tabela de Importação de Atraso de Descarga
O RVA da tabela de endereços de descarga de atraso, se existir. Esta é uma cópia exata da tabela de endereços de importação de atraso. Se o chamador descarregar a DLL, essa tabela deverá ser copiada de volta sobre a tabela de endereços de importação de atraso para que as chamadas subsequentes para a DLL continuem a usar o mecanismo de thunking corretamente.
28
4
Carimbo de data/hora
O carimbo de data/hora da DLL à qual essa imagem foi vinculada.

 

As tabelas referenciadas nessa estrutura de dados são organizadas e classificadas exatamente como suas contrapartes são para importações tradicionais. Para obter detalhes, consulte a 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 atraso ou descarga.

Nome

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

Alça do módulo

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

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

A tabela de endereços de importação de atraso (IAT) é referenciada pelo descritor de importação de atraso por meio do campo pIAT. O auxiliar de carga de atraso atualiza esses ponteiros com os pontos de entrada reais para que os thunks 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 de atraso

A tabela de nomes de importação de 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 de endereços de importação acoplada de atraso e carimbo de data/hora

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

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

A tabela de endereços de importação de descarregamento de atraso (UIAT) é uma tabela opcional de itens de IMAGE_THUNK_DATA que o código de descarregamento usa para manipular 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 os thunks de carregamento de atraso. Na solicitação de descarregamento, a biblioteca pode ser liberada, o *phmod limpo e o UIAT gravado sobre o IAT para restaurar tudo ao seu estado de pré-carregamento.

Seções Especiais

Seções COFF típicas contêm código ou dados que vinculadores e 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. As ferramentas e os carregadores reconhecem essas seções porque 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, de modo que os autores dessa especificação podem se referir a um nome de seção em todos os casos.)

As seções reservadas e seus atributos são descritos na tabela abaixo, seguidos por descrições detalhadas para os tipos de seção que são persistentes 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
.dados
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
.drectivo
Opções do vinculador
IMAGE_SCN_LNK_INFO
.edata
Exportar tabelas
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
.idata
Importar tabelas
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
.idlsym
Inclui SEH registrado (somente imagem) para oferecer suporte a atributos IDL. Para obter informações, consulte "Atributos IDL" em Referências no final deste tópico.
IMAGE_SCN_LNK_INFO
.pdata
Informações de 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
Remanejamentos de imagens
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 ao GP (formato livre)
IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGEM _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 ao GP (formato livre)
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGEM _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 ao GP (formato livre)
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGEM _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 registrados do manipulador de exceções (somente formato livre e 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 referidos pelo código nesse arquivo de objeto. O símbolo pode ser para um símbolo UNDEF ou um que é definido nesse módulo.
.Texto
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 ao 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 das 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 arquivos de imagem.

A 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. Esta 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 para o 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 cuja localização 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 de diretório de depuração identifica o local e o tamanho de um bloco de informações de depuração. O RVA especificado pode 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 for mapeado para o espaço de endereço de tempo de execução). Se for mapeado, o RVA é o seu endereço.

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

Compensação 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
Versão principal
O número da versão principal do formato de dados de depuração.
10
2
MinorVersion
O número da versão secundária do formato de dados de depuração.
12
4
Digite
O formato das informações de depuração. Este campo permite o suporte de vários depuradores. Para obter mais informações, consulte 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 de imagens.
24
4
PointerToRawData
O ponteiro do arquivo para os dados de depuração.

 

Tipo de depuração

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

Constante Valor Descrição
IMAGE_DEBUG_TYPE_UNKNOWN
0
Um valor desconhecido que é 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 omissão de ponteiro de quadro (FPO). 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 do EP.
Indefinido
17
As informações de depuração são incorporadas no arquivo PE no local especificado por PointerToRawData.
Indefinido
19
Armazena 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 de DLL estendidas.

 

Se o campo Tipo 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 de FPO definidas para ela, 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 do 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 foi construído de forma a alcançar determinismo ou reprodutibilidade. Se a entrada não mudar, o arquivo PE de saída é garantido para ser bit-for-bit idêntico, não importa 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 a hora reais quando um arquivo PE ou dados específicos relacionados no 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 comprimento do valor de hash.

Se o campo Tipo 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. Consulte Características da DLL na seção Campos específicos do Windows de cabeçalho opcional (somente imagem).

Características da DLL estendida

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

Constante Valor Descrição
IMAGE_DLLCHARACTERISTICS_EX_CET_COMPAT 0x0001 A imagem é compatível com a Pilha de Sombra CET (Control-flow Enforcement Technology).
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 avançada, como instruções de rastreamento de ramificação indireta (IBT) x86 CET ou BTI (Branch Target Identification) ARM. Este 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). Consulte "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 de FPO_DATA por procedimento RVA e gerará uma entrada de diretório de depuração para eles.

O compilador não deve gerar registros FPO para procedimentos que têm 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 de vinculador para informações de depuração da Microsoft

Para oferecer 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 fazer referência a eles.

A seção .drectve (somente objeto)

Uma seção é uma seção de diretiva se tiver o sinalizador IMAGE_SCN_LNK_INFO definido no cabeçalho da seção e tiver o nome da seção .drectve . O vinculador remove uma seção .drectve depois de 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 cadeia de caracteres 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 de 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.

A 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 da 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 necessário). Somente a tabela de diretório 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). Esta 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 dentro do código executável e das seções de 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 corresponde ao ordinal se um nome público for definido.
Tabela de ponteiro de nome
Uma matriz de ponteiros para os nomes públicos de exportação, classificados em ordem crescente.
Tabela ordinal
Uma matriz dos ordinais que correspondem aos membros da tabela de ponteiro de nome. A correspondência é por posição; portanto, a tabela de ponteiro de nome e a tabela ordinal devem ter o mesmo número de membros. Cada ordinal é um índice na tabela de endereços de exportação.
Exportar tabela de nomes
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 através dos quais os símbolos são importados e exportados; eles não são necessariamente os mesmos que os nomes privados que são usados dentro do arquivo de imagem.

 

Quando outro arquivo de imagem importa um símbolo por nome, o carregador Win32 procura na tabela de ponteiro de nome 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 da 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, é desnecessá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 requer que o usuário conheça 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 do diretório de exportação, que descreve o restante das informações do símbolo de exportação. A tabela de diretório de exportação contém informações de endereço que são usadas para resolver importações para os pontos de entrada dentro desta imagem.

Compensação 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
Nome: RVA
O endereço da cadeia de caracteres ASCII que contém o nome da DLL. Esse endereço é relativo à base da imagem.
16
4
Ordinal Base
O número ordinal inicial para exportações nesta imagem. Este 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 ponteiro de nome. Este também é o número de entradas na tabela ordinal.
28
4
Tabela de endereços de exportação RVA
O endereço da tabela de endereços de exportação, em relação à base da imagem.
32
4
Nome Pointer RVA
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
Tabela ordinal RVA
O endereço da tabela ordinal, relativo à 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 os 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 dentro da seção de exportação (conforme definido pelo endereço e comprimento indicados no cabeçalho opcional), o campo será um RVA de exportação, que é um endereço real em código ou dados. Caso contrário, o campo será um RVA do encaminhador, que nomeia um símbolo em outra DLL.

Compensação Tamanho Campo Descrição
0
4
Exportação 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
Forwarder RVA
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. Consulte 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 RVA de encaminhador exporta uma definição de alguma outra imagem, fazendo com que pareça que está sendo exportada pela imagem atual. Assim, o símbolo é importado e exportado simultaneamente.

Por exemplo, em 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 a ele. A tabela de importação do aplicativo refere-se apenas a Kernel32.dll. Portanto, o aplicativo não é específico para o Windows XP e pode ser executado em qualquer sistema Win32.

Tabela de ponteiro 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 lexicamente 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.

Exportar tabela ordinal

A tabela ordinal de exportação é uma matriz de índices imparciais de 16 bits na tabela de endereços de exportação. Os ordinais são enviesados pelo campo Base Ordinal da tabela de diretório de exportação. Em outras palavras, a base ordinal deve 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 de campo natural. Essas duas tabelas, na verdade, operam como uma tabela, na qual a coluna Ponteiro do Nome da 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 ordinal de exportação são associados por terem a mesma posição (índice) em suas respectivas matrizes.

Assim, quando a tabela de ponteiro 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 enviesado é:

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

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

Ao procurar 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 públicos de exportação não são necessariamente os mesmos que os nomes de símbolos privados que os símbolos 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 comprimento variável.

A seção .idata

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

  • 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 nome de dica

Tabela de diretórios de importação

As informações de importação começam com a tabela de diretório de importação, que descreve o restante das informações de importação. A tabela de diretório de importação contém informações de endereço que são usadas para resolver referências de correção para os pontos de entrada dentro de uma imagem DLL. A tabela de diretório 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 final da tabela de diretório.

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

Compensação Tamanho Campo Descrição
0
4
Importar tabela de pesquisa RVA (características)
O RVA da tabela de pesquisa de importação. Esta 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 vinculada. Depois que a imagem é vinculada, esse campo é definido como o carimbo de data/hora da DLL.
8
4
Cadeia de Forwarder
O índice da primeira referência de encaminhamento.
12
4
Nome: RVA
O endereço de uma cadeia de caracteres ASCII que contém o nome da DLL. Esse endereço é relativo à base da imagem.
16
4
Tabela de endereços de importação RVA (tabela Thunk)
O RVA da tabela de endereços de importação. O conteúdo dessa tabela é idêntico ao conteúdo da tabela de pesquisa de importação até que a imagem seja vinculada.

 

Importar tabela de pesquisa

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 campo 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 ordinal/nome
Se esse bit estiver definido, importe por ordinal. Caso contrário, importe pelo 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 Bit Ordinal/Name Flag for 1 (importar por ordinal). Os bits 30-15 ou 62-15 devem ser 0.
30-0
31
Tabela de Dicas/Nomes RVA
Um RVA de 31 bits de uma entrada de tabela de dica/nome. Esse campo será usado somente se o campo bit Ordinal/Name Flag for 0 (importar por nome). Para PE32+ bits 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:

Compensação 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
Nome
Uma cadeia de caracteres ASCII que contém o nome a ser importado. Essa é a cadeia de caracteres que deve ser correspondida ao nome público na DLL. Essa cadeia de caracteres diferencia maiúsculas de minúsculas e termina por um byte nulo.
*
0 ou 1
Almofada
Um byte de teclado 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 ligação.

A seção .pdata

A seção .pdata contém uma matriz de entradas de tabela de função que são usadas para manipulação 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 das funções (o primeiro campo em cada estrutura) antes de serem emitidas na imagem final. A plataforma de destino determina qual das três variações de formato de entrada da tabela de função descritas abaixo é usada.

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

Compensação Tamanho Campo Descrição
0
4
Endereço inicial
A AV da função correspondente.
4
4
Endereço final
O VA do final da função.
8
4
Manipulador de exceções
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 ao manipulador.
16
4
Endereço final do Prolog
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:

Compensação Tamanho Campo Descrição
0
4
Endereço inicial
A AV da função correspondente.
4
8 bits
Comprimento do Prolog
O número de instruções no prólogo da função.
4
22 bits
Comprimento da função
O número de instruções na função.
4
1 bit
Sinalizador de 32 bits
Se definida, a função consiste em instruções de 32 bits. Se clara, a função consiste em instruções de 16 bits.
4
1 bit
Sinalizador de exceção
Se definido, existe um manipulador de exceção para a função. Caso contrário, nenhum manipulador de exceção existirá.

 

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

Compensação Tamanho Campo Descrição
0
4
Endereço inicial
O RVA da função correspondente.
4
4
Endereço final
O RVA do final da função.
8
4
Descontraia informações
O RVA da informação de descontração.

 

A 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 Tabela de Realocação 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, consulte 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 para 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 que são 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:

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

 

O campo Tamanho do bloco é seguido por qualquer número de entradas de campo Tipo ou Deslocamento. Cada entrada é um WORD (2 bytes) e tem a seguinte estrutura:

Compensação Tamanho Campo Descrição
0
4 bits
Digite
Armazenado nos 4 bits altos do WORD, um valor que indica o tipo de realocação de base a ser aplicado. Para obter mais informações, consulte 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 RVA da página 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 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. Este 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 valor alto 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 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 valor alto 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 esse remanejamento de base ocupa duas vagas.
IMAGE_REL_BASED_MIPS_JMPADDR
5
A interpretação da 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ó é significativa quando o tipo de máquina é 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ó é significativa quando o tipo de máquina é 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ó é significativa quando o tipo de máquina é Thumb. A realocação de base aplica o endereço de 32 bits de um símbolo a um par de instruções MOVW/MOVT consecutivo.
IMAGE_REL_BASED_RISCV_LOW12I
7
Essa realocação só é significativa quando o tipo de máquina é RISC-V. A realocação de base se aplica aos baixos 12 bits de um endereço absoluto de 32 bits formado no formato de instrução RISC-V do tipo I.
IMAGE_REL_BASED_RISCV_LOW12S
8
Essa realocação só é significativa quando o tipo de máquina é RISC-V. A realocação de base se aplica aos baixos 12 bits de um endereço absoluto de 32 bits formado no formato de instrução RISC-V do tipo S.
IMAGE_REL_BASED_LOONGARCH32_MARK_LA
8
Essa realocação só é significativa quando o tipo de máquina é 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ó é significativa quando o tipo de máquina é 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ó é significativa quando o tipo de máquina é 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.

 

A seção .tls

A seção .tls fornece suporte direto a PE e COFF para armazenamento local de thread estático (TLS). TLS é uma classe de armazenamento especial que o Windows oferece suporte na qual 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 forma 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 oferecer suporte a essa construção 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 término por thread e o índice TLS, que são explicados na discussão a seguir.

Observação

Antes do Windows Vista, objetos de dados TLS declarados estaticamente só podem ser usados em arquivos de imagem carregados estaticamente. Esse fato torna não confiável usar dados TLS estáticos em uma DLL, a menos que você saiba que a DLL, ou qualquer coisa estaticamente vinculada a ela, nunca será carregada dinamicamente com a função API LoadLibrary. No entanto, a partir do Windows Vista, 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.

 

Observação

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 do link, o vinculador define o campo Endereço do Índice 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-lhe 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 oferecem suporte a TLS e funcionam 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 bloco de ambiente de thread (TEB) no registro FS. Um ponteiro para a matriz TLS está no deslocamento de 0x2C do 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 Endereço do Índice.

  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 algum 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 nessa matriz fornece o local 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.

O diretório TLS

O diretório TLS tem o seguinte formato:

Deslocamento (PE32/ PE32+) Tamanho (PE32/ PE32+) Campo Descrição
0
4/8
Dados brutos Iniciar VA
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 este 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 o preenchimento zero. Assim como no 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, consulte Funções de retorno de chamada TLS.
16/32
4
Tamanho do Zero Fill
O tamanho em bytes do modelo, além dos dados inicializados delimitados pelos campos VA de Início de Dados Brutos e VA de Final de Dados Brutos. O tamanho total do modelo deve ser o mesmo que o tamanho total dos dados TLS no arquivo de imagem. O preenchimento zero é a quantidade de dados que vem após os dados inicializados diferentes de zero.
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 estão reservados para uso futuro.

 

Funções de retorno de chamada TLS

O programa pode fornecer uma ou mais funções de retorno de chamada TLS para oferecer suporte à inicialização e terminação adicionais para objetos de dados TLS. Um uso típico para tal 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 tornar possível adicionar 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 retorno de chamada suportado), 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. O parâmetro Reason pode ter 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 novo thread foi criado. Esta notificação foi enviada para todos, exceto para o primeiro thread.
DLL_THREAD_DETACH
3
Um tópico está prestes a ser encerrado. Esta notificação foi enviada para todos, exceto para o primeiro thread.
DLL_PROCESS_DETACH
0
Um processo está prestes a terminar, incluindo o thread original.

 

A estrutura de configuração de carga (somente imagem)

A estrutura de configuração de carga (IMAGE_LOAD_CONFIG_DIRECTORY) foi 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 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 o envio de exceções. Se o endereço do manipulador residir no intervalo VA de uma imagem e estiver marcado como reservado com reconhecimento de SEH (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 encerrará o aplicativo. Isso ajuda a evitar a exploração "x86 exception handler hijacking" que foi usada 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á fornece uma estrutura de configuração de carga, ele deve incluir os novos campos SEH reservados. Caso contrário, o vinculador não poderá incluir os dados reservados do SEH e a imagem não será marcada como contendo SEH reservado.

Carregar diretório de configuração

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

Carregar layout de configuração

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

Compensação Tamanho Campo Descrição
0
4
Características
Sinalizadores que indicam atributos do arquivo, atualmente não utilizados.
4
4
TimeDateStamp
Valor do 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, 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 de tempo de tempo C runtime (CRT).
8
2
Versão principal
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 para 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 estã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
[x86 apenas] O VA de uma lista de endereços onde o prefixo LOCK é usado para que eles possam ser substituídos por NOP em máquinas de processador único.
36/48
4/8
Tamanho máximo de alocação
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 que é criado durante a inicialização do processo.
52/76
2
CSDVersion
O identificador de versão do service pack.
54/78
2
Reservado
Deve ser zero.
56/80
4/8
EditList
Reservado para uso pelo sistema.
60/88
4/8
SecurityCookie
Um ponteiro para um cookie que é usado pela implementação do Visual C++ ou GS.
64/96
4/8
SEHandlerTable
[x86 apenas] O VA da tabela classificada de RVAs de cada manipulador SE válido e exclusivo na imagem.
68/104
4/8
SEHandlerCount
[x86 apenas] A contagem de manipuladores exclusivos na tabela.
72/112
4/8
GuardCFCheckFunctionPointer
O VA onde o ponteiro da função de verificação Control Flow Guard está armazenado.
76/120
4/8
GuardCFDispatchFunctionPointer
O VA onde o ponteiro da função de despacho Control Flow Guard está armazenado.
80/128
4/8
GuardCFFunctionTable
O VA da tabela classificada de RVAs de cada função Control Flow Guard na imagem.
84/136
4/8
GuardCFFunctionCount
A contagem de RVAs únicos na tabela acima.
88/144
4
GuardFlags
Controle de sinalizadores relacionados ao Flow Guard.
92/148
12
Integridade do Código
Informações de integridade do código.
104/160
4/8
GuardAddressTakenIatEntryTable
O VA onde o endereço do Control Flow Guard obtido na tabela IAT é armazenado.
108/168
4/8
GuardAddressTakenIatEntryCount
A contagem de RVAs únicos na tabela acima.
112/176
4/8
GuardLongJumpTargetTable
O VA onde a tabela de destino de salto longo do Control Flow Guard está armazenada.
116/184
4/8
GuardLongJumpTargetCount
A contagem de RVAs únicos 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 o fluxo de controle e as verificações de 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 carga de atraso somente leitura.

    #define IMAGE_GUARD_PROTECT_DELAYLOAD_IAT 0x00001000

  • Atrasar a tabela de importação em sua própria seção .didat (sem mais nada nela) que pode ser livremente reprotegida.

    #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 o endereço tomado tabela IAT também está presente na configuração de carga.

    #define IMAGE_GUARD_CF_EXPORT_SUPPRESSION_INFO_PRESENT 0x00004000

  • Módulo permite 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 a etapa das entradas da tabela de função Control Flow Guard (ou seja, a contagem adicional de bytes por entrada de 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 a serem deslocados para a direita do valor GuardFlags para justificar à direita a etapa da tabela de funções Control Flow Guard:

#define IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_SHIFT 28

A seção .rsrc

Os recursos são indexados por uma estrutura de árvore classificada binária 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:

Idioma do Nome do Tipo

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 (Tipo, Nome ou Nível de 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ório, 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 que é percorrido através de tabelas de diretório para alcançar a 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 o mesmo 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 dos dados do recurso
Uma matriz de registros, apontada por tabelas, que descreve o tamanho real e o local dos dados do recurso. Esses registros são as folhas na árvore de descrição de recursos.
Dados de recursos
Dados brutos da seção de recursos. As informações de tamanho e localização no campo 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 título de uma tabela porque a tabela realmente consiste em entradas de diretório (descritas na seção 6.9.2, "Entradas de diretório de recursos") e esta estrutura:

Compensação Tamanho Campo Descrição
0
4
Características
Sinalizadores de recursos. Este campo é reservado para uso futuro. No momento, ele 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 do 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 é uma entrada Nome ou ID é indicado pela tabela de diretório de recursos, que indica quantas entradas Nome e ID a seguem (lembre-se de que todas as entradas Nome precedem todas as entradas de ID da tabela). Todas as entradas da tabela são classificadas em ordem crescente: as entradas Name por cadeia de caracteres que diferencia maiúsculas de minúsculas e as entradas ID por valor numérico. Os deslocamentos são relativos ao endereço no DataDirectory do IMAGE_DIRECTORY_ENTRY_RESOURCE. Consulte Emparelhamento dentro do PE: um tour do formato de arquivo executável portátil Win32 para obter mais informações.

Compensação Tamanho Campo Descrição
0
4
Deslocamento de nome
O deslocamento de uma cadeia de caracteres que fornece a entrada Type, Name ou Language ID, dependendo do nível da tabela.
0
4
ID do número inteiro
Um inteiro de 32 bits que identifica a entrada Type, Name ou Language ID.
4
4
Deslocamento de entrada de dados
Bit alto 0. Endereço de uma entrada de Dados de Recurso (uma folha).
4
4
Deslocamento de subdiretório
Bit alto 1. 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 por 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 comprimento variável no alinhamento das entradas de diretório de tamanho fixo. Cada cadeia de caracteres do diretório de recursos tem o seguinte formato:

Compensação Tamanho Campo Descrição
0
2
Comprimento
O tamanho da cadeia de caracteres, não incluindo o próprio campo de comprimento.
2
variável
Cadeia de caracteres Unicode
Os dados de cadeia de caracteres Unicode de comprimento variável, alinhados por palavras.

 

Entrada de dados de recurso

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

Compensação Tamanho Campo Descrição
0
4
Dados RVA
O endereço de uma unidade de dados de recurso na área Dados do Recurso.
4
4
Tamanho
O tamanho, em bytes, dos dados de recurso apontados pelo campo RVA de dados.
8
4
Página de código
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.

 

A 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 é documentado, mas pode ser entregue às interfaces CLR para manipular metadados.

A 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 é marcada 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 morto (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 morto consistem na assinatura do arquivo. O resto do arquivo é composto por 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 de 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 morto precede cada membro. A lista a seguir mostra a estrutura geral de um arquivo:

Assinatura :"!<arco>\n"
Cabeçalho
1º Membro Linker
Cabeçalho
2º Membro Linker
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 morto

A assinatura do arquivo morto 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 pelo 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>/   "

Arquivar cabeçalhos de membros

Cada membro (vinculador, nomes longos 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 é deixada justificada e preenchida com espaços no final do campo. Não há nenhum caractere nulo de terminação em nenhum desses campos.

Cada cabeçalho de membro começa no primeiro endereço par após o término do membro de arquivo anterior, um byte '\n' (IMAGE_ARCHIVE_PAD) pode ser inserido após um membro de arquivo para fazer com que o membro seguinte inicie em um endereço par.

Compensação Tamanho Campo Descrição
0
16
Nome
O nome do membro do arquivo, com uma barra (/) anexada para encerrar 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
Identificação de usuário
Uma representação decimal ASCII do ID do usuário. Este 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 da ID do grupo. Este 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 Nome tem um dos formatos mostrados na tabela a seguir. Como mencionado anteriormente, cada uma dessas cadeias de caracteres é deixada justificada e preenchida com espaços à direita dentro de um campo de 16 bytes:

Conteúdo do campo Nome Descrição
nome/
O nome do membro do arquivo.
/
O membro do arquivo é um dos dois membros do vinculador. Ambos os membros do vinculador têm esse nome.
//
O membro archive é 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 Linker

O nome do primeiro membro vinculador é "/" (IMAGE_ARCHIVE_LINKER_MEMBER). O primeiro membro vinculador é incluído para compatibilidade com versões anteriores. Ele 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 encontrar o membro do arquivo que contém o símbolo.

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

Compensação Tamanho Campo Descrição
0
4
Número de símbolos
Longo não assinado que contém o número de símbolos indexados. Este número é armazenado em 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 cabeçalhos de membro de arquivo, na qual n é igual ao campo Número de Símbolos. Cada número na matriz é um longo não assinado armazenado no formato big-endian. Para cada símbolo nomeado na tabela de cadeia de caracteres, o elemento correspondente na matriz de deslocamentos fornece o local do membro do arquivo morto que contém o símbolo.
*
*
Tabela de cadeias 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 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 Linker

Como o primeiro membro vinculador, o segundo membro 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 contenham, o segundo membro do vinculador é usado preferencialmente ao primeiro por todos os vinculadores atuais. O segundo membro 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:

Compensação Tamanho Campo Descrição
0
4
Número de Membros
Um 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 longo não assinado. O número m é igual ao valor do campo Número de Membros.
*
4
Número de símbolos
Um longo não assinado 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 (curto não assinado) que mapeia nomes de símbolos para arquivar deslocamentos de membros. O número n é igual ao campo Número de Símbolos. Para cada símbolo nomeado na tabela de cadeia de caracteres, o elemento correspondente na matriz Indices fornece um índice na matriz offsets. A matriz de deslocamentos, por sua vez, fornece o local do membro do arquivo que contém o símbolo.
*
*
Tabela de cadeias 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 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 cadeias de caracteres de nomes de membros de arquivo. Um nome aparece aqui somente quando não há espaço suficiente no campo Nome (16 bytes). O membro longnames é opcional. Ele pode estar vazio com apenas um cabeçalho, ou pode estar completamente ausente sem sequer 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.

Importar formato da biblioteca

As bibliotecas de importação tradicionais, ou seja, bibliotecas que descrevem as exportações de uma imagem para uso por outra, normalmente seguem o layout descrito na seção 7, Formato de arquivo (biblioteca). A principal diferença é que os membros da biblioteca de importação contêm arquivos de pseudoobjeto em vez de arquivos reais, nos quais cada membro inclui as contribuições de seção necessárias para criar as tabelas de importação descritas na seção 6.4, A seção .idata O vinculador gera esse arquivo ao criar o 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 a 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:

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

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

  • Arquivar cabeçalho de membro
  • Importar cabeçalho
  • Cadeia de caracteres de nome de importação terminada em nulo
  • Cadeia de caracteres de nome da DLL terminada em nulo

Esta é uma informação suficiente para reconstruir com precisão todo o conteúdo do membro no momento de sua utilização.

Importar cabeçalho

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

Compensação Tamanho Campo Descrição
0
2
Sig1
Deve ser IMAGE_FILE_MACHINE_UNKNOWN. Para obter mais informações, consulte Tipos de máquina.
2
2
Sig2
Deve ser 0xFFFF.
4
2
Versão
A versão estrutural.
6
2
Máquina
O número que identifica o tipo de máquina de destino. Para obter mais informações, consulte Tipos de máquina.
8
4
Carimbo de data/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, determinada pelo valor no campo Tipo de nome.
18
2 bits
Digite
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, consulte Importar tipo de nome.
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 seguintes valores são definidos para o campo Tipo 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 devem 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 seu cabeçalho de importação associado. Os valores a seguir são definidos para o campo Tipo de Nome 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 deve sempre 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 _, e truncando no primeiro @.

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

Espera-se que vários certificados de atributo sejam usados para verificar a integridade das imagens. No entanto, a 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 ao formulário original do arquivo. Para realizar essa tarefa, as assinaturas Authenticode contêm algo chamado hash de imagem PE

O que é um hash de imagem Authenticode PE?

O hash de imagem Authenticode PE, ou hash de arquivo para abreviar, é 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, ele é usado para detectar se um bloco de memória no disco ficou ruim e os valores armazenados lá ficaram 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 que sua forma original (não modificada). Ou seja, uma soma de verificação destina-se a detectar falhas de memória simples que levam à corrupção, mas um hash de arquivo pode ser usado para detectar modificações intencionais e até sutis em um arquivo, como as 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 de hash assinado contido na assinatura digital Authenticode. Se os hashes de arquivo não corresponderem, parte do arquivo coberto pelo hash de imagem PE foi modificada.

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

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 lançados 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, ser capaz de gerar um hash de imagem PE idêntico incluindo todos os dados do arquivo de imagem no cálculo novamente, porque o arquivo agora contém a assinatura Authenticode que não estava lá originalmente.

Processo para gerar o hash de imagem Authenticode PE

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.

Observação

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 hash. Isso é relevante, porque torna-se possível invalidar o hash de imagem PE em um arquivo de catálogo assinado por Authenticode modificando uma imagem PE que não contém realmente uma assinatura Authenticode.

Todos os dados em seções da imagem PE especificados na tabela de seção são hashed em sua totalidade, exceto para os 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 o arquivo inteiro (incluindo quaisquer certificados de atributo no arquivo). Com toda a probabilidade, a soma de verificação será diferente do valor original depois de inserir a assinatura Authenticode.

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

    • O campo Tabela de Certificados dos diretórios de dados de cabeçalho opcionais.

    • A Tabela de Certificados e os certificados correspondentes apontados pelo campo Tabela de Certificados listados imediatamente acima.

    Para calcular o hash de imagem PE, o Authenticode ordena as seções especificadas na tabela de seção por intervalo de endereços e, em seguida, faz hash da sequência resultante de bytes, passando sobre os 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 um aviso aos depuradores; ele não afeta a integridade real do programa executável. É literalmente possível remover informações de depuração de uma imagem após um produto ter sido entregue 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 Authenticode.

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

Referências

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

Criando, exibindo e gerenciando certificados

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

SignTool

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

Funções ImageHlp