Layout A PE file consists of several headers and sections that instruct the
dynamic linker on how to map the file into memory. An executable image consists of several different regions, each requiring different
memory protection attributes. To ensure proper alignment, the start of each section must align to a page boundary. For instance, the
.text section, which contains program code, is typically mapped as an execute/read-only. Conversely, the
.data section, which holds global variables, is mapped as no-execute/read write. However, to conserve space, sections are not aligned on disk in this manner. The dynamic linker maps each section to memory individually and assigns the correct permissions based on the information in the headers.
Import table The
import address table (IAT) is used as a lookup table when the application calls a function in a different module. The
imports can be specified by ordinal or by name. Because a compiled program cannot know the memory locations of its dependent libraries beforehand, an indirect jump is necessary for API calls. As the dynamic linker holds modules and resolves dependencies, it populates the IAT slots with actual addresses of the corresponding library functions. Although this adds an extra jump, incurring a performance penalty compared to intermodular calls, it minimizes the number of memory pages that require
copy-on-write changes, thus conserving memory and disk I/O. If a call is known to be intermodular beforehand (if indicated by a
dllimport attribute), the compiler can generate optimized code with a simple indirect call
opcode.
Address Space Layout Randomization (ASLR) Modern operating systems use
address space layout randomization (ASLR), a process that makes a PE file's in-memory layout unpredictable and therefore harder to exploit. During ASLR, the
loader randomizes the virtual addresses where key components reside. This includes the executable's base,
shared libraries, the
heap, and the
stack. Most PE files are not
position-independent because mainstream
compilers emit some absolute references relative to an assumed base. To cope with randomized rebasing, the
linker stores a
.reloc table that lets the loader adjust those references at load time. == .NET, metadata, and the PE format ==