Map and projects (the most frequently updated page of this blog)


(in progress)

  • SizeOfOptionalHeader is not the size of the optional header. It's just used to locate the section table from the start of the optional header. It can be smaller than the optional header, or bigger than the header itself. It CAN NOT be negative.
  • NumOfRVA is not used. Up to 16 data directories are read, just depending on SizeOfOptionalHeader.
    TrueNumOfRVA = min(16, (SizeOfOptionalHeader - E0) / 8) (tbc)
  • because of all the following rules, getting the appended data offset is not just LastSection.Offset + LastSection.PhysicalSize

High alignment
  • a section can be physically empty - it's used to allocate empty memory (unpacking, uninitialized variables)
  • a virtually huge section is an easy way to break or slow down tools
  • compared to the section table,
    sections can be in a different physical order
  • compared to the section table,
    sections CAN NOT be in a different virtual order
  • if a a section is virtually empty,
    then its physical size is used
  • a section CAN NOT be physically and virtually empty
  • if a section is physically bigger than virtually,
    then its physical size is replaced by its virtual size
  • physical gaps are allowed: aka, data present in the file between sections, that won't be read in memory
  • virtual Gaps are NOT allowed - besides SectionAlignment rounding, sections must be virtually continuous
  • the LAST (in physical order) section can be physically truncated (smaller than its physical size)
  • the other sections can not be physically truncated
Low Alignment
  • no gaps are possible. the file is read as is.
  • the only check for sections is that physical and virtual offsets and size should be equal: Address == Offset & VSize == PSize. Their values don't matter.
  • the section table can be empty (NumOfSections is null, thus no table needed at all).
  • if there is no sections, then SizeOfOptionalHeader is ignored
Thanks to Peter Ferrie, Costin Ionescu.