windowsassemblynasmportable-executablefile-format

Understanding SizeOfHeaders


Learning some nasm, and file formats for my assembly project. I am currently very confused about SizeOfHeaders.

Taking a look at the official documentation:

The size of the PE header and the section (object) table. The raw data for the sections starts immediately after all the header components.

Taking a look at another official documentation:

The combined size of the following items, rounded to a multiple of the value specified in the FileAlignment member.

  • e_lfanew member of IMAGE_DOS_HEADER
  • 4 byte signature
  • size of IMAGE_FILE_HEADER
  • size of optional header
  • size of all section headers

Other sources online say:

The combined size of an MS‑DOS stub, PE header, and section headers rounded up to a multiple of FileAlignment.

As you can see each source is giving a different explanation of what is comprised of SizeOfHeaders.

In NASM, the SizeOfHeaders could be computed as such:

dd sections_start - dos_stub_start + (FileAlignment - 1)) // FileAlignment

That would be the example of the implementation of simplest source, and one that I have used, however the second official source that I listed, specifically says the e_lfanew member of the dos header, not the whole dos stub or not any of the dos header or stub at all for the first source.

So that example may very well be incorrect.

Looking online, there doesn't seem to be any conclusive information previously recorded on the internet about this issue.


Solution

  • This is how I calculate value of the member SizeOfHeaders in IMAGE_OPTIONAL_HEADER:

    PE executable file begins with DOS_HEADER (size 64), followed by MZ executable 16bit DOS stub file, which may have variable size.

    DOS_HEADER.e_lfanew (the last DWORD) specifies file address (offset) of PE, LE or NE signature in the executable file. Adding the signature size (4) to e_lfanew value gives the offset of IMAGE_FILE_HEADER. Size of this file header is fixed (20).

    File header is followed by IMAGE_OPTIONAL_HEADER with size 224 or 240 bytes for 32bit or 64bit versions.

    Member IMAGE_FILE_HEADER.NumberOfSections specifies how many IMAGE_SECTION_HEADER instances follow the optional header. Each section header is 40 bytes long. Adding it all together and rounding it up to IMAGE_OPTIONAL_HEADER.FileAlignment (usually 512) gives the final value of IMAGE_OPTIONAL_HEADER.SizeOfHeaders.

    A good GUI tool for inspection of 32bit COFF and PE files is PEview by W.J.Radburn.