Partilhar via


Formato PE

Esta especificação descreve a estrutura de arquivos executáveis (imagem) e arquivos de objeto na família Windows de sistemas operacionais. Esses arquivos são referidos como Portable Executable (PE) e Common Object File Format (COFF) arquivos, 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 aspetos. 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 Portable Executable (PE) e Common Object File Format (COFF) arquivos, 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:

Designação Descrição
certificado de atributo
Um certificado que é usado para associar declarações verificáveis a uma imagem. Várias declarações diferentes verificáveis podem ser associadas a um arquivo; Uma das mais úteis é uma declaração de um fabricante de software que indica qual é 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, exceto para permitir sua inserção em arquivos de imagem.
carimbo de data/hora
Um carimbo que é usado para diferentes fins 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 Tipo de Depuração. Se o valor do selo for 0 ou 0xFFFFFFFF, ele não representa um carimbo de data/hora real ou significativo.
ponteiro de arquivo
A localização de um item dentro do próprio arquivo, antes de ser processado pelo vinculador (no caso de arquivos de objeto) ou pelo carregador (no caso de arquivos de imagem). Em outras palavras, 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 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, este é o endereço de um item depois que ele é carregado na memória, com o endereço base do arquivo de imagem subtraído dele. O RVA de um item quase sempre difere de sua posição dentro do arquivo no disco (ponteiro de arquivo).
Em um arquivo de objeto, um RVA é menos significativo porque os locais de memória não são atribuídos. Neste caso, um RVA seria um endereço dentro de uma seção (descrito mais adiante nesta tabela), ao qual uma realocação é posteriormente aplicada durante a vinculação. Para simplificar, um compilador deve apenas definir o primeiro RVA em cada seção como zero.
secçã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 no 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íguos. 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 VA deve ser considerado apenas um endereço. Um VA não é tão previsível quanto um RVA porque o carregador pode não carregar a imagem 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 imediatamente antes do cabeçalho PE é a seção MS-DOS 2.0 e é usada apenas para compatibilidade MS-DOS.

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

  • não utilizados

  • Identificador OEM

    Informações OEM

    Deslocamento para cabeçalho PE

  • MS-DOS 2.0 Programa de Stub e Tabela de Realocação

  • não utilizados

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

  • Cabeçalhos de secção

  • Páginas de imagem:

    importar informações

    informações de exportação

    Recolocações de base

    informações sobre o recurso

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

  • Cabeçalho Microsoft COFF

  • Cabeçalhos de secção

  • Dados brutos:

    código

    dados

    informações de depuração

    Recolocaçõ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.

MS-DOS Stub (Apenas imagem)

O stub 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 MS-DOS stub. Esse deslocamento de arquivo é colocado no local 0x3c durante a vinculação.

Assinatura (somente imagem)

Após o stub de MS-DOS, no deslocamento de arquivo especificado na 0x3c de deslocamento, há uma assinatura de 4 bytes que identifica o arquivo como um arquivo de imagem de formato PE. Esta 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.

Deslocamento Tamanho Domínio 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úmerodeSecções
O número de secções. Isso indica o tamanho da tabela de seção, que segue imediatamente os cabeçalhos.
4
4
TimeDateStamp
Os 32 bits baixos do número de segundos desde 00:00 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 de objeto. Para obter uma descrição do formato de cabeçalho, consulte cabeçalho opcional (somente imagem).
18
2
Caraterísticas
Os sinalizadores que indicam os atributos do arquivo. Para valores de sinalizadores específicos, consulte Características.

Tipos de máquinas

O campo Máquina 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 é 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
Alfa 64, espaço de endereçamento de 64 bits
IMAGE_FILE_MACHINE_AM33
0x1d3
Matsushita AM33
IMAGE_FILE_MACHINE_AMD64
0x8664
x64
IMAGE_FILE_MACHINE_ARM
0x1c0
ARM 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 bytes 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 de ponto flutuante
IMAGE_FILE_MACHINE_R4000
0x166
MIPS pequeno endian
IMAGE_FILE_MACHINE_RISCV32
0x5032
RISC-V espaço de endereçamento de 32 bits
IMAGE_FILE_MACHINE_RISCV64
0x5064
RISC-V espaço de endereçamento de 64 bits
IMAGE_FILE_MACHINE_RISCV128
0x5128
RISC-V espaço de endereçamento 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 pequeno-endian WCE v2

Caraterísticas

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

Bandeira 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 preferido. Se o endereço base não estiver disponível, o carregador relata um erro. O comportamento padrão do vinculador é remover relocaçõ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 indica um erro de vinculador.
IMAGE_FILE_LINE_NUMS_STRIPPED
0x0004
Os números de linha COFF foram removidos. Este 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. Este 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
Esta bandeira está reservada para uso futuro.
IMAGE_FILE_BYTES_REVERSED_LO
0x0080
Little endian: o bit menos significativo (LSB) precede o bit mais significativo (MSB) na memória. Este 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 troca.
IMAGE_FILE_SYSTEM
0x1000
O arquivo de imagem é um arquivo de sistema, não um programa de usuário.
IMAGE_FILE_DLL
0x2000
O arquivo de imagem é uma biblioteca de vínculo dinâmico (DLL). Esses arquivos são considerados arquivos executáveis para quase todos os fins, embora não possam ser executados diretamente.
IMAGE_FILE_UP_SYSTEM_ONLY
0x4000
O arquivo deve ser executado somente em uma máquina uniprocessador.
IMAGE_FILE_BYTES_REVERSED_HI
0x8000
Big endian: o MSB precede o LSB na memória. Este 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. Este cabeçalho é opcional no sentido de que alguns arquivos (especificamente, arquivos de objeto) não o têm. 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 nenhuma 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 que uma investigação no arquivo para um diretório de dados específico não vai além SizeOfOptionalHeader. Para obter mais informações, consulte cabeçalho de arquivo COFF (objeto e imagem).

O campo NumberOfRvaAndSizes do cabeçalho opcional também deve ser usado para garantir que nenhuma sonda 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 PE32+ são abordadas nas respetivas secções.

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

Deslocamento (PE32/PE32+) Tamanho (PE32/PE32+) Parte do cabeçalho Descrição
0
28/24
Campos padrão
Campos que são definidos para todas as implementações de COFF, incluindo UNIX.
28/24
68/88
Campos específicos do Windows
Campos adicionais para suportar funcionalidades específicas do Windows (por exemplo, subsistemas).
96/112
Variável
Diretórios de dados
Pares de endereço/tamanho para tabelas especiais encontradas no arquivo de imagem e 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 que sã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+.

Deslocamento Tamanho Domínio 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 inicializados 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
EndereçoOfEntryPoint
O endereço do ponto de entrada relativo à base de imagem quando o arquivo executável é carregado na memória. Para imagens de programas, este é o endereço inicial. Para drivers de dispositivo, este é o endereço da função de inicialização. Um ponto de entrada é opcional para DLLs. Quando nenhum ponto de entrada estiver presente, este 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 este campo adicional, que está ausente em PE32+, seguindo BaseOfCode.

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

Campos de Windows-Specific de cabeçalho opcionais (somente imagem)

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

Deslocamento (PE32/ PE32+) Tamanho (PE32/ PE32+) Domínio Descrição
28/24
4/8
Base de imagens
O endereço preferido do primeiro byte de imagem quando carregado na memória; deve ser um múltiplo de 64 K. O padrão para DLLs é 0x10000000. O padrão para Windows CE EXEs é 0x00010000. O padrão para Windows NT, Windows 2000, Windows XP, Windows 95, Windows 98 e Windows Me é 0x00400000.
32/32
4
SeçãoAlinhamento
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) que é usado para alinhar os dados brutos de 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 da versão principal do sistema operacional necessário.
42/42
2
MinorOperatingSystemVersion
O número da versão secundária do sistema operacional necessário.
44/44
2
MajorImageVersion
O número da versão principal da imagem.
46/46
2
MinorImageVersion
O número da versão secundária da imagem.
48/48
2
MajorSubsystemVersion
O número da versão principal do subsistema.
50/50
2
MinorSubsystemVersion
O número da versão secundária 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 de MS-DOS, cabeçalho PE e cabeçalhos de seção arredondado para um múltiplo de FileAlignment.
64/64
4
Soma de verificação
A soma de verificação do arquivo de imagem. O algoritmo para calcular a soma de verificação é incorporado no IMAGHELP.DLL. Os seguintes 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
DllCharacteristics
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 reservar. Apenas 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 pilha local a reservar. Apenas 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
LoaderFlags
Reservado, deve ser zero.
92/108
4
NúmerodeRvaAndTamanhos
O número de entradas do diretório de dados no restante do cabeçalho opcional. Cada um descreve um local e 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
Aplicação de arranque 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
Isolamento consciente, mas não isole a imagem.
IMAGE_DLLCHARACTERISTICS_ NO_SEH
0x0400
Não utiliza o tratamento de exceções estruturadas (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 relativo ao endereço base da imagem quando a tabela é carregada. O segundo campo indica 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 Domínio 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 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 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 Seção .rsrc.
120/136
8
Tabela de exceções
O endereço e o tamanho da tabela de exceção. Para obter mais informações, consulte Seção .pdata.
128/144
8
Tabela de Certificados
O endereço e o tamanho da tabela de certificados de atributos. Para obter mais informações, consulte A tabela de certificado de atributo (somente imagem).
136/152
8
Tabela de recolocaçã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 inicial e o tamanho dos dados de depuração. Para obter mais informações, consulte 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 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 The Load Configuration Structure (Image Only).
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 Tabela de endereços de importação.
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 Delay-Load Importar tabelas (somente imagem).
208/224
8
Cabeçalho de tempo de execução CLR
O endereço e o tamanho do cabeçalho do 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 atributos. 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 no quadro de secçõ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.

Deslocamento Tamanho Domínio Descrição
0
8
Designação
Uma cadeia de caracteres codificada UTF-8 de 8 bytes e acolchoada em nulo. Se a cadeia de caracteres tiver exatamente 8 caracteres, não haverá terminação nula. Para nomes mais longos, este 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 suportam 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. Este 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, este campo é o endereço do primeiro byte antes da realocação ser aplicada; Para simplificar, os compiladores devem definir isso como zero. Caso contrário, é um valor arbitrário que é subtraído de compensações 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, este deve ser um múltiplo de FileAlignment do cabeçalho opcional. Se for menor que VirtualSize, o restante da seção será preenchido com zero. Como o campo SizeOfRawData é arredondado, mas o campo VirtualSize não, é possível que SizeOfRawData também seja maior que VirtualSize. Quando uma seção contém apenas dados não inicializados, esse campo 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, este 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 obter o melhor desempenho. Quando uma seção contém apenas dados não inicializados, esse campo deve ser zero.
24
4
PointerToRelocações
O ponteiro de 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úmero de recolocações
O número de entradas de recolocação para a secção. Isso é definido como zero para imagens executáveis.
34
2
NúmerodeNúmeros de linha
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
Caraterí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.

Bandeira 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 acolchoada para o próximo limite. Este sinalizador está 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 secção contém comentários ou outras informações. A secção .drectve tem este 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 secçã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 através 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 apenas para arquivos de objeto.
IMAGE_SCN_ALIGN_2BYTES
0x00200000
Alinhe os dados em um limite de 2 bytes. Válido apenas para arquivos de objeto.
IMAGE_SCN_ALIGN_4BYTES
0x00300000
Alinhe os dados em um limite de 4 bytes. Válido apenas para arquivos de objeto.
IMAGE_SCN_ALIGN_8BYTES
0x00400000
Alinhe os dados em um limite de 8 bytes. Válido apenas para arquivos de objeto.
IMAGE_SCN_ALIGN_16BYTES
0x00500000
Alinhe os dados em um limite de 16 bytes. Válido apenas para arquivos de objeto.
IMAGE_SCN_ALIGN_32BYTES
0x00600000
Alinhe os dados em um limite de 32 bytes. Válido apenas para arquivos de objeto.
IMAGE_SCN_ALIGN_64BYTES
0x00700000
Alinhe dados em um limite de 64 bytes. Válido apenas para arquivos de objeto.
IMAGE_SCN_ALIGN_128BYTES
0x00800000
Alinhe os dados em um limite de 128 bytes. Válido apenas para arquivos de objeto.
IMAGE_SCN_ALIGN_256BYTES
0x00900000
Alinhe os dados em um limite de 256 bytes. Válido apenas para arquivos de objeto.
IMAGE_SCN_ALIGN_512BYTES
0x00A00000
Alinhe os dados em um limite de 512 bytes. Válido apenas para arquivos de objeto.
IMAGE_SCN_ALIGN_1024BYTES
0x00B00000
Alinhe os dados em um limite de 1024 bytes. Válido apenas para arquivos de objeto.
IMAGE_SCN_ALIGN_2048BYTES
0x00C00000
Alinhe os dados em um limite de 2048 bytes. Válido apenas para arquivos de objeto.
IMAGE_SCN_ALIGN_4096BYTES
0x00D00000
Alinhe os dados em um limite de 4096 bytes. Válido apenas para arquivos de objeto.
IMAGE_SCN_ALIGN_8192BYTES
0x00E00000
Alinhe os dados em um limite de 8192 bytes. Válido apenas para arquivos de objeto.
IMAGE_SCN_LNK_NRELOC_OVFL
0x01000000
A secção contém recolocações alargadas.
IMAGE_SCN_MEM_DISCARDABLE
0x02000000
A secção pode ser eliminada 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 secção não pode ser paginada.
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 secçã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 for 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 relocaçõ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 a seguem. Assim, uma seção de objeto chamada .text$X realmente contribui para a seção .text na imagem.

No entanto, os caracteres que seguem o "$" determinam a ordenação 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 contíguamente 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 termina junto, após o .text$W contribuições e antes do .text$Y contribuições.

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

Outros conteúdos do ficheiro

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

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 do 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 Secçã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 para cada seção estão localizados no deslocamento de arquivo que foi 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 de 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.

Relocações 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 relocaçõ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.

Deslocamento Tamanho Domínio Descrição
0
4
Endereço virtual
O endereço do item ao qual a realocação é aplicada. Este é o deslocamento desde o início da seção, mais o valor do campo RVA/Deslocamento da seção. Consulte Tabela de Seção (Cabeçalhos de Seção). Por exemplo, se o primeiro byte da seção tiver um endereço de 0x10, o terceiro byte terá um endereço de 0x12.
4
4
SymbolTableIndex
Um índice baseado em zero na tabela de símbolos. Este símbolo indica o endereço a utilizar para a recolocaçã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
Tipo
Um valor que indica o tipo de realocação que deve ser executada. Os tipos de realocação válidos dependem do tipo de máquina. 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 registo de recolocação indica que tipo de recolocação deve ser efetuada. Diferentes tipos de realocação são definidos para cada tipo de máquina.

Processadores x64

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

Constante Valor Descrição
IMAGE_REL_AMD64_ABSOLUTE
0x0000
A recolocaçã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 dar 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 de extensão.
IMAGE_REL_AMD64_SSPAN32
0x0010
Um valor dependente de extensão assinada 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 recolocação é ignorada.
IMAGE_REL_ARM_ADDR32
0x0001
O VA de 32 bits do destino.
IMAGE_REL_ARM_ADDR32NB
0x0002
O RVA de 32 bits do 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 dar suporte a informações de depuração e armazenamento local de thread estático.
IMAGE_REL_ARM_MOV32
0x0010
O VA de 32 bits do destino. Essa realocação é aplicada usando uma instrução MOVW para os 16 bits baixos, seguida por um MOVT para os 16 bits altos.
IMAGE_REL_THUMB_MOV32
0x0011
O VA de 32 bits do destino. Essa realocação é aplicada usando uma instrução MOVW para os 16 bits baixos, seguida por um MOVT para os 16 bits altos.
IMAGE_REL_THUMB_BRANCH20
0x0012
A instrução é corrigida com o deslocamento relativo de 21 bits para o destino alinhado de 2 bytes. A parte menos significativa do deslocamento é sempre zero e não é armazenada. Essa realocação corresponde a uma instrução B condicional de 32 bits do Thumb-2.
Não utilizado
0x0013
IMAGE_REL_THUMB_BRANCH24
0x0014
A instrução é corrigida com o deslocamento relativo de 25 bits para o destino alinhado de 2 bytes. A parte menos significativa do deslocamento é zero e não é armazenada. Esta 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 recolocação só é válida quando se segue imediatamente a uma 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 recolocação é ignorada.
IMAGE_REL_ARM64_ADDR32
0x0001
O VA de 32 bits do destino.
IMAGE_REL_ARM64_ADDR32NB
0x0002
O RVA de 32 bits do alvo.
IMAGE_REL_ARM64_BRANCH26
0x0003
O deslocamento relativo de 26 bits para o destino, para instruções B e BL.
IMAGE_REL_ARM64_PAGEBASE_REL21
0x0004
A base da página do destino, para instrução ADRP.
IMAGE_REL_ARM64_REL21
0x0005
O deslocamento relativo de 12 bits para o alvo, para instrução ADR
IMAGE_REL_ARM64_PAGEOFFSET_12A
0x0006
O deslocamento de página de 12 bits do destino, para instruções ADD/ADDS (imediato) com deslocamento zero.
IMAGE_REL_ARM64_PAGEOFFSET_12L
0x0007
O deslocamento de página de 12 bits do destino, para instrução LDR (indexado, 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 dar 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 alvo, para instruções ADD/ADDS (imediato) com deslocamento zero.
IMAGE_REL_ARM64_SECREL_HIGH12A
0x000A
Bit 12:23 de deslocamento de seção do alvo, 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 relocações específicas de SH5 são anotadas como SHM (SH Media).

Constante Valor Descrição
IMAGE_REL_SH3_ABSOLUTE
0x0000
A recolocação é ignorada.
IMAGE_REL_SH3_DIRECT16
0x0001
Uma referência ao local de 16 bits que contém o VA do símbolo de destino.
IMAGE_REL_SH3_DIRECT32
0x0002
O VA de 32 bits do símbolo de destino.
IMAGE_REL_SH3_DIRECT8
0x0003
Uma referência ao local de 8 bits que contém o VA do símbolo de destino.
IMAGE_REL_SH3_DIRECT8_WORD
0x0004
Uma referência à instrução de 8 bits que contém o VA efetivo de 16 bits do símbolo de destino.
IMAGE_REL_SH3_DIRECT8_LONG
0x0005
Uma referência à instrução de 8 bits que contém o VA efetivo de 32 bits do símbolo de destino.
IMAGE_REL_SH3_DIRECT4
0x0006
Uma referência ao local de 8 bits cujos 4 bits baixos contêm o VA do símbolo de destino.
IMAGE_REL_SH3_DIRECT4_WORD
0x0007
Uma referência à instrução de 8 bits cujos 4 bits baixos contêm o VA efetivo de 16 bits do símbolo de destino.
IMAGE_REL_SH3_DIRECT4_LONG
0x0008
Uma referência à instrução de 8 bits cujos 4 bits baixos contêm o VA efetivo de 32 bits do símbolo de destino.
IMAGE_REL_SH3_PCREL8_WORD
0x0009
Uma referência à instrução de 8 bits que contém o deslocamento relativo efetivo de 16 bits do símbolo de destino.
IMAGE_REL_SH3_PCREL8_LONG
0x000A
Uma referência à instrução de 8 bits que contém o deslocamento relativo efetivo de 32 bits do símbolo de destino.
IMAGE_REL_SH3_PCREL12_WORD
0x000B
Uma referência à instrução de 16 bits cujos 12 bits baixos contêm o deslocamento relativo efetivo de 16 bits do símbolo de destino.
IMAGE_REL_SH3_STARTOF_SECTION
0x000C
Uma referência a um local de 32 bits que é o VA da seção que contém o símbolo de destino.
IMAGE_REL_SH3_SIZEOF_SECTION
0x000D
Uma referência ao local de 32 bits que é o tamanho da seção que contém o símbolo de destino.
IMAGE_REL_SH3_SECTION
0x000E
O índice de seção de 16 bits da seção que contém o destino. 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 dar suporte a informações de depuração e armazenamento local de thread estático.
IMAGE_REL_SH3_DIRECT32_NB
0x0010
O RVA de 32 bits do símbolo de destino.
IMAGE_REL_SH3_GPREL4_LONG
0x0011
GP parente.
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 16 bits baixos do endereço de 32 bits.
IMAGE_REL_SHM_REFHALF
0x0015
Os 16 bits altos do endereço de 32 bits.
IMAGE_REL_SHM_RELLO
0x0016
Os 16 bits baixos do endereço relativo.
IMAGE_REL_SHM_RELHALF
0x0017
Os 16 bits altos do endereço relativo.
IMAGE_REL_SHM_PAIR
0x0018
A realocação é válida apenas quando se segue imediatamente a 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 recolocação é ignorada.
IMAGE_REL_PPC_ADDR64
0x0001
O VA de 64 bits do destino.
IMAGE_REL_PPC_ADDR32
0x0002
O VA de 32 bits do destino.
IMAGE_REL_PPC_ADDR24
0x0003
Os 24 bits baixos do VA do alvo. Isso é válido somente quando o símbolo de destino é absoluto e pode ser estendido ao seu valor original.
IMAGE_REL_PPC_ADDR16
0x0004
Os 16 bits baixos do VA do alvo.
IMAGE_REL_PPC_ADDR14
0x0005
Os 14 bits baixos do VA do alvo. Isso é válido somente quando o símbolo de destino é absoluto e pode ser estendido ao seu valor original.
IMAGE_REL_PPC_REL24
0x0006
Um deslocamento relativo ao PC de 24 bits para a localização do símbolo.
IMAGE_REL_PPC_REL14
0x0007
Um deslocamento relativo ao PC de 14 bits para a localização 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 dar suporte a informações de depuração e armazenamento local de thread estático.
IMAGE_REL_PPC_SECTION
0x000C
O índice de seção de 16 bits da seção que contém o destino. 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 dar suporte a informações de depuração e armazenamento local de thread estático.
IMAGE_REL_PPC_REFHI
0x0010
Os 16 bits altos do VA de 32 bits do 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 foram retirados do local que está sendo realocado.
IMAGE_REL_PPC_REFLO
0x0011
Os 16 bits baixos do VA do alvo.
IMAGE_REL_PPC_PAIR
0x0012
Uma recolocação que só é válida quando se segue imediatamente a uma recolocaçã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 recolocação é ignorada.
IMAGE_REL_I386_DIR16
0x0001
Não suportado.
IMAGE_REL_I386_REL16
0x0002
Não suportado.
IMAGE_REL_I386_DIR32
0x0006
O VA de 32 bits do alvo.
IMAGE_REL_I386_DIR32NB
0x0007
RVA de 32 bits do alvo.
IMAGE_REL_I386_SEG12
0x0009
Não suportado.
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 dar suporte a informações de depuração e armazenamento local de thread estático.
IMAGE_REL_I386_TOKEN
0x000C
O token CLR.
IMAGE_REL_I386_SECREL7
0x000D
Um deslocamento de 7 bits da base da seção que contém o destino.
IMAGE_REL_I386_REL32
0x0014
O deslocamento relativo de 32 bits para o destino. Isso suporta a 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 relocaçõ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 recolocação é ignorada.
IMAGE_REL_IA64_IMM14
0x0001
A realocação de instrução pode ser seguida por uma realocação ADDEND cujo valor é adicionado ao endereço de destino antes de ser inserido no slot especificado no pacote IMM14. O alvo de realocação deve ser absoluto ou a imagem deve ser fixa.
IMAGE_REL_IA64_IMM22
0x0002
A realocação de instrução pode ser seguida por uma realocação ADDEND cujo valor é adicionado ao endereço de destino antes de ser inserido no slot especificado no pacote IMM22. O alvo de realocação deve ser absoluto ou a imagem deve ser fixa.
IMAGE_REL_IA64_IMM64
0x0003
O número de ranhura desta recolocaçã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 desta realocação devem conter o número do slot, enquanto o restante é o endereço do pacote. O pacote é corrigido com o deslocamento relativo de 25 bits para o destino alinhado de 16 bits. Os 4 bits baixos do deslocamento são zero e não são armazenados.
IMAGE_REL_IA64_GPREL22
0x0009
A realocação de instrução pode ser seguida por uma realocação ADDEND cujo valor é adicionado ao endereço de destino e, em seguida, um deslocamento relativo 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 ao 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 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 desde o início da seção.
IMAGE_REL_IA64_SECREL64I
0x000D
O número da ranhura para esta recolocaçã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 desde o início da seção.
IMAGE_REL_IA64_SECREL32
0x000E
O endereço dos dados a serem corrigidos com o deslocamento de 32 bits do destino desde o início de sua seção.
IMAGE_REL_IA64_DIR32NB
0x0010
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 realocá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 alvos realocá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 realocá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 realocá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 se encaixar 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 zero e descartados) no slot 2.
IMAGE_REL_IA64_PCREL60F
0x0017
Uma correção relativa ao PC de 60 bits. Se o deslocamento de destino se encaixar em um campo de 25 bits assinado, converta todo o pacote em um pacote MFB com NOP. F no slot 1 e uma instrução BR de 25 bits (4 bits mais baixos todos zero e descartados) no slot 2.
IMAGE_REL_IA64_PCREL60I
0x0018
Uma correção relativa ao PC de 60 bits. Se o deslocamento de destino se encaixar em um campo de 25 bits assinado, converta todo o pacote em um pacote MIB com NOP. Eu 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_PCREL60M
0x0019
Uma correção relativa ao PC de 60 bits. Se o deslocamento de destino se encaixar em um campo de 25 bits assinado, converta todo o pacote em um pacote MMB com NOP. M no slot 1 e uma instrução BR de 25 bits (4 bits mais baixos todos zero e descartados) 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 se segue imediatamente a uma das seguintes realocações: IMM14, IMM22, IMM64, GPREL22, LTOFF22, LTOFF64, SECREL22, SECREL64I ou SECREL32. Seu valor contém a adenda a ser aplicada 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 recolocaçã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 26 bits baixos 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 16 bits baixos 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 dar 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 destino desde o início de sua seção. Uma recolocação IMAGE_REL_MIPS_PAIR deve seguir-se imediatamente a 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 26 bits baixos do VA do alvo. Isso suporta a instrução MIPS16 JAL.
IMAGE_REL_MIPS_REFWORDNB
0x0022
RVA de 32 bits do alvo.
IMAGE_REL_MIPS_PAIR
0x0025
A recolocação só é válida quando se segue imediatamente a uma recolocaçã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 recolocação é ignorada.
IMAGE_REL_M32R_ADDR32
0x0001
O VA de 32 bits do alvo.
IMAGE_REL_M32R_ADDR32NB
0x0002
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 estendido por sinal
IMAGE_REL_M32R_PCREL16
0x0006
O deslocamento de 16 bits do alvo do PC, deslocado para a esquerda por 2 bits e estendido por sinal
IMAGE_REL_M32R_PCREL8
0x0007
O deslocamento de 8 bits do alvo do PC, deslocado para a esquerda por 2 bits e estendido por sinal
IMAGE_REL_M32R_REFHALF
0x0008
As 16 MSBs do VA alvo.
IMAGE_REL_M32R_REFHI
0x0009
Os 16 MSBs do VA alvo, ajustados para a extensão do 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 LSB do VA alvo.
IMAGE_REL_M32R_PAIR
0x000B
A recolocação deve seguir-se à recolocação da 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 dar suporte a informações de depuração e armazenamento local de thread estático.
IMAGE_REL_M32R_TOKEN
0x000E
O token CLR.

 

Números de linha COFF (preterido)

Os números 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 com 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.

Deslocamento Tamanho Domínio 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
Número da linha
Quando diferente de zero, este 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 Type é uma união de dois campos de 4 bytes: SymbolTableIndex e VirtualAddress.

Deslocamento Tamanho Domínio Descrição
0
4
SymbolTableIndex
Usado quando Linenumber é zero: índice para entrada de tabela de símbolo 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, ele contém o VA dentro da seção .

 

Um registro de número de linha pode definir o campo Linenumber como zero e apontar para uma definição de função na tabela de símbolos ou pode funcionar como uma entrada de número de linha padrão fornecendo um inteiro positivo (número de linha) e o endereço correspondente no código 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, ele 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 Linenumber 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 definidos como zero). Em seguida, seguir-se-iam registos com valores de número de linha de 1, 2 e 3, correspondendo às linhas de origem, conforme mostrado:

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

Tabela de símbolos COFF

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

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

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

Deslocamento Tamanho Domínio Descrição
0
8
Nome (*)
O nome do símbolo, representado por uma união de três estruturas. Uma matriz de 8 bytes é usada se o nome não tiver mais de 8 bytes de comprimento. 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 deste campo depende de SectionNumber e StorageClass. Um significado típico é o endereço relocável.
12
2
Número da Secção
O inteiro assinado que identifica a seção, usando um índice baseado em um na tabela de seção. Alguns valores têm um significado especial, conforme definido na seção 5.4.2, "Valores de número de seção".
14
2
Tipo
Um número que representa o tipo. As ferramentas da Microsoft definem este 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 Storage Class.
17
1
NúmerodeAuxSymbols
O número de entradas da tabela de símbolos auxiliares que seguem este registo.

 

Zero ou mais registros auxiliares da tabela de símbolos seguem imediatamente cada registro padrão da tabela de símbolos. No entanto, normalmente não mais do que um registro auxiliar de tabela de símbolos segue um registro de tabela de símbolos padrão (exceto para registros .file com nomes de arquivo longos). Cada registo auxiliar tem o mesmo tamanho que um registo de tabela de símbolos padrão (18 bytes), mas em vez de definir um novo símbolo, o registo 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 tabelas 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 de 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 fornece um deslocamento na tabela de cadeia de caracteres. Para determinar se o nome em si ou um deslocamento é dado, teste os primeiros 4 bytes para igual a zero.

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

Deslocamento Tamanho Domínio Descrição
0
8
Nome curto
Uma matriz de 8 bytes. Esta matriz é preenchida com nulos à direita se o nome tiver menos de 8 bytes de comprimento.
0
4
Zeros
Um campo que é definido como todos os zeros se o nome tiver mais de 8 bytes.
4
4
Deslocamento
Um deslocamento na tabela de cadeia de caracteres.

 

Valores de número de 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, este campo é um inteiro assinado e pode ter valores negativos. Os seguintes valores, 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 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 realocá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 COFF estão listados aqui para integridade.

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 vazios e funções
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 de 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
Um sindicato
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, retorno de função ou matriz do tipo base especificado no LSB. As ferramentas da Microsoft usam esse campo apenas para indicar se o símbolo é uma função, para que os dois únicos valores resultantes sejam 0x0 e 0x20 para o campo Tipo. No entanto, outras ferramentas podem usar este 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. Por conseguinte, o valor especial -1 deve ser entendido como o 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 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 fim da função, para fins de depuração.
IMAGE_SYM_CLASS_NULL
0
Nenhuma classe de armazenamento atribuída.
IMAGE_SYM_CLASS_AUTOMATIC
1
A variável automática (pilha). O campo Valor especifica o deslocamento do quadro da 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 especifica 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 representa um nome de seção.
IMAGE_SYM_CLASS_REGISTER
4
Uma variável de registo. O campo Valor especifica o número do registo.
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 de nome de marca da União.
IMAGE_SYM_CLASS_TYPE_DEFINITION
13
Uma entrada Typedef.
IMAGE_SYM_CLASS_UNDEFINED_STATIC
14
Uma declaração de dados estáticos.
IMAGE_SYM_CLASS_ENUM_TAG
15
Uma entrada de nome de marca de tipo enumerado.
IMAGE_SYM_CLASS_MEMBER_OF_ENUM
16
Um membro de uma enumeração. O campo 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ímbolos 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 STATIC 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 design COFF tradicional também inclui formatos de gravação auxiliares para matrizes 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 seguintes itens: 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 de UNDEFINED (0) não define a função e não tem um registro auxiliar. Os registos de símbolos de definição de função são seguidos de um registo auxiliar no formato descrito abaixo:

Deslocamento Tamanho Domínio Descrição
0
4
Índice de Tags
O índice da tabela de símbolos do registro de símbolo .bf (função start) 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, o SizeOfRawData no cabeçalho da seção será maior ou igual a este campo, dependendo das considerações de alinhamento.
8
4
PointerToLinenumber
O deslocamento de arquivo da primeira entrada de número de linha COFF para a função, ou zero se não existir. Para obter mais informações, consulte COFF Line Numbers (Deprecated).
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, este campo é definido como zero.
16
2
Não utilizado

 

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

Para cada definição de função na tabela de símbolos, três itens descrevem o início, o fim e o número de linhas. Cada um destes 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 registos dos símbolos .bf e .ef (mas não os registos .lf) são seguidos de um registo auxiliar com o seguinte formato:

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

 

Formato Auxiliar 3: Externos fracos

"Externos fracos" são um mecanismo para arquivos de objeto que permite flexibilidade no momento 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 ligada, então uma referência externa ao símbolo é 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, é definido no módulo que contém a referência fraca para SYM1.

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

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

 

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

Formato Auxiliar 4: Arquivos

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

Deslocamento Tamanho Domínio Descrição
0
18
Nome do arquivo
Uma cadeia de caracteres ANSI que dá o nome do arquivo de origem. Este é preenchido com nulos se for menor do 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 classe de armazenamento STATIC (3). O registo auxiliar fornece informações sobre a secção a que se refere. Assim, ele duplica algumas das informações no cabeçalho da seção.

Deslocamento Tamanho Domínio 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úmero de recolocações
O número de entradas de recolocação para a secção.
6
2
NúmerodeNúmeros de linha
O número de entradas de número de linha para a seção.
8
4
Soma de verificação
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 para a 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. Isto aplica-se se a secção for uma secção COMDAT.
15
3
Não utilizado

 

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 sinalizador IMAGE_SCN_LNK_COMDAT é 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 das seções COMDAT.

O primeiro símbolo que tem o valor da seção da seção COMDAT deve ser o símbolo da seção. Este símbolo tem o nome da secção, o campo Valor igual a zero, o número da secçã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 registo auxiliar. O segundo símbolo é chamado de "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 secção que defina o mesmo símbolo COMDAT pode ser ligada; os restantes são removidos.
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 tiverem o 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 secção está ligada se uma outra secção COMDAT estiver ligada. Esta outra secção é indicada pelo campo Número do registo de símbolos auxiliares para a definição da secçã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 secção a que esta secção está associada deve ser uma secção COMDAT, que pode ser outra secção COMDAT associativa. A cadeia de associação de uma seção associativa COMDAT 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 definida.
IMAGE_COMDAT_SELECT_LARGEST
6
O vinculador escolhe a maior definição entre todas as definições para este 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.

Deslocamento Tamanho Domínio Descrição
0
1
bTipo de Aux
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 cordas COFF

Imediatamente após a tabela de símbolos COFF está a tabela de cadeia de caracteres COFF. A posição desta 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 resto 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.

A seguir ao 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 certificados de atributo (somente imagem)

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

Deslocamento Tamanho Domínio 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
Veja a seguir
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, desde o início da entrada de certificado de atributo atual. Isso continua até que a soma dos valores dwLength arredondados 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 Tamanho, a tabela de certificado de atributo ou o campo Tamanho estará corrompido.

Por exemplo, se a Entrada de Tabela de Certificados do Diretório de Dados de Cabeçalho Opcional contiver:

virtual address = 0x5000
size = 0x1000

O primeiro certificado começa no deslocamento 0x5000 a partir do início do arquivo no disco. Para avançar através de 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 encontrar 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 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 toda a tabela.

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 atributos 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 WIN_CERTIFICATE wRevision incluem (mas não estão limitadas a) o seguinte.

Valor Designação 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 WIN_CERTIFICATE membro wCertificateType 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 Designação Observações
0x0001
WIN_CERT_TYPE_X509
bCertificate contém um certificado X.509
Não suportado
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
Não suportado

 

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 de PKCS#7 SignedData. Para obter detalhes sobre o formato de assinatura digital Authenticode, consulte Windows Authenticode Portable Executable Signature Format.

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

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)

Este comprimento deve incluir o tamanho de qualquer preenchimento utilizado para satisfazer o requisito de que cada estrutura WIN_CERTIFICATE esteja alinhada com palavras quadriagudas:

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

O tamanho da Tabela de Certificados -especificado na entrada Tabela de Certificados no 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 ImageHlp Functions.

Dados do certificado

Conforme indicado na seção anterior, os certificados na tabela de certificados de atributos 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 em que o algoritmo de hash produz um resumo de mensagem que está relacionado à integridade de um arquivo. No entanto, uma soma de verificação é produzida por um algoritmo simples e é usada principalmente para detetar 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 deteta corrupção de arquivos. 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 detetar modificações intencionais e até mesmo sutis em um arquivo, como aquelas introduzidas por vírus, hackers ou programas de cavalo de Troia.

Quando incluído em um certificado, o resumo da imagem deve excluir determinados campos na imagem PE, como a entrada Checksum e Certificate Table em Optional Header Data Directories. 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 os certificados são adicionados ou removidos de um arquivo PE. Com base nos parâmetros que são passados para ImageGetDigestStream , outros dados da imagem PE podem ser omitidos do cálculo de hash. Para obter um link para a página de referência da função, consulte Referências.

Delay-Load Importar tabelas (somente imagem)

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

A tabela de diretórios Delay-Load

A tabela de diretório delay-load é a contrapartida da tabela de diretório de importação. Ele pode ser recuperado através da entrada Delay Import Descriptor na lista opcional de diretórios de dados de cabeçalho (deslocamento 200). A tabela está organizada da seguinte forma:

Deslocamento Tamanho Domínio Descrição
0
4
Atributos
Deve ser zero.
4
4
Designação
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 atraso de carregamento.
12
4
Tabela de endereços de importação de atraso
O RVA da tabela de endereços de importação de carga tardia. Para obter mais informações, consulte Tabela de endereços de importação de atraso (IAT).
16
4
Tabela de nomes de importação de atraso
O RVA da tabela de nomes delay-load, que contém os nomes das importações que podem precisar ser carregadas. Isso corresponde ao layout da tabela de nomes de importação. Para obter mais informações, 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-carga, se existir. Esta é uma cópia exata da tabela de endereços de importação de atraso. Se o chamador descarregar a DLL, esta tabela deve 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 bloqueio corretamente.
28
4
Carimbo de data/hora
O carimbo de data/hora da DLL à qual esta imagem foi vinculada.

 

As tabelas referenciadas nesta estrutura de dados são organizadas e ordenadas tal como as suas homólogas para as importações tradicionais. Para obter detalhes, consulte Seção .idata.

Atributos

Até o momento, nenhum sinalizador de atributo está definido. O vinculador define esse campo como zero na imagem. Este 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.

Designação

O nome da DLL a ser carregada com atraso reside na seção de dados somente leitura da imagem. É 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 através do campo pIAT. O auxiliar de carga tardia 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 vinculada a atraso e carimbo de data/hora

A tabela de endereços de importação vinculada a 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.

Atrasar a descarga da tabela de endereços de importação

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 lidar com uma solicitação de descarga 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 a UIAT gravada sobre o IAT para restaurar tudo ao seu estado de pré-carregamento.

Secções Especiais

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

No entanto, algumas seções COFF têm significados especiais quando encontradas em arquivos de objeto ou arquivos de imagem. Ferramentas e carregadores reconhecem essas seções porque 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 desta 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 secção Conteúdo Caraterísticas
.bss
Dados não inicializados (formato livre)
IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
.cormeta
Metadados CLR que indicam que o arquivo de objeto contém código gerenciado
IMAGE_SCN_LNK_INFO
.data
Dados inicializados (formato livre)
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
.debug$F
Informações de depuração de FPO geradas (somente objeto, somente arquitetura x86 e agora obsoleta)
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
.debug$P
Tipos de depuração pré-compilados (somente objeto)
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
.debug$S
Símbolos de depuração (somente objeto)
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
.debug$T
Tipos de depuração (somente objeto)
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
.drective
Opções 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 suportar atributos IDL. Para obter informações, consulte "Atributos IDL" em Referências no final deste tópico.
IMAGE_SCN_LNK_INFO
.pdata
Informações sobre exceções
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
.rdata
Dados inicializados somente leitura
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
.reloc
Relocações 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; Este 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; Este 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; Este 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 (formato livre e somente x86/object)
IMAGE_SCN_LNK_INFO Contém o índice de símbolos 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 | IMAGE_SCN_MEM_READ
.tls
Armazenamento thread-local (somente objeto)
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
.tls$
Armazenamento thread-local (somente objeto)
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
.vsdata
Dados inicializados relativos ao GP (formato livre e apenas 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 forma 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 no espaço de endereço da imagem. Uma seção .debug existe somente quando as informações de depuração são mapeadas no espaço de endereço.

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

Os arquivos de imagem contêm um diretório de depuração opcional que indica qual forma de informação de depuração está presente e onde ela está. Este 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 existir), 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 no espaço de endereço em tempo de execução). Se estiver mapeado, o RVA é o seu endereço.

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

Deslocamento Tamanho Domínio Descrição
0
4
Caraterí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 Major:
O número da versão principal do formato de dados de depuração.
10
2
Versão Menor
O número da versão secundária do formato de dados de depuração.
12
4
Tipo
O formato das informações de depuração. Este campo permite o suporte de vários depuradores. Para obter mais informações, consulte Debug Type.
16
4
SizeOfData
O tamanho dos dados de depuração (não incluindo o diretório de depuração em si).
20
4
EndereçoOfRawData
O endereço dos dados de depuração quando carregados, em relação à base de imagem.
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 Type 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 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 dos arquivos.
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 do ponteiro do 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 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 da 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 construir o arquivo PE/COFF.
IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS 20 Bits de características 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 é 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 hora reais quando um arquivo PE ou dados específicos relacionados dentro do PE são produzidos. Os dados brutos dessa entrada de depuração podem estar vazios ou podem conter um valor de hash calculado precedido por um valor de quatro bytes que representa o 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 de Windows-Specific de cabeçalho opcionais (somente imagem).

Características da DLL estendida

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

Constante Valor Descrição
IMAGE_DLLCHARACTERISTICS_EX_CET_COMPAT 0x0001 A imagem é compatível com a tecnologia de imposição de fluxo de controle (CET) Shadow Stack.
IMAGE_DLLCHARACTERISTICS_EX_FORWARD_CFI_COMPAT 0x0040 Todos os alvos 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 dianteira, como instruções x86 CET-Indirect Branch Tracking (IBT) ou ARM Branch Target Identification (BTI). 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 um .debug$S subseção.

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

O vinculador reconhece esses registros de .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 tenham 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 do vinculador para informações de depuração da Microsoft

Para suportar informações de depuração, o vinculador:

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

  • Processa esses dados juntamente 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 ele.

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 .drectve nome da seção. 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 que são 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 deve 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 de vinculação dinâmica. Os símbolos exportados geralmente são encontrados em DLLs, mas as DLLs também podem importar símbolos.

Uma visão geral da estrutura geral da seção de exportação é descrita abaixo. As tabelas descritas são geralmente contíguas no arquivo na ordem mostrada (embora isso não seja 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ório 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.
Exportar tabela de endereços
Uma matriz de RVAs de símbolos exportados. Estes são os endereços reais das funções exportadas e dados dentro do código executável e seções de dados. Outros arquivos de imagem podem importar um símbolo usando um índice para esta 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 de exportação públicos, classificados em ordem crescente.
Tabela ordinal
Uma matriz dos ordinais que correspondem aos membros da tabela de ponteiros 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 ponteiros de nome apontam para esta área. Estes 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 pesquisa a tabela de ponteiro de nome para uma cadeia de caracteres correspondente. Se uma cadeia de caracteres correspondente for encontrada, o ordinal associado será identificado procurando o membro correspondente na tabela ordinal (ou seja, o membro da tabela ordinal com o mesmo índice que o ponteiro de cadeia 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 ponteiros de nome por 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ório de exportação

As informações do símbolo de exportação começam com a tabela de 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.

Deslocamento Tamanho Domínio 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 das versões principal e secundária podem ser definidos pelo utilizador.
10
2
Versão Secundária
O número da versão secundária.
12
4
Designação: RVA
O endereço da cadeia de caracteres ASCII que contém o nome da DLL. Este 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, relativo à base da imagem.
32
4
Nome Ponteiro RVA
O endereço da tabela de ponteiro de nome de exportação, relativo à 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.

 

Exportar tabela de endereços

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 é um encaminhador RVA, que nomeia um símbolo em outra DLL.

Deslocamento Tamanho Domínio Descrição
0
4
Exportação RVA
O endereço do símbolo exportado quando carregado na memória, relativo à base da imagem. Por exemplo, o endereço de uma função exportada.
0
4
Transitário 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 encaminhador RVA exporta uma definição de alguma outra imagem, fazendo parecer que está sendo exportada pela imagem atual. Assim, o símbolo é simultaneamente importado e exportado.

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.

Exportar tabela de ponteiro de nome

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 é definido somente se a tabela de ponteiro de nome de exportação contiver um ponteiro para ele.

Tabela ordinal de exportação

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 natural do campo. Essas duas tabelas, na verdade, operam como uma tabela, na qual a coluna Ponteiro de Nome de Exportação aponta para um nome público (exportado) e a coluna Ordinal de Exportação fornece o ordinal correspondente para esse nome público. Um membro da tabela de ponteiro de nome de exportação e um membro da tabela ordinal de exportação são associados por terem a mesma posição (índice) em suas respetivas matrizes.

Assim, quando a tabela de ponteiro de nome de exportação é pesquisada e uma string correspondente é encontrada na posição i, o algoritmo para encontrar o RVA do símbolo e 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 reais da cadeia de caracteres que foram apontados pela tabela de ponteiro de nome de exportação. As cadeias de caracteres nesta tabela são nomes públicos que outras imagens podem usar para importar os símbolos. Esses nomes de exportação pública 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 pode 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 secçã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 esquema de ficheiro 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

  • Hint-Name Tabela

Tabela de diretório 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 de diretório de importação tem o seguinte formato:

Deslocamento Tamanho Domínio Descrição
0
4
Tabela de Pesquisa de Importação 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 este campo.)
4
4
Carimbo de data/hora
O carimbo que é 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
Corrente de Forwarder
O índice da primeira referência do transitário.
12
4
Designação: RVA
O endereço de uma cadeia de caracteres ASCII que contém o nome da DLL. Este endereço é relativo à base da imagem.
16
4
Importar tabela de endereços RVA (tabela Thunk)
O RVA da tabela de endereços de importação. O conteúdo desta 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. Neste 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 por nome. Bit é mascarado como 0x80000000 para PE32, 0x8000000000000000 para PE32+.
15-0
16
Número ordinal
Um número ordinal de 16 bits. Este campo é 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 dicas/nomes. Este campo é usado somente se o campo de 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:

Deslocamento Tamanho Domínio Descrição
0
2
Sugestão
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
Designação
Uma cadeia de caracteres ASCII que contém o nome a ser importado. Esta é 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 é encerrada por um byte nulo.
*
0 ou 1
Almofada
Um byte zero pad à direita que aparece após o byte nulo à direita, se necessário, para alinhar a próxima entrada em um limite par.

 

Importar tabela de endereços

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 secção .pdata

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

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

Deslocamento Tamanho Domínio Descrição
0
4
Iniciar Endereço
O VA 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 para o manipulador.
16
4
Endereço final 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:

Deslocamento Tamanho Domínio Descrição
0
4
Iniciar Endereço
O VA 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 estiver 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:

Deslocamento Tamanho Domínio Descrição
0
4
Iniciar Endereço
O RVA da função correspondente.
4
4
Endereço final
O RVA do final da função.
8
4
Informações sobre o desenrolar
O RVA da informação de descontrair.

 

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 relocações de base que são resolvidas pelo vinculador, a menos que a imagem de carga não possa ser carregada na base de imagem especificada no cabeçalho PE.

Bloco de realocação de base

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

Deslocamento Tamanho Domínio Descrição
0
4
Página RVA
A base de imagem mais a página RVA são adicionadas 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:

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

 

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

Tipos de realocação de base

Constante Valor Descrição
IMAGE_REL_BASED_ABSOLUTE
0
A realocação da base é ignorada. Este tipo pode ser usado para preencher um bloco.
IMAGE_REL_BASED_HIGH
1
A realocação de base adiciona os altos 16 bits da diferença ao campo de 16 bits no offset. O campo de 16 bits representa o alto valor de uma palavra de 32 bits.
IMAGE_REL_BASED_LOW
2
A realocação de base adiciona os 16 bits baixos da diferença ao campo de 16 bits no deslocamento. O campo de 16 bits representa a metade baixa 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 altos 16 bits da diferença ao campo de 16 bits no offset. O campo de 16 bits representa o alto valor de uma palavra de 32 bits. Os 16 bits baixos do valor de 32 bits são armazenados na palavra de 16 bits que segue essa realocação de base. Isto significa que esta relocalização da base ocupa duas faixas horárias.
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 aplica-se aos altos 20 bits 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 aplica-se aos baixos 12 bits de um endereço absoluto de 32 bits formado em RISC-V formato de instrução 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 aplica-se aos baixos 12 bits de um endereço absoluto de 32 bits formado em RISC-V formato de instrução 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 aplica-se 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 aplica-se 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 secçã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 suporta 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 forma, sem usar a API do Windows:

__declspec (thread) int tlsFlag = 1;

Para dar 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 terminação por thread e o índice TLS, que são explicados na discussão a seguir.

Observação

Antes do Windows Vista, os objetos de dados TLS declarados estaticamente só podiam 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 LoadLibrary API. No entanto, começando com o Windows Vista, melhorias foram feitas no carregador do Windows para suportar melhor o 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 se forem carregadas dinamicamente usando LoadLibrary. O carregador é capaz de alocar slots TLS para tais DLLs no momento do carregamento, atenuando as limitações presentes em versões anteriores do Windows.

 

Observação

As referências a deslocamentos de 32 bits e multiplicadores de índice de 4 aplicam-se 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 através das seguintes etapas:

  1. No momento do link, o vinculador define o campo Endereço do índice do diretório TLS. Este 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 lá para criar o diretório TLS. Outros compiladores que suportam TLS e trabalham com o vinculador da Microsoft devem usar essa mesma técnica.

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

  3. O carregador atribui o valor do índice TLS ao local indicado pelo campo 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 nesta matriz fornece a localização dos dados TLS para um determinado módulo (EXE ou DLL) dentro do programa. O índice TLS indica qual membro da matriz usar. O índice é um número (significativo apenas para o sistema) que identifica o módulo.

O diretório TLS

O diretório TLS tem o seguinte formato:

Deslocamento (PE32/ PE32+) Tamanho (PE32/ PE32+) Domínio Descrição
0
4/8
Dados brutos Start 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 cada vez que um thread é criado, portanto, ele não deve ser corrompido. Note 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 para o preenchimento zero. Tal como acontece com o campo Raw Data Start VA, 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. Este local está em uma seção de dados comum, para que possa ser dado um nome simbólico que é 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 preenchimento zero
O tamanho em bytes do modelo, além dos dados inicializados delimitados pelos campos VA inicial de dados brutos e VA 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 não zero inicializados.
20/36
4
Caraterísticas
Os quatro bits [23:20] descrevem informações de alinhamento. Os valores possíveis são aqueles definidos como IMAGE_SCN_ALIGN_*, que também são usados para descrever o alinhamento da seção em arquivos de objeto. Os outros 28 bits são reservados para uso futuro.

 

Funções de retorno de chamada TLS

O programa pode fornecer uma ou mais funções de retorno de chamada TLS para suportar 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 suporte para retorno de chamada), caso em que a matriz de retorno de chamada tem exatamente um membro - um ponteiro nulo.

O protótipo para 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:

Cenário Valor Descrição
DLL_PROCESS_ATTACH
1
Um novo processo foi iniciado, incluindo o primeiro tópico.
DLL_THREAD_ATTACH
2
Um novo thread foi criado. Esta notificação foi enviada para todos, exceto para o primeiro tópico.
DLL_THREAD_DETACH
3
Um thread está prestes a ser encerrado. Esta notificação foi enviada para todos, exceto para o primeiro tópico.
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 anteriormente usada 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 despacho de exceções. Se o endereço do manipulador reside no intervalo VA de uma imagem e está marcado como reservado com reconhecimento de SEH (ou seja, IMAGE_DLLCHARACTERISTICS_NO_SEH está claro no campo DllCharacteristics do cabeçalho opcional, conforme descrito anteriormente), o manipulador deve 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 pode incluir os dados SEH reservados e a imagem não é 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. A esse respeito, 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:

Deslocamento Tamanho Domínio Descrição
0
4
Caraterí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 execução C (CRT).
8
2
Versão Major:
Número da versão principal.
10
2
Versão Menor
Número da versão secundária.
12
4
GlobalFlagsClear
O carregador global sinaliza para limpar esse processo à medida que o carregador inicia o processo.
16
4
GlobalFlagsSet
O carregador global sinaliza para definir esse processo à medida que o carregador inicia o processo.
20
4
CriticalSectionDefaultTimeout
O valor de tempo limite padrão a ser usado para as seções críticas desse processo que são abandonadas.
24
4/8
DeCommitFreeBlockThreshold
Memória que deve ser libertada 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
[Apenas x86] 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
MaximumAllocationSize
Tamanho máximo de alocação, em bytes.
40/56
4/8
VirtualMemoryThreshold
Tamanho máximo da memória virtual, em bytes.
44/64
4/8
ProcessAffinityMask
Definir este campo para 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 de processo que é criado durante a inicialização do processo.
52/76
2
CSDVersion
O identificador de versão do service pack.
54/78
2
DependentLoadFlags
Os sinalizadores de carga padrão usados quando o sistema operacional resolve as importações vinculadas estaticamente de um módulo.
56/80
4/8
EditList
Reservado para uso pelo sistema.
60/88
4/8
Cookie de Segurança
Um ponteiro para um cookie que é usado pela implementação do Visual C++ ou GS.
64/96
4/8
SEHandlerTable
[Apenas x86] O VA da tabela classificada de RVAs de cada manipulador SE válido e exclusivo na imagem.
68/104
4/8
SEHandlerCount
[Apenas x86] 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 do Control Flow Guard está armazenado.
80/128
4/8
GuardCFFunctionTable
O VA da tabela ordenada 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
Bandeiras de Guarda
Sinalizadores relacionados ao Control Flow Guard.
92/148
12
Integridade do código
Informações de integridade de código.
104/160
4/8
GuardAddressTakenIatEntryTable
O VA onde o endereço do Control Flow Guard é armazenado na tabela IAT.
108/168
4/8
GuardAddressTakenIatEntryCount
A contagem de RVAs únicos na tabela acima.
112/176
4/8
GuardLongJumpTargetTable
O VA onde a tabela de alvos de salto longo 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 realiza verificações de integridade do fluxo de controle usando o suporte fornecido pelo sistema.

    #define IMAGE_GUARD_CF_INSTRUMENTED 0x00000100

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

    #define IMAGE_GUARD_CFW_INSTRUMENTED 0x00000200

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

    #define IMAGE_GUARD_CF_FUNCTION_TABLE_PRESENT 0x00000400

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

    #define IMAGE_GUARD_SECURITY_COOKIE_UNUSED 0x00000800

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

    #define IMAGE_GUARD_PROTECT_DELAYLOAD_IAT 0x00001000

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

    #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 a supressão de exportações.

    #define IMAGE_GUARD_CF_ENABLE_EXPORT_SUPPRESSION 0x00008000

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

    #define IMAGE_GUARD_CF_LONGJUMP_TABLE_PRESENT 0x00010000

  • Máscara para o subcampo que contém a passada das entradas da tabela de funções do 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 para deslocar à direita o valor GuardFlags para justificar à direita a tabela de funções Control Flow Guard:

#define IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_SHIFT 28

A Secçã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.

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

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

Dados Descrição
Tabelas do Diretório de Recursos (e Entradas do Diretório de Recursos)
Uma série de tabelas, uma para cada grupo de nós na árvore. Todos os nós de nível superior (Tipo) são listados na primeira tabela. As entradas nesta tabela apontam para tabelas de segundo nível. Cada árvore de segundo nível tem a mesma ID de tipo, mas IDs de nome diferentes. As árvores de terceiro nível têm os mesmos 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, apontados por tabelas, que descrevem o tamanho real e a localização 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 do 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:

Deslocamento Tamanho Domínio Descrição
0
4
Caraterísticas
Sinalizadores de recursos. Este campo está reservado para uso futuro. Atualmente, está definido para 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 Name que usam IDs numéricos para entradas Type, Name ou Language.

 

Entradas do diretório de recursos

As entradas do 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 Name ou ID é indicada pela tabela de diretório de recursos, que indica quantas entradas Name e ID a seguem (lembre-se de que todas as entradas Name precedem todas as entradas ID da tabela). Todas as entradas da tabela são classificadas em ordem crescente: as entradas Name por string que diferencia maiúsculas de minúsculas e as entradas ID por valor numérico. Os deslocamentos são relativos ao endereço no IMAGE_DIRECTORY_ENTRY_RESOURCE DataDirectory. Consulte Peering Inside the PE: A tour of the Win32 Portable Executable File Format para obter mais informações.

Deslocamento Tamanho Domínio 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 de 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 Recursos (uma folha).
4
4
Deslocamento do 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 de Recursos. 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 de diretório de recursos tem o seguinte formato:

Deslocamento Tamanho Domínio Descrição
0
2
Comprimento
O tamanho da cadeia de caracteres, não incluindo o campo de comprimento em si.
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 Recursos descreve uma unidade real de dados brutos na área Dados de Recursos. Uma entrada de Dados de Recursos tem o seguinte formato:

Deslocamento Tamanho Domínio 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 do recurso apontados pelo campo Data RVA.
8
4
Página de código
A página de código que é usada para decodificar valores de ponto de código dentro dos 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 lidar com 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 está marcada IMAGE_SCN_LNK_INFO. Ele contém o índice de símbolos 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 não seção .sxdata.

Formato de arquivo (biblioteca)

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

Os primeiros 8 bytes de um arquivo consistem na assinatura do arquivo. O resto do arquivo é composto por uma série de membros do arquivo, como se segue:

  • O primeiro e o segundo membros são "membros linker". Cada um desses membros tem seu próprio formato, conforme descrito na seção Importar Nome Tipo. 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". Este membro opcional consiste em uma série de cadeias de caracteres ASCII terminadas em nulo em que cada cadeia de caracteres é o nome de outro membro do arquivo.

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

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

Assinatura :"!<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)

Arquivar assinatura de arquivo

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

!<arch>\n

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

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

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 texto ASCII que é deixada justificada e acolchoada 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 final 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 comece em um endereço par.

Deslocamento Tamanho Domínio Descrição
0
16
Designação
O nome do membro do arquivo, com uma barra (/) anexada para encerrar o nome. Se o primeiro caractere for uma barra, o nome tem uma interpretação especial, conforme descrito na tabela a seguir.
16
12
Data
A data e hora em que o membro do arquivo foi criado: Esta é a representação decimal ASCII do número de segundos desde 1/1/1970 UCT.
28
6
ID de utilizador
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 do 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. Este é 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 acolchoada 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 linker. Ambos os membros do linker 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 do vinculador é "/" (IMAGE_ARCHIVE_LINKER_MEMBER). O primeiro membro do vinculador é incluído para compatibilidade com versões anteriores. Ele não é usado por vinculadores atuais, mas seu formato deve estar correto. Este 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 do vinculador tem o seguinte formato. Esta informação aparece após o cabeçalho:

Deslocamento Tamanho Domínio 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
Compensações
Uma matriz de deslocamentos de arquivo para arquivar cabeçalhos de membros, em que 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 que contém o símbolo.
*
*
Tabela de String
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. Este fato implica que os símbolos na tabela de cadeia 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 do linker, o segundo membro do linker 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 em preferência ao primeiro por todos os vinculadores atuais. O segundo membro do vinculador inclui nomes de símbolos em ordem lexical, o que permite uma pesquisa mais rápida por nome.

O segundo membro tem o seguinte formato. Esta informação aparece após o cabeçalho:

Deslocamento Tamanho Domínio 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
Compensações
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 mapeiam 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 Índices fornece um índice na matriz de deslocamentos. A matriz de deslocamentos, por sua vez, fornece a localização do membro do arquivo que contém o símbolo.
*
*
Tabela de String
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 do arquivo. Um nome aparece aqui apenas 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 de biblioteca

As bibliotecas de importação tradicionais, ou seja, as bibliotecas que descrevem as exportações de uma imagem para uso por outra, normalmente seguem o layout descrito na seção 7, Formato de arquivo (biblioteca). A principal diferença é que os membros da biblioteca de importação contêm arquivos de pseudo-objeto em vez de arquivos reais, 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 da 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 escrever apenas as informações canônicas na biblioteca e permitir que o aplicativo que a usa posteriormente gere os dados necessários imediatamente.

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 ficheiro
  • Cabeçalhos de secção
  • Dados que correspondem a cada um dos cabeçalhos de secção
  • Tabela de símbolos COFF
  • Cordas

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

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

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

Importar cabeçalho

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

Deslocamento Tamanho Domínio 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 da estrutura.
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
Time-Date Carimbo
A hora e a data em que o arquivo foi criado.
12
4
Tamanho dos dados
O tamanho das cadeias de caracteres que seguem o cabeçalho.
16
2
Ordinal/Dica
O ordinal ou a dica para a importação, determinado pelo valor no campo Tipo de nome.
18
2 bits
Tipo
O tipo de importação. Para obter valores e descrições específicos, consulte Tipo de importação.
3 bits
Tipo de nome
O tipo de nome de importação. Para obter mais informações, 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.

Importar tipo de nome

O nome do símbolo de importação terminado por 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/Dica 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 a esquerda ?, @ ou, opcionalmente, _.
IMPORT_OBJECT_NAME_UNDECORATE 3 O nome de importação é o nome do símbolo público, mas ignorando a entrelinha ?, @ ou, opcionalmente, _, e truncando no primeiro @.

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

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

O que é um Authenticode PE Image Hash?

O hash de imagem do Authenticode PE, ou hash de arquivo para abreviar, é semelhante a uma soma de verificação de arquivo na medida em que produz um pequeno valor relacionado à integridade de um arquivo. Uma soma de verificação é produzida por um algoritmo simples e é usada principalmente para detetar falhas de memória. Ou seja, ele é usado para detetar 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 deteta corrupção de arquivos. 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 detetar falhas de memória simples que levam à corrupção, mas um hash de arquivo pode ser usado para detetar modificações intencionais e até mesmo sutis em um arquivo, como aquelas introduzidas por vírus, hackers ou programas de cavalo de Troia.

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 do arquivo não corresponderem, parte do arquivo coberto pelo hash da imagem PE foi modificada.

O que é coberto em um hash de imagem do 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, informações de depuração não podem ser removidas de arquivos divulgados publicamente); às vezes é simplesmente impossível. Por exemplo, não é possível incluir todas as informações dentro de um arquivo de imagem em uma assinatura Authenticode, inserir a assinatura Authenticode que contém esse hash de imagem PE na imagem PE e, mais tarde, 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 originalmente lá.

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

Todos os dados nas seções da imagem PE especificadas na tabela de seção são colocados em hash em sua totalidade, exceto 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 com certificados de atributos. 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 reassinatura 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 listado imediatamente acima.

    Para calcular o hash da imagem PE, o Authenticode ordena as seções especificadas na tabela de seções por intervalo de endereços e, em seguida, hashes a 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 é colocada em hash. Esta área geralmente contém informações de depuração. As informações de depuração geralmente podem ser consideradas consultivas aos depuradores; isso não afeta a integridade real do programa executável. É literalmente possível remover informações de depuração de uma imagem após 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 notar 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)

Criação, visualização e gerenciamento de certificados

Kernel-Mode Passo a passo de assinatura de código (.doc)

SignTool

Windows Authenticode Portable Executable Signature Format (.docx)

funções ImageHlp