// PE file format
 
            // IMAGE_DOS_HEADER
            // - sizeof(IMAGE_DOS_HEADER): 64 bytes
 
            struct IMAGE_DOS_HEADER {
                WORD    e_magic;                // 0x00 Magic number (0x5A4D; "MZ")
                WORD    e_cblp;                 // 0x02 Bytes on last page of file
                WORD    e_cp;                   // 0x04 Pages in file
                WORD    e_crlc;                 // 0x06 Number of relocations
                WORD    e_cparhdr;              // 0x08 Size of header in paragraphs
                WORD    e_minalloc;             // 0x0A Minimum extra paragraphs needed
                WORD    e_maxalloc;             // 0x0C Maximum extra paragraphs needed
                WORD    e_ss;                   // 0x0E Initial (relative) SS value
                WORD    e_sp;                   // 0x10 Initial SP value
                WORD    e_csum;                 // 0x12 Checksum
                WORD    e_ip;                   // 0x14 Initial IP value
                WORD    e_cs;                   // 0x16 Initial (relative) CS value
     ┌──────────WORD    e_lfarlc;               // 0x18 File address of relocation table (RELOC offset)
     │          WORD    e_ovno;                 // 0x1A Overlay number
     │          WORD    e_res1[4];              // 0x1C Reserved words
     │          WORD    e_oemid;                // 0x24 OEM identifier (for e_oeminfo)
     │          WORD    e_oeminfo;              // 0x26 OEM information; e_oemid specific
     │          WORD    e_res2[10];             // 0x28 Reserved words
     │┌─────────LONG    e_lfanew;               // 0x3C File address of new exe header (PE offset)
     ││     };
     ││
     ││
     ││
     ││
     ││     // DOS Stub Program
     ││     // - sizeof(DOS stub dummy bytes): 64 bytes
     ││
     └─────→0E 1F BA 0E 00 B4 09 CD  21 B8 01 4C CD 21 54 68   ........!..L.!Th
      │     69 73 20 70 72 6F 67 72  61 6D 20 63 61 6E 6E 6F   is program canno
      │     74 20 62 65 20 72 75 6E  20 69 6E 20 44 4F 53 20   t be run in DOS
      │     6D 6F 64 65 2E 0D 0D 0A  24 00 00 00 00 00 00 00   mode....$.......
      
      
      
      
      │     // Rich Header
      │     // - Contains version information of linked libraries
      
      │     DWORD   XORedDanS;                  // XOR-Encoded 0x536E6144 ("DanS")
      │     BYTE    XORedZeros[12];             // XOR-Encoded zeros-padding for alignment on 16 bytes
      │     struct RICH_ENTRY_1 {
      │         DWORD compid;                   // Linker version
      │         DWORD count;                    // Linking frequency
      │     };
      │     struct RICH_ENTRY_2;
      │     struct RICH_ENTRY_3;
      │     ...
      │     DWORD   RichSignature;              // 0x68636952; "Rich"
      │     DWORD   XorMask;                    // Used for encrypting Rich header entries
      │     BYTE    DummyBytes[];               // Consists of zeros
      
      
      
      
      │     // IMAGE_NT_HEADERS
      │     // - sizeof(IMAGE_NT_HEADERS): 248 bytes
      
      │     struct IMAGE_NT_HEADERS {
      └────────→DWORD   Signature;                      // 0x00004550; "PE\0\0"
     
                struct IMAGE_FILE_HEADER {              // sizeof(IMAGE_FILE_HEADER) = 20 bytes
                    WORD    Machine;                    // 0x00 System architecture on build
                    WORD    NumberOfSections;           // 0x02 Number of sections
                    DWORD   TimeDateStamp;              // 0x04 Datetime on build
                    DWORD   PointerToSymbolTable;       // 0x08
                    DWORD   NumberOfSymbols;            // 0x0C
                    WORD    SizeOfOptionalHeader;       // 0x10 224 bytes(0x00E0)
                    WORD    Characteristics;            // 0x12
                };
                 
                struct IMAGE_OPTIONAL_HEADER {          // sizeof(IMAGE_OPTIONAL_HEADER) = 224 bytes
                    // Standard fields
                    WORD    Magic;                      // 0x00 32-bit(0x010B), 64-bit(0x020B)
                    BYTE    MajorLinkerVersion;         // 0x02
                    BYTE    MinorLinkerVersion;         // 0x03
                    DWORD   SizeOfCode;                 // 0x04
                    DWORD   SizeOfInitializedData;      // 0x08
                    DWORD   SizeOfUninitializedData;    // 0x0C
                    DWORD   AddressOfEntryPoint;        // 0x10
      ┌─────────────DWORD   BaseOfCode;                 // 0x14 .text section
     ┌──────────────DWORD   BaseOfData;                 // 0x18 .rdata section
     ││
     ││             // NT additional fields
     ││             DWORD   ImageBase;                  // 0x1C
     ││             DWORD   SectionAlignment;           // 0x20
     ││             DWORD   FileAlignment;              // 0x24 Unit size of each section
     ││             WORD    MajorOperatingSystemVersion;// 0x28
     ││             WORD    MinorOperatingSystemVersion;// 0x2A
     ││             WORD    MajorImageVersion;          // 0x2C
     ││             WORD    MinorImageVersion;          // 0x2E
     ││             WORD    MajorSubsystemVersion;      // 0x30
     ││             WORD    MinorSubsystemVersion;      // 0x32
     ││             DWORD   Win32VersionValue;          // 0x34
     ││             DWORD   SizeOfImage;                // 0x38
     ││             DWORD   SizeOfHeaders;              // 0x3C Total header size of file (not memory)
     ││             DWORD   CheckSum;                   // 0x40
     ││             WORD    Subsystem;                  // 0x44 Driver(1) GUI(2) CLI(3)
     ││             WORD    DllCharacteristics;         // 0x46
     ││             DWORD   SizeOfStackReserve;         // 0x48
     ││             DWORD   SizeOfStackCommit;          // 0x4C
     ││             DWORD   SizeOfHeapReserve;          // 0x50
     ││             DWORD   SizeOfHeapCommit;           // 0x54
     ││             DWORD   LoaderFlags;                // 0x58
     ││             DWORD   NumberOfRvaAndSizes;        // 0x5C Number of Data Directories
     ││
     ││             // Data directory tables
     ││             struct IMAGE_DATA_DIRECTORY_1 {     // 0x60 IMAGE_DIRECOTRY_ENTRY_EXPORT
    ┌───────────────────DWORD VirtualAddress;           // Relative virtual address from ImageBase
    │││                 DWORD Size;
    │││             };
    │││             struct IMAGE_DATA_DIRECTORY_2 {     // 0x68 IMAGE_DIRECOTRY_ENTRY_IMPORT
   ┌────────────────────DWORD VirtualAddress;           // Relative virtual address from ImageBase
   ││││                 DWORD Size;
   ││││             };
   ││││             struct IMAGE_DATA_DIRECTORY_3;      // 0x70 IMAGE_DIRECOTRY_ENTRY_RESOURCE
   ││││             struct IMAGE_DATA_DIRECTORY_4;      // 0x78 IMAGE_DIRECOTRY_ENTRY_EXCEPTION
   ││││             struct IMAGE_DATA_DIRECTORY_5;      // 0x80 IMAGE_DIRECOTRY_ENTRY_SECURITY
   ││││             struct IMAGE_DATA_DIRECTORY_6;      // 0x88 IMAGE_DIRECOTRY_ENTRY_BASERELOC
   ││││             struct IMAGE_DATA_DIRECTORY_7;      // 0x90 IMAGE_DIRECOTRY_ENTRY_DEBUG
   ││││             struct IMAGE_DATA_DIRECTORY_8;      // 0x98 IMAGE_DIRECOTRY_ENTRY_ARCHITECTURE
   ││││             struct IMAGE_DATA_DIRECTORY_9;      // 0xA0 IMAGE_DIRECOTRY_ENTRY_GLOBALPTR
   ││││             struct IMAGE_DATA_DIRECTORY_10;     // 0xA8 IMAGE_DIRECOTRY_ENTRY_TLS
   ││││             struct IMAGE_DATA_DIRECTORY_11;     // 0xB0 IMAGE_DIRECOTRY_ENTRY_LOAD_CONFIG
   ││││             struct IMAGE_DATA_DIRECTORY_12;     // 0xB8 IMAGE_DIRECOTRY_ENTRY_BOUND_IMPORT
   ││││             struct IMAGE_DATA_DIRECTORY_13 {    // 0xC0 IMAGE_DIRECOTRY_ENTRY_IAT
   ││├──────────────────DWORD VirtualAddress;           // Relative virtual address from ImageBase
   ││││                 DWORD Size;
   ││││             };
   ││││             struct IMAGE_DATA_DIRECTORY_14;     // 0xC8 IMAGE_DIRECOTRY_ENTRY_DELAY_IMPORT
   ││││             struct IMAGE_DATA_DIRECTORY_15;     // 0xD0 IMAGE_DIRECOTRY_ENTRY_COM_DESCRIPTOR
   ││││             struct IMAGE_DATA_DIRECTORY_16;     // 0xD8 NULL
   ││││         };
   ││││     };
   ││││
   ││││
   ││││
   ││││
   ││││     // Multiple IMAGE_SECTION_HEADERs
   ││││     // - sizeof(IMAGE_SECTION_HEADER): 40 bytes
   ││││
   ││││     struct IMAGE_SECTION_HEADER_1 {             // .text section header
   ││││         BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];  // #typedef IMAGE_SIZEOF_SHORT_NAME 8
   ││││         union {
   ││││             DWORD PhysicalAddress;
   ││││             DWORD VirtualSize;
   ││││         } Misc;
   │││├─────────DWORD   VirtualAddress;
   ││││         DWORD   SizeOfRawData;
   ││││         DWORD   PointerToRawData;
   ││││         DWORD   PointerToRelocations;
   ││││         DWORD   PointerToLinenumbers;
   ││││         WORD    NumberOfRelocations;
   ││││         WORD    NumberOfLinenumbers;
   ││││         DWORD   Characteristics;                // Memory access permission
   ││││     };
   ││││     struct IMAGE_SECTION_HEADER_2 {             // .rdata section header
   ││││         BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];
   ││││         union {
   ││││             DWORD PhysicalAddress;
   ││││             DWORD VirtualSize;
   ││││         } Misc;
   ││├──────────DWORD   VirtualAddress;
   ││││         DWORD   SizeOfRawData;
   ││││         DWORD   PointerToRawData;
   ││││         DWORD   PointerToRelocations;
   ││││         DWORD   PointerToLinenumbers;
   ││││         WORD    NumberOfRelocations;
   ││││         WORD    NumberOfLinenumbers;
   ││││         DWORD   Characteristics;                // Memory access permission
   ││││     };
   ││││     struct IMAGE_SECTION_HEADER_3;              // .data section header
   ││││     struct IMAGE_SECTION_HEADER_4;
   ││││     ...
   ││││
   ││││
   ││││
   ││││
   ││││     // SECTION .text
   ││││     // - Holds program code
   ││││
   │││└────→PROGRAM CODE...
   │││
   │││
   │││
   │││
   │││      // SECTION .rdata
   │││      // - Holds IAT, EAT, const variables, and strings
   │││
   │││      // IMPORT Address Table (IAT)
   ││└─────→DWORD   AddressOfData_1;─┐                  // RVA from ImageBase (PIMAGE_IMPORT_BY_NAME)
   ││       DWORD   AddressOfData_2; │
   ││       DWORD   AddressOfData_3; │
   ││       ...                      │
  ┌││────────────────────────────────┘
  │││
  │││       (중간 생략)
  │││  
  │││       // EXPORT directory structure
  │││       struct IMAGE_EXPORT_DIRECTORY {
  ││└──────────→DWORD   Characteristics;
  ││            DWORD   TimeDateStamp;
  ││            WORD    MajorVersion;
  ││            WORD    MinorVersion;
  ││            DWORD   Name;
  ││            DWORD   Base;
  ││            DWORD   NumberOfFunctions;
  ││            DWORD   NumberOfNames;
  ││┌───────────DWORD   AddressOfFunctions;             // Relative virtual address from ImageBase
  │││┌──────────DWORD   AddressOfNames;                 // Relative virtual address from ImageBase
  ││││┌─────────DWORD   AddressOfNameOrdinals;          // Relative virtual address from ImageBase
  │││││     };
  │││││
  │││││     // EXPORT Address Table (EAT) (Sorted by ordinal number)
  ││└──────→PVOID pfnFunctionB;
  ││ ││     PVOID pfnFunctionC;
  ││ ││     PVOID pfnFunctionA;
  ││ ││     ...
  ││ ││
  ││ ││     // EXPORT Name Pointer Table (Alphabetically Sorted)
  ││ └─────→char *szFunctionNameA;─┐                    // Relative virtual address from ImageBase
  ││  │     char *szFunctionNameB; │                    // Relative virtual address from ImageBase
  ││  │     char *szFunctionNameC; │                    // Relative virtual address from ImageBase
  ││  │     ...                    │
  ││ ┌│────────────────────────────┘
  ││ ││     //EXPORT Ordinal Table (Alphabetically Sorted)
  ││ │└────→SHORT nFunctionOrdinalA;
  ││ │      SHORT nFunctionOrdinalB;
  ││ │      SHORT nFunctionOrdinalC;
  ││ │      ...
  ││ │
  ││ │      // EXPORT Function name strings (Alphabetically Sorted)
  ││ └─────→"ExportFunctionA\0"                         // NULL-terminated string
  ││        "ExportFunctionB\0"                         // NULL-terminated string
  ││        "ExportFunctionC\0"                         // NULL-terminated string
  ││        ...
  ││
  ││        // IMPORT Directory Table
  ││        struct IMAGE_IMPORT_DESCRIPTOR_1 {          // One structure to one imported DLL module
  │└───────────→union {
  │                 DWORD   Characteristics;
  │   ┌─────────────DWORD   OriginalFirstThunk;         // RVA from ImageBase (PIMAGE_THUNK_DATA32)
  │   │         } DUMMYUNIONNAME;
  │   │         DWORD   TimeDateStamp;
  │   │         DWORD   ForwarderChain;
  │   │         DWORD   Name;
  │   │         DWORD   FirstThunk;
  │   │     };
  │   │     struct IMAGE_IMPORT_DESCRIPTOR_2;
  │   │     struct IMAGE_IMPORT_DESCRIPTOR_3;
  │   │     ...
  │   │
  │   │     // IMPORT Name Table
  │   │     struct IMAGE_THUNK_DATA32_1 {
  │   └────────→union {
  │                 DWORD   ForwarderString;
  │                 DWORD   Function;
  │                 DWORD   Ordinal;
  ├─────────────────DWORD   AddressOfData;              // RVA from ImageBase (PIMAGE_IMPORT_BY_NAME)
  │             } u1;
  │         };
  │         struct IMAGE_THUNK_DATA32_2;
  │         struct IMAGE_THUNK_DATA32_3;
  │         ...
  │    
  │         // IMPORT Hints/Name & DLL Names (IMAGE_IMPORT_BY_NAME structures)
  └────────→WORD    Hint_1;
            "ImportFunctionA\0"
            WORD    Hint_2;
            "ImportFunctionB\0"
            WORD    Hint_3;
            "ImportFunctionC\0"
            ...
 
 
 
 
            // SECTION .data
            // - Holds global variables excepting const and static local variables
 
            (이하 생략)

 

References