Windows PE File Structure
Last updated
Last updated
Shameless plug
This course is provided to you for free by the Malcore team: https://m4lc.io/course/winpe/register
Consider registering, and using Malcore, so we can continue to provide free content for the entire community. You can also join our Discord server here: https://m4lc.io/course/winpe/discord
We offer free threat intel in our Discord via our custom designed Discord bot. Join the Discord to discuss this course in further detail or to ask questions.
You can also support us by buying us a coffee
The Windows Portable Executable (PE) file format is a structure used by Windows binary files. It is derived from the Common Object File Format (COFF) used in Unix systems; it is fundamental for Windows systems.
In this course we will break down the Windows PE structure thoroughly.
NOTE: To help visualize some of this information you can see a full analysis of this file done by Malcore here: https://m4lc.io/course/winpe/full
The purpose of the DOS header is to maintain backwards compatibility with older systems. It is a remnant of the DOS era, and tells the system that this is an executable in DOS while providing a pointer to the PE header where modern executable information starts.
e_magic
: The signature that the system recognizes as a valid DOS executable
Offset: 0x0000
e_lfanew
: The pointer to the PE header location
Offset: 0x003C
Offset: 0x0040
Small program that runs in DOS mode, usually contains the message: This program cannot be run in DOS mode.
Offset is specified by e_lfanew
header.
Marks the start of the PE file
For example if e_lfanew
is 0x000080
the signature is at 0x80
The signature in bytes is always: \x50\x45\x00\x00
and displayed in ASCII it is always: PE\0\0
Offset is typically directly after the PE signature
Contains general metadata about the file
Machine
Offset: 0x00
Description: Indicates the target architecture of the file.
Possible Values:
0x014C
– Intel 386 (x86).
0x0200
– Intel Itanium.
0x8664
– x64 (AMD64).
0x01C0
– ARM.
0x01C4
– ARMv7.
0xAA64
– ARM64.
0x0100
– MIPS R3000.
NOTE: There may be more values, we just couldn't think of any other ones
Number of Sections
Offset: 0x02
Description: The number of section the PE file (counts the section header not the full section).
Timestamp
Offset: 0x04
Description: Contains the timestamp of the file creation or last modified time.
Usage: This can be used to analyze when a PE file was compiled or built.
You can see a timestamp after compilation being retrieved from the file here: https://m4lc.io/course/winpe/timestamp
PointerToSymbolTable
Offset: 0x08
Description: Points to the start of the symbol table in the file.
In executables and DLL files, this field is usually set to 0x00000000
.
Number of Symbols
Offset: 0x0C
Description: The number of entries in the symbol table. Is usually set to 0x00000000
.
SizeOfOptionalHeader
Offset: 0x10
Description: Specifies the size of the Optional Header
.
For 32-bit files, the size is usually 0x00E0
(224 bytes).
For 64-bit files, the size is usually 0x00F0
(240 bytes).
Characteristics
Offset: 0x12
Description: Contains flags that describe the attributes of the PE file (such as if it's an exe or a DLL).
Possible Values:
0x0002
– Executable image.
0x0020
– Application can handle addresses larger than 2GB (large address aware).
0x0100
– The file is a DLL.
0x2000
– The file is a system file.
0x4000
– File is a dynamically loadable driver.
0x8000
– File is removable media-aware.
Despite its name this is required for executable images and DLL files. It contains a bunch of information that is needed to properly load the PE file and execute the file in memory. You can see a lot of this information pulled out of a real file and visualize it here: https://m4lc.io/course/winpe/info
Magic
Offset: 0x00 (PE32 and PE32+)
Size: 2 bytes
Description:
Identifies the file format:
0x10B for 32 bit.
0x20B for 64 bit.
Used to determine between 32-bit and 64-bit executable formats.
Major Linker Version
Offset: 0x02
Size: 1 byte
Description:
The major version number of the linker that generated the file.
Indicates the compatibility of the file with the linker software.
Possible values:
2 (0x02
)
Linker Version: Microsoft Linker 2.x
Visual Studio Version: Early Microsoft C Compilers
3 (0x03
)
Linker Version: Microsoft Linker 3.x
Visual Studio Version: Early Microsoft C/C++ Compilers
5 (0x05
)
Linker Version: Microsoft Linker 5.x
Visual Studio Version: Visual Studio 97
6 (0x06
)
Linker Version: Microsoft Linker 6.x
Visual Studio Version: Visual Studio 6.0
7 (0x07
)
Linker Version: Microsoft Linker 7.0
Visual Studio Version: Visual Studio .NET 2002
7 (0x07
)
Linker Version: Microsoft Linker 7.10
Visual Studio Version: Visual Studio .NET 2003
8 (0x08
)
Linker Version: Microsoft Linker 8.0
Visual Studio Version: Visual Studio 2005
9 (0x09
)
Linker Version: Microsoft Linker 9.0
Visual Studio Version: Visual Studio 2008
10 (0x0A
)
Linker Version: Microsoft Linker 10.0
Visual Studio Version: Visual Studio 2010
11 (0x0B
)
Linker Version: Microsoft Linker 11.0
Visual Studio Version: Visual Studio 2012
12 (0x0C
)
Linker Version: Microsoft Linker 12.0
Visual Studio Version: Visual Studio 2013
14 (0x0E
)
Linker Version: Microsoft Linker 14.0
Visual Studio Version: Visual Studio 2015
14 (0x0E
)
Linker Version: Microsoft Linker 14.1
Visual Studio Version: Visual Studio 2017
14 (0x0E
)
Linker Version: Microsoft Linker 14.2
Visual Studio Version: Visual Studio 2019
14 (0x0E
)
Linker Version: Microsoft Linker 14.3
Visual Studio Version: Visual Studio 2022
NOTE: There are probably more that are not listed
Minor Linker Version
Offset: 0x03
Size: 1 byte
Description:
The minor version number of the linker that generated the file.
Possible values:
0:
Initial versions; often seen in older files.
10 (0x0A
):
Microsoft Linker version 5.10, corresponding to Visual Studio 97.
12 (0x0C
):
Microsoft Linker version 6.0, corresponding to Visual Studio 6.0.
16 (0x10
):
Microsoft Linker version 7.0, corresponding to Visual Studio .NET 2002.
20 (0x14
):
Microsoft Linker version 7.10, corresponding to Visual Studio .NET 2003.
30 (0x1E
):
Microsoft Linker version 8.0, corresponding to Visual Studio 2005.
36 (0x24
):
Microsoft Linker version 9.0, corresponding to Visual Studio 2008.
40 (0x28
):
Microsoft Linker version 10.0, corresponding to Visual Studio 2010.
46 (0x2E
):
Microsoft Linker version 11.0, corresponding to Visual Studio 2012.
48 (0x30
):
Microsoft Linker version 12.0, corresponding to Visual Studio 2013.
50 (0x32
):
Microsoft Linker version 14.0, corresponding to Visual Studio 2015.
52 (0x34
):
Microsoft Linker version 14.1, corresponding to Visual Studio 2017.
28 (0x1C
):
Microsoft Linker version 14.2, corresponding to Visual Studio 2019.
36 (0x24
):
Microsoft Linker version 14.3, corresponding to Visual Studio 2022.
NOTE: There are probably more that are not listed
SizeOfCode
Offset: 0x04
Size: 4 bytes
Description:
The total size of all sections that contain executable code.
SizeOfInitializedData
Offset: 0x08
Size: 4 bytes
Description:
The total size of all sections containing initialized data.
SizeOfUninitializedData
Offset: 0x0C
Size: 4 bytes
Description:
The total size of all sections containing uninitialized data.
AddressOfEntryPoint
Offset: 0x10
Size: 4 bytes
Description:
RVA of the entry point function.
This is where execution starts after the program is loaded.
BaseOfCode
Offset: 0x14
Size: 4 bytes
Description:
The RVA of the start of the code section.
Indicates where the code segment begins in memory.
BaseOfData (PE32 only)
Offset: 0x18
Size: 4 bytes
Description:
The RVA of the start of the data section.
This field is not present in PE32+.
Possible for BaseOfData
to be missing in PE32+ (which is why there is no image of it in this course)
ImageBase
Offset: 0x1C (PE32), 0x18 (PE32+)
Size: 4 bytes (PE32), 8 bytes (PE32+)
Description:
The preferred memory address at which the image should be loaded.
Defaults to 0x400000
for PE32 and 0x140000000
for PE32+.
SectionAlignment
Offset: 0x20
Size: 4 bytes
Description:
The alignment of sections in memory.
Typically 0x1000
(4KB) but must be greater than or equal to FileAlignment.
FileAlignment
Offset: 0x24
Size: 4 bytes
Description:
The alignment of sections in the file on disk.
Usually set to 0x200
(512 bytes) but can vary based on the file format.
MajorOperatingSystemVersion
Offset: 0x28
Size: 2 bytes
Description:
The major version of the minimum required operating system.
MinorOperatingSystemVersion
Offset: 0x2A
Size: 2 bytes
Description:
The minor version of the minimum required operating system.
MajorImageVersion
Offset: 0x2C
Size: 2 bytes
Description:
The major version number of the image, set by the developer.
MinorImageVersion
Offset: 0x2E
Size: 2 bytes
Description:
The minor version number of the image.
MajorSubsystemVersion
Offset: 0x30
Size: 2 bytes
Description:
The major version of the subsystem that the image requires.
MinorSubsystemVersion
Offset: 0x32
Size: 2 bytes
Description:
The minor version of the subsystem.
Win32VersionValue
Offset: 0x34
Size: 4 bytes
Description:
Reserved, usually set to 0.
SizeOfImage
Offset: 0x38
Size: 4 bytes
Description:
The total size of the image, aligned to SectionAlignment.
This includes headers and all sections.
SizeOfHeaders
Offset: 0x3C
Size: 4 bytes
Description:
The size of all headers combined.
Aligned to FileAlignment.
CheckSum
Offset: 0x40
Size: 4 bytes
Description:
The checksum of the image.
Required for kernel-mode drivers; optional for user-mode executables.
Subsystem
Offset: 0x44
Size: 2 bytes
Description:
Specifies the subsystem required to run the image.
Common values:
0x02: Windows GUI.
0x03: Windows Console.
DllCharacteristics
Offset: 0x46
Size: 2 bytes
Description:
Flags indicating specific characteristics of the DLL.
SizeOfStackReserve
Offset: 0x48 (PE32), 0x48 (PE32+)
Size: 4 bytes (PE32), 8 bytes (PE32+)
Description:
The size of memory reserved for the stack.
Defaults to 1 MB for PE32 and 4 MB for PE32+.
SizeOfStackCommit
Offset: 0x4C (PE32), 0x50 (PE32+)
Size: 4 bytes (PE32), 8 bytes (PE32+)
Description:
The size of memory initially committed for the stack.
SizeOfHeapReserve
Offset: 0x50 (PE32), 0x58 (PE32+)
Size: 4 bytes (PE32), 8 bytes (PE32+)
Description:
The size of memory reserved for the heap.
SizeOfHeapCommit
Offset: 0x54 (PE32), 0x60 (PE32+)
Size: 4 bytes (PE32), 8 bytes (PE32+)
Description:
The size of memory initially committed for the heap.
LoaderFlags
Offset: 0x58 (PE32), 0x68 (PE32+)
Size: 4 bytes
Description:
Reserved for system use, usually set to 0.
NumberOfRvaAndSizes
Offset: 0x5C (PE32), 0x6C (PE32+)
Size: 4 bytes
Description:
The number of data directories following this field.
Typically set to 16, covering standard PE data directories like Import Table, Export Table, etc.
The data directory is a set of pointers that are part of the OptionalHeader
. It directs the Windows loader to various tables and structures that manage the execution of the program.
Let’s break down each directory in detail:
Export Table
Offset (PE32): 0x60
, Offset (PE32+): 0x70
Purpose:
Contains addresses of functions, variables, and symbols that the module exports for use by other modules.
Used for linking and referencing functions provided by the module.
Fields:
RVA: Pointer to the start of the Export Table.
Size: Size of the Export Table data.
Import Table
Offset (PE32): 0x68
, Offset (PE32+): 0x78
Purpose:
Contains information about functions, symbols, and variables imported from other modules.
Used for dynamic linking, allowing the module to use functions provided by other DLLs.
Fields:
RVA: Pointer to the start of the Import Table.
Size: Size of the Import Table data.
You can see a visualization of the import table of this file here: https://m4lc.io/course/winpe/imports
Resource Table
Offset (PE32): 0x70
, Offset (PE32+): 0x80
Purpose:
Contains resources like icons, dialogs, menus, strings, bitmaps, and other user interface components.
Allows for localization and UI customization within the PE file.
Fields:
RVA: Pointer to the start of the Resource Table.
Size: Size of the Resource Table data.
Exception Table
Offset (PE32): 0x78
, Offset (PE32+): 0x88
Purpose:
Holds information for exception handling, particularly for x64 Structured Exception Handling (SEH).
Used to manage hardware exceptions and software-defined exceptions during execution.
Fields:
RVA: Pointer to the start of the Exception Table.
Size: Size of the Exception Table data.
Certificate Table
Offset (PE32): 0x80
, Offset (PE32+): 0x90
Purpose:
Contains digital certificates for the file.
Used for verifying the integrity and authenticity of the PE file, often part of Authenticode signature verification.
Fields:
RVA: Pointer to the start of the Certificate Table (points to a file offset, not an RVA).
Size: Size of the certificate data.
You can see what it looks like when certificates are pulled from a file here: https://m4lc.io/course/winpe/certs
Base Relocation Table
Offset (PE32): 0x88
, Offset (PE32+): 0x98
Purpose:
Contains base relocations that enable the executable to be loaded at a different base address than specified by ImageBase.
Adjusts memory addresses when the image cannot be loaded at its preferred address.
Fields:
RVA: Pointer to the start of the Base Relocation Table.
Size: Size of the Base Relocation Table data.
Debug Directory
Offset (PE32): 0x90
, Offset (PE32+): 0xA0
Purpose:
Contains information useful for debugging tools.
Includes information about symbols, source files, and debugging information needed for analysis.
Fields:
RVA: Pointer to the start of the Debug Directory.
Size: Size of the Debug Directory data.
Architecture
Offset (PE32): 0x98
, Offset (PE32+): 0xA8
Purpose:
Reserved for future use, typically set to 0.
Fields:
RVA: Usually set to 0.
Size: Usually set to 0.
GlobalPtr
Offset (PE32): 0xA0
, Offset (PE32+): 0xB0
Purpose:
Reserved for global pointer optimization; generally set to 0.
Fields:
RVA: Typically 0.
Size: Typically 0.
TLS Table
Offset (PE32): 0xA8
, Offset (PE32+): 0xB8
Purpose:
Contains initialization data for Thread Local Storage (TLS).
TLS provides a mechanism for data that is specific to individual threads.
Fields:
RVA: Pointer to the start of the TLS Table.
Size: Size of the TLS Table data.
Load Config Table
Offset (PE32): 0xB0
, Offset (PE32+): 0xC0
Purpose:
Contains security features like SafeSEH, CFG (Control Flow Guard), and other load-time configurations.
Used to enhance security during execution.
Fields:
RVA: Pointer to the start of the Load Config Table.
Size: Size of the Load Config Table data.
Bound Import
Offset (PE32): 0xB8
, Offset (PE32+): 0xC8
Purpose:
Contains information about functions that are bound to specific addresses.
Helps speed up the loading process by avoiding the need for dynamic import resolution.
Fields:
RVA: Pointer to the start of the Bound Import Table.
Size: Size of the Bound Import Table data.
Import Address Table (IAT)
Offset (PE32): 0xC0
, Offset (PE32+): 0xD0
Purpose:
Provides the actual addresses of imported functions used by the executable.
Used during runtime to resolve addresses for dynamically linked functions.
Fields:
RVA: Pointer to the start of the IAT.
Size: Size of the IAT data.
A section in a PE file represents different parts of the file the contain code, data, and other resources that make the file execute. Each section is defined by a header that describes its properties, size, and memory alignment.
You can see a visualization of the sections of the file used for this course here: https://m4lc.io/course/winpe/sections
Common sections in PE files include:
.text
Contains the executable code if the program, where the CPU executes its instructions
.data
Stories initialized global variables and static variables. These variables have a defined value before execution
.bss
Holds uninitialized data
.rdata
Contains read-only constants, strings, and data that should not be modified
.rsrc
Stores resources that the file will use
.edata
Contains the export table
.idata
Like .edata
but contains the import table
.reloc
Contains relocation information allowing the executable to be loaded at different addresses
.pdata
Contains exception data
.tls
Holds Thread Local Storage that initializes values to specific threads
Each section is 40 bytes long and contains multiple pieces to it. As you can see in the image and table below:
Name
VirtualSize
VirtualAddress
SizeOfRawData
PointerToRawData
PointerToRelocations
PointerToLinenumbers
NumberOfRelocations
NumberOfLinenumbers
Characteristics
That's really all there is to it. In this course we have broken down the PE file format and provided you with visualizations of how the format works. We appreciate you taking the time to read through this course and hope you got something out of it.
Once again:
A lot of this information can be visualized and seen done during analysis by following these links:
Also, please remember that this course is provided to you for free by the Malcore team: https://m4lc.io/course/winpe/register
Consider registering, and using Malcore, so we can continue to provide free content for the entire community. You can also join our Discord server here: https://m4lc.io/course/winpe/discord
We offer free threat intel in our Discord via our custom designed Discord bot. Join the Discord to discuss this course in further detail or to ask questions.
You can also support us by buying us a coffee
Tools used for this course:
Malcore: https://malcore.io
Malcat: https://malcat.fr/
Offset | Size (Bytes) | Field Name | Description |
---|---|---|---|
Offset (PE32) | Offset (PE32+) | Size | Field Name | Description |
---|---|---|---|---|
Offset (PE32) | Offset (PE32+) | Size | Field Name | Description |
---|---|---|---|---|
Offset | Size (Bytes) | Field Name | Description |
---|---|---|---|
0x00
2
Machine
Indicates the architecture.
0x02
2
NumberOfSections
The number of sections in the PE file.
0x04
4
TimeDateStamp
Timestamp indicating when the file was created or last modified.
0x08
4
PointerToSymbolTable
The file offset to the symbol table.
0x0C
4
NumberOfSymbols
The number of entries in the symbol table.
0x10
2
SizeOfOptionalHeader
The size of the Optional Header
.
0x12
2
Characteristics
Flags that indicate the attributes and characteristics of the file
0x00
0x00
2
Magic
Specifies whether the file is 32(0x10B
) or 64(0x20B
) bit.
0x02
0x02
1
Major Linker Version
Major version of the linker used to create the file.
0x03
0x03
1
Minor Linker Version
Minor version of the linker used to create the file.
0x04
0x04
4
SizeOfCode
Total size of all code sections when loaded in memory.
0x08
0x08
4
SizeOfInitializedData
Total size of all initialized data sections when loaded in memory.
0x0C
0x0C
4
SizeOfUninitializedData
Total size of all uninitialized data sections when loaded in memory.
0x10
0x10
4
AddressOfEntryPoint
RVA (Relative Virtual Address) of the entry point function
0x14
0x14
4
BaseOfCode
RVA of the start of the code section.
0x18
N/A
4
BaseOfData
(PE32 only) RVA of the start of the data section.
0x1C
0x18
4/8
ImageBase
Preferred address of the image when loaded in memory.
0x20
0x20
4
SectionAlignment
Alignment of sections when loaded in memory.
0x24
0x24
4
FileAlignment
Alignment of sections in the file on disk.
0x28
0x28
2
MajorOperatingSystemVersion
Major version of the minimum OS required to run the file.
0x2A
0x2A
2
MinorOperatingSystemVersion
Minor version of the minimum OS required to run the file.
0x2C
0x2C
2
MajorImageVersion
Major version number of the image.
0x2E
0x2E
2
MinorImageVersion
Minor version number of the image.
0x30
0x30
2
MajorSubsystemVersion
Major version of the subsystem required to run the file.
0x32
0x32
2
MinorSubsystemVersion
Minor version of the subsystem required to run the file.
0x34
0x34
4
Win32VersionValue
Reserved, usually set to 0.
0x38
0x38
4
SizeOfImage
Total size of the image, including all headers and sections, aligned to SectionAlignment.
0x3C
0x3C
4
SizeOfHeaders
Combined size of the DOS Header, PE Header, Optional Header, and Section Headers, aligned to FileAlignment.
0x40
0x40
4
CheckSum
Checksum of the image. Required for drivers; optional for user-mode executables.
0x44
0x44
2
Subsystem
Specifies the subsystem required
0x46
0x46
2
DllCharacteristics
Flags indicating characteristics of the DLL
0x48
0x48
4/8
SizeOfStackReserve
Size of the stack to reserve.
0x4C
0x50
4/8
SizeOfStackCommit
Size of the stack to commit initially.
0x50
0x58
4/8
SizeOfHeapReserve
Size of the heap to reserve.
0x54
0x60
4/8
SizeOfHeapCommit
Size of the heap to commit initially.
0x58
0x68
4
LoaderFlags
Reserved, usually set to 0.
0x5C
0x6C
4
NumberOfRvaAndSizes
Number of data directories in the Optional Header.
0x60
0x70
8
Export Table
Exports functions and symbols for other modules.
0x68
0x78
8
Import Table
Imports functions and symbols from other modules.
0x70
0x80
8
Resource Table
Contains resources like icons, strings, and dialogs.
0x78
0x88
8
Exception Table
Exception handling information.
0x80
0x90
8
Certificate Table
Digital signatures for verifying the file's integrity.
0x88
0x98
8
Base Relocation Table
Base address relocation information.
0x90
0xA0
8
Debug Directory
Debugging information used by debuggers.
0x98
0xA8
8
Architecture
Reserved, generally set to 0.
0xA0
0xB0
8
GlobalPtr
Reserved for global pointer information.
0xA8
0xB8
8
TLS Table
Thread Local Storage (TLS) initialization data.
0xB0
0xC0
8
Load Config Table
Security and other load configuration information.
0xB8
0xC8
8
Bound Import
List of functions bound to specific addresses.
0xC0
0xD0
8
Import Address Table
Address table for imported functions.
0xC8
0xD8
8
Delay Import
Delayed loading information for imported functions.
0xD0
0xE0
8
CLR Runtime Header
.NET metadata for managed code.
0xD8
0xE8
8
Reserved
Reserved, typically set to 0.
0x00
8
Name
An ASCII string representing the section name
0x08
4
VirtualSize
The total size of the section in memory. It might be larger than the size on disk due to alignment.
0x0C
4
VirtualAddress
The RVA of the section in memory, relative to the image base.
0x10
4
SizeOfRawData
The size of the section data in the file, aligned to the FileAlignment.
0x14
4
PointerToRawData
The file offset where the section's data starts.
0x18
4
PointerToRelocations
The file offset of the relocation entries for the section.
0x1C
4
PointerToLinenumbers
The file offset of the line-number entries for the section.
0x20
2
NumberOfRelocations
The number of relocation entries for the section.
0x22
2
NumberOfLinenumbers
The number of line-number entries for the section.
0x24
4
Characteristics
Flags indicating attributes of the section.