Portable Executable (PE) は、Windows および UEFI PE/COFF イメージで使用される実行可能イメージ形式です。ELF とは異なり、PE にはプログラムヘッダーテーブルがありません。ローダーは COFF ヘッダー、オプションヘッダー、セクションテーブル、データディレクトリからイメージをマップします。
ファイルレイアウト #
PE イメージは DOS ヘッダー (MZ) から始まります。その e_lfanew メンバーは、PE\0\0 シグネチャで始まる NT ヘッダーを指します。DOS ヘッダーの後には DOS スタブが続きます。一部のツールチェーンは、NT ヘッダーの前に標準外の Rich ヘッダーも出力します。
NT ヘッダーには COFF ファイルヘッダーが含まれ、実行可能イメージと DLL にはオプションヘッダーも含まれます。COFF ヘッダーには、対象マシン、セクション数、タイムスタンプ、シンボルテーブルの位置(最終イメージでは通常未使用)、オプションヘッダーのサイズ、実行可能イメージまたは DLL などの特性が記録されます。再配置可能な COFF オブジェクトファイルにはオプションヘッダーがありません。
オプションヘッダーとアドレス指定 #
PE32 オプションヘッダーは 224 バイト、PE32+ ヘッダーは 240 バイトです。PE32+ は 64 ビットのアドレスフィールドを使用し、BaseOfData を省略します。Magic は PE32 (0x10b)、PE32+ (0x20b)、または ROM イメージ (0x107) を識別します。
RVA、つまり relative virtual address は、イメージベースからのオフセットです。実行時の仮想アドレスは ImageBase + RVA です。優先 ImageBase は要求にすぎず、ベース再配置レコードによってローダーは ASLR 対応イメージを別の場所にマップできます。AddressOfEntryPoint と BaseOfCode は RVA です。BaseOfCode はイメージ内の最初のコードバイトを識別しますが、実行可能コード全体が連続していることを保証するものではありません。
FileAlignment はディスク上のセクションのアライメントを制御し、SectionAlignment はメモリ内のアライメントを制御します。通常、後者は前者以上です。SizeOfHeaders は、すべてのヘッダーとセクションデータ前のパディングを含み、SizeOfImage はメモリ内のアライメント済み範囲です。Subsystem は、Windows GUI、コンソール、EFI ブートサービスドライバーなど、必要な環境を選択します。データディレクトリは、インポート、エクスポート、リソース、例外、証明書、ベース再配置、デバッグ情報、TLS、その他のローダー機能のテーブルを指します。
セクション #
各セクションヘッダーは、ファイルデータの範囲を仮想メモリの範囲にマップし、読み取り可能、書き込み可能、実行可能、初期化済みデータ、未初期化データなどの特性を付与します。よく知られた名前には .text、.rdata、.data、.pdata、.reloc がありますが、名前は慣例であり、ローダーの要件ではありません。VirtualSize は SizeOfRawData を超えることがあり、ローダーは残りをゼロで埋めます。これが未初期化データの表現方法です。
コメント
GitHub で閲覧・コメントする(投稿にはログインが必要です)