Reverse Engineering/Build Process & Portable Executable

[Reverse Engineering] PE (Portable Executable) Header Structure Analysis

DF_m@ster 2025. 8. 7. 14:17

PE (Portable Executable)

PE (Portable Executable) 정의 : Windows OS에서 실행 가능한 Executable File Format이다. x86 아키텍처의 경우 PE32, x86-64 아키텍처의 경우 PE32+이라고 칭한다.

본 문단은, PE Body 를 제외한 PE Header 를 분석한 글로, PE Header의 구조 분석 글은 아래 링크를 참조 바란다.

 

 

 

PE (Portable Executable) Structure

PE 파일은 아래와 같은 구조로 구성되어 있으며, 각 섹션은 고유의 역할을 수행한다.

PE (Portable Executable) Structure

 

 

 

PE Header

Dos Header 

Dos Header 정의

PE 파일이 MS-DOS 환경과의 호환성을 유지하기 위해 포함된 영역으로, PE Signature와 NT Header의 Offset 정보를 저장한다.

 

Dos Header 주요 Field

 - e_magic (0x00~03) : PE File의 File Signature 정보. (Hex Value / Ascii Value : 0x4D5A / MZ)

 - e_lfanew (0x3C~3F) : NT Header의 시작 주소 정보.

 

Dos Header Structure (_IMAGE_DOS_HEADER)

‘_IMAGE_DOS_HEADER’ 구조체 크기는 0x40이다.

typedef struct _IMAGE_DOS_HEADER {
    WORD  e_magic;      /* 00: MZ Header signature */
    WORD  e_cblp;       /* 02: Bytes on last page of file */
    WORD  e_cp;         /* 04: Pages in file */
    WORD  e_crlc;       /* 06: Relocations */
    WORD  e_cparhdr;    /* 08: Size of header in paragraphs */
    WORD  e_minalloc;   /* 0a: Minimum extra paragraphs needed */
    WORD  e_maxalloc;   /* 0c: Maximum extra paragraphs needed */
    WORD  e_ss;         /* 0e: Initial (relative) SS value */
    WORD  e_sp;         /* 10: Initial SP value */
    WORD  e_csum;       /* 12: Checksum */
    WORD  e_ip;         /* 14: Initial IP value */
    WORD  e_cs;         /* 16: Initial (relative) CS value */
    WORD  e_lfarlc;     /* 18: File address of relocation table */
    WORD  e_ovno;       /* 1a: Overlay number */
    WORD  e_res[4];     /* 1c: Reserved words */
    WORD  e_oemid;      /* 24: OEM identifier (for e_oeminfo) */
    WORD  e_oeminfo;    /* 26: OEM information; e_oemid specific */
    WORD  e_res2[10];   /* 28: Reserved words */
    DWORD e_lfanew;     /* 3c: Offset to extended header */
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

Dos Header

 

 

 

DOS STUB

DOS STUB 정의

MS-DOS 환경에서 실행을 방지하고자 특정 메시지("This program cannot be run in DOS mode.")를 출력하는 영역으로, PE 파일이 Windows 환경에서 실행되도록 유도하는 역할을 한다.

DOS STUB

 

RICH Header 정의

PE 파일 내부에 존재하는 비공식적인(Non-Standard) 헤더로, Microsoft Visual Studio에서 빌드된 PE 파일의 빌드 환경 정보를 포함하는 영역이다. 해당 영역은 PE Loader가 사용하지 않고 디버깅 및 분석 용도로만 존재한다.

 

RICH Header 해석

해당 영역은 다음과 같은 로직으로 해석할 수 있다.

  1. 0x04 Byte씩 값을 읽어 들이고, 값이 ‘0x686356952’(RICH) 일 경우, Loop를 종료한다. (예시에서는 ‘0xD8~DB’ 영역에 해당한다.)
  2. 이후 해당 영역의 다음 0x04 Byte를 읽어들인다. 해당 값은 XOR 복호화 Key로 사용된다. (예시에서는 ‘0x3D3DB475’ 값에 해당한다.)
  3. 이후 ‘0x686356952’(RICH) 값이 나타난 이전부터 다시 0x04 Byte를 읽어들이고, 이전에 확보한 Key 값으로 XOR 복호화를 진행한다. 이때, XOR 복호화 된 값이 ‘0x536E6144’(DanS) 일 경우, Loop를 종료한다. (예시에서는 ‘0x80~83’ 영역에 해당한다.)
  4. 이후 복호화된 XOR 값을 통해, Compiler Version, Build Toolkit(Like LINK, CL, MASM) 정보, Build Count 등의 정보들을 저장한다.

 

RICH Header (Before & After Decrypt)

RICH Header (Before Decrypt)
RICH Header (After Decrypt)

 

 

 

NT Header

NT Header 정의

PE 파일의 실행 속성과 로딩 정보를 정의하는 핵심 Header로, Signature, File Header, Optional Header를 포함한다. 특징으로 DOS Header의 e_lfanew Field로 접근이 가능고, Structure의 정의가 x86의 경우와 x86-64의 경우로 나뉜다.

 

NT Header 주요 Field

 - Signature 정의 : PE 파일이 Windows 실행 파일(PE Format)임을 식별하는 고유한 Marker로, "PE " (0x00004550) 값을 갖는다.

 

     - Signature 주요 Field

     - Signature (0x00~03) : PE File의 File Signature 정보. ( Hex Value / Ascii Value :  0x50450000 / "PE  ")

 

     - Signature Structure

DWORD Signature;

Signature Structure

 

 

 

 - File Header 정의 : PE 파일의 기본 속성과 구조 정보를 정의하는 헤더로, Machine Type, Number of Sections, Timestamp, Flag 등의 정보를 포함한다. 특징으로 Signature 바로 뒤에 위치하고, x86과 x86-64의 환경에서 모두 동일한 Structure를 갖는다.

 

     - File Header 주요 Field

         - Machine : PE 파일이 실행될 CPU 아키텍처(예: x86, x86-64, ARM 등)를 식별하는 2 Byte 값이다. WinNT.h에 정의된 상수를 사용하여 해석한다.

#define IMAGE_FILE_MACHINE_UNKNOWN        0x0000  // Unknown machine type  
#define IMAGE_FILE_MACHINE_I386           0x014c  // Intel 386  
#define IMAGE_FILE_MACHINE_R3000          0x0162  // MIPS little-endian, 0x160 big-endian  
#define IMAGE_FILE_MACHINE_R4000          0x0166  // MIPS little-endian  
#define IMAGE_FILE_MACHINE_R10000         0x0168  // MIPS little-endian  
#define IMAGE_FILE_MACHINE_WCEMIPSV2      0x0169  // MIPS little-endian WCE v2  
#define IMAGE_FILE_MACHINE_ALPHA          0x0184  // Alpha_AXP  
#define IMAGE_FILE_MACHINE_SH3            0x01A2  // SH3 little-endian  
#define IMAGE_FILE_MACHINE_SH3DSP         0x01A3  // SH3 DSP  
#define IMAGE_FILE_MACHINE_SH3E           0x01A4  // SH3E little-endian  
#define IMAGE_FILE_MACHINE_SH4            0x01A6  // SH4 little-endian  
#define IMAGE_FILE_MACHINE_SH5            0x01A8  // SH5  
#define IMAGE_FILE_MACHINE_ARM            0x01C0  // ARM Little-Endian  
#define IMAGE_FILE_MACHINE_THUMB          0x01C2  // ARM Thumb  
#define IMAGE_FILE_MACHINE_AM33           0x01D3  // AM33  
#define IMAGE_FILE_MACHINE_POWERPC        0x01F0  // IBM PowerPC Little-Endian  
#define IMAGE_FILE_MACHINE_POWERPCFP      0x01F1  // PowerPC with floating point  
#define IMAGE_FILE_MACHINE_IA64           0x0200  // Intel 64  
#define IMAGE_FILE_MACHINE_MIPS16         0x0266  // MIPS 16-bit  
#define IMAGE_FILE_MACHINE_ALPHA64        0x0284  // ALPHA64  
#define IMAGE_FILE_MACHINE_MIPSFPU        0x0366  // MIPS with FPU  
#define IMAGE_FILE_MACHINE_MIPSFPU16      0x0466  // MIPS with FPU 16-bit  
#define IMAGE_FILE_MACHINE_AXP64          IMAGE_FILE_MACHINE_ALPHA64  // ALPHA64 alias  
#define IMAGE_FILE_MACHINE_TRICORE        0x0520  // Infineon TriCore  
#define IMAGE_FILE_MACHINE_CEF            0x0CEF  // CEF  
#define IMAGE_FILE_MACHINE_EBC            0x0EBC  // EFI Byte Code  
#define IMAGE_FILE_MACHINE_AMD64          0x8664  // AMD64 (K8)  
#define IMAGE_FILE_MACHINE_M32R           0x9041  // M32R little-endian  
#define IMAGE_FILE_MACHINE_CEE            0xC0EE  // CEE  

 

         -  Number of Sections : PE 파일이 갖는 Section의 개수로, 최소 1개 이상을 갖는다. 해당 값을 기반으로 Section Header의 구조체를 읽게 된다. 이때, Number of Sections 값이 실제 Section의 갯수보다 적으면 문제없이 실행되지만, 반대로 Number of Sections 값이 더 많게 될 경우 오류가 발생한다.

         -  Time Date Stamp : PE 파일이 Build된 UTC 시간을 나타내는 4바이트 값이다.

         -  Pointer to Symbol Table : COFF 형식의 Symbol Table이 위치한 File Offset을 가리키는 Pointer로, 일반적인 PE 실행 파일에서는 거의 사용되지 않는다.

         -  Size of Optional Header : IMAGE_OPTIONAL_HEADER 구조체의 크기를 나타낸다.

         -  Characteristics : PE 파일의 속성과 실행 방식(예: 실행 가능 여부, DLL 여부, 32비트/64비트 지원 등)을 결정하는 2 Byte의 Flag이다. WinNT.h에 정의되어 있다.

#define IMAGE_FILE_RELOCS_STRIPPED         0x0001  // Relocation info stripped from file  
#define IMAGE_FILE_EXECUTABLE_IMAGE        0x0002  // File is executable (i.e. no unresolved external references)  
#define IMAGE_FILE_LINE_NUMS_STRIPPED      0x0004  // Line numbers stripped from file  
#define IMAGE_FILE_LOCAL_SYMS_STRIPPED     0x0008  // Local symbols stripped from file  
#define IMAGE_FILE_AGGRESIVE_WS_TRIM       0x0010  // Aggressively trim working set  
#define IMAGE_FILE_LARGE_ADDRESS_AWARE     0x0020  // App can handle >2GB addresses  
#define IMAGE_FILE_BYTES_REVERSED_LO       0x0080  // Bytes of machine word are reversed  
#define IMAGE_FILE_32BIT_MACHINE           0x0100  // 32-bit word machine  
#define IMAGE_FILE_DEBUG_STRIPPED          0x0200  // Debugging info stripped from file in .DBG file  
#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400  // If image is on removable media, copy and run from swap file  
#define IMAGE_FILE_NET_RUN_FROM_SWAP       0x0800  // If image is on network, copy and run from swap file  
#define IMAGE_FILE_SYSTEM                  0x1000  // System file  
#define IMAGE_FILE_DLL                     0x2000  // File is a DLL  
#define IMAGE_FILE_UP_SYSTEM_ONLY          0x4000  // File should only be run on a uniprocessor system

 

File Header Structure (_IMAGE_FILE_HEADER)

typedef struct _IMAGE_FILE_HEADER {
    WORD  Machine;                 /* 00: Target machine type */
    WORD  NumberOfSections;        /* 02: Number of sections */
    DWORD TimeDateStamp;           /* 04: Time and date stamp */
    DWORD PointerToSymbolTable;    /* 08: File offset to symbol table */
    DWORD NumberOfSymbols;         /* 0C: Number of symbols */
    WORD  SizeOfOptionalHeader;    /* 10: Size of the optional header */
    WORD  Characteristics;         /* 12: Characteristics flags */
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

 

_IMAGE_FILE_HEADER

 

 

 

 - Optional Header 정의 : PE 실행 파일의 Memory Layout(Entry Point, Section Alignment, Image Size, Sub System 등)을 정의하는 NT Header의 내부 구조체로, 이름과 달리 실행 가능한 PE 파일에서는 반드시 존재한다.

 

 - Optional Header 주요 Field 

         - Magic : PE 파일이 32비트(0x10B, PE)인지 64비트(0x20B, PE+)인지 식별하는 Signature 값이다.

         - Major Linker Version, MinorLinkerVersion : PE 파일을 빌드할 때 사용된 링커의 버전 정보를 나타낸다.

         - Size of Initialized Data : 초기화된 데이터를 포함하는 Section(.data)의 크기를 의미한다.

         - Size of Uninitialized Data : 초기화되지 않은 데이터를 포함하는 Section(.bss)의 크기를 의미한다.

         - Address of Entry Point : PE 파일 내부 EP (Entry Point)의 RVA 값이다. EP 값과 Image Base의 값을 더하여 RIP/EIP 레지스터에 저장하게되고, 이를 통해 프로그램 실행 시작 주소가 된다.

         - Base of Data : Data Section의 메모리 내부 시작 RVA 정보를 나타낸다. 64비트에서는 존재하지 않는다.

         - Base of Code : Text Section의 메모리 내부 시작 RVA 정보를 나타낸다.

         - Image Base : PE 파일이 Memory에 Load되는 Base Address로, 일반적으로 EXE는 0x400000, DLL은 0x10000000, SYS은 커널 메모리 영역에 위치하게된다.

         - Section Alignment : PE 파일이 Memory에 Load될 때, 각 Section이 Alignment(정렬)되는 최소 단위(기본 4KB, 0x1000)이다.

         - File Alignment : PE 파일이 Disk에 File 형태로 존재할 때, 각 Section이 Alignment(정렬)되는 최소 단위(기본 512 Byte, 0x200)이다.

         - Size of Image : PE 파일이 Memory에 Loac된 이후의 전체 크기를 나타낸다.

         - Size of Headers : PE 파일의 모든 Header(DOS Header, PE Header, Section Header 등)의 총 크기 정보를 저장한다.

         - Dll Characteristics : PE 파일의 보안 및 로딩 동작(ASLR, DEP, SEH 비활성화, 코드 무결성 검증 등)을 제어하는 2 Byte의 Flag 값으로, PE Loader가 Loding 과정 이전에 확인하는 중요한 값이다.

#define IMAGE_DLLCHARACTERISTICS_RESERVED_1       0x0001  // Reserved, must be zero  
#define IMAGE_DLLCHARACTERISTICS_RESERVED_2       0x0002  // Reserved, must be zero  
#define IMAGE_DLLCHARACTERISTICS_RESERVED_3       0x0004  // Reserved, must be zero  
#define IMAGE_DLLCHARACTERISTICS_RESERVED_4       0x0008  // Reserved, must be zero  
#define IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA  0x0020  // Supports high entropy 64-bit virtual address space  
#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE     0x0040  // DLL can be relocated at load time (ASLR)
#define IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY  0x0080  // Enforce code integrity checks  
#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT        0x0100  // Compatible with NX (No-Execute)  
#define IMAGE_DLLCHARACTERISTICS_NO_ISOLATION     0x0200  // Aware of isolation but does not isolate the image  
#define IMAGE_DLLCHARACTERISTICS_NO_SEH           0x0400  // Does not use Structured Exception Handling (SEH)  
#define IMAGE_DLLCHARACTERISTICS_NO_BIND          0x0800  // Do not bind the image  
#define IMAGE_DLLCHARACTERISTICS_APPCONTAINER     0x1000  // Must run in an AppContainer  
#define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER       0x2000  // WDM driver  
#define IMAGE_DLLCHARACTERISTICS_GUARD_CF         0x4000  // Supports Control Flow Guard (CFG)  
#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000  // Aware of Terminal Server

 

         - Data Directory : PE 파일 내부 다양한 Table(Import Table, Export Table, Resource Table 등)의 Virtual Address와 Size를 저장하는 배열 구조체(Array Structure)로, PE Loader가 해당 정보를 기반으로, PE 파일을 Memory에 적절하게 Load하게된다.

Data Directory

 

             - 각 Array 항목은 8 Byte (4 Byte + 4 Byte)이며, 총 15개의 항목이 존재한다. 때문에, Data Directory의 전체 크기는 0x78 Byte이다.

#define IMAGE_DIRECTORY_ENTRY_EXPORT                0   // Export Directory  
#define IMAGE_DIRECTORY_ENTRY_IMPORT                1   // Import Directory  
#define IMAGE_DIRECTORY_ENTRY_RESOURCE              2   // Resource Directory  
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION             3   // Exception Directory  
#define IMAGE_DIRECTORY_ENTRY_SECURITY              4   // Security Directory  
#define IMAGE_DIRECTORY_ENTRY_BASERELOC             5   // Base Relocation Table  
#define IMAGE_DIRECTORY_ENTRY_DEBUG                 6   // Debug Directory  
#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT             7   // (X86 usage)  
#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE          7   // Architecture Specific Data  
#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR             8   // RVA of GP  
#define IMAGE_DIRECTORY_ENTRY_TLS                   9   // TLS Directory  
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG           10   // Load Configuration Directory  
#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT          11   // Bound Import Directory in headers  
#define IMAGE_DIRECTORY_ENTRY_IMPORT_ADDRESS_TABLE  12   // Import Address Table  
#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT          13   // Delay Load Import Descriptors  
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR        14   // COM Runtime Descriptor

 

             - TLS (Thread Local Storage) 개념 : 멀티스레드 환경에서 각 스레드마다 독립적인 데이터 공간을 제공하는 메커니즘으로, 각 스레드가 개별적으로 접근 가능한 전용 변수를 저장하는 공간이다. 때문에, TLS 영역의 데이터는 다른 스레드와 공유되지 않음.

 

             - Data Directory 주요 Field

                  - Virtual Address : 해당 Section의 RVA Address 정보를 의미한다.

                  - Size : 해당 Section이 Memory에 Load된 이후의 Size 정보를 의미한다.

 

             - Data Directory Structure (IMAGE_DATA_DIRECTORY)

typedef struct _IMAGE_DATA_DIRECTORY {
    DWORD VirtualAddress;  /* 00: RVA (Relative Virtual Address) of the table */
    DWORD Size;            /* 04: Size of the table in bytes */
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

 

 - Optional Header Structure (_IMAGE_OPTIONAL_HEADER)

typedef struct _IMAGE_OPTIONAL_HEADER {
    WORD  Magic;                     /* 00: Magic number (0x10b for PE32, 0x107 for ROM) */
    BYTE  MajorLinkerVersion;        /* 02: Major linker version */
    BYTE  MinorLinkerVersion;        /* 03: Minor linker version */
    DWORD SizeOfCode;                /* 04: Size of the code section */
    DWORD SizeOfInitializedData;     /* 08: Size of initialized data section */
    DWORD SizeOfUninitializedData;   /* 0C: Size of uninitialized data section */
    DWORD AddressOfEntryPoint;       /* 10: Address of entry point */
    DWORD BaseOfCode;                /* 14: Base address of code section */
    DWORD BaseOfData;                /* 18: Base address of data section */
    DWORD ImageBase;                 /* 1C: Preferred image base */
    DWORD SectionAlignment;          /* 20: Section alignment in memory */
    DWORD FileAlignment;             /* 24: Section alignment on disk */
    WORD  MajorOperatingSystemVersion; /* 28: Major OS version */
    WORD  MinorOperatingSystemVersion; /* 2A: Minor OS version */
    WORD  MajorImageVersion;         /* 2C: Major image version */
    WORD  MinorImageVersion;         /* 2E: Minor image version */
    WORD  MajorSubsystemVersion;     /* 30: Major subsystem version */
    WORD  MinorSubsystemVersion;     /* 32: Minor subsystem version */
    DWORD Win32VersionValue;         /* 34: Reserved (must be 0) */
    DWORD SizeOfImage;               /* 38: Size of the entire image in memory */
    DWORD SizeOfHeaders;             /* 3C: Size of headers (DOS, PE, section headers) */
    DWORD CheckSum;                  /* 40: Checksum of the image */
    WORD  Subsystem;                 /* 44: Subsystem required to run this image */
    WORD  DllCharacteristics;        /* 46: DLL characteristics flags */
    DWORD SizeOfStackReserve;        /* 48: Size of stack to reserve */
    DWORD SizeOfStackCommit;         /* 4C: Size of stack to commit */
    DWORD SizeOfHeapReserve;         /* 50: Size of heap to reserve */
    DWORD SizeOfHeapCommit;          /* 54: Size of heap to commit */
    DWORD LoaderFlags;               /* 58: Loader flags (obsolete, must be 0) */
    DWORD NumberOfRvaAndSizes;       /* 5C: Number of entries in the DataDirectory array */
    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; /* 60: Data directory array */
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
typedef struct _IMAGE_OPTIONAL_HEADER64 {
    WORD        Magic;                   /* 00: Magic number (0x20b for PE32+) */
    BYTE        MajorLinkerVersion;      /* 02: Major linker version */
    BYTE        MinorLinkerVersion;      /* 03: Minor linker version */
    DWORD       SizeOfCode;              /* 04: Size of the code section */
    DWORD       SizeOfInitializedData;   /* 08: Size of the initialized data section */
    DWORD       SizeOfUninitializedData; /* 0C: Size of the uninitialized data section */
    DWORD       AddressOfEntryPoint;     /* 10: Address of entry point */
    DWORD       BaseOfCode;              /* 14: Base address of code section */
    ULONGLONG   ImageBase;               /* 18: Preferred image base */
    DWORD       SectionAlignment;        /* 20: Section alignment in memory */
    DWORD       FileAlignment;           /* 24: Section alignment on disk */
    WORD        MajorOperatingSystemVersion; /* 28: Major OS version */
    WORD        MinorOperatingSystemVersion; /* 2A: Minor OS version */
    WORD        MajorImageVersion;       /* 2C: Major image version */
    WORD        MinorImageVersion;       /* 2E: Minor image version */
    WORD        MajorSubsystemVersion;   /* 30: Major subsystem version */
    WORD        MinorSubsystemVersion;   /* 32: Minor subsystem version */
    DWORD       Win32VersionValue;       /* 34: Reserved (must be 0) */
    DWORD       SizeOfImage;             /* 38: Size of the entire image in memory */
    DWORD       SizeOfHeaders;           /* 3C: Size of headers (DOS, PE, section headers) */
    DWORD       CheckSum;                /* 40: Checksum of the image */
    WORD        Subsystem;               /* 44: Subsystem required to run this image */
    WORD        DllCharacteristics;      /* 46: DLL characteristics flags */
    ULONGLONG   SizeOfStackReserve;      /* 48: Size of stack to reserve */
    ULONGLONG   SizeOfStackCommit;       /* 50: Size of stack to commit */
    ULONGLONG   SizeOfHeapReserve;       /* 58: Size of heap to reserve */
    ULONGLONG   SizeOfHeapCommit;        /* 60: Size of heap to commit */
    DWORD       LoaderFlags;             /* 68: Loader flags (obsolete, must be 0) */
    DWORD       NumberOfRvaAndSizes;     /* 6C: Number of entries in the DataDirectory array */
    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; /* 70: Data directory array */
} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64;

_IMAGE_OPTIONAL_HEADER

 

NT Header Structure (_IMAGE_NT_HEADERS)

typedef struct _IMAGE_NT_HEADERS {
    DWORD Signature;         /* "PE"\0\0 */	/* 0x00~03 */
    IMAGE_FILE_HEADER FileHeader;		        /* 0x04~17 */
    IMAGE_OPTIONAL_HEADER32 OptionalHeader;	/* 0x18~60 + Data Directory */
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
typedef struct _IMAGE_NT_HEADERS64 {
    DWORD Signature;         /* "PE"\0\0 */	/* 0x00~03 */
    IMAGE_FILE_HEADER FileHeader;		        /* 0x04~17 */
    IMAGE_OPTIONAL_HEADER64 OptionalHeader;	/* 0x18~70 + Data Directory */
} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64;