Windows Win32 Debug PE
Windows Win32 Debug PE
Windows Win32 Debug PE
Article • 02/29/2024
This specification describes the structure of executable (image) files and object files
under the Windows family of operating systems. These files are referred to as Portable
Executable (PE) and Common Object File Format (COFF) files, respectively.
7 Note
This document is provided to aid in the development of tools and applications for
Windows but is not guaranteed to be a complete specification in all respects.
Microsoft reserves the right to alter this document without notice.
This revision of the Microsoft Portable Executable and Common Object File Format
Specification replaces all previous revisions of this specification.
General Concepts
This document specifies the structure of executable (image) files and object files under
the Microsoft Windows family of operating systems. These files are referred to as
Portable Executable (PE) and Common Object File Format (COFF) files, respectively. The
name "Portable Executable" refers to the fact that the format is not architecture specific.
Certain concepts that appear throughout this specification are described in the
following table:
ノ Expand table
Name Description
date/time A stamp that is used for different purposes in several places in a PE or COFF file. In
stamp most cases, the format of each stamp is the same as that used by the time
functions
in the C run-time library. For exceptions, see the descripton of
Name Description
file pointer The location of an item within the file itself, before being processed by the linker (in
the case of object files) or the loader (in the case of image files). In other words,
this is a position within the file as stored on disk.
linker A reference to the linker that is provided with Microsoft Visual Studio.
object file A file that is given as input to the linker. The linker produces an image file, which in
turn is used as input by the loader. The term "object file" does not necessarily
imply any connection to object-oriented programming.
reserved, A description of a field that indicates that the value of the field must be zero
for must be 0 generators and consumers must ignore the field.
Relative In an image file, this is the address of an item after it is loaded into memory,
with virtual the base address of the image file subtracted from it. The RVA of an item almost
address always differs from its position within the file on disk (file pointer).
(RVA) In an object file, an RVA is less meaningful because memory locations are not
assigned. In this case, an RVA would be an address within a section (described
later in this table), to which a relocation is later applied during linking. For
simplicity, a compiler should just set the first RVA in each section to zero.
section The basic unit of code or data within a PE or COFF file. For example, all code in an
object file can be combined within a single section or (depending on compiler
behavior) each function can occupy its own section. With more sections, there is
more file overhead, but the linker is able to link in code more selectively. A section
is similar to a segment in Intel 8086 architecture. All the raw data in a section must
be loaded contiguously. In addition, an image file can contain a number of
sections, such as .tls or .reloc , which have special purposes.
Virtual Same as RVA, except that the base address of the image file is not subtracted.
The Address address is called a VA because Windows creates a distinct VA space for each
(VA) process, independent of physical memory. For almost all purposes, a VA should be
considered just an address. A VA is not as predictable as an RVA because the
loader might not load the image at its preferred location.
Overview
The following list describes the Microsoft PE executable format, with the base of the
image header at the top. The section from the MS-DOS 2.0 Compatible EXE Header
through to the unused section just before the PE header is the MS-DOS 2.0 Section, and
is used for MS-DOS compatibility only.
OEM Identifier
OEM Information
Offset to PE Header
unused
Section Headers
Image Pages:
import info
export info
base relocations
resource info
Section Headers
Raw Data:
code
data
debug info
relocations
File Headers
MS-DOS Stub (Image Only)
Signature (Image Only)
COFF File Header (Object and Image)
Machine Types
Characteristics
Optional Header (Image Only)
Optional Header Standard Fields (Image Only)
Optional Header Windows-Specific Fields (Image Only)
Optional Header Data Directories (Image Only)
The PE file header consists of a Microsoft MS-DOS stub, the PE signature, the COFF file
header, and an optional header. A COFF object file header consists of a COFF file header
and an optional header. In both cases, the file headers are followed immediately by
section headers.
At location 0x3c, the stub has the file offset to the PE signature. This information
enables Windows to properly execute the image file, even though it has an MS-DOS
stub. This file offset is placed at location 0x3c during linking.
ノ Expand table
12 4 NumberOfSymbols The number of entries in the symbol table. This data can
be used to locate the string table, which immediately
follows the symbol table. This value should be zero for
an image because COFF debugging information is
deprecated.
18 2 Characteristics The flags that indicate the attributes of the file. For
specific flag values, see Characteristics.
Machine Types
The Machine field has one of the following values, which specify the CPU type. An image
file can be run only on the specified machine or on a system that emulates the specified
machine.
ノ Expand table
Characteristics
The Characteristics field contains flags that indicate attributes of the object or image file.
The following flags are currently defined:
ノ Expand table
IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 Image only. This indicates that the image file is
valid and can be run. If this flag is not set, it
indicates a linker error.
Note that the size of the optional header is not fixed. The SizeOfOptionalHeader field in
the COFF header must be used to validate that a probe into the file for a particular data
directory does not go beyond SizeOfOptionalHeader. For more information, see COFF
File Header (Object and Image).
The NumberOfRvaAndSizes field of the optional header should also be used to ensure
that no probe for a particular data directory entry goes beyond the optional header. In
addition, it is important to validate the optional header magic number for format
compatibility.
The optional header magic number determines whether an image is a PE32 or PE32+
executable.
ノ Expand table
0x10b PE32
0x20b PE32+
PE32+ images allow for a 64-bit address space while limiting the image size to
2 gigabytes. Other PE32+ modifications are addressed in their respective sections.
ノ Expand table
96/112 Variable Data Address/size pairs for special tables that are
directories found in the image file and are used by
the operating system (for example, the
import table and the export table).
The first eight fields of the optional header are standard fields that are defined for every
implementation of COFF. These fields contain general information that is useful for
loading and running an executable file. They are unchanged for the PE32+ format.
ノ Expand table
4 4 SizeOfCode The size of the code (text) section, or the sum of all
code sections if there are multiple sections.
8 4 SizeOfInitializedData The size of the initialized data section, or the sum of all
such sections if there are multiple data sections.
Offset Size Field Description
PE32 contains this additional field, which is absent in PE32+, following BaseOfCode.
ノ Expand table
24 4 BaseOfData The address that is relative to the image base of the beginning-of-
data section when it is loaded into memory.
The next 21 fields are an extension to the COFF optional header format. They contain
additional information that is required by the linker and loader in Windows.
ノ Expand table
Windows Subsystem
The following values defined for the Subsystem field of the optional header determine
which Windows subsystem (if any) is required to run the image.
ノ Expand table
Windows processes
IMAGE_SUBSYSTEM_WINDOWS_CE_GUI 9 Windows CE
IMAGE_SUBSYSTEM_XBOX 14 XBOX
DLL Characteristics
The following values are defined for the DllCharacteristics field of the optional header.
ノ Expand table
Each data directory gives the address and size of a table or string that Windows uses.
These data directory entries are all loaded into memory so that the system can use them
at run time. A data directory is an 8-byte field that has the following declaration:
C++
The first field, VirtualAddress, is actually the RVA of the table. The RVA is the address of
the table relative to the base address of the image when the table is loaded. The second
field gives the size in bytes. The data directories, which form the last part of the optional
header, are listed in the following table.
Note that the number of directories is not fixed. Before looking for a specific directory,
check the NumberOfRvaAndSizes field in the optional header.
Also, do not assume that the RVAs in this table point to the beginning of a section
or that the sections that contain specific tables have specific names.
ノ Expand table
96/112 8 Export Table The export table address and size. For more
information see .edata Section (Image Only).
104/120 8 Import Table The import table address and size. For more
information, see The .idata Section.
112/128 8 Resource Table The resource table address and size. For more
information, see The .rsrc Section.
120/136 8 Exception Table The exception table address and size. For more
information, see The .pdata Section.
128/144 8 Certificate Table The attribute certificate table address and size. For
more information, see The Attribute Certificate Table
(Image Only).
136/152 8 Base Relocation The base relocation table address and size. For more
Table information, see The .reloc Section (Image Only).
144/160 8 Debug The debug data starting address and size. For more
information, see The .debug Section.
160/176 8 Global Ptr The RVA of the value to be stored in the global
pointer register. The size member of this structure
must be set to zero.
168/184 8 TLS Table The thread local storage (TLS) table address and size.
For more information, see The .tls Section.
176/192 8 Load Config The load configuration table address and size. For
Table more information, see The Load Configuration
Structure (Image Only).
184/200 8 Bound Import The bound import table address and size.
Offset Size Field Description
(PE/PE32+)
192/208 8 IAT The import address table address and size. For more
information, see Import Address Table.
200/216 8 Delay Import The delay import descriptor address and size. For
Descriptor more information, see Delay-Load Import Tables
(Image Only).
208/224 8 CLR Runtime The CLR runtime header address and size. For more
Header information, see The .cormeta Section (Object Only).
216/232 8 Reserved,
must be zero
The Certificate Table entry points to a table of attribute certificates. These certificates are
not loaded into memory as part of the image. As such, the first field of this entry, which
is normally an RVA, is a file pointer instead.
Each row of the section table is, in effect, a section header. This table immediately
follows the optional header, if any. This positioning is required because the file header
does not contain a direct pointer to the section table. Instead, the location of the
section table is determined by calculating the location of the first byte after the headers.
Make sure to use the size of the optional header as specified in the file header.
The number of entries in the section table is given by the NumberOfSections field in the
file header. Entries in the section table are numbered starting from one (1). The code
and data memory section entries are in the order chosen by the linker.
In an image file, the VAs for sections must be assigned by the linker so that they are in
ascending order and adjacent, and they must be a multiple of the SectionAlignment
value in the optional header.
Each section header (section table entry) has the following format, for a total of 40 bytes
per entry.
ノ Expand table
Offset Size Field Description
8 4 VirtualSize The total size of the section when loaded into memory.
If this value is greater than SizeOfRawData, the section
is zero-padded. This field is valid only for executable
images and should be set to zero for object files.
16 4 SizeOfRawData The size of the section (for object files) or the size of the
initialized data on disk (for image files). For executable
images, this must be a multiple of FileAlignment from
the optional header. If this is less than VirtualSize, the
remainder of the section is zero-filled. Because the
SizeOfRawData field is rounded but the VirtualSize
field is not, it is possible for SizeOfRawData to be
greater than VirtualSize as well. When a section
contains only uninitialized data, this field should be
zero.
20 4 PointerToRawData The file pointer to the first page of the section within
the COFF file. For executable images, this must be a
multiple of FileAlignment from the optional header. For
object files, the value should be aligned on a 4-byte
boundary for best performance. When a section
contains only uninitialized data, this field should be
zero.
Section Flags
The section flags in the Characteristics field of the section header indicate characteristics
of the section.
ノ Expand table
However, the characters following the "$" determine the ordering of the contributions to
the image section. All contributions with the same object-section name are allocated
contiguously in the image, and the blocks of contributions are sorted in lexical order by
object-section name. Therefore, everything in object files with section name .text$X
ends up together, after the .text$W contributions and before the .text$Y contributions.
The data structures that were described so far, up to and including the optional header,
are all located at a fixed offset from the beginning of the file (or from the PE header if
the file is an image that contains an MS-DOS stub).
The remainder of a COFF object or image file contains blocks of data that are not
necessarily at any specific file offset. Instead, the locations are defined by pointers in the
optional header or a section header.
An exception is for images with a SectionAlignment value of less than the page size of
the architecture (4 K for Intel x86 and for MIPS, and 8 K for Itanium). For a description of
SectionAlignment, see Optional Header (Image Only). In this case, there are constraints
on the file offset of the section data, as described in section 5.1, "Section Data." Another
exception is that attribute certificate and debug information must be placed at the very
end of an image file, with the attribute certificate table immediately preceding the
debug section, because the loader does not map these into memory. The rule about
attribute certificate and debug information does not apply to object files, however.
Section Data
Initialized data for a section consists of simple blocks of bytes. However, for sections
that contain all zeros, the section data need not be included.
The data for each section is located at the file offset that was given by the
PointerToRawData field in the section header. The size of this data in the file is indicated
by the SizeOfRawData field. If SizeOfRawData is less than VirtualSize, the remainder is
padded with zeros.
In an image file, the section data must be aligned on a boundary as specified by the
FileAlignment field in the optional header. Section data must appear in order of the
RVA values for the corresponding sections (as do the individual section headers in the
section table).
There are additional restrictions on image files if the SectionAlignment value in the
optional header is less than the page size of the architecture. For such files, the location
of section data in the file must match its location in memory when the image is loaded,
so that the physical offset for section data is the same as the RVA.
Image files do not contain COFF relocations, because all referenced symbols have
already been assigned addresses in a flat address space. An image contains relocation
information in the form of base relocations in the .reloc section (unless the image has
the IMAGE_FILE_RELOCS_STRIPPED attribute). For more information, see The .reloc
Section (Image Only).
For each section in an object file, an array of fixed-length records holds the section's
COFF relocations. The position and length of the array are specified in the section
header. Each element of the array has the following format.
ノ Expand table
4 4 SymbolTableIndex A zero-based index into the symbol table. This symbol gives
the address that is to be used for the relocation. If the
specified symbol has section storage class, then the symbol's
address is the address with the first section of the same
name.
If the symbol referred to by the SymbolTableIndex field has the storage class
IMAGE_SYM_CLASS_SECTION, the symbol's address is the beginning of the section. The
section is usually in the same file, except when the object file is part of an archive
(library). In that case, the section can be found in any other object file in the archive that
has the same archive-member name as the current object file. (The relationship with the
archive-member name is used in the linking of import tables, that is, the .idata section.)
Type Indicators
The Type field of the relocation record indicates what kind of relocation should be
performed. Different relocation types are defined for each type of machine.
x64 Processors
The following relocation type indicators are defined for x64 and compatible processors.
ノ Expand table
IMAGE_REL_AMD64_REL32 0x0004 The 32-bit relative address from the byte following
the relocation.
IMAGE_REL_AMD64_SECTION 0x000A The 16-bit section index of the section that contains
the target. This is used to support debugging
information.
IMAGE_REL_AMD64_SECREL 0x000B The 32-bit offset of the target from the beginning of
its section. This is used to support debugging
information and static thread local storage.
IMAGE_REL_AMD64_SECREL7 0x000C A 7-bit unsigned offset from the base of the section
that contains the target.
ARM Processors
The following relocation type indicators are defined for ARM processors.
ノ Expand table
IMAGE_REL_ARM_REL32 0x000A The 32-bit relative address from the byte following
the relocation.
IMAGE_REL_ARM_SECTION 0x000E The 16-bit section index of the section that contains
the target. This is used to support debugging
information.
IMAGE_REL_ARM_SECREL 0x000F The 32-bit offset of the target from the beginning of
its section. This is used to support debugging
information and static thread local storage.
Unused 0x0013
ARM64 Processors
The following relocation type indicators are defined for ARM64 processors.
ノ Expand table
instruction.
The following relocation type indicators are defined for SH3 and SH4 processors. SH5-
specific relocations are noted as SHM (SH Media).
ノ Expand table
The following relocation type indicators are defined for PowerPC processors.
ノ Expand table
IMAGE_REL_PPC_ADDR24 0x0003 The low 24 bits of the VA of the target. This is valid only
when the target symbol is absolute and can be sign-
extended to its original value.
IMAGE_REL_PPC_ADDR14 0x0005 The low 14 bits of the target's VA. This is valid only when
the target symbol is absolute and can be sign-extended
to its original value.
IMAGE_REL_PPC_SECREL 0x000B The 32-bit offset of the target from the beginning of
its section. This is used to support debugging
information and static thread local storage.
IMAGE_REL_PPC_SECTION 0x000C The 16-bit section index of the section that contains the
target. This is used to support debugging information.
IMAGE_REL_PPC_SECREL16 0x000F The 16-bit offset of the target from the beginning of
its section. This is used to support debugging
information and static thread local storage.
IMAGE_REL_PPC_REFHI 0x0010 The high 16 bits of the target's 32-bit VA. This is used for
the first instruction in a two-instruction sequence that
loads a full address. This relocation must be immediately
followed by a PAIR relocation whose SymbolTableIndex
contains a signed 16-bit displacement that is added to
the upper 16 bits that was taken from the location that is
being relocated.
IMAGE_REL_PPC_SECRELLO 0x0013 The low 16 bits of the 32-bit offset of the target from the
beginning of its section.
The following relocation type indicators are defined for Intel 386 and compatible
processors.
ノ Expand table
IMAGE_REL_I386_SECTION 0x000A The 16-bit section index of the section that contains the
target. This is used to support debugging information.
IMAGE_REL_I386_SECREL 0x000B The 32-bit offset of the target from the beginning of
its section. This is used to support debugging
information and static thread local storage.
IMAGE_REL_I386_SECREL7 0x000D A 7-bit offset from the base of the section that contains
the target.
The following relocation type indicators are defined for the Intel Itanium processor
family and compatible processors. Note that relocations on instructions use the
bundle's offset and slot number for the relocation offset.
ノ Expand table
Constant Value Description
IMAGE_REL_IA64_IMM64 0x0003 The slot number of this relocation must be one (1).
The relocation can be followed by an ADDEND
relocation whose value is added to the target address
before it is stored in all three slots of the IMM64
bundle.
IMAGE_REL_IA64_DIR32 0x0004 The target's 32-bit VA. This is supported only for
/LARGEADDRESSAWARE:NO images.
IMAGE_REL_IA64_SECTION 0x000B The 16-bit section index of the section contains the
target. This is used to support debugging
information.
IMAGE_REL_IA64_SECREL64I 0x000D The slot number for this relocation must be one (1).
The instruction is fixed up with the 64-bit offset of the
target from the beginning of its section. This
relocation can be followed immediately by an
ADDEND relocation whose Value field contains the
32-bit unsigned offset of the target from the
beginning of the section.
MIPS Processors
The following relocation type indicators are defined for MIPS processors.
ノ Expand table
IMAGE_REL_MIPS_JMPADDR 0x0003 The low 26 bits of the target's VA. This supports the
MIPS J and JAL instructions.
IMAGE_REL_MIPS_REFHI 0x0004 The high 16 bits of the target's 32-bit VA. This is used
for the first instruction in a two-instruction sequence
that loads a full address. This relocation must be
immediately followed by a PAIR relocation whose
SymbolTableIndex contains a signed 16-bit
displacement that is added to the upper 16 bits that
are taken from the location that is being relocated.
IMAGE_REL_MIPS_SECTION 0x000A The 16-bit section index of the section contains the
target. This is used to support debugging
information.
IMAGE_REL_MIPS_SECREL 0x000B The 32-bit offset of the target from the beginning of
its section. This is used to support debugging
information and static thread local storage.
IMAGE_REL_MIPS_SECRELLO 0x000C The low 16 bits of the 32-bit offset of the target from
the beginning of its section.
IMAGE_REL_MIPS_SECRELHI 0x000D The high 16 bits of the 32-bit offset of the target
from the beginning of its section. An
IMAGE_REL_MIPS_PAIR relocation must immediately
follow this one. The SymbolTableIndex of the PAIR
relocation contains a signed 16-bit displacement that
is added to the upper 16 bits that are taken from the
location that is being relocated.
IMAGE_REL_MIPS_JMPADDR16 0x0010 The low 26 bits of the target's VA. This supports the
MIPS16 JAL instruction.
Mitsubishi M32R
The following relocation type indicators are defined for the Mitsubishi M32R processors.
ノ Expand table
IMAGE_REL_M32R_PCREL24 0x0005 The target's 24-bit offset from the program counter
(PC), shifted left by 2 bits and sign-extended
IMAGE_REL_M32R_PCREL16 0x0006 The target's 16-bit offset from the PC, shifted left by 2
bits and sign-extended
IMAGE_REL_M32R_PCREL8 0x0007 The target's 8-bit offset from the PC, shifted left by 2
bits and sign-extended
IMAGE_REL_M32R_REFHI 0x0009 The 16 MSBs of the target VA, adjusted for LSB sign
extension. This is used for the first instruction in a two-
instruction sequence that loads a full 32-bit address.
This relocation must be immediately followed by a
PAIR relocation whose SymbolTableIndex contains a
signed 16-bit displacement that is added to the upper
16 bits that are taken from the location that is being
relocated.
IMAGE_REL_M32R_PAIR 0x000B The relocation must follow the REFHI relocation. Its
SymbolTableIndex contains a displacement and not an
index into the symbol table.
IMAGE_REL_M32R_SECTION 0x000C The 16-bit section index of the section that contains
the target. This is used to support debugging
information.
IMAGE_REL_M32R_SECREL 0x000D The 32-bit offset of the target from the beginning of
its section. This is used to support debugging
information and static thread local storage.
COFF line numbers indicate the relationship between code and line numbers in source
files. The Microsoft format for COFF line numbers is similar to standard COFF, but it has
been extended to allow a single section to relate to line numbers in multiple source files.
COFF line numbers consist of an array of fixed-length records. The location (file
offset) and size of the array are specified in the section header. Each line-number
record is of the following format.
ノ Expand table
4 2 Linenumber When nonzero, this field specifies a one-based line number. When
zero, the Type field is interpreted as a symbol table index for a
function.
The Type field is a union of two 4-byte fields: SymbolTableIndex and VirtualAddress.
ノ Expand table
A line-number record can either set the Linenumber field to zero and point to a function
definition in the symbol table or it can work as a standard line-number entry by giving a
positive integer (line number) and the corresponding address in the object code.
A group of line-number entries always begins with the first format: the index of a
function symbol. If this is the first line-number record in the section, then it is also the
COMDAT symbol name for the function if the section's COMDAT flag is set. See
COMDAT Sections (Object Only). The function's auxiliary record in the symbol table has
a pointer to the Linenumber field that points to this same line-number record.
A record that identifies a function is followed by any number of line-number entries that
give actual line-number information (that is, entries with Linenumber greater than zero).
These entries are one-based, relative to the beginning of the function, and represent
every source line in the function except for the first line.
For example, the first line-number record for the following example would specify the
ReverseSign function (SymbolTableIndex of ReverseSign and Linenumber set to zero).
Then records with Linenumber values of 1, 2, and 3 would follow, corresponding to
source lines as shown:
C++
The symbol table is an array of records, each 18 bytes long. Each record is either a
standard or auxiliary symbol-table record. A standard record defines a symbol or name
and has the following format.
ノ Expand table
Zero or more auxiliary symbol-table records immediately follow each standard symbol-
table record. However, typically not more than one auxiliary symbol-table record follows
a standard symbol-table record (except for .file records with long file names). Each
auxiliary record is the same size as a standard symbol-table record (18 bytes), but rather
than define a new symbol, the auxiliary record gives additional information on the last
symbol defined. The choice of which of several formats to use depends on the
StorageClass field. Currently-defined formats for auxiliary symbol table records are
shown in section 5.5, "Auxiliary Symbol Records."
Tools that read COFF symbol tables must ignore auxiliary symbol records whose
interpretation is unknown. This allows the symbol table format to be extended to add
new auxiliary records, without breaking existing tools.
The ShortName field in a symbol table consists of 8 bytes that contain the name itself, if
it is not more than 8 bytes long, or the ShortName field gives an offset into the string
table. To determine whether the name itself or an offset is given, test the first 4 bytes for
equality to zero.
ノ Expand table
0 8 ShortName An array of 8 bytes. This array is padded with nulls on the right
if the name is less than 8 bytes long.
0 4 Zeroes A field that is set to all zeros if the name is longer than 8 bytes.
Normally, the Section Value field in a symbol table entry is a one-based index into
the section table. However, this field is a signed integer and can take negative values.
The following values, less than one, have special meanings.
ノ Expand table
Type Representation
The Type field of a symbol table entry contains 2 bytes, where each byte represents type
information. The LSB represents the simple (base) data type, and the MSB represents the
complex type, if any:
ノ Expand table
MSB LSB
Complex type: none, pointer, function, array. Base type: integer, floating-point, and so on.
The following values are defined for base type, although Microsoft tools generally do
not use this field and set the LSB to 0. Instead, Visual C++ debug information is used to
indicate types. However, the possible COFF values are listed here for completeness.
ノ Expand table
IMAGE_SYM_TYPE_STRUCT 8 A structure
IMAGE_SYM_TYPE_UNION 9 A union
The most significant byte specifies whether the symbol is a pointer to, function
returning, or array of the base type that is specified in the LSB. Microsoft tools use this
field only to indicate whether the symbol is a function, so that the only two resulting
values are 0x0 and 0x20 for the Type field. However, other tools can use this field to
communicate more information.
ノ Expand table
Although the traditional COFF format uses many storage-class values, Microsoft tools
rely on Visual C++ debug format for most symbolic information and generally use only
four storage-class values: EXTERNAL (2), STATIC (3), FUNCTION (101), and FILE (103).
Except in the second column heading below, "Value" should be taken to mean the Value
field of the symbol record (whose interpretation depends on the number found as the
storage class).
ノ Expand table
defined.
The traditional COFF design also includes auxiliary-record formats for arrays and
structures. Microsoft tools do not use these, but instead place that symbolic information
in Visual C++ debug format in the debug sections.
ノ Expand table
4 4 TotalSize The size of the executable code for the function itself. If
the function is in its own section, the SizeOfRawData in
the section header is greater or equal to this field,
depending on alignment considerations.
8 4 PointerToLinenumber The file offset of the first COFF line-number entry for
the function, or zero if none exists. For more
information, see COFF Line Numbers (Deprecated).
16 2 Unused
For each function definition in the symbol table, three items describe the beginning,
ending, and number of lines. Each of these symbols has storage class FUNCTION (101):
A symbol record named .bf (begin function). The Value field is unused.
A symbol record named .lf (lines in function). The Value field gives the number of lines in
the function.
A symbol record named .ef (end of function). The Value field has the same number as
the Total Size field in the function-definition symbol record.
The .bf and .ef symbol records (but not .lf records) are followed by an auxiliary record
with the following format:
ノ Expand table
0 4 Unused
6 6 Unused
16 2 Unused
"Weak externals" are a mechanism for object files that allows flexibility at link time. A
module can contain an unresolved external symbol (sym1), but it can also include an
auxiliary record that indicates that if sym1 is not present at link time, another external
symbol (sym2) is used to resolve references instead.
Weak externals are represented by a symbol table record with EXTERNAL storage class,
UNDEF section number, and a value of zero. The weak-external symbol record is
followed by an auxiliary record with the following format:
ノ Expand table
8 10 Unused
Note that the Characteristics field is not defined in WINNT.H; instead, the Total Size field
is used.
Auxiliary Format 4: Files
This format follows a symbol-table record with storage class FILE (103). The symbol
name itself should be .file, and the auxiliary record that follows it gives the name of a
source-code file.
ノ Expand table
0 18 File An ANSI string that gives the name of the source file. This is padded
Name with nulls if it is less than the maximum length.
This format follows a symbol-table record that defines a section. Such a record has a
symbol name that is the name of a section (such as .text or .drectve) and has storage
class STATIC (3). The auxiliary record provides information about the section to which it
refers. Thus, it duplicates some of the information in the section header.
ノ Expand table
15 3 Unused
COMDAT Sections (Object Only)
The Selection field of the section definition auxiliary format is applicable if the section is
a COMDAT section. A COMDAT section is a section that can be defined by more than
one object file. (The flag IMAGE_SCN_LNK_COMDAT is set in the Section Flags field of
the section header.) The Selection field determines the way in which the linker resolves
the multiple definitions of COMDAT sections.
The first symbol that has the section value of the COMDAT section must be the section
symbol. This symbol has the name of the section, the Value field equal to zero, the
section number of the COMDAT section in question, the Type field equal to
IMAGE_SYM_TYPE_NULL, the Class field equal to IMAGE_SYM_CLASS_STATIC, and one
auxiliary record. The second symbol is called "the COMDAT symbol" and is used by the
linker in conjunction with the Selection field.
ノ Expand table
ノ Expand table
2 4 SymbolTableIndex The symbol index of the COFF symbol to which this CLR
token definition refers.
Following the size are null-terminated strings that are pointed to by symbols in the
COFF symbol table.
ノ Expand table
The virtual address value from the Certificate Table entry in the Optional Header Data
Directory is a file offset to the first attribute certificate entry. Subsequent entries are
accessed by advancing that entry's dwLength bytes, rounded up to an 8-byte multiple,
from the start of the current attribute certificate entry. This continues until the sum of
the rounded dwLength values equals the Size value from the Certificates Table entry in
the Optional Header Data Directory. If the sum of the rounded dwLength values does
not equal the Size value, then either the attribute certificate table or the Size field is
corrupted.
For example, if the Optional Header Data Directory's Certificate Table Entry contains:
C++
1. Add the first attribute certificate's dwLength value to the starting offset.
2. Round the value from step 1 up to the nearest 8-byte multiple to find the offset
of the second attribute certificate entry.
3. Add the offset value from step 2 to the second attribute certificate entry's
dwLength value and round up to the nearest 8-byte multiple to determine the
offset of the third attribute certificate entry.
4. Repeat step 3 for each successive certificate until the calculated offset equals
0x6000 (0x5000 start + 0x1000 total size), which indicates that you've walked the
entire table.
Alternatively, you can enumerate the certificate entries by calling the Win32
ImageEnumerateCertificates function in a loop. For a link to the function's reference
page, see References.
Attribute certificate table entries can contain any certificate type, as long as the entry
has the correct dwLength value, a unique wRevision value, and a unique
wCertificateType value. The most common type of certificate table entry is a
WIN_CERTIFICATE structure, which is documented in Wintrust.h and discussed in the
remainder of this section.
The options for the WIN_CERTIFICATE wRevision member include (but are not limited
to) the following.
ノ Expand table
The options for the WIN_CERTIFICATE wCertificateType member include (but are not
limited to) the items in the following table. Note that some values are not currently
supported.
ノ Expand table
Value Name Notes
If the bCertificate content does not end on a quadword boundary, the attribute
certificate entry is padded with zeros, from the end of bCertificate to the next quadword
boundary.
The dwLength value is the length of the finalized WIN_CERTIFICATE structure and is
computed as:
This length should include the size of any padding that is used to satisfy the
requirement that each WIN_CERTIFICATE structure is quadword aligned:
The Certificate Table size-specified in the Certificates Table entry in the Optional
Header Data Directories (Image Only)- includes the padding.
For more information on using the ImageHlp API to enumerate, add, and remove
certificates from PE Files, see ImageHlp Functions.
Certificate Data
As stated in the preceding section, the certificates in the attribute certificate table can
contain any certificate type. Certificates that ensure a PE file's integrity may include a PE
image hash.
A PE image hash (or file hash) is similar to a file checksum in that the hash algorithm
produces a message digest that is related to the integrity of a file. However, a checksum
is produced by a simple algorithm and is used primarily to detect whether a block of
memory on disk has gone bad and the values stored there have become corrupted. A
file hash is similar to a checksum in that it also detects file corruption. However, unlike
most checksum algorithms, it is very difficult to modify a file without changing the file
hash from its original unmodified value. A file hash can thus be used to detect
intentional and even subtle modifications to a file, such as those introduced by viruses,
hackers, or Trojan horse programs.
When included in a certificate, the image digest must exclude certain fields in the PE
Image, such as the Checksum and Certificate Table entry in Optional Header Data
Directories. This is because the act of adding a Certificate changes these fields and
would cause a different hash value to be calculated.
The Win32 ImageGetDigestStream function provides a data stream from a target PE file
with which to hash functions. This data stream remains consistent when certificates are
added to or removed from a PE file. Based on the parameters that are passed to
ImageGetDigestStream, other data from the PE image can be omitted from the hash
computation. For a link to the function's reference page, see References.
ノ Expand table
Offset Size Field Description
4 4 Name The RVA of the name of the DLL to be loaded. The name resides in
the read-only data section of the image.
8 4 Module The RVA of the module handle (in the data section of the image)
Handle of the DLL to be delay-loaded. It is used for storage by the routine
that is supplied to manage delay-loading.
12 4 Delay The RVA of the delay-load import address table. For more
Import information, see Delay Import Address Table (IAT).
Address
Table
16 4 Delay The RVA of the delay-load name table, which contains the names
Import of the imports that might need to be loaded. This matches the
Name Table layout of the import name table. For more information, see
Hint/Name Table.
20 4 Bound Delay The RVA of the bound delay-load address table, if it exists.
Import Table
24 4 Unload The RVA of the unload delay-load address table, if it exists. This is
Delay an exact copy of the delay import address table. If the caller
Import Table unloads the DLL, this table should be copied back over the delay
import address table so that subsequent calls to the DLL continue
to use the thunking mechanism correctly.
28 4 Time Stamp The timestamp of the DLL to which this image has been bound.
The tables that are referenced in this data structure are organized and sorted just as
their counterparts are for traditional imports. For details, see The .idata Section.
Attributes
As yet, no attribute flags are defined. The linker sets this field to zero in the image. This
field can be used to extend the record by indicating the presence of new fields, or it can
be used to indicate behaviors to the delay or unload helper functions.
Name
The name of the DLL to be delay-loaded resides in the read-only data section of the
image. It is referenced through the szName field.
Module Handle
The handle of the DLL to be delay-loaded is in the data section of the image. The
phmod field points to the handle. The supplied delay-load helper uses this location to
store the handle to the loaded DLL.
The delay import address table (IAT) is referenced by the delay import descriptor
through the pIAT field. The delay-load helper updates these pointers with the real entry
points so that the thunks are no longer in the calling loop. The function pointers are
accessed by using the expression pINT->u1.Function .
The delay import name table (INT) contains the names of the imports that might require
loading. They are ordered in the same fashion as the function pointers in the IAT. They
consist of the same structures as the standard INT and are accessed by using the
expression pINT->u1.AddressOfData->Name[0] .
Special Sections
The .debug Section
Debug Directory (Image Only)
Debug Type
.debug$F (Object Only)
.debug$S (Object Only)
.debug$P (Object Only)
.debug$T (Object Only)
Linker Support for Microsoft Debug Information
The .drectve Section (Object Only)
The .edata Section (Image Only)
Export Directory Table
Export Address Table
Export Name Pointer Table
Export Ordinal Table
Export Name Table
The .idata Section
Import Directory Table
Import Lookup Table
Hint/Name Table
Import Address Table
The .pdata Section
The .reloc Section (Image Only)
Base Relocation Block
Base Relocation Types
The .tls Section
The TLS Directory
TLS Callback Functions
The Load Configuration Structure (Image Only)
Load Configuration Directory
Load Configuration Layout
The .rsrc Section
Resource Directory Table
Resource Directory Entries
Resource Directory String
Resource Data Entry
The .cormeta Section (Object Only)
The .sxdata Section
Typical COFF sections contain code or data that linkers and Microsoft Win32 loaders
process without special knowledge of the section contents. The contents are relevant
only to the application that is being linked or executed.
However, some COFF sections have special meanings when found in object files or
image files. Tools and loaders recognize these sections because they have special flags
set in the section header, because special locations in the image optional header point
to them, or because the section name itself indicates a special function of the section.
(Even if the section name itself does not indicate a special function of the section, the
section name is dictated by convention, so the authors of this specification can refer to a
section name in all cases.)
The reserved sections and their attributes are described in the table below, followed by
detailed descriptions for the section types that are persisted into executables and the
section types that contain metadata for extensions.
ノ Expand table
format and object file. The symbol can be for an UNDEF symbol or one
x86/object only) that is defined in that module.
Some of the sections listed here are marked "object only" or "image only" to indicate
that their special semantics are relevant only for object files or image files, respectively.
A section that is marked "image only" might still appear in an object file as a way of
getting into the image file, but the section has no special meaning to the linker, only to
the image file loader.
The next section describes the format of the debug directory, which can be anywhere in
the image. Subsequent sections describe the "groups" in object files that contain debug
information.
The default for the linker is that debug information is not mapped into the address
space of the image. A .debug section exists only when debug information is mapped in
the address space.
Debug Directory (Image Only)
Image files contain an optional debug directory that indicates what form of debug
information is present and where it is. This directory consists of an array of debug
directory entries whose location and size are indicated in the image optional header.
The debug directory can be in a discardable .debug section (if one exists), or it can be
included in any other section in the image file, or not be in a section at all.
Each debug directory entry identifies the location and size of a block of debug
information. The specified RVA can be zero if the debug information is not covered by a
section header (that is, it resides in the image file and is not mapped into the run-time
address space). If it is mapped, the RVA is its address.
ノ Expand table
4 4 TimeDateStamp The time and date that the debug data was created.
16 4 SizeOfData The size of the debug data (not including the debug
directory itself).
20 4 AddressOfRawData The address of the debug data when loaded, relative to the
image base.
Debug Type
The following values are defined for the Type field of the debug directory entry:
ノ Expand table
Constant Value Description
IMAGE_DEBUG_TYPE_FIXUP 6 Reserved.
IMAGE_DEBUG_TYPE_RESERVED10 10 Reserved.
IMAGE_DEBUG_TYPE_CLSID 11 Reserved.
C++
#define FRAME_FPO 0
#define FRAME_TRAP 1
#define FRAME_TSS 2
The following values are defined for the extended DLL characteristics bits.
ノ Expand table
Constant Value Description
Object files can contain .debug$F sections whose contents are one or more FPO_DATA
records (frame pointer omission information). See "IMAGE_DEBUG_TYPE_FPO" in Debug
Type.
The linker recognizes these .debug$F records. If debug information is being generated,
the linker sorts the FPO_DATA records by procedure RVA and generates a debug
directory entry for them.
The compiler should not generate FPO records for procedures that have a standard
frame format.
This section contains Visual C++ debug information (precompiled information). These
are shared types among all of the objects that were compiled by using the precompiled
header that was generated with this object.
.debug$T (Object Only)
Gathers all relevant debug data from the .debug$F, debug$S, .debug$P, and
.debug$T sections.
Processes that data along with the linker-generated debugging information into
the PDB file, and creates a debug directory entry to refer to it.
A .drectve section consists of a string of text that can be encoded as ANSI or UTF-8. If
the UTF-8 byte order marker (BOM, a three-byte prefix that consists of 0xEF, 0xBB, and
0xBF) is not present, the directive string is interpreted as ANSI. The directive string is a
series of linker options that are separated by spaces. Each option contains a hyphen, the
option name, and any appropriate attribute. If an option contains spaces, the option
must be enclosed in quotes. The .drectve section must not have relocations or line
numbers.
An overview of the general structure of the export section is described below. The tables
described are usually contiguous in the file in the order shown (though this is not
required). Only the export directory table and export address table are required to
export symbols as ordinals. (An ordinal is an export that is accessed directly by its export
address table index.) The name pointer table, ordinal table, and export name table all
exist to support use of export names.
ノ Expand table
Table Description
Name
Export A table with just one row (unlike the debug directory). This table indicates the
directory locations and sizes of the other export tables.
table
Export An array of RVAs of exported symbols. These are the actual addresses of the
address exported functions and data within the executable code and data sections. Other
table image files can import a symbol by using an index to this table (an ordinal) or,
optionally, by using the public name that corresponds to the ordinal if a public
name is defined.
Name An array of pointers to the public export names, sorted in ascending order.
pointer
table
Ordinal An array of the ordinals that correspond to members of the name pointer table. The
table correspondence is by position; therefore, the name pointer table and the ordinal
table must have the same number of members. Each ordinal is an index into the
export address table.
Export A series of null-terminated ASCII strings. Members of the name pointer table point
name table into this area. These names are the public names through which the symbols are
imported and exported; they are not necessarily the same as the private names that
are used within the image file.
When another image file imports a symbol by name, the Win32 loader searches the
name pointer table for a matching string. If a matching string is found, the associated
ordinal is identified by looking up the corresponding member in the ordinal table (that
is, the member of the ordinal table with the same index as the string pointer found in
the name pointer table). The resulting ordinal is an index into the export address table,
which gives the actual location of the desired symbol. Every export symbol can be
accessed by an ordinal.
When another image file imports a symbol by ordinal, it is unnecessary to search the
name pointer table for a matching string. Direct use of an ordinal is therefore more
efficient. However, an export name is easier to remember and does not require the user
to know the table index for the symbol.
ノ Expand table
4 4 Time/Date The time and date that the export data was created.
Stamp
8 2 Major Version The major version number. The major and minor version
numbers can be set by the user.
12 4 Name RVA The address of the ASCII string that contains the name of the
DLL. This address is relative to the image base.
16 4 Ordinal Base The starting ordinal number for exports in this image. This field
specifies the starting ordinal number for the export address
table. It is usually set to 1.
24 4 Number of The number of entries in the name pointer table. This is also
Name Pointers the number of entries in the ordinal table.
28 4 Export The address of the export address table, relative to the image
Address Table base.
RVA
32 4 Name Pointer The address of the export name pointer table, relative to the
RVA image base. The table size is given by the Number of Name
Pointers field.
36 4 Ordinal The address of the ordinal table, relative to the image base.
Table RVA
ノ Expand table
0 4 Export The address of the exported symbol when loaded into memory,
RVA relative to the image base. For example, the address of an exported
function.
A forwarder RVA exports a definition from some other image, making it appear as if it
were being exported by the current image. Thus, the symbol is simultaneously imported
and exported.
For example, in Kernel32.dll in Windows XP, the export named "HeapAlloc" is forwarded
to the string "NTDLL.RtlAllocateHeap." This allows applications to use the Windows XP-
specific module Ntdll.dll without actually containing import references to it. The
application's import table refers only to Kernel32.dll. Therefore, the application is not
specific to Windows XP and can run on any Win32 system.
The export name pointer table is an array of addresses (RVAs) into the export name
table. The pointers are 32 bits each and are relative to the image base. The pointers are
ordered lexically to allow binary searches.
An export name is defined only if the export name pointer table contains a pointer to it.
The export name pointer table and the export ordinal table form two parallel arrays that
are separated to allow natural field alignment. These two tables, in effect, operate as
one table, in which the Export Name Pointer column points to a public (exported) name
and the Export Ordinal column gives the corresponding ordinal for that public name. A
member of the export name pointer table and a member of the export ordinal table are
associated by having the same position (index) in their respective arrays.
Thus, when the export name pointer table is searched and a matching string is found at
position i, the algorithm for finding the symbol's RVA and biased ordinal is:
C++
i = Search_ExportNamePointerTable (name);
ordinal = ExportOrdinalTable [i];
When searching for a symbol by (biased) ordinal, the algorithm for finding the symbol's
RVA and name is:
C++
The export name table contains the actual string data that was pointed to by the export
name pointer table. The strings in this table are public names that other images can use
to import the symbols. These public export names are not necessarily the same as the
private symbol names that the symbols have in their own image file and source code,
although they can be.
Every exported symbol has an ordinal value, which is just the index into the export
address table. Use of export names, however, is optional. Some, all, or none of the
exported symbols can have export names. For exported symbols that do have export
names, corresponding entries in the export name pointer table and export ordinal table
work together to associate each name with an ordinal.
The structure of the export name table is a series of null-terminated ASCII strings of
variable length.
Directory Table
Null
Null
Null
Hint-Name Table
The import information begins with the import directory table, which describes the
remainder of the import information. The import directory table contains address
information that is used to resolve fixup references to the entry points within a DLL
image. The import directory table consists of an array of import directory entries, one
entry for each DLL to which the image refers. The last directory entry is empty (filled
with null values), which indicates the end of the directory table.
ノ Expand table
Offset Size Field Description
0 4 Import Lookup Table The RVA of the import lookup table. This table contains a
RVA (Characteristics) name or ordinal for each import. (The name
"Characteristics" is used in Winnt.h, but no longer
describes this field.)
4 4 Time/Date Stamp The stamp that is set to zero until the image is bound.
After the image is bound, this field is set to the
time/data stamp of the DLL.
12 4 Name RVA The address of an ASCII string that contains the name of
the DLL. This address is relative to the image base.
16 4 Import Address Table The RVA of the import address table. The contents of
RVA (Thunk Table) this table are identical to the contents of the import
lookup table until the image is bound.
An import lookup table is an array of 32-bit numbers for PE32 or an array of 64-bit
numbers for PE32+. Each entry uses the bit-field format that is described in the
following table. In this format, bit 31 is the most significant bit for PE32 and bit 63 is the
most significant bit for PE32+. The collection of these entries describes all imports from
a given DLL. The last entry is set to zero (NULL) to indicate the end of the table.
ノ Expand table
31/63 1 Ordinal/Name If this bit is set, import by ordinal. Otherwise, import by name.
Flag Bit is masked as 0x80000000 for PE32, 0x8000000000000000
for PE32+.
15-0 16 Ordinal Number A 16-bit ordinal number. This field is used only if the
Ordinal/Name Flag bit field is 1 (import by ordinal). Bits 30-15
or 62-15 must be 0.
30-0 31 Hint/Name A 31-bit RVA of a hint/name table entry. This field is used only
Table RVA if the Ordinal/Name Flag bit field is 0 (import by name). For
PE32+ bits 62-31 must be zero.
Hint/Name Table
One hint/name table suffices for the entire import section. Each entry in the hint/name
table has the following format:
ノ Expand table
0 2 Hint An index into the export name pointer table. A match is attempted
first with this value. If it fails, a binary search is performed on the
DLL's export name pointer table.
2 variable Name An ASCII string that contains the name to import. This is the
string that must be matched to the public name in the DLL. This
string is case sensitive and terminated by a null byte.
* 0 or 1 Pad A trailing zero-pad byte that appears after the trailing null byte, if
necessary, to align the next entry on an even boundary.
For 32-bit MIPS images, function table entries have the following format:
ノ Expand table
Offset Size Field Description
For the ARM, PowerPC, SH3 and SH4 Windows CE platforms, function table entries have
the following format:
ノ Expand table
4 1 bit 32-bit Flag If set, the function consists of 32-bit instructions. If clear, the
function consists of 16-bit instructions.
4 1 bit Exception If set, an exception handler exists for the function. Otherwise, no
Flag exception handler exists.
For x64 and Itanium platforms, function table entries have the following format:
ノ Expand table
The loader is not required to process base relocations that are resolved by the linker,
unless the load image cannot be loaded at the image base that is specified in the PE
header.
ノ Expand table
0 4 Page The image base plus the page RVA is added to each offset to create the
RVA VA where the base relocation must be applied.
4 4 Block The total number of bytes in the base relocation block, including the
Size Page RVA and Block Size fields and the Type/Offset fields that follow.
The Block Size field is then followed by any number of Type or Offset field entries. Each
entry is a WORD (2 bytes) and has the following structure:
ノ Expand table
0 4 Type Stored in the high 4 bits of the WORD, a value that indicates the type of
bits base relocation to be applied. For more information, see Base Relocation
Types.
Offset Size Field Description
0 12 Offset Stored in the remaining 12 bits of the WORD, an offset from the starting
bits address that was specified in the Page RVA field for the block. This
offset specifies where the base relocation is to be applied.
To apply a base relocation, the difference is calculated between the preferred base
address and the base where the image is actually loaded. If the image is loaded at its
preferred base, the difference is zero and thus the base relocations do not have to be
applied.
ノ Expand table
Note that any amount of TLS data can be supported by using the API calls TlsAlloc,
TlsFree, TlsSetValue, and TlsGetValue. The PE or COFF implementation is an alternative
approach to using the API and has the advantage of being simpler from the high-level-
language programmer's viewpoint. This implementation enables TLS data to be defined
and initialized similarly to ordinary static variables in a program. For example, in Visual C+
+, a static TLS variable can be defined as follows, without using the Windows API:
To support this programming construct, the PE and COFF .tls section specifies the
following information: initialization data, callback routines for per-thread initialization
and termination, and the TLS index, which are explained in the following discussion.
7 Note
Before Windows Vista, statically declared TLS data objects can be used only in
statically loaded image files. This fact makes it unreliable to use static TLS data in a
DLL unless you know that the DLL, or anything statically linked with it, will never be
loaded dynamically with the LoadLibrary API function. However, starting with
Windows Vista, improvements were made to the Windows loader to better support
the dynamic loading of DLLs with static TLS. This change means that DLLs with
statically declared TLS data objects can now be used more reliably, even if they are
loaded dynamically using LoadLibrary. The loader is capable of allocating TLS slots
for such DLLs at load time, mitigating the limitations present in earlier versions of
Windows.
7 Note
References to 32-bit offsets and index multipliers of 4 apply to systems with 32-bit
architectures. In a system based on 64-bit architectures, adjust them as necessary.
Executable code accesses a static TLS data object through the following steps:
1. At link time, the linker sets the Address of Index field of the TLS directory. This field
points to a location where the program expects to receive the TLS index.
The Microsoft run-time library facilitates this process by defining a memory image
of the TLS directory and giving it the special name " tls_used" (Intel x86 platforms)
or "_tls_used" (other platforms). The linker looks for this memory image and uses
the data there to create the TLS directory. Other compilers that support TLS and
work with the Microsoft linker must use this same technique.
2. When a thread is created, the loader communicates the address of the thread's TLS
array by placing the address of the thread environment block (TEB) in the FS
register. A pointer to the TLS array is at the offset of 0x2C from the beginning of
TEB. This behavior is Intel x86-specific.
3. The loader assigns the value of the TLS index to the place that was indicated by the
Address of Index field.
4. The executable code retrieves the TLS index and also the location of the TLS array.
5. The code uses the TLS index and the TLS array location (multiplying the index by 4
and using it as an offset to the array) to get the address of the TLS data area for
the given program and module. Each thread has its own TLS data area, but this is
transparent to the program, which does not need to know how data is allocated
for individual threads.
6. An individual TLS data object is accessed as some fixed offset into the TLS data
area.
The TLS array is an array of addresses that the system maintains for each thread. Each
address in this array gives the location of TLS data for a given module (EXE or DLL)
within the program. The TLS index indicates which member of the array to use. The
index is a number (meaningful only to the system) that identifies the module.
ノ Expand table
0 4/8 Raw Data Start The starting address of the TLS template. The template
VA is a block of data that is used to initialize TLS data. The
system copies all of this data each time a thread is
created, so it must not be corrupted. Note that this
address is not an RVA; it is an address for which there
should be a base relocation in the .reloc section.
4/8 4/8 Raw Data The address of the last byte of the TLS, except for the
End VA zero fill. As with the Raw Data Start VA field, this is a VA,
not an RVA.
8/16 4/8 Address The location to receive the TLS index, which the loader
of Index assigns. This location is in an ordinary data section, so it
can be given a symbolic name that is accessible to the
program.
12/24 4/8 Address The pointer to an array of TLS callback functions. The
of array is null-terminated, so if no callback function is
Callbacks supported, this field points to 4 bytes set to zero. For
information about the prototype for these functions, see
TLS Callback Functions.
16/32 4 Size of Zero The size in bytes of the template, beyond the initialized
Fill data delimited by the Raw Data Start VA and Raw Data
End VA fields. The total template size should be the
same as the total size of TLS data in the image file. The
zero fill is the amount of data that comes after the
initialized nonzero data.
20/36 4 Characteristics The four bits [23:20] describe alignment info. Possible
values are those defined as IMAGE_SCN_ALIGN_*, which
are also used to describe alignment of section in object
files. The other 28 bits are reserved for future use.
C++
typedef VOID
(NTAPI *PIMAGE_TLS_CALLBACK) (
PVOID DllHandle,
DWORD Reason,
PVOID Reserved
);
The Reserved parameter should be set to zero. The Reason parameter can take the
following values:
ノ Expand table
DLL_THREAD_ATTACH 2 A new thread has been created. This notification sent for all but
the first thread.
The load configuration structure has the following layout for 32-bit and 64-bit PE files:
ノ Expand table
The GuardFlags field contains a combination of one or more of the following flags and
subfields:
Delayload import table in its own .didat section (with nothing else in it) that can be
freely reprotected.
Module contains suppressed export information. This also infers that the address
taken IAT table is also present in the load config.
Mask for the subfield that contains the stride of Control Flow Guard function table
entries (that is, the additional count of bytes per table entry).
Additionally, the Windows SDK winnt.h header defines this macro for the amount of bits
to right-shift the GuardFlags value to right-justify the Control Flow Guard function table
stride:
#define IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_SHIFT 28
A series of resource directory tables relates all of the levels in the following way: Each
directory table is followed by a series of directory entries that give the name or identifier
(ID) for that level (Type, Name, or Language level) and an address of either a data
description or another directory table. If the address points to a data description, then
the data is a leaf in the tree. If the address points to another directory table, then that
table lists directory entries at the next level down.
A leaf's Type, Name, and Language IDs are determined by the path that is taken through
directory tables to reach the leaf. The first table determines Type ID, the second table
(pointed to by the directory entry in the first table) determines Name ID, and the third
table determines Language ID.
ノ Expand table
Data Description
Resource Directory A series of tables, one for each group of nodes in the tree. All top-level
Tables (and Resource (Type) nodes are listed in the first table. Entries in this table point to
Directory Entries) second-level tables. Each second-level tree has the same Type ID but
different Name IDs. Third-level trees have the same Type and Name
IDs but different Language IDs.
Each individual table is immediately followed by directory entries, in which
each entry has a name or numeric identifier and a pointer to a data
description or a table at the next lower level.
Resource Directory Two-byte-aligned Unicode strings, which serve as string data that is
Strings pointed to by directory entries.
Resource Data An array of records, pointed to by tables, that describe the actual size
Description and location of the resource data. These records are the leaves in the
resource-description tree.
Resource Data Raw data of the resource section. The size and location information in the
Resource Data Descriptions field delimit the individual regions of
resource data.
ノ Expand table
Offset Size Field Description
4 4 Time/Date Stamp The time that the resource data was created by the resource
compiler.
The directory entries make up the rows of a table. Each resource directory entry has the
following format. Whether the entry is a Name or ID entry is indicated by the resource
directory table, which indicates how many Name and ID entries follow it (remember that
all the Name entries precede all the ID entries for the table). All entries for the table are
sorted in ascending order: the Name entries by case-sensitive string and the ID entries
by numeric value. Offsets are relative to the address in the
IMAGE_DIRECTORY_ENTRY_RESOURCE DataDirectory. See Peering Inside the PE: A Tour
of the Win32 Portable Executable File Format for more information.
ノ Expand table
0 4 Name Offset The offset of a string that gives the Type, Name, or Language
ID entry, depending on level of table.
4 4 Subdirectory High bit 1. The lower 31 bits are the address of another
Offset Size Field Description
The resource directory string area consists of Unicode strings, which are word-aligned.
These strings are stored together after the last Resource Directory entry and before the
first Resource Data entry. This minimizes the impact of these variable-length strings on
the alignment of the fixed-size directory entries. Each resource directory string has the
following format:
ノ Expand table
0 2 Length The size of the string, not including length field itself.
ノ Expand table
0 4 Data RVA The address of a unit of resource data in the Resource Data area.
4 4 Size The size, in bytes, of the resource data that is pointed to by the
Data RVA field.
8 4 Codepage The code page that is used to decode code point values within
the resource data. Typically, the code page would be the
Unicode code page.
12 4 Reserved,
must be 0.
The .cormeta Section (Object Only)
CLR metadata is stored in this section. It is used to indicate that the object file contains
managed code. The format of the metadata is not documented, but can be handed to
the CLR interfaces for handling metadata.
Additionally, the compiler marks a COFF object as registered SEH by emitting the
absolute symbol "@feat.00" with the LSB of the value field set to 1. A COFF object with
no registered SEH handlers would have the "@feat.00" symbol, but no .sxdata section.
The COFF archive format provides a standard mechanism for storing collections of
object files. These collections are commonly called libraries in programming
documentation.
The first 8 bytes of an archive consist of the file signature. The rest of the archive
consists of a series of archive members, as follows:
The first and second members are "linker members." Each of these members has
its own format as described in section Import Name Type. Typically, a linker places
information into these archive members. The linker members contain the directory
of the archive.
The third member is the "longnames" member. This optional member consists of a
series of null-terminated ASCII strings in which each string is the name of another
archive member.
The rest of the archive consists of standard (object-file) members. Each of these
members contains the contents of one object file in its entirety.
An archive member header precedes each member. The following list shows the general
structure of an archive:
ノ Expand table
Signature :"!<arch>\n"
ノ Expand table
Header
ノ Expand table
Header
ノ Expand table
Header
Longnames Member
ノ Expand table
Header
ノ Expand table
Header
...
ノ Expand table
Header
!<arch>\n
#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>/ "
Each member header starts on the first even address after the end of the previous
archive member, one byte '\n' (IMAGE_ARCHIVE_PAD) may be inserted after an archive
member to make the following member start on an even address.
ノ Expand table
0 16 Name The name of the archive member, with a slash (/) appended to
terminate the name. If the first character is a slash, the name has a
special interpretation, as described in the following table.
Offset Size Field Description
16 12 Date The date and time that the archive member was created: This is the
ASCII decimal representation of the number of seconds since
1/1/1970 UCT.
28 6 User ID An ASCII decimal representation of the user ID. This field does not
contain a meaningful value on Windows platforms because Microsoft
tools emit all blanks.
34 6 Group ID An ASCII decimal representation of the group ID. This field does not
contain a meaningful value on Windows platforms because Microsoft
tools emit all blanks.
40 8 Mode An ASCII octal representation of the member's file mode. This is the
ST_MODE value from the C run-time function _wstat.
The Name field has one of the formats shown in the following table. As mentioned
earlier, each of these strings is left justified and padded with trailing spaces within a field
of 16 bytes:
ノ Expand table
Contents of Description
Name field
/ The archive member is one of the two linker members. Both of the linker
members have this name.
// The archive member is the longnames member, which consists of a series of null-
terminated ASCII strings. The longnames member is the third archive member and
is optional.
/n The name of the archive member is located at offset n within the longnames
member. The number n is the decimal representation of the offset. For example:
"/26" indicates that the name of the archive member is located 26 bytes beyond
the beginning of the longnames member contents.
First Linker Member
The name of the first linker member is "/" (IMAGE_ARCHIVE_LINKER_MEMBER). The
first linker member is included for backward compatibility. It is not used by current
linkers, but its format must be correct. This linker member provides a directory of
symbol names, as does the second linker member. For each symbol, the information
indicates where to find the archive member that contains the symbol.
The first linker member has the following format. This information appears after the
header:
ノ Expand table
0 4 Number Unsigned long that contains the number of indexed symbols. This
of number is stored in big-endian format. Each object-file member
Symbols typically defines one or more external symbols.
* * String A series of null-terminated strings that name all the symbols in the
Table directory. Each string begins immediately after the null character in
the previous string. The number of strings must be equal to the value
of the Number of Symbols field.
The elements in the offsets array must be arranged in ascending order. This fact implies
that the symbols in the string table must be arranged according to the order of archive
members. For example, all the symbols in the first object-file member would have to be
listed before the symbols in the second object file.
ノ Expand table
Longnames Member
The name of the longnames member is "//" (IMAGE_ARCHIVE_LONGNAMES_MEMBER).
The longnames member is a series of strings of archive member names. A name appears
here only when there is insufficient room in the Name field (16 bytes). The longnames
member is optional. It can be empty with only a header, or it can be completely absent
without even a header.
The strings are null-terminated. Each string begins immediately after the null byte in the
previous string.
Traditional import libraries, that is, libraries that describe the exports from one image for
use by another, typically follow the layout described in section 7, Archive (Library) File
Format. The primary difference is that import library members contain pseudo-object
files instead of real ones, in which each member includes the section contributions that
are required to build the import tables that are described in section 6.4, The .idata
Section The linker generates this archive while building the exporting application.
The section contributions for an import can be inferred from a small set of information.
The linker can either generate the complete, verbose information into the import library
for each member at the time of the library's creation or write only the canonical
information to the library and let the application that later uses it generate the
necessary data on the fly.
In an import library with the long format, a single member contains the following
information:
Import Header
The import header contains the following fields and offsets:
ノ Expand table
Offset Size Field Description
6 2 Machine The number that identifies the type of target machine. For
more information, see Machine Types.
8 4 Time-Date The time and date that the file was created.
Stamp
12 4 Size Of Data The size of the strings that follow the header.
16 2 Ordinal/Hint Either the ordinal or the hint for the import, determined by the
value in the Name Type field.
18 2 Type The import type. For specific values and descriptions, see
bits Import Type.
3 Name Type The import name type. For more information, see Import Name
bits Type.
This structure is followed by two null-terminated strings that describe the imported
symbol's name and the DLL from which it came.
Import Type
The following values are defined for the Type field in the import header:
ノ Expand table
IMPORT_OBJECT_DATA 1 Data.
ノ Expand table
Several attribute certificates are expected to be used to verify the integrity of the
images. However, the most common is Authenticode signature. An Authenticode
signature can be used to verify that the relevant sections of a PE image file have not
been altered in any way from the file’s original form. To accomplish this task,
Authenticode signatures contain something called a PE image hash
In an Authenticode signature, the file hash is digitally signed by using a private key
known only to the signer of the file. A software consumer can verify the integrity of the
file by calculating the hash value of the file and comparing it to the value of signed hash
contained in the Authenticode digital signature. If the file hashes do not match, part of
the file covered by the PE image hash has been modified.
This section describes how a PE image hash is calculated and what parts of the PE image
can be modified without invalidating the Authenticode signature.
7 Note
The PE image hash for a specific file can be included in a separate catalog file
without including an attribute certificate within the hashed file. This is relevant,
because it becomes possible to invalidate the PE image hash in an Authenticode-
signed catalog file by modifying a PE image that does not actually contain an
Authenticode signature.
All data in sections of the PE image that are specified in the section table are hashed in
their entirety except for the following exclusion ranges:
The file CheckSum field of the Windows-specific fields of the optional header.
This checksum includes the entire file (including any attribute certificates in the
file). In all likelihood, the checksum will be different than the original value after
inserting the Authenticode signature.
Information related to attribute certificates. The areas of the PE image that are
related to the Authenticode signature are not included in the calculation of the PE
image hash because Authenticode signatures can be added to or removed from an
image without affecting the overall integrity of the image. This is not a problem,
because there are user scenarios that depend on re-signing PE images or adding a
time stamp. Authenticode excludes the following information from the hash
calculation:
The Certificate Table and corresponding certificates that are pointed to by the
Certificate Table field listed immediately above.
To calculate the PE image hash, Authenticode orders the sections that are
specified in the section table by address range, then hashes the resulting sequence
of bytes, passing over the exclusion ranges.
Information past of the end of the last section. The area past the last section
(defined by highest offset) is not hashed. This area commonly contains debug
information. Debug information can generally be considered advisory to
debuggers; it does not affect the actual integrity of the executable program. It is
quite literally possible to remove debug information from an image after a product
has been delivered and not affect the functionality of the program. In fact, this is
sometimes done as a disk-saving measure. It is worth noting that debug
information contained within the specified sections of the PE Image cannot be
removed without invaliding the Authenticode signature.
You can use the makecert and signtool tools provided in the Windows Platform SDK
to experiment with creating and verifying Authenticode signatures. For more
information, see Reference, below.
References
Downloads and tools for Windows (includes the Windows SDK)
Creating, Viewing, and Managing Certificates
(.doc) SignTool
ImageHlp Functions
Feedback
Was this page helpful? Yes No
The image access functions access the data in an executable image. These functions
provide high-level access to the base of images and very specific access to the most
common parts of an image's data.
GetImageConfigInformation
GetImageUnusedHeaderBytes
ImageLoad
ImageUnload
MapAndLoad
SetImageConfigInformation
UnMapAndLoad
Feedback
Was this page helpful? ツ Yes ト No