.EXE Windows Executable
.exe

Windows Executable

An EXE file is a Windows Portable Executable (PE) binary starting with the MZ signature (4D 5A), containing compiled machine code that runs directly on the processor. HIGH security risk — FileDex provides format reference only.

File structure
Header schema
Records structured data
Metadata1981
By FileDex
Not convertible

EXE files contain native machine code and cannot be converted between formats. FileDex displays format information and security analysis reference for Windows executables.

Common questions

What is an EXE file?

An EXE file is a Windows executable in Portable Executable (PE) format that contains compiled machine code, resources, and metadata. The Windows loader reads the PE headers to determine the target CPU architecture, required DLL imports, and entry point address, then maps the binary into memory and begins execution. EXE files can contain native x86, x64, or ARM64 code, .NET bytecode for the Common Language Runtime, or bundled applications from tools like PyInstaller or Electron.

Is it safe to open an EXE file?

Running an EXE grants it the full privilege level of the launching user. Untrusted EXE files can install malware, steal credentials, encrypt files for ransom, or establish persistent backdoors. Only run executables from verified publishers with valid Authenticode signatures. Check unknown files on VirusTotal before execution — Windows SmartScreen warns about unsigned files but does not detect all threats.

What do the MZ bytes at the start of an EXE mean?

The bytes 4D 5A (ASCII "MZ") at offset 0x00 are the initials of Mark Zbikowski, who designed the original DOS executable format at Microsoft around 1981. Every Windows EXE, DLL, and SYS driver begins with these two bytes. The signature survived four decades because each successor format — NE (1985), PE (1993) — kept the MZ header for backward compatibility.

What is the difference between a 32-bit and 64-bit EXE?

A 32-bit EXE uses PE32 format (Optional Header magic 0x10B) with 4-byte address fields. A 64-bit EXE uses PE32+ (magic 0x20B) with 8-byte fields, supporting memory above 4 GB. The COFF Machine field identifies the target: 0x14C for x86, 0x8664 for x86-64, 0xAA64 for ARM64. Windows 64-bit runs 32-bit EXEs through the WoW64 compatibility layer.

Why does SmartScreen block an EXE that is not malicious?

SmartScreen uses a reputation system based on download volume and signing history. A newly signed or unsigned EXE triggers a warning regardless of its actual content because it has no reputation data yet. Extended Validation (EV) code signing certificates bypass the reputation check immediately. Standard certificates require accumulated download history before SmartScreen stops warning.

Can EXE files run on macOS or Linux?

Not natively. EXE files target the Windows PE loader and Windows API. On macOS, Wine or CrossOver translates Windows API calls to macOS equivalents at runtime. On Linux, Wine provides the same translation layer. Virtual machines (Parallels, VMware, VirtualBox) run a full Windows installation. Mono can execute some .NET EXE files cross-platform by providing a CLR implementation.

Can FileDex convert EXE files to another format?

No. EXE files contain compiled processor instructions or .NET bytecode that cannot be meaningfully converted to another format. There is no automated tool that converts a Windows executable into a macOS or Linux binary. FileDex provides PE format reference documentation and security analysis context. No EXE files are uploaded, executed, or processed.

What is the Rich header in an EXE file?

The Rich header is an undocumented structure Microsoft's linker inserts between the DOS stub and the PE signature. It contains XOR-encrypted build metadata: compiler versions, linker versions, and object file counts for every tool in the build chain. Security researchers use Rich header analysis for malware attribution because it fingerprints the exact development environment.

What makes .EXE special

A name in every binary
MZ = Mark Zbikowski, since 1981
The 4D 5A bytes at the start of every EXE file are the ASCII initials of Mark Zbikowski, a lead MS-DOS architect at Microsoft. His two-letter signature has been the first bytes of billions of executables for over four decades.
A fossil in every program
"Cannot be run in DOS mode"
Every modern EXE contains a DOS stub program that prints this message and exits. No one runs PE executables under DOS anymore, but the Microsoft linker still generates the stub by default. Windows 98's setup program used a custom stub to run a real DOS installer.
The undocumented fingerprint
Rich header leaks your build tools
Between the DOS stub and PE signature, Microsoft's linker embeds an XOR-encrypted structure (the Rich header) that records every compiler and tool version used to build the binary. Never officially documented, it has been used to attribute state-sponsored malware to specific threat actors.
Four generations, one header
COM (1970s) to PE (1993) — MZ survived
x86 executables evolved through COM (flat binary), MZ (DOS relocatable), NE (16-bit Windows, 1985), and PE (32/64-bit, 1993). Each generation kept the MZ header at byte zero for backward compatibility, making it the longest-lived structural artifact in PC software.

The MZ Signature: A Name Frozen in Every Binary

Open any Windows executable in a hex editor and the first two bytes read 4D 5A — ASCII for "MZ." Those initials belong to Mark Zbikowski, one of the lead architects of MS-DOS at Microsoft, who designed the original DOS executable format around 1981. More than four decades later, every Windows EXE, DLL, SYS driver, and OCX control still begins with Zbikowski's initials. No other file format in computing history carries a personal signature across billions of files for this long.

Continue reading — full technical deep dive

The MZ header was never meant to last. It solved a specific 1981 problem: distinguishing relocatable executables from flat COM binaries on MS-DOS. But when Microsoft needed new executable formats — first the 16-bit New Executable (NE) for Windows 1.0 in 1985, then the 32/64-bit Portable Executable (PE) for Windows NT 3.1 in 1993 — they kept the MZ header as a backward-compatibility stub rather than starting fresh. The result is a format where the first 64 bytes of every modern 64-bit Windows application are a relic of the 8086 era.

The DOS Stub: A Message from 1993

Between the MZ header and the PE signature sits the DOS stub — a small real-mode MS-DOS program. In almost every EXE built by modern compilers, this stub does one thing: print "This program cannot be run in DOS mode" and exit. The message is a fossil. No one has run a PE executable under real-mode DOS in decades, yet the message persists because the Microsoft linker generates it by default and removing it serves no purpose.

The stub is not purely ceremonial. Microsoft's linker supports a /STUB switch that replaces the default stub with a functional DOS program, creating a fat binary that runs different code depending on the operating system. Windows 98's setup program used this technique — the same EXE file contained both a 16-bit DOS installer and a 32-bit PE installer.

PE Binary Structure

The PE format is a layered binary container. From the first byte to the last section, the layout follows a strict hierarchy:

DOS Header (64 bytes): The e_magic field at offset 0x00 holds 4D 5A. The e_lfanew field at offset 0x3C is a 4-byte pointer to the PE signature. Everything between these two fields (e_cblp, e_cp, e_crlc, and other DOS-era relocation fields) is ignored by the Windows PE loader but must be present for structural validity.

DOS Stub (variable length): Starts at offset 0x40. Typically 64-128 bytes of real-mode x86 code. The loader skips it entirely — only real-mode DOS would execute this code.

Rich Header (variable, undocumented): Between the DOS stub and the PE signature, Microsoft's linker inserts an XOR-encrypted block of build metadata. This structure, never described in the official PE specification, begins with the marker DanS (after XOR decryption) and contains comp.id entries that fingerprint every object file and library linked into the binary — recording the exact compiler version, build tool version, and source count for each. Security researchers discovered the Rich header's forensic value when analyzing state-sponsored malware: the Lazarus Group's toolchain signatures were identified through Rich header artifacts, and the Olympic Destroyer malware contained a deliberately forged Rich header designed to frame a different threat actor. For malware analysts, the Rich header is an involuntary build environment confession.

PE Signature (4 bytes): The literal bytes 50 45 00 00 ("PE\0\0") at the offset specified by e_lfanew. If these bytes are missing or corrupted, the Windows loader rejects the file.

COFF Header (20 bytes): Immediately follows the PE signature. The Machine field (2 bytes at offset +0) identifies the target CPU: 0x14C for Intel i386, 0x8664 for AMD64, 0xAA64 for ARM64. NumberOfSections (2 bytes at +2) declares how many section headers follow. TimeDateStamp (4 bytes at +4) records when the linker produced the binary — this is the primary dating mechanism for PE files and is accurate for most production builds. SizeOfOptionalHeader (2 bytes at +16) and Characteristics (2 bytes at +18) complete the structure.

Optional Header (PE32: 224 bytes, PE32+: 240 bytes): Despite the name, this header is mandatory for executables. Its first field, Magic (2 bytes), distinguishes format versions: 0x10B for PE32 (32-bit), 0x20B for PE32+ (64-bit). AddressOfEntryPoint (4 bytes at +16) is the RVA where execution begins. ImageBase specifies the preferred load address — 4 bytes in PE32, 8 bytes in PE32+, enabling PE32+ to address memory above 4 GB. The Subsystem field (2 bytes at +68) determines whether Windows creates a console window (value 3, IMAGE_SUBSYSTEM_WINDOWS_CUI) or a GUI process (value 2, IMAGE_SUBSYSTEM_WINDOWS_GUI). DllCharacteristics (2 bytes at +70) encode critical security flags: bit 0x0040 enables ASLR, bit 0x0100 enables DEP/NX compatibility, and bit 0x4000 enables Control Flow Guard.

Data Directories: Starting at offset 96 (PE32) or 112 (PE32+), an array of 8-byte entries (RVA + Size pairs) points the loader to import tables, export tables, resource trees, exception handlers, the certificate table (Authenticode signatures), base relocations, debug information, TLS data, and the CLR runtime header for .NET assemblies.

Section Table: Each entry is 40 bytes. The Name field (8 bytes, null-padded ASCII) identifies the section: .text holds executable code, .rdata holds read-only data and import descriptors, .data holds initialized global variables, .rsrc holds resources (icons, manifests, version information, embedded files), and .reloc holds base relocation entries that enable ASLR to rebase the image at a random address.

PE32 vs PE32+: The 64-bit Transition

PE32+ is not a new format — it is PE32 with wider address fields. The structural difference is precise: ImageBase grows from 4 bytes to 8. SizeOfStackReserve, SizeOfStackCommit, SizeOfHeapReserve, and SizeOfHeapCommit each grow from 4 bytes to 8. The BaseOfData field present in PE32 is removed entirely in PE32+. This makes the PE32+ optional header 16 bytes larger (240 vs 224 bytes) despite having one fewer field.

The Machine field in the COFF header determines the instruction set: 0x14C for 32-bit x86, 0x8664 for 64-bit x86-64. Windows on ARM64 added 0xAA64 for native ARM64 binaries and 0xA641 for ARM64EC — an interoperability mode where ARM64 code can call x64 functions and vice versa, designed to ease the transition from x64 to ARM64 on Windows.

A 64-bit Windows installation runs 32-bit PE32 executables through WoW64 (Windows 32-bit on Windows 64-bit), a compatibility layer that translates system calls and manages separate 32-bit and 64-bit registry views. A 32-bit Windows installation cannot run PE32+ executables at all.

The COM to PE Evolution

Executable formats on x86 PCs evolved through four generations. COM files (1970s-1981) were flat memory images with no header — the OS loaded the entire file at a fixed segment offset and jumped to byte zero. Maximum size: 65,280 bytes (one 64K segment minus 256 bytes for the Program Segment Prefix). MZ EXE (1981) added a header with relocation entries, allowing programs to exceed 64K and load at variable memory addresses. New Executable (NE) (1985) introduced segment tables, resource forks, and imported/exported functions for the 16-bit Windows and OS/2 environments. NE files still begin with an MZ header and DOS stub. Portable Executable (PE) (1993) replaced NE's segment model with a flat 32-bit address space, COFF-derived headers, and the section table architecture still used today. Each generation maintained backward compatibility by retaining the MZ header at byte zero.

Code Signing and the Trust Chain

Windows Authenticode signs PE files by computing a hash of the binary — excluding the checksum field and the certificate table data directory entry — and embedding an X.509 certificate chain in the PE attribute certificate table (data directory entry 4). The signature includes a timestamp from a Timestamping Authority (TSA) so the signature remains valid after the signing certificate expires.

SmartScreen builds on Authenticode by adding reputation. A validly signed EXE from an unknown publisher still triggers a warning until enough users have downloaded and run it without incident. An unsigned EXE triggers a stronger warning. Extended Validation (EV) code signing certificates bypass the reputation requirement — EV-signed binaries are trusted immediately. This economic mechanism means legitimate small developers face SmartScreen friction while large publishers with EV certificates do not.

Why EXE Files Are Dangerous by Design

The EXE format is not dangerous because of vulnerabilities — it is dangerous because executing arbitrary code is exactly what it was designed to do. An EXE file is a direct instruction to the processor. When Windows loads an EXE, the loader maps the sections into memory, resolves import table entries to DLL functions, and transfers control to the entry point. From that moment, the code has the full privilege level of the user who launched it.

This is why EXE is the primary malware delivery vector. Email services block .exe attachments. Browsers display download warnings. Windows enforces User Account Control prompts for elevation. Enterprise environments deploy AppLocker or Windows Defender Application Control to whitelist approved executables. Every layer of defense exists because the format itself offers no safety — a valid EXE is indistinguishable from malware at the binary level until the code actually runs.

Antivirus engines spend the majority of their analysis budget on PE files. Static analysis parses headers, section entropy, import tables, and Rich header artifacts. Dynamic analysis executes the binary in a sandbox and monitors system calls, registry modifications, file writes, and network connections. Heuristic engines flag unusual section names, abnormal entry point locations, packed or encrypted code sections, and missing or forged Authenticode signatures. The PE format's complexity — hundreds of header fields, arbitrary section layouts, embedded resources, TLS callbacks that execute before the entry point — creates an enormous surface area for evasion techniques.

.EXE compared to alternatives

.EXE compared to alternative formats
Formats Criteria Winner
.EXE vs .MSI
Installation model
MSI packages use a relational database with transactional install/uninstall, Group Policy deployment, and automatic repair. EXE installers run arbitrary code with no standardized rollback — an interrupted install may leave the system in a broken state.
MSI wins
.EXE vs .DLL
Execution model
Both use the PE format with identical header structures. An EXE is a standalone process loaded by the Windows loader. A DLL is a shared library loaded into another process's address space. The COFF Characteristics flag IMAGE_FILE_DLL (0x2000) is the structural difference.
Draw
.EXE (PE) vs .ELF
Platform
PE is the native executable format for Windows. ELF (Executable and Linkable Format) is the native format for Linux, FreeBSD, and most Unix systems. Both serve the same role — holding machine code, sections, and dynamic linking metadata — for different operating systems.
Draw
.EXE (PE) vs .MACH-O
Platform
Mach-O is the native executable format for macOS, iOS, and Apple platforms. PE serves Windows. Mach-O supports universal binaries (multiple architectures in one file) natively; PE requires separate 32-bit and 64-bit binaries.
Draw
.EXE vs .MSI
Code signing
Both support Authenticode digital signatures. EXE signatures are embedded in the PE attribute certificate table. MSI signatures are embedded in the OLE Compound Document structure. Both use the same X.509 certificate chains and SmartScreen reputation system.
Draw

Technical reference

MIME Type
application/vnd.microsoft.portable-executable
Magic Bytes
4D 5A MZ DOS header. PE signature at offset specified by e_lfanew field.
Developer
Microsoft
Year Introduced
1993
Open Standard
No
000000004D5A MZ

MZ DOS header. PE signature at offset specified by e_lfanew field.

Binary Structure

A PE executable is a layered binary beginning with the 64-byte DOS MZ header at offset 0x00. The e_magic field (2 bytes) holds the MZ signature (4D 5A), identifying the file as a DOS-compatible executable. The remaining DOS header fields (e_cblp through e_ovno) occupy offsets 0x02 through 0x3B and are ignored by the modern PE loader but must be structurally present. The critical e_lfanew field at offset 0x3C is a 4-byte little-endian pointer to the PE signature (50 45 00 00). Between the DOS stub (which starts at offset 0x40 and typically contains the 'cannot be run in DOS mode' message) and the PE signature, Microsoft's linker inserts the undocumented Rich header — an XOR-encrypted block of build tool fingerprints containing comp.id entries that record compiler and linker versions. The Rich header has no fixed size and is not described in the official PE specification. After the PE signature comes the 20-byte COFF header: Machine (2 bytes, e.g., 0x8664 for AMD64), NumberOfSections (2 bytes), TimeDateStamp (4 bytes, Unix epoch), PointerToSymbolTable (4 bytes, zero for images), NumberOfSymbols (4 bytes, zero for images), SizeOfOptionalHeader (2 bytes, 0xE0 for PE32 or 0xF0 for PE32+), and Characteristics (2 bytes, bit flags including EXECUTABLE_IMAGE and LARGE_ADDRESS_AWARE). The Optional Header follows — mandatory for executables despite its name — at 224 bytes for PE32 (magic 0x10B) or 240 bytes for PE32+ (magic 0x20B).

OffsetLengthFieldExampleDescription
0x00 2 e_magic MZ signature (Mark Zbikowski)
0x02 58 DOS header fields Legacy DOS relocation fields, ignored by PE loader
0x3C 4 e_lfanew File offset pointer to PE signature
0x40+ varies DOS stub Prints 'This program cannot be run in DOS mode'
varies varies Rich header Undocumented build environment fingerprint (DanS marker)
e_lfanew 4 PE signature PE\0\0 — validates PE format
e_lfanew+4 2 Machine CPU architecture: i386 / AMD64 / ARM64
e_lfanew+6 2 NumberOfSections Count of section table entries
e_lfanew+8 4 TimeDateStamp Linker build timestamp
e_lfanew+20 2 SizeOfOptionalHeader 224 bytes (PE32) or 240 bytes (PE32+)
e_lfanew+22 2 Characteristics EXECUTABLE_IMAGE (0x0002), DLL (0x2000), etc.
e_lfanew+24 2 Optional Header Magic PE32 (0x10B) or PE32+ (0x20B)
e_lfanew+40 4/8 AddressOfEntryPoint Execution start address relative to ImageBase
e_lfanew+52/48 4/8 ImageBase Preferred load address (4 bytes PE32, 8 bytes PE32+)
e_lfanew+92/94 2 Subsystem GUI (2) or Console (3)
e_lfanew+94/96 2 DllCharacteristics ASLR (0x0040), DEP (0x0100), CFG (0x4000)
1981Mark Zbikowski designs the MZ executable format for MS-DOS, establishing the 4D 5A magic bytes that persist in every Windows executable today1985Microsoft introduces the New Executable (NE) format with Windows 1.0 — a 16-bit segmented format supporting imported functions and resources, still beginning with an MZ header1993Windows NT 3.1 ships with the Portable Executable (PE) format, replacing NE with a 32-bit flat address space derived from the Unix COFF specification2003Windows XP Professional x64 Edition introduces PE32+ (64-bit PE) with 8-byte ImageBase and expanded address fields for the AMD64 architecture2005Windows Vista introduces mandatory ASLR support via the DllCharacteristics DYNAMIC_BASE flag, randomizing PE image load addresses to mitigate exploits2015Windows 10 adds Control Flow Guard (CFG) as a DllCharacteristics flag, validating indirect call targets at runtime to prevent code-reuse attacks2020Windows on ARM introduces the ARM64EC (Emulation Compatible) Machine type (0xA641), enabling ARM64 and x64 code to coexist in a single PE binary
Read MZ and PE signatures with xxd other
xxd -l 2 program.exe && xxd -s $(python3 -c "import struct; f=open('program.exe','rb'); f.seek(0x3c); print(struct.unpack('<I',f.read(4))[0])") -l 4 program.exe

Reads the first 2 bytes (MZ signature 4D 5A), then uses the e_lfanew pointer at offset 0x3C to locate and display the 4-byte PE signature (50 45 00 00). Confirms the file is a valid PE executable.

Inspect PE headers with dumpbin other
dumpbin /headers program.exe

Microsoft's dumpbin (Visual Studio Build Tools) reads the DOS header, PE signature, COFF header, optional header, and section table. Output includes machine type, entry point, image base, subsystem, DllCharacteristics flags, and section virtual addresses.

Identify PE type with file utility other
file program.exe

Reports PE32 or PE32+ format, subsystem (GUI or console), target architecture (x86, x86-64, ARM64), and whether the binary is stripped or has debug info. Available on Linux, macOS, and Windows via Git Bash.

Display PE sections and imports with objdump other
objdump -x program.exe | head -80

GNU objdump parses the PE COFF headers, section table (names, virtual addresses, sizes, flags), and import table entries. Available via MinGW, MSYS2, or any Linux distribution with binutils.

Verify Authenticode code signature other
signtool verify /pa /v program.exe

Microsoft signtool (Windows SDK) validates the PE Authenticode certificate chain against the system trust store. The /pa flag uses the default authentication verification policy. The /v flag displays certificate details and signing timestamp.

HIGH

Attack Vectors

  • Arbitrary code execution — an EXE runs native machine code at the launching user's privilege level by design, not by exploit
  • Privilege escalation — EXE files can request elevation via UAC manifest or exploit system services to gain SYSTEM-level access
  • Supply chain compromise — malicious code injected during build, distribution, or update processes produces a structurally valid EXE indistinguishable from the legitimate binary
  • DLL side-loading — manipulated import tables or DLL search order cause the EXE to load attacker-controlled DLLs at startup
  • Code cave injection — unused space within PE sections is overwritten with shellcode, preserving the original entry point and Authenticode signature hash boundaries

Mitigation: FileDex does not execute, load, upload, or parse EXE files. This is a reference-only format page providing PE structure documentation and security analysis context.

PE-bear tool
Open-source PE viewer with graphical header inspection, section map, import/export browser, and resource tree — supports PE32 and PE32+
PE editor and viewer from NTCore with hex view, header editing, resource browser, import rebuilder, and dependency walker functionality
PEiD tool
Identifies PE packers, cryptors, and compilers by matching signatures against a database of known packer entry point patterns — essential for malware triage
Ghidra tool
NSA's open-source reverse engineering framework with PE disassembler, decompiler, and binary analysis tools — runs on Windows, macOS, and Linux
VirusTotal service
Scans PE files against 70+ antivirus engines and displays detailed PE header information, import tables, section entropy, and Authenticode signature status
dumpbin tool
Microsoft's official PE dumper (Visual Studio Build Tools) for inspecting headers, imports, exports, relocations, and disassembly from the command line