# PE(Portable Executable)ファイルフォーマットの基本構造 めも

ref: PE(Portable Executable)ファイルフォーマット その1 ファイルの基本構造

# PE(Portable Executable) format

  • Windowsのローダが認識する実行可能ファイルのフォーマット
  • .binにしてCreateProcess()やLoadLibrary(), LoadLibraryEx()でロードできる
  • 他にNE, LEフォーマットがある

# ヘッダ

  • 先頭から順に3つのヘッダがある
  • MS-DOS用ヘッダおよびプログラム
  • NTヘッダ
  • セクションテーブルおよびセクションデータ

# MS-DOSヘッダおよびプログラム

  • MS-DOSヘッダ
    • 最初のe_magicはMZ, 4D5A
    • e_lfanewはMS-DOS領域の後にくるNTヘッダの位置を表している
      • NTヘッダの位置はImageNtHeaderという関数でも得られる
      • Locates the IMAGE_NT_HEADERS structure in a PE image and returns a pointer to the data.

  • MS-DOS Real-Mode Stub Program
    • 制限なし
    • これらのヘッダによってThis program cannnot be run in DOS mode.を出力する
// WinNT.h
// WINDOWS SDK winnt.h
typedef struct _IMAGE_DOS_HEADER {      // DOS .EXE header
    WORD   e_magic;                     // Magic number
    WORD   e_cblp;                      // Bytes on last page of file
    WORD   e_cp;                        // Pages in file
    WORD   e_crlc;                      // Relocations
    WORD   e_cparhdr;                   // Size of header in paragraphs
    WORD   e_minalloc;                  // Minimum extra paragraphs needed
    WORD   e_maxalloc;                  // Maximum extra paragraphs needed
    WORD   e_ss;                        // Initial (relative) SS value
    WORD   e_sp;                        // Initial SP value
    WORD   e_csum;                      // Checksum
    WORD   e_ip;                        // Initial IP value
    WORD   e_cs;                        // Initial (relative) CS value
    WORD   e_lfarlc;                    // File address of relocation table
    WORD   e_ovno;                      // Overlay number
    WORD   e_res[4];                    // Reserved words
    WORD   e_oemid;                     // OEM identifier (for e_oeminfo)
    WORD   e_oeminfo;                   // OEM information; e_oemid specific
    WORD   e_res2[10];                  // Reserved words
    LONG   e_lfanew;                    // File address of new exe header
  } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

# NTヘッダ

  • マジックナンバとヘッダのかたまり
  • 以下の3つを持っている
    • Signature
    • FileHeader
    • OptionalHeader

# Signature

  • ファイル形式を示すSignature
  • 以下の通り定義されているDWORD(32bit)の値
形式 値(hex) 値(ASCII)
IMAGE_DOS_SIGNATURE 0x4D5A MZ
IMAGE_OS2_SIGNATURE 0x4E45 NE
IMAGE_OS2_SIGNATURE_LE 0x4C45 LE
IMAGE_NT_SIGNATURE 0x50450000 PE00

# File Header

  • IMAGE_FILE_HEAD
typedef struct _IMAGE_FILE_HEADER {
    WORD    Machine;
    WORD    NumberOfSections;
    DWORD   TimeDateStamp;
    DWORD   PointerToSymbolTable; // 0
    DWORD   NumberOfSymbols;      // 0
    WORD    SizeOfOptionalHeader; // size of optional header continuing file header
    WORD    Characteristics;      // flags
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

#define IMAGE_SIZEOF_FILE_HEADER             20
  • machine
    • ファイルの対象マシン
    • IMAGE_FILE_MACHINE_XXX
      • IMAGE_FILE_MACHINE_I386(0x14c): x86
      • IMAGE_FILE_MACHINE_UNKNOWN(0): x86

# Optional Header

  • Magic
    • 通常は0x10
    • PE+は64bit用
形式 値(hex)
PE32 0x10b
PE+ 0x20b
ROM 0x107
  • AddressOfEntryPoint
    • エントリポイント(実行開始位置)のアドレス
    • RVA(Relative Virtual Addres): 相対仮想アドレスが表されている
      • 物理アドレスからイメージのロードアドレスを引いた値のこと
      • 仮想アドレス + ロードアドレス = 物理アドレス
  • BaseOfCode
    • メモリにロードされるときにのコード開始セクションのRVA(相対仮想アドレス)
  • BaseOfCodeは実行可能なCodeSection(.text)の先頭アドレスで, AddressOfEntryPointはそのファイルが実行される際に呼び出されるentryアドレスであるという違いがある
  • 基本的に, AddressOfEntryPointはBaseOfCodeと異なる
Last Updated: 2020-1-2 14:43:19