PE File DOS Header

The MS-DOS Header is a 64-byte structure at the beginning of a PE file. Along with the DOS stub, the DOS header is responsible for MS-DOS backward compatibility.

The DOS header is what makes the PE file DOS executable.

The Important Parts of the DOS Header

The most important parts of the DOS header are the first and last members: e_magic and e_lfanew.

e_magic

e_magic is the ‘magic number’, and it is the first member of the DOS Header structure. It is a WORD data type, so it is 16 bits (2 bytes) long, and it always has a value of 0x5A4D or MZ. It designates the file as DOS executable.

e_lfanew

e_lfanew holds an offset to the beginning of the NT Headers. It is always located at offset 0x3C., and it’s a LONG data type, so it has a size of 32 bits (4 bytes).

The DOS Header Structure

The DOS Header is a 64-byte struct:

typedef struct _IMAGE_DOS_HEADER {      // MS-DOS EXE header
    WORD   e_magic;                     // Magic number: 0x5A4D or MZ
    WORD   e_cblp;                      // Bytes on last page of file
    WORD   e_cp;                        // Pages in file
    WORD   e_crlc;                      // Relocations
    WORD   e_cparhdr;                   // Size of header, in paragraphs
    WORD   e_minalloc;                  // Min - extra paragraphs needed
    WORD   e_maxalloc;                  // Max - extra paragraphs needed
    WORD   e_ss;                        // Initial (relative) SS value
    WORD   e_sp;                        // Initial SP value
    WORD   e_csum;                      // Checksum
    WORD   e_ip;                        // Initial IP value
    WORD   e_cs;                        // Initial (relative) CS value
    WORD   e_lfarlc;                    // File address of relocation table
    WORD   e_ovno;                      // Overlay number
    WORD   e_res[4];                    // Reserved words
    WORD   e_oemid;                     // OEM identifier
    WORD   e_oeminfo;                   // OEM information
    WORD   e_res2[10];                  // Reserved words
    LONG   e_lfanew;                    // Offset to NT header
  } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

Here’s a brief overview of the key components in the DOS Header struct:

  • e_magic: The “magic number” 0x5A4D, which is the hexadecimal representation of the ASCII characters “MZ.” This is a signature that identifies the file as a DOS-compatible executable.
  • e_cblp: The count of bytes in the last page of the file that is not used. Typically set to 0.
  • e_cp: The count of 512-byte pages in the file. This field is also usually set to 0.
  • e_crlc: Number of relocation entries in the file. Usually set to 0.
  • e_cparhdr: The size of the header in 16-byte paragraphs. For a standard PE file, this field is often set to 4.
  • e_minalloc: Minimum number of paragraphs allocated to the program. Typically set to 0x10.
  • e_maxalloc: Maximum number of paragraphs allocated to the program. Typically set to 0xFFFF.
  • e_ss: Initial stack segment value. This field is typically set to 0.
  • e_sp: Initial stack pointer value. It is typically set to 0xB8.
  • e_csum: Checksum. It is often set to 0.
  • e_ip: Initial instruction pointer (IP) value. Typically set to 0.
  • e_cs: Initial code segment value. It is typically set to 0.
  • e_lfarlc: The file address of the relocation table. It is usually set to 0x40.
  • e_ovno: Overlay number. It is often set to 0.
  • e_res: An array reserved for future use.
  • e_oemid: OEM identifier. It is typically set to 0.
  • e_oeminfo: OEM information. It is often set to 0.
  • e_res2: A 10-byte array reserved for future use.
  • e_lfanew: A 4-byte field that specifies the file offset to the PE header – the position in the file where the actual PE header begins.

The MS-DOS header is a historical artifact that has its origins in the days of MS-DOS and is retained for compatibility and alignment purposes in modern Windows PE files. However, its content is largely ignored by modern Windows operating systems when executing PE files.

Scroll to Top