PE 形式

この仕様では、オペレーティング システムの Windows ファミリの実行可能ファイル (イメージ) ファイルとオブジェクト ファイルの構造について説明します。 これらのファイルは、それぞれポータブル実行可能ファイル (PE) ファイルと Common Object File Format (COFF) ファイルと呼ばれます。

このドキュメントは、Windows 用のツールおよびアプリケーションの開発を支援するために提供されていますが、あらゆる点で完全な仕様であることは保証されません。 Microsoft は、予告なしにこのドキュメントを変更する権利を留保します。

Microsoft Portable Executable および Common Object File Format Specification のこのリビジョンは、この仕様の以前のリビジョンをすべて置き換えます。

一般的な概念

この文書では、Microsoft Windows ファミリのオペレーティング システムでの実行可能 (イメージ) ファイルとオブジェクト ファイルの構造を指定します。 これらのファイルは、それぞれポータブル実行可能ファイル (PE) ファイルと Common Object File Format (COFF) ファイルと呼ばれます。 「Portable Executable」という名前は、形式がアーキテクチャ固有ではないという事実を表しています。

この仕様全体で使用される特定の概念については、次の表で説明します。

名前 説明
属性証明書
検証可能なステートメントをイメージに関連付けるために使用される証明書。 さまざまな検証可能なステートメントをファイルに関連付けることができます。最も役立つものの 1 つは、イメージのメッセージ ダイジェストがどのようなものであると予想されるかを示すソフトウェア メーカーの声明です。 メッセージ ダイジェストはチェックサムに似ていますが、偽造が非常に困難である点が異なります。 したがって、元のファイルと同じメッセージ ダイジェストを持つようにファイルを変更することは非常に困難です。 このステートメントは、公開キーまたは秘密キーの暗号化スキームを使用して、製造元によって作成されたものであることを検証できます。 このドキュメントでは、イメージ ファイルへの挿入を許可する以外の属性証明書の詳細について説明します。
日付/時刻スタンプ
PE または COFF ファイル内の複数の場所で異なる目的で使用されるスタンプ。 ほとんどの場合、各スタンプの形式は、C ランタイム ライブラリの時間関数で使用される形式と同じです。 例外については、「デバッグの種類」の IMAGE_DEBUG_TYPE_REPRO の説明を参照してください。 スタンプ値が 0 または 0xFFFFFFFF の場合、実際の日付/時刻スタンプまたは意味のある日付/時刻スタンプは表されません。
ファイル ポインター
リンカー (オブジェクト ファイルの場合) またはローダー (イメージ ファイルの場合) によって処理される前の、ファイル自体内の項目の場所。 つまり、これはディスクに格納されているファイル内の位置です。
リンカー
Microsoft Visual Studio で提供されるリンカーへの参照。
オブジェクト ファイル
リンカーへの入力として指定されるファイル。 リンカーによってイメージ ファイルが生成され、ローダーによる入力として使用されます。 「オブジェクト ファイル」という用語は、必ずしもオブジェクト指向プログラミングとの関連を意味するものではありません。
予約済み、0 である必要があります
ジェネレーターではフィールドの値が 0 でなければならず、コンシューマーではフィールドを無視する必要があることを示すフィールドの説明。
相対仮想アドレス (RVA)
イメージ ファイルでは、これはメモリにロードされた後のアイテムのアドレスであり、そこからイメージ ファイルのベース アドレスが減算されます。 項目の RVA は、ほとんどの場合、ディスク上のファイル内の位置 (ファイル ポインター) と異なります。
オブジェクト ファイルでは、RVA はメモリの場所が割り当てられないため、あまり意味がありません。 この場合、RVA はセクション内のアドレス (この表で後述) となり、後でリンク中に再配置が適用されます。 わかりやすくするために、コンパイラは各セクションの最初の RVA を 0 に設定するだけです。
セクション
PE または COFF ファイル内のコードまたはデータの基本単位。 たとえば、オブジェクト ファイル内のすべてのコードを 1 つのセクション内で結合したり、(コンパイラーの動作に応じて) 各関数が独自のセクションを占有したりできます。 セクションが多いほど、ファイルオーバーヘッドが増えますが、リンカーはコード内でより選択的にリンクできます。 セクションは、Intel 8086 アーキテクチャのセグメントに似ています。 セクション内のすべての生データを連続して読み込む必要があります。 さらに、イメージ ファイルには、特別な目的を持つ .tls や .reloc などのいくつかのセクションを含めることができます。
仮想アドレス (VA)
RVA と同じですが、イメージ ファイルのベース アドレスが減算されないことを除きます。 Windows は物理メモリとは独立してプロセスごとに個別の VA スペースを作成するため、このアドレスは VA と呼ばれます。 ほぼすべての目的で、VA は単なるアドレスと見なす必要があります。 VA は RVA ほど予測できません。ローダーがイメージを希望の場所に読み込まない可能性があるためです。

概要

次の一覧では、Microsoft PE 実行可能ファイルの形式について説明します。画像ヘッダーの基点は上部にあります。 MS-DOS 2.0 互換 EXE ヘッダーから PE ヘッダー直前の未使用セクションまでが MS-DOS 2.0 セクションであり、MS-DOS 互換のためだけに使用されます。

  • MS-DOS 2.0 互換 EXE ヘッダー

  • 未使用

  • OEM 識別子

    OEM 情報

    PE ヘッダーへのオフセット

  • MS-DOS 2.0 スタブ プログラムと再配置テーブル

  • 未使用

  • PE ヘッダー (8 バイト境界に整列)

  • セクション ヘッダー

  • イメージ ページ:

    インポート情報

    エクスポート情報

    ベース再配置

    リソース情報

次の一覧では、Microsoft COFF オブジェクト モジュール形式について説明します。

  • Microsoft COFF ヘッダー

  • セクション ヘッダー

  • 生データ:

    コード

    データ

    デバッグ情報

    再配置

ヘッダー ファイル

PE ファイル ヘッダーは、Microsoft MS-DOS スタブ、PE 署名、COFF ファイル ヘッダー、および省略可能なヘッダーで構成されます。 COFF オブジェクト ファイル ヘッダーは、COFF ファイル ヘッダーと省略可能なヘッダーで構成されます。 どちらの場合も、ファイル ヘッダーの直後にセクション ヘッダーが続きます。

MS-DOS スタブ (イメージのみ)

MS-DOS スタブは、MS-DOS で実行される有効なアプリケーションです。 これは EXE イメージの前面に配置されます。 リンカーはここに既定のスタブを配置し、イメージが MS-DOS で実行されるときに「このプログラムは DOS モードでは実行できません」というメッセージを出力します。 ユーザーは、/STUB リンカー オプションを使用して別のスタブを指定できます。

場所 0x3c では、スタブには PE 署名へのファイル オフセットがあります。 この情報により、MS-DOS スタブがある場合でも、Windows はイメージ ファイルを適切に実行できます。 このファイル オフセットは、リンク時に 0x3c 位置に配置されます。

署名 (イメージのみ)

MS-DOS スタブの後、オフセット 0x3c で指定されたファイル オフセットは、PE 形式のイメージ ファイルとしてファイルを識別する 4 バイト署名です。 この署名は「PE\0\0」(文字「P」と「E」の後に 2 つの null バイトが続く)です。

COFF ファイル ヘッダー (オブジェクトとイメージ)

オブジェクト ファイルの先頭、またはイメージ ファイルの署名の直後は、次の形式の標準の COFF ファイル ヘッダーです。 Windows ローダーでは、セクションの数が 96 に制限されることに注意してください。

オフセット サイズ フィールド 説明
0
2
Machine
ターゲット マシンのタイプを識別する番号。 詳細については、「メッセージの種類」を参照してください。
2
2
NumberOfSections
セクション数。 これは、ヘッダーのすぐ後に続くセクション テーブルのサイズを示します。
4
4
TimeDateStamp
1970 年 1 月 1 日 00:00 からの秒数の下位 32 ビット (C ランタイムの time_t 値)。ファイルがいつ作成されたかを示します。
8
4
PointerToSymbolTable
COFF シンボル テーブルのファイル オフセット。COFF シンボル テーブルが存在しない場合は 0。 COFF デバッグ情報は非推奨であるため、イメージの場合、この値は 0 にする必要があります。
12
4
NumberOfSymbols
シンボル テーブル内のエントリの数。 このデータを使用すれば、シンボル テーブルのすぐ後に続く文字列テーブルを検索することができます。 COFF デバッグ情報は非推奨であるため、イメージの場合、この値は 0 にする必要があります。
16
2
SizeOfOptionalHeader
オプションのヘッダーのサイズ。これは、実行可能ファイルでは必須ですが、オブジェクト ファイルには必要ありません。 オブジェクト ファイルの場合、この値は 0 とする必要があります。 ヘッダー形式の説明については、「省略可能なヘッダー (イメージのみ)」を参照してください。
18
2
Characteristics
ファイルの属性を示すフラグ。 特定のフラグ値については、「特性」を参照してください。

マシンの種類

Machine フィールドには、CPU の種類を指定する次のいずれかの値があります。 イメージ ファイルは、指定したコンピューターまたは指定したマシンをエミュレートするシステムでのみ実行できます。

定数 説明
IMAGE_FILE_MACHINE_UNKNOWN
0x0
このフィールドの内容は、どのマシンタイプにも適用できると想定されています
IMAGE_FILE_MACHINE_ALPHA
0x184
アルファ AXP、32 ビット アドレス空間
IMAGE_FILE_MACHINE_ALPHA64
0x284
アルファ 64、64 ビット アドレス空間
IMAGE_FILE_MACHINE_AM33
0x1d3
Matsushita AM33
IMAGE_FILE_MACHINE_AMD64
0x8664
X64
IMAGE_FILE_MACHINE_ARM
0x1c0
ARM リトル エンディアン
IMAGE_FILE_MACHINE_ARM64
0xaa64
ARM64 リトル エンディアン
IMAGE_FILE_MACHINE_ARMNT
0x1c4
ARM Thumb-2 リトル エンディアン
IMAGE_FILE_MACHINE_AXP64
0x284
AXP 64 (アルファ 64 と同じ)
IMAGE_FILE_MACHINE_EBC
0xebc
EFI バイト コード
IMAGE_FILE_MACHINE_I386
0x14c
Intel 386 以降のプロセッサと互換性のあるプロセッサ
IMAGE_FILE_MACHINE_IA64
0x200
Intel Itanium プロセッサ ファミリ
IMAGE_FILE_MACHINE_LOONGARCH32
0x6232
LoongArch 32 ビット プロセッサ ファミリ
IMAGE_FILE_MACHINE_LOONGARCH64
0x6264
LoongArch 64 ビット プロセッサ ファミリ
IMAGE_FILE_MACHINE_M32R
0x9041
三菱 M32R リトルエンディアン
IMAGE_FILE_MACHINE_MIPS16
0x266
MIPS16
IMAGE_FILE_MACHINE_MIPSFPU
0x366
FPU を使用した MIPS
IMAGE_FILE_MACHINE_MIPSFPU16
0x466
FPU を使用した MIPS16
IMAGE_FILE_MACHINE_POWERPC
0x1f0
Power PC リトル エンディアン
IMAGE_FILE_MACHINE_POWERPCFP
0x1f1
浮動小数点をサポートする電源 PC
IMAGE_FILE_MACHINE_R4000
0x166
MIPS リトル エンディアン
IMAGE_FILE_MACHINE_RISCV32
0x5032
RISC-V 32 ビット アドレス空間
IMAGE_FILE_MACHINE_RISCV64
0x5064
RISC-V 64 ビット アドレス空間
IMAGE_FILE_MACHINE_RISCV128
0x5128
RISC-V 128 ビット アドレス空間
IMAGE_FILE_MACHINE_SH3
0x1a2
Hitachi SH3
IMAGE_FILE_MACHINE_SH3DSP
0x1a3
Hitachi SH3 DSP
IMAGE_FILE_MACHINE_SH4
0x1a6
Hitachi SH4
IMAGE_FILE_MACHINE_SH5
0x1a8
Hitachi SH5
IMAGE_FILE_MACHINE_THUMB
0x1c2
Thumb
IMAGE_FILE_MACHINE_WCEMIPSV2
0x169
MIPS リトルエンディアン WCE v2

特性

Characteristics フィールドには、オブジェクトまたはイメージ ファイルの属性を示すフラグが含まれています。 現在、次のフラグが定義されています。

フラグ 説明
IMAGE_FILE_RELOCS_STRIPPED
0x0001
イメージのみ、Windows CE、および Microsoft Windows NT 以降。 これは、ファイルにベース再配置が含まれていないため、優先ベース アドレスで読み込む必要があることを示します。 ベース アドレスが使用できない場合、ローダーはエラーを報告します。 リンカーの既定の動作では、実行可能ファイル (EXE) からベース再配置を削除します。
IMAGE_FILE_EXECUTABLE_IMAGE
0x0002
イメージのみ。 これは、イメージ ファイルが有効であり、実行できることを示します。 このフラグが設定されていない場合は、リンカー エラーを示します。
IMAGE_FILE_LINE_NUMS_STRIPPED
0x0004
COFF 行番号が削除されました。 このフラグは非推奨であり、0 にする必要があります。
IMAGE_FILE_LOCAL_SYMS_STRIPPED
0x0008
ローカル シンボルの COFF シンボル テーブルエントリが削除されました。 このフラグは非推奨であり、0 にする必要があります。
IMAGE_FILE_AGGRESSIVE_WS_TRIM
0x0010
廃止されています。 ワーキング セットを積極的にトリミングします。 このフラグは Windows 2000 以降では非推奨であり、0 にする必要があります。
IMAGE_FILE_LARGE_ADDRESS_ AWARE
0x0020
アプリケーションは > 2-GB のアドレスを処理できます。
0x0040
このフラグは、今後使用するために予約されています。
IMAGE_FILE_BYTES_REVERSED_LO
0x0080
リトル エンディアン: 最下位ビット (LSB) は、メモリ内の最上位ビット (MSB) の前にあります。 このフラグは非推奨であり、0 にする必要があります。
IMAGE_FILE_32BIT_MACHINE
0x0100
マシンは、32 ビットワード アーキテクチャに基づいています。
IMAGE_FILE_DEBUG_STRIPPED
0x0200
デバッグ情報がイメージ ファイルから削除されます。
IMAGE_FILE_REMOVABLE_RUN_ FROM_SWAP
0x0400
イメージがリムーバブル メディア上にある場合は、イメージを完全に読み込み、スワップ ファイルにコピーします。
IMAGE_FILE_NET_RUN_FROM_SWAP
0x0800
イメージがネットワーク メディア上にある場合は、イメージを完全に読み込み、スワップ ファイルにコピーします。
IMAGE_FILE_SYSTEM
0x1000
イメージ ファイルはシステム ファイルであり、ユーザー プログラムではありません。
IMAGE_FILE_DLL
0x2000
イメージ ファイルはダイナミック リンク ライブラリ (DLL) です。 このようなファイルは、ほとんどの目的で実行可能ファイルと見なされますが、直接実行することはできません。
IMAGE_FILE_UP_SYSTEM_ONLY
0x4000
ファイルは、単一プロセッサ コンピューターでのみ実行する必要があります。
IMAGE_FILE_BYTES_REVERSED_HI
0x8000
ビッグ エンディアン: MSB はメモリ内の LSB の前にあります。 このフラグは非推奨であり、0 にする必要があります。

省略可能なヘッダー (イメージのみ)

すべてのイメージ ファイルには、ローダーに情報を提供するオプションのヘッダーがあります。 このヘッダーは、一部のファイル (具体的にはオブジェクト ファイル) に含まれていないという意味では省略可能です。 イメージ ファイルの場合は、このヘッダーが必要です。 オブジェクト ファイルにはオプションのヘッダーを含めることができますが、通常、このヘッダーはオブジェクト ファイル内でサイズを増やす以外の機能を持ちません。

省略可能なヘッダーのサイズは固定されていないことに注意してください。 COFF ヘッダーの SizeOfOptionalHeader フィールドを使用して、特定のデータ ディレクトリのファイルへのプローブが SizeOfOptionalHeader を超えていないことを検証する必要があります。 詳細については、「COFF ファイル ヘッダー (オブジェクトとイメージ)」を参照してください。

また、省略可能なヘッダーの NumberOfRvaAndSizes フィールドを使用して、特定のデータ ディレクトリ エントリのプローブが省略可能なヘッダーを超えないことを確認する必要があります。 さらに、フォーマットの互換性のために、オプションのヘッダー マジック番号を検証することが重要です。

オプションのヘッダー マジック番号は、イメージが PE32 または PE32 以降の実行可能ファイルであるかどうかを決定します。

マジック ナンバー PE 形式
0x10b
PE32
0x20b
PE32+

PE32 以降のイメージでは、イメージ サイズを 2 ギガバイトに制限しながら、64 ビットのアドレス空間を使用できます。 その他の PE32 以降の変更については、それぞれのセクションで説明します。

省略可能なヘッダー自体には、3 つの主要な部分があります。

オフセット (PE32/PE32+) サイズ (PE32/PE32+) ヘッダー パーツ 説明
0
28/24
標準フィールド
UNIX を含む、COFF のすべての実装に対して定義されているフィールド。
28/24
68/88
Windows 固有のフィールド
Windows の特定の機能 (サブシステムなど) をサポートするための追加フィールド。
96/112
変数:
データ ディレクトリ
イメージ ファイル内にあり、オペレーティング システムによって使用される特別なテーブル (インポート テーブルとエクスポート テーブルなど) のアドレスとサイズのペア。

省略可能なヘッダーの標準フィールド (イメージのみ)

省略可能なヘッダーの最初の 8 つのフィールドは、COFF のすべての実装に対して定義されている標準フィールドです。 これらのフィールドには、実行可能ファイルの読み込みと実行に役立つ一般的な情報が含まれています。 PE32+ 形式では変更されません。

オフセット サイズ フィールド 説明
0
2
Magic
イメージ ファイルの状態を識別する符号なし整数。 最も一般的な数は 0x10B であり、通常の実行可能ファイルとして識別されます。 0x107 は ROM イメージとして識別し、0x20B は PE32+ 実行可能ファイルとして識別します。
2
1
MajorLinkerVersion
リンカーのメジャー バージョン番号。
3
1
MinorLinkerVersion
リンカーのマイナー バージョン番号。
4
4
SizeOfCode
コード (テキスト) セクションのサイズ、またはセクションが複数ある場合はすべてのコード セクションの合計。
8
4
SizeOfInitializedData
初期化されたデータ セクションのサイズ、またはデータ セクションが複数ある場合は、そのようなすべてのセクションの合計。
12
4
SizeOfUninitializedData
初期化されていないデータ セクション (BSS) のサイズ、または BSS セクションが複数ある場合は、そのようなすべてのセクションの合計。
16
4
AddressOfEntryPoint
実行可能ファイルがメモリにロードされるときの、イメージ ベースを基準としたエントリ ポイントのアドレス。 プログラム イメージの場合、これは開始アドレスです。 デバイス ドライバーの場合、これは初期化関数のアドレスです。 エントリ ポイントは、DLL では省略可能です。 エントリ ポイントが存在しない場合、このフィールドは 0 である必要があります。
20
4
BaseOfCode
コードの先頭セクションがメモリにロードされるときの、そのイメージ ベースに対する相対アドレス。

PE32 には、BaseOfCode に続く PE32 以降では存在しない、この追加フィールドが含まれています。

オフセット サイズ フィールド 説明
24
4
BaseOfData
データの先頭セクションがメモリにロードされるときの、そのイメージ ベースに対する相対アドレス。

省略可能なヘッダー Windows 固有のフィールド (イメージのみ)

次の 21 個のフィールドは、COFF オプションのヘッダー形式の拡張です。 これらには、Windows のリンカーとローダーに必要な追加情報が含まれています。

オフセット (PE32/PE32+) サイズ (PE32/PE32+) フィールド 説明
28/24
4/8
ImageBase
メモリにロードされるときのイメージの最初のバイトの優先アドレス。64 K の倍数である必要があります。DLL の既定値は 0x10000000 です。 Windows CE EXE の既定値は 0x00010000 です。 Windows NT、Windows 2000、Windows XP、Windows 95、Windows 98、Windows Me の既定値は0x00400000 です。
32/32
4
SectionAlignment
セクションがメモリに読み込まれるときのその配置 (バイト単位)。 FileAlignment 以上である必要があります。 既定値は、アーキテクチャのページ サイズです。
36/36
4
FileAlignment
イメージ ファイル内のセクションの生データを揃えるために使用される配置係数 (バイト単位)。 値は、512 ~ 64 K (その値を含む) の 2 の累乗にする必要があります。 既定値は 512 です。 SectionAlignment がアーキテクチャのページ サイズより小さい場合、FileAlignment は SectionAlignment と一致する必要があります。
40/40
2
MajorOperatingSystemVersion
必要なオペレーティング システムのメジャー バージョン番号。
42/42
2
MinorOperatingSystemVersion
必要なオペレーティング システムのマイナー バージョン番号。
44/44
2
MajorImageVersion
イメージのメジャー バージョン番号。
46/46
2
MinorImageVersion
イメージのマイナー バージョン番号。
48/48
2
MajorSubsystemVersion
サブアセンブリのメジャー バージョン番号。
50/50
2
MinorSubsystemVersion
サブアセンブリのマイナー バージョン番号。
52/52
4
Win32VersionValue
予約済み、0 でなければなりません。
56/56
4
SizeOfImage
イメージがメモリに読み込まれるときに、すべてのヘッダーを含む、イメージのサイズ (バイト単位)。 SectionAlignment の倍数である必要があります。
60/60
4
SizeOfHeaders
FileAlignment の倍数に切り上げられた、MS DOS スタブ、PE ヘッダー、およびセクション ヘッダーの合計サイズ。
64/64
4
CheckSum
イメージ ファイルのチェックサム。 チェックサムを計算するアルゴリズムは IMAGHELP.DLL に組み込まれています。 すべてのドライバー、起動時にロードされる DLL、およびクリティカルな Windows プロセスにロードされる DLL は、ロード時に検証のためにチェックされます。
68/68
2
Subsystem
このイメージを実行するために必要なサブシステム。 詳細については、「Windows サブシステム」を参照してください。
70/70
2
DllCharacteristics
詳細については、この仕様で後述する「DLL の特性」を参照してください。
72/72
4/8
SizeOfStackReserve
予約するスタックのサイズ。 SizeOfStackCommitのみがコミットされます。残りは、予約サイズに達するまで、一度に 1 ページずつ使用できるようになります。
76/80
4/8
SizeOfStackCommit
コミットするスタックのサイズ。
80/88
4/8
SizeOfHeapReserve
予約するローカル ヒープ領域のサイズ。 SizeOfHeapCommitのみがコミットされます。残りは、予約サイズに達するまで、一度に 1 ページずつ使用できるようになります。
84/96
4/8
SizeOfHeapCommit
コミットするローカル ヒープ領域のサイズ。
88/104
4
LoaderFlags
予約済み、0 でなければなりません。
92/108
4
NumberOfRvaAndSizes
省略可能なヘッダーの残りの部分にあるデータ ディレクトリ エントリの数。 それぞれによって、場所とサイズが記述されます。
Windows サブシステム

オプションのヘッダーの Subsystem フィールドに定義されている次の値により、イメージの実行にどの Windows サブシステム (存在する場合) が必要かが決まります。

定数 説明
IMAGE_SUBSYSTEM_UNKNOWN
0
不明なサブシステム。
IMAGE_SUBSYSTEM_NATIVE
1
デバイス ドライバーとネイティブ Windows プロセス
IMAGE_SUBSYSTEM_WINDOWS_GUI
2
Windows グラフィカル ユーザー インターフェイス (GUI) サブシステム
IMAGE_SUBSYSTEM_WINDOWS_CUI
3
Windows 文字サブシステム
IMAGE_SUBSYSTEM_OS2_CUI
5
OS/2 文字サブシステム
IMAGE_SUBSYSTEM_POSIX_CUI
7
Posix 文字サブシステム
IMAGE_SUBSYSTEM_NATIVE_WINDOWS
8
ネイティブ Win9x ドライバー
IMAGE_SUBSYSTEM_WINDOWS_CE_GUI
9
Windows CE
IMAGE_SUBSYSTEM_EFI_APPLICATION
10
拡張ファームウェア インターフェイス (EFI) アプリケーション
IMAGE_SUBSYSTEM_EFI_BOOT_ SERVICE_DRIVER
11
ブート サービスを備えた EFI ドライバー
IMAGE_SUBSYSTEM_EFI_RUNTIME_ DRIVER
12
ランタイム サービスを備えたEFIドライバー
IMAGE_SUBSYSTEM_EFI_ROM
13
EFI ROM イメージ
IMAGE_SUBSYSTEM_XBOX
14
XBOX
IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION
16
Windows ブート アプリケーション。
DLL 特性

省略可能なヘッダーの DllCharacteristics フィールドには、次の値が定義されています。

定数 説明
0x0001
予約済み、0 でなければなりません。
0x0002
予約済み、0 でなければなりません。
0x0004
予約済み、0 でなければなりません。
0x0008
予約済み、0 でなければなりません。
IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA
0x0020
イメージでは、エントロピが高い 64 ビットの仮想アドレス空間を処理できます。
IMAGE_DLLCHARACTERISTICS_
DYNAMIC_BASE
0x0040
DLL は読み込み時に再配置できます。
IMAGE_DLLCHARACTERISTICS_
FORCE_INTEGRITY
0x0080
コード整合性チェックが適用されます。
IMAGE_DLLCHARACTERISTICS_
NX_COMPAT
0x0100
イメージは NX と互換性があります。
IMAGE_DLLCHARACTERISTICS_ NO_ISOLATION
0x0200
分離は認識されますが、イメージは分離しません。
IMAGE_DLLCHARACTERISTICS_ NO_SEH
0x0400
構造化例外 (SE) 処理は使用しません。 このイメージでは SE ハンドラーを呼び出すことはできません。
IMAGE_DLLCHARACTERISTICS_ NO_BIND
0x0800
イメージはバインドしないでください。
IMAGE_DLLCHARACTERISTICS_APPCONTAINER
0x1000
イメージは AppContainer で実行する必要があります。
IMAGE_DLLCHARACTERISTICS_ WDM_DRIVER
0x2000
WDM ドライバー。
IMAGE_DLLCHARACTERISTICS_GUARD_CF
0x4000
イメージでは、制御フロー ガードがサポートされています。
IMAGE_DLLCHARACTERISTICS_ TERMINAL_SERVER_AWARE
0x8000
ターミナル サーバー対応。

省略可能なヘッダー データ ディレクトリ (イメージのみ)

各データ ディレクトリには、Windows で使用されるテーブルまたは文字列のアドレスとサイズが指定されます。 これらのデータ ディレクトリ エントリはすべてメモリに読み込まれるので、システムは実行時にそれらを使用できます。 データ ディレクトリは、次の宣言を持つ 8 バイトのフィールドです。

typedef struct _IMAGE_DATA_DIRECTORY {
    DWORD   VirtualAddress;
    DWORD   Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

最初のフィールド VirtualAddress は、実際にはテーブルの RVA です。 RVA は、テーブルの読み込み時のイメージのベース アドレスを基準としたテーブルのアドレスです。 2 番目のフィールドは、バイト単位でサイズを指定します。 省略可能なヘッダーの最後の部分を形成するデータ ディレクトリを次の表に示します。

ディレクトリの数は固定されていないことに注意してください。 特定のディレクトリを探す前に、省略可能なヘッダーの NumberOfRvaAndSizes フィールドをチェックします。

また、このテーブルの RVA がセクションの先頭を指している、または特定のテーブルを含むセクションに特定の名前があるとは想定しないでください。

オフセット (PE/PE32+) サイズ フィールド 説明
96/112
8
Export Table
エクスポート テーブルのアドレスとサイズ。 詳細については、「.edata セクション (イメージのみ)」を参照してください。
104/120
8
Import Table
インポート テーブルのアドレスとサイズ。 詳細については、.idata セクションを参照してください。
112/128
8
Resource Table
リソース テーブルのアドレスとサイズ。 詳細については、.rsrc セクションに関するページを参照してください。
120/136
8
Exception Table
例外テーブルのアドレスとサイズ。 詳細については、.pdata セクションに関するページを参照してください。
128/144
8
Certificate Table
属性証明書テーブルのアドレスとサイズ。 詳細については、「属性証明書テーブル (イメージのみ)」を参照してください。
136/152
8
Base Relocation Table
ベース再配置テーブルのアドレスとサイズ。 詳細については、.reloc セクション (イメージのみ) を参照してください。
144/160
8
Debug
デバッグ データの開始アドレスとサイズ。 詳細については、.debug セクションを参照してください。
152/168
8
Architecture
予約済み、0 である必要があります
160/176
8
Global Ptr
グローバル ポインター レジスタに格納される値の RVA。 この構造体のサイズ メンバーは 0 に設定する必要があります。
168/184
8
TLS Table
スレッド ローカル ストレージ (TLS) テーブルのアドレスとサイズ。 詳細については、.tls セクションに関するページを参照してください。
176/192
8
Load Config Table
読み込み構成テーブルのアドレスとサイズ。 詳細については、「構成構造体の読み込み (イメージのみ)」を参照してください。
184/200
8
Bound Import
バインドされたインポート テーブルのアドレスとサイズ。
192/208
8
IAT
インポート アドレス テーブルのアドレスとサイズ。 詳細については、「インポート アドレス テーブル」を参照してください。
200/216
8
Delay Import Descriptor
遅延インポート記述子のアドレスとサイズ。 詳細については、「インポート テーブルの遅延読み込み (イメージのみ)」を参照してください。
208/224
8
CLR Runtime Header
CLR ランタイム ヘッダーのアドレスとサイズ。 詳細については、「.cormeta セクション (オブジェクトのみ)」を参照してください。
216/232
8
予約済み、0 でなければなりません

属性証明書のテーブルを指す証明書テーブル エントリ。 これらの証明書は、イメージの一部としてメモリに読み込まれません。 したがって、このエントリの最初のフィールドは通常 RVA ですが、代わりにファイル ポインターになります。

セクション テーブル (セクション ヘッダー)

セクション テーブルの各行は、実際にはセクション ヘッダーです。 このテーブルは、省略可能なヘッダー (ある場合) の直後に表示されます。 ファイル ヘッダーにセクション テーブルへの直接ポインターが含まれていないため、この配置が必要です。 代わりに、セクション テーブルの場所は、ヘッダーの後の最初のバイトの位置を計算することによって決定されます。 ファイル ヘッダーで指定されている省略可能なヘッダーのサイズを必ず使用してください。

セクション テーブル内のエントリの数は、ファイル ヘッダーの NumberOfSections フィールドによって指定されます。 セクション テーブルのエントリには、1 から始まる番号が付けられます。 コードとデータ メモリ セクションのエントリは、リンカーによって選択された順序で行われます。

イメージ ファイルでは、セクションの VA が昇順で隣接するようにリンカーによって割り当てられる必要があり、オプションのヘッダーの SectionAlignment 値の倍数である必要があります。

各セクション ヘッダー (セクション テーブル エントリ) には、エントリあたり合計 40 バイトの次の形式があります。

オフセット サイズ フィールド 説明
0
8
Name
8 バイトの null 埋め込み UTF-8 エンコード文字列。 文字列の長さがちょうど 8 文字の場合、終端の null はありません。 長い名前の場合、このフィールドにはスラッシュ (/) が含まれます。その後に、文字列テーブルへのオフセットである 10 進数の ASCII 表現が続きます。 実行可能イメージは文字列テーブルを使用せず、8 文字を超えるセクション名をサポートしていません。 オブジェクト ファイル内の長い名前は、実行可能ファイルに出力されると切り捨てられます。
8
4
VirtualSize
メモリに読み込まれるときのセクションの合計サイズ。 この値が SizeOfRawData より大きい場合、セクションは 0 で埋め込まれます。 このフィールドは実行可能イメージに対してのみ有効であり、オブジェクト ファイルの場合は 0 に設定する必要があります。
12
4
VirtualAddress
実行可能イメージの場合、セクションがメモリにロードされるときのイメージ ベースに対するセクションの最初のバイトのアドレス。 オブジェクト ファイルの場合、このフィールドは再配置が適用される前の最初のバイトのアドレスです。わかりやすくするために、コンパイラはこれをゼロに設定する必要があります。 それ以外の場合は、再配置中にオフセットから減算される任意の値です。
16
4
SizeOfRawData
セクションのサイズ (オブジェクト ファイルの場合) またはディスク上で初期化されたデータのサイズ (イメージ ファイルの場合)。 実行可能イメージの場合、これは省略可能なヘッダーからの FileAlignment の倍数である必要があります。 これが VirtualSize より小さい場合、セクションの残りの部分は 0 で埋められます。 SizeOfRawData フィールドは丸められますが、VirtualSize フィールドは丸めないため、SizeOfRawData も VirtualSize より大きくなる可能性があります。 セクションに初期化されていないデータのみが含まれている場合、このフィールドは 0 にする必要があります。
20
4
PointerToRawData
COFF ファイル内のセクションの先頭ページへのファイル ポインター。 実行可能イメージの場合、これは省略可能なヘッダーからの FileAlignment の倍数である必要があります。 オブジェクト ファイルの場合、パフォーマンスを最大限に高めるには、値を 4 バイト境界に配置する必要があります。 セクションに初期化されていないデータのみが含まれている場合、このフィールドは 0 にする必要があります。
24
4
PointerToRelocations
セクションの再配置エントリの先頭へのファイル ポインター。 これは、実行可能イメージの場合、または再配置がない場合は 0 に設定されます。
28
4
PointerToLinenumbers
セクションの行番号エントリの先頭へのファイル ポインター。 COFF 行番号がない場合、これは 0 に設定されます。 COFF デバッグ情報は非推奨であるため、イメージの場合、この値は 0 にする必要があります。
32
2
NumberOfRelocations
セクションの再配置エントリの数。 実行可能イメージの場合、これは 0 に設定されます。
34
2
NumberOfLinenumbers
セクションの行番号エントリの数。 COFF デバッグ情報は非推奨であるため、イメージの場合、この値は 0 にする必要があります。
36
4
特性
セクションの特性を記述したフラグ。 詳しくは、「セクション フラグ」をご覧ください。

 

セクション フラグ

セクション ヘッダーの Characteristics フィールドのセクション フラグは、セクションの特性を示します。

フラグ 説明
0x00000000
将来利用するために予約されています。
0x00000001
将来利用するために予約されています。
0x00000002
将来利用するために予約されています。
0x00000004
将来利用するために予約されています。
IMAGE_SCN_TYPE_NO_PAD
0x00000008
セクションを次の境界に埋め込むべきではありません。 このフラグは廃止され、IMAGE_SCN_ALIGN_1BYTES に置き換えられました。 これは、オブジェクト ファイルに対して有効です。
0x00000010
将来利用するために予約されています。
IMAGE_SCN_CNT_CODE
0x00000020
セクションには実行可能コードが含まれています。
IMAGE_SCN_CNT_INITIALIZED_DATA
0x00000040
セクションには、初期化されたデータが含まれています。
IMAGE_SCN_CNT_UNINITIALIZED_ DATA
0x00000080
このセクションには初期化されていないデータが含まれています。
IMAGE_SCN_LNK_OTHER
0x00000100
将来利用するために予約されています。
IMAGE_SCN_LNK_INFO
0x00002000
セクションには、コメントまたはその他の情報が含まれています。 .drectve セクションには、この型があります。 これは、オブジェクト ファイルに対してのみ有効です。
0x00000400
将来利用するために予約されています。
IMAGE_SCN_LNK_REMOVE
0x00000800
セクションはイメージの一部になりません。 これは、オブジェクト ファイルに対して有効です。
IMAGE_SCN_LNK_COMDAT
0x00001000
セクションには COMDAT データが含まれています。 詳細については、「COMDAT セクション (オブジェクトのみ)」を参照してください。 これは、オブジェクト ファイルに対して有効です。
IMAGE_SCN_GPREL
0x00000800
このセクションには、グローバル ポインター (GP) を介して参照されるデータが含まれています。
IMAGE_SCN_MEM_PURGEABLE
0x00020000
将来利用するために予約されています。
IMAGE_SCN_MEM_16BIT
0x00020000
将来利用するために予約されています。
IMAGE_SCN_MEM_LOCKED
0x00040000
将来利用するために予約されています。
IMAGE_SCN_MEM_PRELOAD
0x00080000
将来利用するために予約されています。
IMAGE_SCN_ALIGN_1BYTES
0x00100000
1 バイト境界にデータを配置します。 オブジェクト ファイルに対してのみ有効です。
IMAGE_SCN_ALIGN_2BYTES
0x00200000
2 バイト境界にデータを配置します。 オブジェクト ファイルに対してのみ有効です。
IMAGE_SCN_ALIGN_4BYTES
0x00300000
4 バイト境界にデータを配置します。 オブジェクト ファイルに対してのみ有効です。
IMAGE_SCN_ALIGN_8BYTES
0x00400000
8 バイト境界にデータを配置します。 オブジェクト ファイルに対してのみ有効です。
IMAGE_SCN_ALIGN_16BYTES
0x00500000
16 バイト境界にデータを配置します。 オブジェクト ファイルに対してのみ有効です。
IMAGE_SCN_ALIGN_32BYTES
0x00600000
32 バイト境界にデータを配置します。 オブジェクト ファイルに対してのみ有効です。
IMAGE_SCN_ALIGN_64BYTES
0x00700000
64 バイト境界にデータを配置します。 オブジェクト ファイルに対してのみ有効です。
IMAGE_SCN_ALIGN_128BYTES
0x00800000
128 バイト境界にデータを配置します。 オブジェクト ファイルに対してのみ有効です。
IMAGE_SCN_ALIGN_256BYTES
0x00900000
256 バイト境界にデータを配置します。 オブジェクト ファイルに対してのみ有効です。
IMAGE_SCN_ALIGN_512BYTES
0x00A00000
512 バイト境界にデータを配置します。 オブジェクト ファイルに対してのみ有効です。
IMAGE_SCN_ALIGN_1024BYTES
0x00B00000
1024 バイト境界にデータを配置します。 オブジェクト ファイルに対してのみ有効です。
IMAGE_SCN_ALIGN_2048BYTES
0x00C00000
2048 バイト境界にデータを配置します。 オブジェクト ファイルに対してのみ有効です。
IMAGE_SCN_ALIGN_4096BYTES
0x00D00000
4096 バイト境界にデータを配置します。 オブジェクト ファイルに対してのみ有効です。
IMAGE_SCN_ALIGN_8192BYTES
0x00E00000
8192 バイト境界にデータを配置します。 オブジェクト ファイルに対してのみ有効です。
IMAGE_SCN_LNK_NRELOC_OVFL
0x01000000
セクションには拡張再配置が含まれています。
IMAGE_SCN_MEM_DISCARDABLE
0x02000000
セクションは、必要に応じてカード解除できます。
IMAGE_SCN_MEM_NOT_CACHED
0x04000000
セクションをキャッシュできません。
IMAGE_SCN_MEM_NOT_PAGED
0x08000000
セクションはページングできません。
IMAGE_SCN_MEM_SHARED
0x10000000
セクションはメモリ内で共有できます。
IMAGE_SCN_MEM_EXECUTE
0x20000000
セクションはコードとして実行できます。
IMAGE_SCN_MEM_READ
0x40000000
セクションを読み取ることができます。
IMAGE_SCN_MEM_WRITE
0x80000000
セクションは書き込むことができます。

 

IMAGE_SCN_LNK_NRELOC_OVFL は、セクションの再配置の数が、セクション ヘッダーで予約されている 16 ビットを超えていることを示します。 このビットが設定されており、セクション ヘッダーの NumberOfRelocations フィールドが 0xffff の場合、実際の再配置カウントは、最初の再配置の 32 ビットの VirtualAddress フィールドに格納されます。 IMAGE_SCN_LNK_NRELOC_OVFL が設定されており、セクション内の再配置の数が 0xffff 未満の場合、エラーになります。

グループ化されたセクション (オブジェクトのみ)

オブジェクト ファイルのセクション名では、「$」文字 (ドル記号) が特別に解釈されます。

オブジェクト セクションの内容を含むイメージ セクションを決定するとき、リンカーは「$」とそれに続くすべての文字を破棄します。 したがって、.text$X という名前のオブジェクト セクションは、実際には画像内の .text セクションにコントリビュートします。

ただし、「$」に続く文字によって、画像セクションへのコントリビューションの順序が決まります。 同じオブジェクト セクション名を持つすべてのコントリビューションはイメージ内で連続して割り当てられ、コントリビューションのブロックはオブジェクト セクション名ごとに字句順に並べ替えられます。 したがって、セクション名が .text$X のオブジェクト ファイル内のすべてのものは、.text$W コントリビューションの後、および .text$Y コントリビューションの前に割り当てられます。

イメージ ファイル内のセクション名に「$」文字が含まれることはありません。

ファイルのその他の内容

省略可能なヘッダーまでのデータ構造は、すべてファイルの先頭からの固定オフセットに配置されます (または、ファイルが MS-DOS スタブを含むイメージの場合は PE ヘッダーから)。

COFF オブジェクトまたはイメージ ファイルの残りの部分には、必ずしも特定のファイル オフセットにあるとは限らないデータ ブロックが含まれています。 代わりに、場所は、省略可能なヘッダーまたはセクション ヘッダー内のポインターによって定義されます。

例外は、SectionAlignment 値がアーキテクチャのページ サイズ (Intel x86 と MIPS の場合は 4 K、Itanium の場合は 8 K) より小さいイメージです。 SectionAlignment の説明については、「省略可能なヘッダー (画像のみ)」を参照してください。 この場合、「5.1 セクション データ」で説明したように、セクション データのファイル オフセットには制約があります。もう 1 つの例外は、属性証明書とデバッグ情報をイメージ ファイルの最後に配置し、属性証明書テーブルをデバッグ セクションの直前に配置する必要があることです。これは、ローダーがこれらをメモリにマップしないためです。 ただし、属性証明書とデバッグ情報に関する規則は、オブジェクト ファイルには適用されません。

セクション データ

セクションの初期化されたデータは、単純なバイト ブロックで構成されます。 ただし、ゼロをすべて含むセクションでは、セクション データを含める必要はありません。

各セクションのデータは、セクション ヘッダーの PointerToRawData フィールドによって指定されたファイル オフセットにあります。 ファイル内のこのデータのサイズは、SizeOfRawData フィールドによって示されます。 SizeOfRawData が VirtualSize より小さい場合、残りは 0 で埋められます。

画像ファイルでは、セクション データは、オプションのヘッダーの FileAlignment フィールドで指定された境界上に整列する必要があります。 セクション データは、対応するセクションの RVA 値の順序で表示される必要があります (セクション テーブル内の個々のセクション ヘッダーも同様)。

オプションのヘッダーの SectionAlignment 値がアーキテクチャのページ サイズより小さい場合、画像ファイルには追加の制限があります。 このようなファイルの場合、セクション データの物理オフセットが RVA と同じになるように、ファイル内のセクション データの場所はイメージのロード時のメモリ内の場所と一致する必要があります。

COFF 再配置 (オブジェクトのみ)

オブジェクト ファイルには COFF 再配置が含まれており、これによりセクション データがイメージ ファイルに配置され、その後メモリにロードされるときにセクション データをどのように変更するかを指定します。

参照されるすべてのシンボルにはフラット アドレス空間内のアドレスがすでに割り当てられているため、イメージ ファイルには COFF 再配置は含まれません。 イメージには、.reloc セクション内のベース再配置の形式で再配置情報が含まれています (イメージに IMAGE_FILE_RELOCS_STRIPPED 属性がない場合)。 詳細については、.reloc セクション (イメージのみ) を参照してください。

オブジェクト ファイル内のセクションごとに、固定長レコードの配列にセクションの COFF 再配置が保持されます。 配列の位置と長さはセクション ヘッダーで指定されます。 配列の各要素の形式は次のとおりです。

オフセット サイズ フィールド 説明
0
4
VirtualAddress
再配置が適用されるアイテムのアドレス。 これは、セクションの先頭からのオフセットに、セクションの RVA/Offset フィールドの値を加えた値です。 「セクション テーブル (セクション ヘッダー)」を参照してください。 たとえば、セクションの最初のバイトに 0x10 のアドレスがある場合、3 番目のバイトには 0x12 のアドレスがあります。
4
4
SymbolTableIndex
シンボル テーブルへの 0 から始まるインデックス。 このシンボルは、再配置に使用されるアドレスを示します。 指定されたシンボルにセクションのストレージ クラスがある場合、シンボルのアドレスは、同じ名前の最初のセクションを持つアドレスになります。
8
2

実行する必要がある再配置の種類を示す値。 有効な再配置の種類は、コンピューターの種類によって異なります。 「型インジケーター」を参照してください。

 

SymbolTableIndex フィールドによって参照されるシンボルにストレージ クラス IMAGE_SYM_CLASS_SECTION がある場合、シンボルのアドレスはセクションの先頭になります。 このセクションは通常、オブジェクト ファイルがアーカイブ (ライブラリ) の一部である場合を除き、同じファイル内にあります。 その場合、そのセクションは、現在のオブジェクト ファイルと同じアーカイブ メンバー名を持つアーカイブ内の他のオブジェクト ファイル内で見つけることができます。 (アーカイブ メンバー名との関係は、インポート テーブル、つまり .idata セクションのリンクに使用されます。)

型インジケーター

再配置レコードの型フィールドは、どのような種類の再配置を実行する必要があるかを示します。 マシンの型ごとに異なる再配置の型が定義されます。

x64 プロセッサ

x64 および互換性のあるプロセッサに対して、次の再配置型インジケーターが定義されています。

定数 説明
IMAGE_REL_AMD64_ABSOLUTE
0x0000
再配置は無視されます。
IMAGE_REL_AMD64_ADDR64
0x0001
再配置ターゲットの 64 ビット VA。
IMAGE_REL_AMD64_ADDR32
0x0002
再配置ターゲットの 32 ビット VA。
IMAGE_REL_AMD64_ADDR32NB
0x0003
イメージ ベース (RVA) のない 32 ビット アドレス。
IMAGE_REL_AMD64_REL32
0x0004
再配置後のバイトからの 32 ビット相対アドレス。
IMAGE_REL_AMD64_REL32_1
0x0005
再配置からのバイト距離 1 を基準とした 32 ビット アドレス。
IMAGE_REL_AMD64_REL32_2
0x0006
再配置からのバイト距離 2 を基準とした 32 ビット アドレス。
IMAGE_REL_AMD64_REL32_3
0x0007
再配置からのバイト距離 3 を基準とした 32 ビット アドレス。
IMAGE_REL_AMD64_REL32_4
0x0008
再配置からのバイト距離 4 を基準とした 32 ビット アドレス。
IMAGE_REL_AMD64_REL32_5
0x0009
再配置からのバイト距離 5 を基準とした 32 ビット アドレス。
IMAGE_REL_AMD64_SECTION
0x000A
ターゲットを含むセクションの 16 ビット セクション インデックス。 これは、デバッグ情報をサポートするために使用されます。
IMAGE_REL_AMD64_SECREL
0x000B
セクションの先頭からのターゲットの 32 ビット オフセット。 これは、デバッグ情報と静的スレッド ローカル ストレージをサポートするために使用されます。
IMAGE_REL_AMD64_SECREL7
0x000C
ターゲットを含むセクションのベースからの 7 ビット符号なしオフセット。
IMAGE_REL_AMD64_TOKEN
0x000D
CLR トークン。
IMAGE_REL_AMD64_SREL32
0x000E
オブジェクトに出力される 32 ビット符号付きスパン依存値。
IMAGE_REL_AMD64_PAIR
0x000F
スパンに依存するすべての値の直後に続く必要があるペア。
IMAGE_REL_AMD64_SSPAN32
0x0010
リンク時に適用される 32 ビット符号付きスパン依存値。

 

ARM プロセッサ

ARM プロセッサには、次の再配置型インジケーターが定義されています。

定数 説明
IMAGE_REL_ARM_ABSOLUTE
0x0000
再配置は無視されます。
IMAGE_REL_ARM_ADDR32
0x0001
再配置ターゲットの 32 ビット VA。
IMAGE_REL_ARM_ADDR32NB
0x0002
ターゲットの 32 ビット RVA。
IMAGE_REL_ARM_BRANCH24
0x0003
ターゲットに対する 24 ビットの相対変位。
IMAGE_REL_ARM_BRANCH11
0x0004
サブルーチン呼び出しへの参照。 この参照は、11 ビット オフセットを持つ 2 つの 16 ビット命令で構成されています。
IMAGE_REL_ARM_REL32
0x000A
再配置後のバイトからの 32 ビット相対アドレス。
IMAGE_REL_ARM_SECTION
0x000E
ターゲットを含むセクションの 16 ビット セクション インデックス。 これは、デバッグ情報をサポートするために使用されます。
IMAGE_REL_ARM_SECREL
0x000F
セクションの先頭からのターゲットの 32 ビット オフセット。 これは、デバッグ情報と静的スレッド ローカル ストレージをサポートするために使用されます。
IMAGE_REL_ARM_MOV32
0x0010
再配置ターゲットの 32 ビット VA。 この再配置は、下位 16 ビットの MOVW 命令と、上位 16 ビットの MOVT を使用して適用されます。
IMAGE_REL_THUMB_MOV32
0x0011
再配置ターゲットの 32 ビット VA。 この再配置は、下位 16 ビットの MOVW 命令と、上位 16 ビットの MOVT を使用して適用されます。
IMAGE_REL_THUMB_BRANCH20
0x0012
命令は、2 バイトのアラインされたターゲットに対する 21 ビットの相対変位で固定されます。 変位の最下位ビットは常に 0 であり、格納されません。 この再配置は、Thumb-2 の 32 ビット条件付き B 命令に対応します。
未使用
0x0013
IMAGE_REL_THUMB_BRANCH24
0x0014
命令は、2 バイトのアラインされたターゲットに対する 25 ビットの相対変位で固定されます。 変位の最下位ビットは 0 であり、格納されません。この再配置は、Thumb-2 B 命令に対応します。
IMAGE_REL_THUMB_BLX23
0x0015
命令は、4 バイトのアラインされたターゲットに対する 25 ビットの相対変位で固定されます。 変位の下位 2 ビットはゼロであり、格納されません。
この再配置は、Thumb-2 BLX 命令に対応します。
IMAGE_REL_ARM_PAIR
0x0016
再配置は、ARM_REFHI または THUMB_REFHI の直後にある場合にのみ有効です。 その SymbolTableIndex には、シンボル テーブルへのインデックスではなく変位が含まれます。

 

ARM64 プロセッサ

ARM64 プロセッサには、次の再配置型インジケーターが定義されています。

定数 説明
IMAGE_REL_ARM64_ABSOLUTE
0x0000
再配置は無視されます。
IMAGE_REL_ARM64_ADDR32
0x0001
再配置ターゲットの 32 ビット VA。
IMAGE_REL_ARM64_ADDR32NB
0x0002
ターゲットの 32 ビット RVA。
IMAGE_REL_ARM64_BRANCH26
0x0003
ターゲットに対する 26 ビットの相対変位。B 命令と BL 命令に対応。
IMAGE_REL_ARM64_PAGEBASE_REL21
0x0004
ターゲットのページ ベース。ADRP 命令に対応。
IMAGE_REL_ARM64_REL21
0x0005
ターゲットに対する 12 ビットの相対変位。ADR 命令に対応。
IMAGE_REL_ARM64_PAGEOFFSET_12A
0x0006
ターゲットの 12 ビット ページ オフセット。ADD/ADDS 命令 (イミディエイト) (シフトなし) に対応。
IMAGE_REL_ARM64_PAGEOFFSET_12L
0x0007
ターゲットの 12 ビット ページ オフセット。LDR 命令 (インデックス付き、符号なしイミディエイト) に対応。
IMAGE_REL_ARM64_SECREL
0x0008
セクションの先頭からのターゲットの 32 ビット オフセット。 これは、デバッグ情報と静的スレッド ローカル ストレージをサポートするために使用されます。
IMAGE_REL_ARM64_SECREL_LOW12A
0x0009
ターゲットのセクション オフセットのビット 0:11。ADD/ADDS 命令 (イミディエイト) (シフトなし) に対応。
IMAGE_REL_ARM64_SECREL_HIGH12A
0x000A
ターゲットのセクション オフセットのビット 12:23。ADD/ADDS 命令 (イミディエイト) (シフトなし) に対応。
IMAGE_REL_ARM64_SECREL_LOW12L
0x000B
ターゲットのセクション オフセットのビット 0:11。LDR 命令 (インデックス付き、符号なしイミディエイト) に対応。
IMAGE_REL_ARM64_TOKEN
0x000C
CLR トークン。
IMAGE_REL_ARM64_SECTION
0x000D
ターゲットを含むセクションの 16 ビット セクション インデックス。 これは、デバッグ情報をサポートするために使用されます。
IMAGE_REL_ARM64_ADDR64
0x000E
再配置ターゲットの 64 ビット VA。
IMAGE_REL_ARM64_BRANCH19
0x000F
再配置ターゲットへの 19 ビット オフセット。条件付き B 命令に対応。
IMAGE_REL_ARM64_BRANCH14
0x0010
再配置先への 14 ビット オフセット。TBZ 命令および TBNZ 命令に対応。
IMAGE_REL_ARM64_REL32
0x0011
再配置後のバイトからの 32 ビット相対アドレス。
日立 SuperH プロセッサ

次の再配置型インジケーターが SH3 および SH4 プロセッサー用に定義されています。 SH5 固有の再配置は、SHM (SH メディア) として示されます。

定数 説明
IMAGE_REL_SH3_ABSOLUTE
0x0000
再配置は無視されます。
IMAGE_REL_SH3_DIRECT16
0x0001
ターゲット シンボルの VA を含む 16 ビット位置への参照。
IMAGE_REL_SH3_DIRECT32
0x0002
ターゲット シンボルの 32 ビット VA。
IMAGE_REL_SH3_DIRECT8
0x0003
ターゲット シンボルの VA を含む 8 ビット位置への参照。
IMAGE_REL_SH3_DIRECT8_WORD
0x0004
ターゲット シンボルの有効な 16 ビット VA を含む 8 ビット命令への参照。
IMAGE_REL_SH3_DIRECT8_LONG
0x0005
ターゲット シンボルの有効な 32 ビット VA を含む 8 ビット命令への参照。
IMAGE_REL_SH3_DIRECT4
0x0006
下位 4 ビットにターゲット シンボルの VA が含まれる 8 ビット位置への参照。
IMAGE_REL_SH3_DIRECT4_WORD
0x0007
下位 4 ビットにターゲット シンボルの有効な 16 ビット VA が含まれる 8 ビット命令への参照。
IMAGE_REL_SH3_DIRECT4_LONG
0x0008
下位 4 ビットにターゲット シンボルの有効な 32 ビット VA が含まれる 8 ビット命令への参照。
IMAGE_REL_SH3_PCREL8_WORD
0x0009
ターゲット シンボルの実効 16 ビット相対オフセットを含む 8 ビット命令への参照。
IMAGE_REL_SH3_PCREL8_LONG
0x000A
ターゲット シンボルの実効 32 ビット相対オフセットを含む 8 ビット命令への参照。
IMAGE_REL_SH3_PCREL12_WORD
0x000B
下位 12 ビットにターゲット シンボルの実効 16 ビット相対オフセットが含まれる 16 ビット命令への参照。
IMAGE_REL_SH3_STARTOF_SECTION
0x000C
ターゲット シンボルを含むセクションの VA である 32 ビットの位置への参照。
IMAGE_REL_SH3_SIZEOF_SECTION
0x000D
ターゲット シンボルを含むセクションのサイズである 32 ビットの位置への参照。
IMAGE_REL_SH3_SECTION
0x000E
ターゲットを含むセクションの 16 ビット セクション インデックス。 これは、デバッグ情報をサポートするために使用されます。
IMAGE_REL_SH3_SECREL
0x000F
セクションの先頭からのターゲットの 32 ビット オフセット。 これは、デバッグ情報と静的スレッド ローカル ストレージをサポートするために使用されます。
IMAGE_REL_SH3_DIRECT32_NB
0x0010
ターゲット シンボルの 32 ビット RVA。
IMAGE_REL_SH3_GPREL4_LONG
0x0011
GP 相対。
IMAGE_REL_SH3_TOKEN
0x0012
CLR トークン。
IMAGE_REL_SHM_PCRELPT
0x0013
longwords の現在の命令からのオフセット。 NOMODE ビットが設定されていない場合は、下位ビットの逆ビットをビット 32 に挿入して PTA または PTB を選択します。
IMAGE_REL_SHM_REFLO
0x0014
32 ビット アドレスの下位 16 ビット。
IMAGE_REL_SHM_REFHALF
0x0015
32 ビット アドレスの上位 16 ビット。
IMAGE_REL_SHM_RELLO
0x0016
相対アドレスの下位 16 ビット。
IMAGE_REL_SHM_RELHALF
0x0017
相対アドレスの上位 16 ビット。
IMAGE_REL_SHM_PAIR
0x0018
再配置は、REFHALF、RELHALF、または RELLO 再配置の直後にある場合にのみ有効です。 再配置の SymbolTableIndex フィールドには、シンボル テーブルへのインデックスではなく、変位が含まれています。
IMAGE_REL_SHM_NOMODE
0x8000
再配置はセクション モードを無視します。

 

IBM PowerPC プロセッサ

PowerPC プロセッサには、次の再配置型インジケーターが定義されています。

定数 説明
IMAGE_REL_PPC_ABSOLUTE
0x0000
再配置は無視されます。
IMAGE_REL_PPC_ADDR64
0x0001
再配置ターゲットの 64 ビット VA。
IMAGE_REL_PPC_ADDR32
0x0002
再配置ターゲットの 32 ビット VA。
IMAGE_REL_PPC_ADDR24
0x0003
ターゲットの VA の下位 24 ビット。 これは、ターゲット シンボルが絶対シンボルであり、元の値に符号拡張できる場合にのみ有効です。
IMAGE_REL_PPC_ADDR16
0x0004
ターゲットの VA の下位 16 ビット。
IMAGE_REL_PPC_ADDR14
0x0005
ターゲットの VA の下位 14 ビット。 これは、ターゲット シンボルが絶対シンボルであり、元の値に符号拡張できる場合にのみ有効です。
IMAGE_REL_PPC_REL24
0x0006
シンボルの位置に対する 24 ビット PC 相対オフセット。
IMAGE_REL_PPC_REL14
0x0007
シンボルの位置に対する 14 ビット PC 相対オフセット。
IMAGE_REL_PPC_ADDR32NB
0x000A
ターゲットの 32 ビット RVA。
IMAGE_REL_PPC_SECREL
0x000B
セクションの先頭からのターゲットの 32 ビット オフセット。 これは、デバッグ情報と静的スレッド ローカル ストレージをサポートするために使用されます。
IMAGE_REL_PPC_SECTION
0x000C
ターゲットを含むセクションの 16 ビット セクション インデックス。 これは、デバッグ情報をサポートするために使用されます。
IMAGE_REL_PPC_SECREL16
0x000F
セクションの先頭からのターゲットの 16 ビット オフセット。 これは、デバッグ情報と静的スレッド ローカル ストレージをサポートするために使用されます。
IMAGE_REL_PPC_REFHI
0x0010
ターゲットの 32 ビット VA の上位 16 ビット。 これは、完全なアドレスを読み込む 2 命令シーケンスの最初の命令に使用されます。 この再配置の直後には、再配置される場所から取得された上位 16 ビットに追加される符号付き 16 ビット変位が SymbolTableIndex に含まれる PAIR 再配置が続く必要があります。
IMAGE_REL_PPC_REFLO
0x0011
ターゲットの VA の下位 16 ビット。
IMAGE_REL_PPC_PAIR
0x0012
REFHI または SECRELHI 再配置の直後にある場合にのみ有効な再配置。 その SymbolTableIndex には、シンボル テーブルへのインデックスではなく変位が含まれます。
IMAGE_REL_PPC_SECRELLO
0x0013
セクションの先頭からのターゲットの 32 ビット オフセットの下位 16 ビット。
IMAGE_REL_PPC_GPREL
0x0015
GP レジスタに対するターゲットの 16 ビット符号付き変位。
IMAGE_REL_PPC_TOKEN
0x0016
CLR トークン。

 

Intel 386 プロセッサ

Intel 386 プロセッサおよび互換性のあるプロセッサに対して、次の再配置型インジケーターが定義されています。

定数 説明
IMAGE_REL_I386_ABSOLUTE
0x0000
再配置は無視されます。
IMAGE_REL_I386_DIR16
0x0001
サポートされていません。
IMAGE_REL_I386_REL16
0x0002
サポートされていません。
IMAGE_REL_I386_DIR32
0x0006
ターゲットの 32 ビット VA。
IMAGE_REL_I386_DIR32NB
0x0007
ターゲットの 32 ビット RVA。
IMAGE_REL_I386_SEG12
0x0009
サポートされていません。
IMAGE_REL_I386_SECTION
0x000A
ターゲットを含むセクションの 16 ビット セクション インデックス。 これは、デバッグ情報をサポートするために使用されます。
IMAGE_REL_I386_SECREL
0x000B
セクションの先頭からのターゲットの 32 ビット オフセット。 これは、デバッグ情報と静的スレッド ローカル ストレージをサポートするために使用されます。
IMAGE_REL_I386_TOKEN
0x000C
CLR トークン。
IMAGE_REL_I386_SECREL7
0x000D
ターゲットを含むセクションのベースからの 7 ビットのオフセット。
IMAGE_REL_I386_REL32
0x0014
ターゲットに対する 32 ビットの相対変位。 これにより、x86 相対分岐と呼び出し命令がサポートされます。

 

Intel Itanium プロセッサ ファミリ (IPF)

次の再配置型インジケーターは、Intel Itanium プロセッサ ファミリおよび互換プロセッサ用に定義されています。 命令の再配置では、バンドルのオフセットと再配置オフセットのスロット番号が使用されることに注意してください。

定数 説明
IMAGE_REL_IA64_ABSOLUTE
0x0000
再配置は無視されます。
IMAGE_REL_IA64_IMM14
0x0001
命令の再配置の後に ADDEND 再配置を続けることができ、その値は IMM14 バンドルの指定されたスロットに挿入される前にターゲット アドレスに追加されます。 再配置先は絶対であるか、イメージを固定する必要があります。
IMAGE_REL_IA64_IMM22
0x0002
命令の再配置の後に ADDEND 再配置を続けることができ、その値は IMM22 バンドルの指定されたスロットに挿入される前にターゲット アドレスに追加されます。 再配置先は絶対であるか、イメージを固定する必要があります。
IMAGE_REL_IA64_IMM64
0x0003
この再配置のスロット番号は (1) である必要があります。 再配置の後に ADDEND 再配置を続けることができ、その値は IMM64 バンドルの 3 つのスロットすべてに格納される前にターゲット アドレスに追加されます。
IMAGE_REL_IA64_DIR32
0x0004
ターゲットの 32 ビット VA。 これは、/LARGEADDRESSAWARE:NO イメージでのみサポートされます。
IMAGE_REL_IA64_DIR64
0x0005
ターゲットの 64 ビット VA。
IMAGE_REL_IA64_PCREL21B
0x0006
命令は、16 ビットのアラインされたターゲットに対する 25 ビットの相対変位で固定されます。 変位の下位 4 ビットはゼロであり、格納されません。
IMAGE_REL_IA64_PCREL21M
0x0007
命令は、16 ビットのアラインされたターゲットに対する 25 ビットの相対変位で固定されます。 変位の下位 4 ビットはゼロであり、格納されません。
IMAGE_REL_IA64_PCREL21F
0x0008
この再配置のオフセットの LSB にはスロット番号を含める必要があります。残りはバンドル アドレスです。 バンドルは、16 ビットのアラインされたターゲットに対する 25 ビットの相対変位で固定されます。 変位の下位 4 ビットはゼロであり、格納されません。
IMAGE_REL_IA64_GPREL22
0x0009
命令の再配置の後には、値がターゲット アドレスに追加される ADDEND 再配置が続き、その後、22 ビットの GP 相対オフセットが計算されて GPREL22 バンドルに適用されます。
IMAGE_REL_IA64_LTOFF22
0x000A
この命令は、ターゲット シンボルのリテラル テーブル エントリへの 22 ビット GP 相対オフセットで固定されます。 リンカーは、この再配置とそれに続く ADDEND 再配置に基づいて、このリテラル テーブル エントリを作成します。
IMAGE_REL_IA64_SECTION
0x000B
ターゲットを含むセクションの 16 ビット セクション インデックス。 これは、デバッグ情報をサポートするために使用されます。
IMAGE_REL_IA64_SECREL22
0x000C
命令は、セクションの先頭からターゲットの 22 ビット オフセットで固定されます。 この再配置の直後に ADDEND 再配置を続けることができます。ADDEND 再配置の値フィールドには、セクションの先頭からのターゲットの 32 ビット符号なしオフセットが含まれます。
IMAGE_REL_IA64_SECREL64I
0x000D
この再配置のスロット番号は (1) である必要があります。 命令は、セクションの先頭からターゲットの 64 ビット オフセットで固定されます。 この再配置の直後に ADDEND 再配置を続けることができます。ADDEND 再配置の値フィールドには、セクションの先頭からのターゲットの 32 ビット符号なしオフセットが含まれます。
IMAGE_REL_IA64_SECREL32
0x000E
セクションの先頭からターゲットの 32 ビット オフセットで固定されるデータのアドレス。
IMAGE_REL_IA64_DIR32NB
0x0010
ターゲットの 32 ビット RVA。
IMAGE_REL_IA64_SREL14
0x0011
これは、2 つの再配置可能なターゲットの違いを含む符号付き 14 ビット イミディエイトに適用されます。 これは、コンパイラがこの値を既に出力していることを示すリンカーの宣言型フィールドです。
IMAGE_REL_IA64_SREL22
0x0012
これは、2 つの再配置可能なターゲットの違いを含む符号付き 22 ビット イミディエイトに適用されます。 これは、コンパイラがこの値を既に出力していることを示すリンカーの宣言型フィールドです。
IMAGE_REL_IA64_SREL32
0x0013
これは、2 つの再配置可能な値の違いを含む符号付き 32 ビット イミディエイトに適用されます。 これは、コンパイラがこの値を既に出力していることを示すリンカーの宣言型フィールドです。
IMAGE_REL_IA64_UREL32
0x0014
これは、2 つの再配置可能な値の差を含む符号なし 32 ビット イミディエイトに適用されます。 これは、コンパイラがこの値を既に出力していることを示すリンカーの宣言型フィールドです。
IMAGE_REL_IA64_PCREL60X
0x0015
MLX バンドルの BRL 命令として常に残る 60 ビットの PC 相対フィックスアップ。
IMAGE_REL_IA64_PCREL60B
0x0016
60 ビット PC 相対フィックスアップ。 ターゲット変位が符号付き 25 ビット フィールドに収まる場合は、バンドル全体を、スロット 1 に NOP.B があり、スロット 2 に 25 ビット BR 命令 (最下位 4 ビットがすべてゼロであり削除される) を含む MBB バンドルに変換します。
IMAGE_REL_IA64_PCREL60F
0x0017
60 ビット PC 相対フィックスアップ。 ターゲット変位が符号付き 25 ビット フィールドに収まる場合は、バンドル全体を、スロット 1 に NOP.F があり、スロット 2 に 25 ビット BR 命令 (最下位 4 ビットがすべてゼロであり削除される) を含む MFB バンドルに変換します。
IMAGE_REL_IA64_PCREL60I
0x0018
60 ビット PC 相対フィックスアップ。 ターゲット変位が符号付き 25 ビット フィールドに収まる場合は、バンドル全体を、スロット 1 に NOP.I があり、スロット 2 に 25 ビット BR 命令 (最下位 4 ビットがすべてゼロであり削除される) を含む MIB バンドルに変換します。
IMAGE_REL_IA64_PCREL60M
0x0019
60 ビット PC 相対フィックスアップ。 ターゲット変位が符号付き 25 ビット フィールドに収まる場合は、バンドル全体を、スロット 1 に NOP.M があり、スロット 2 に 25 ビット BR 命令 (最下位 4 ビットがすべてゼロであり削除される) を含む MMB バンドルに変換します。
IMAGE_REL_IA64_IMMGPREL64
0x001a
64 ビットの GP 相対フィックスアップ。
IMAGE_REL_IA64_TOKEN
0x001b
CLR トークン。
IMAGE_REL_IA64_GPREL32
0x001c
32 ビットの GP 相対フィックスアップ。
IMAGE_REL_IA64_ADDEND
0x001F
再配置は、IMM14、IMM22、IMM64、GPREL22、LTOFF22、LTOFF64、SECREL22、SECREL64I、または SECREL32 のいずれかの再配置の直後にある場合にのみ有効です。 その値には、データではなく、バンドル内の命令に適用する追加要素が含まれています。

 

MIPS プロセッサ

MIPS プロセッサには、次の再配置型インジケーターが定義されています。

定数 説明
IMAGE_REL_MIPS_ABSOLUTE
0x0000
再配置は無視されます。
IMAGE_REL_MIPS_REFHALF
0x0001
ターゲットの 32 ビット VA の上位 16 ビット。
IMAGE_REL_MIPS_REFWORD
0x0002
ターゲットの 32 ビット VA。
IMAGE_REL_MIPS_JMPADDR
0x0003
ターゲットの VA の下位 26 ビット。 これにより、MIPS J 命令と JAL 命令がサポートされます。
IMAGE_REL_MIPS_REFHI
0x0004
ターゲットの 32 ビット VA の上位 16 ビット。 これは、完全なアドレスを読み込む 2 命令シーケンスの最初の命令に使用されます。 この再配置の直後には、再配置される場所から取得された上位 16 ビットに追加される符号付き 16 ビット変位が SymbolTableIndex に含まれる PAIR 再配置が続く必要があります。
IMAGE_REL_MIPS_REFLO
0x0005
ターゲットの VA の下位 16 ビット。
IMAGE_REL_MIPS_GPREL
0x0006
GP レジスタに対するターゲットの 16 ビット符号付き変位。
IMAGE_REL_MIPS_LITERAL
0x0007
IMAGE_REL_MIPS_GPREL と同じです。
IMAGE_REL_MIPS_SECTION
0x000A
ターゲットを含むセクションの 16 ビット セクション インデックス。 これは、デバッグ情報をサポートするために使用されます。
IMAGE_REL_MIPS_SECREL
0x000B
セクションの先頭からのターゲットの 32 ビット オフセット。 これは、デバッグ情報と静的スレッド ローカル ストレージをサポートするために使用されます。
IMAGE_REL_MIPS_SECRELLO
0x000C
セクションの先頭からのターゲットの 32 ビット オフセットの下位 16 ビット。
IMAGE_REL_MIPS_SECRELHI
0x000D
セクションの先頭からのターゲットの 32 ビット オフセットの上位 16 ビット。 IMAGE_REL_MIPS_PAIR 再配置は、この後すぐに行う必要があります。 PAIR 再配置の SymbolTableIndex には、再配置される場所から取得された上位 16 ビットに追加される符号付き 16 ビット変位が含まれます。
IMAGE_REL_MIPS_JMPADDR16
0x0010
ターゲットの VA の下位 26 ビット。 MIPS16 JAL 命令に対応しています。
IMAGE_REL_MIPS_REFWORDNB
0x0022
ターゲットの 32 ビット RVA。
IMAGE_REL_MIPS_PAIR
0x0025
REFHI または SECRELHI 再配置の直後にある場合にのみ有効な再配置。 その SymbolTableIndex には、シンボル テーブルへのインデックスではなく変位が含まれます。

 

三菱 M32R

三菱 M32R プロセッサには、次の再配置型インジケーターが定義されています。

定数 説明
IMAGE_REL_M32R_ABSOLUTE
0x0000
再配置は無視されます。
IMAGE_REL_M32R_ADDR32
0x0001
ターゲットの 32 ビット VA。
IMAGE_REL_M32R_ADDR32NB
0x0002
ターゲットの 32 ビット RVA。
IMAGE_REL_M32R_ADDR24
0x0003
ターゲットの 24 ビット VA。
IMAGE_REL_M32R_GPREL16
0x0004
GP レジスタからのターゲットの 16 ビット オフセット。
IMAGE_REL_M32R_PCREL24
0x0005
プログラム カウンタ (PC) からのターゲットの 24 ビット オフセット。2 ビット左にシフトされ、符号拡張されます
IMAGE_REL_M32R_PCREL16
0x0006
PC からのターゲットの 16 ビット オフセット。2 ビット左にシフトされ、符号拡張されます
IMAGE_REL_M32R_PCREL8
0x0007
PC からのターゲットの 8 ビット オフセット。2 ビット左にシフトされ、符号拡張されます
IMAGE_REL_M32R_REFHALF
0x0008
ターゲット VA の 16 MSB。
IMAGE_REL_M32R_REFHI
0x0009
LSB 符号拡張用に調整されたターゲット VA の 16 MSB。 これは、完全な 32 ビット アドレスを読み込む 2 命令シーケンスの最初の命令に使用されます。 この再配置の直後には、再配置される場所から取得された上位 16 ビットに追加される符号付き 16 ビット変位が SymbolTableIndex に含まれる PAIR 再配置が続く必要があります。
IMAGE_REL_M32R_REFLO
0x000A
ターゲット VA の 16 LSB。
IMAGE_REL_M32R_PAIR
0x000B
再配置は、REFHI 再配置の後に続く必要があります。 その SymbolTableIndex には、シンボル テーブルへのインデックスではなく変位が含まれます。
IMAGE_REL_M32R_SECTION
0x000C
ターゲットを含むセクションの 16 ビット セクション インデックス。 これは、デバッグ情報をサポートするために使用されます。
IMAGE_REL_M32R_SECREL
0x000D
セクションの先頭からのターゲットの 32 ビット オフセット。 これは、デバッグ情報と静的スレッド ローカル ストレージをサポートするために使用されます。
IMAGE_REL_M32R_TOKEN
0x000E
CLR トークン。

 

COFF 行番号 (非推奨)

COFF 行番号は生成されなくなり、将来的には使用されなくなります。

COFF 行番号は、ソース ファイル内のコードと行番号の関係を示します。 COFF 行番号の Microsoft 形式は標準の COFF に似ていますが、1 つのセクションを複数のソース ファイルの行番号に関連付けることができるように拡張されています。

COFF 行番号は、固定長レコードの配列で構成されます。 配列の場所 (ファイル オフセット) とサイズは、セクション ヘッダーで指定します。 各行番号レコードの形式は次のとおりです。

オフセット サイズ フィールド 説明
0
4
型 (*)
これは、SymbolTableIndex と VirtualAddress の 2 つのフィールドの和集合です。 SymbolTableIndex と RVA のどちらを使用するかは、Linenumber の値によって異なります。
4
2
Linenumber
0 以外の場合、このフィールドは 1 から始まる行番号を指定します。 0 の場合、型フィールドは関数のシンボル テーブル インデックスとして解釈されます。

 

型フィールドは、SymbolTableIndex と VirtualAddress の 2 つの 4 バイト フィールドの和集合です。

オフセット サイズ フィールド 説明
0
4
SymbolTableIndex
Linenumber が 0 の場合に使用されます。関数のテーブル エントリをシンボル化するためのインデックスです。 この形式は、行番号レコードのグループが参照する関数を示すために使用されます。
0
4
VirtualAddress
Linenumber が 0 以外の場合に使用されます。指定されたソース行に対応する実行可能コードの RVA。 オブジェクト ファイルには、セクション内の VA が含まれます。

 

行番号レコードは、Linenumber フィールドを 0 に設定してシンボル テーブル内の関数定義をポイントすることも、正の整数 (行番号) とオブジェクト コード内の対応するアドレスを指定することによって標準の行番号エントリとして機能することもできます。

行番号エントリのグループは、常に最初の形式 (関数シンボルのインデックス) で始まります。 これがセクション内の最初の行番号レコードである場合、セクションの COMDAT フラグが設定されている場合、これは関数の COMDAT シンボル名でもあります。 「COMDAT セクション (オブジェクトのみ)」を参照してください。 シンボル テーブル内の関数の補助レコードには、これと同じ行番号レコードを指す Linenumber フィールドへのポインターがあります。

関数を識別するレコードの後には、実際の行番号情報を提供する任意の数の行番号エントリ (つまり、Linenumber が 0 より大きいエントリ) が続きます。 これらのエントリは、関数の先頭を基準にして 1 から始まり、最初の行を除く関数内のすべてのソース行を表します。

たとえば、次の例の最初の行番号レコードは、ReverseSign 関数 (ReverseSign の SymbolTableIndex と Linenumber が 0 に設定) を指定します。 次に、Linenumber の値が 1、2、3 のレコードが続き、次に示すようにソース行に対応します。

// some code precedes ReverseSign function
int ReverseSign(int i)
1: {
2:  return -1 * i;
3: }

COFF シンボル テーブル

このセクションのシンボル テーブルは、従来の COFF 形式から継承されます。 Microsoft Visual C++ のデバッグ情報とは異なります。 ファイルには、COFF シンボル テーブルと Visual C++ デバッグ情報の両方を含めることができます。これら 2 つは別々に保持されます。 一部の Microsoft ツールは、COMDAT 情報をリンカーに伝達するなど、限られた重要な目的でシンボル テーブルを使用します。 セクション名とファイル名、およびコード シンボルとデータ シンボルは、シンボル テーブルに一覧表示されます。

シンボル テーブルの場所は、COFF ヘッダーに示されます。

シンボル テーブルはレコードの配列であり、各長さは 18 バイトです。 各レコードは、標準または補助シンボル/テーブル レコードです。 標準レコードはシンボルまたは名前を定義し、次の形式を持っています。

オフセット サイズ フィールド 説明
0
8
名前 (*)
3 つの構造体の和集合で表されるシンボルの名前。 名前の長さが 8 バイト以下の場合は、8 バイトの配列が使用されます。 詳細については、「シンボル名の表現」を参照してください。
8
4

シンボルに関連付けられた値。 このフィールドの解釈は、SectionNumber と StorageClass によって異なります。 一般的な意味は、再配置可能なアドレスです。
12
2
SectionNumber
セクション テーブルへの 1 から始まるインデックスを使用して、セクションを識別する符号付き整数。 セクション 5.4.2「セクション番号値」で定義されているように、一部の値には特別な意味があります。
14
2

型を表す数値。 Microsoft ツールでは、このフィールドを 0x20 (関数) または0x0 (関数ではない) に設定します。 詳細については、「型の表現」を参照してください。
16
1
StorageClass
ストレージ クラスを表す列挙値。 詳細については、ストレージ クラスに関する記事をご覧ください。
17
1
NumberOfAuxSymbols
このレコードに続く補助シンボル テーブル項目の数。

 

0 個以上の補助シンボル テーブル レコードは、各標準シンボル テーブル レコードのすぐ後に続きます。 ただし、通常、標準のシンボル テーブル レコードの後に続く補助シンボル テーブル レコードは複数存在しません (ファイル名が長い .file レコードを除く)。 各補助レコードは標準シンボル テーブル レコード (18 バイト) と同じサイズですが、新しいシンボルを定義するのではなく、最後に定義されたシンボルに関する追加情報を提供します。 使用する形式は、StorageClass フィールドによって異なります。 補助シンボル テーブル レコードの現在定義されている形式は、「補助シンボル レコード」セクション 5.5 に示されています。

COFF シンボル テーブルを読み取るツールでは、解釈が不明な補助シンボル レコードを無視する必要があります。 これにより、シンボル テーブル形式を拡張して、既存のツールを中断することなく、新しい補助レコードを追加できます。

シンボル名表現

シンボル テーブルの ShortName フィールドは、長さが 8 バイト以下の場合、名前自体を含む 8 バイトで構成されます。または、ShortName フィールドが文字列テーブルへのオフセットを与えます。 名前自体またはオフセットが指定されているかどうかを判断するには、最初の 4 バイトで 0 に等しいかどうかをテストします。

慣例により、名前は 0 で終わる UTF-8 でエンコードされた文字列として扱われます。

オフセット サイズ フィールド 説明
0
8
ShortName
8 バイトの配列。 名前の長さが 8 バイト未満の場合、この配列は右側に null で埋め込まれます。
0
4
0
名前が 8 バイトを超える場合、すべての 0 に設定されるフィールド。
4
4
オフセット
文字列テーブルへのオフセット。

 

セクション番号の値

通常、シンボル テーブル エントリの Section Value フィールドは、セクション テーブルへの 1 から始まるインデックスです。 ただし、このフィールドは符号付き整数であり、負の値を取ることができます。 次の値は 1 未満で、特別な意味を持ちます。

定数 説明
IMAGE_SYM_UNDEFINED
0
シンボル レコードにはセクションがまだ割り当てられません。 値 0 は、外部シンボルへの参照が他の場所で定義されていることを示します。 0 以外の値は、値で指定されたサイズを持つ共通シンボルです。
IMAGE_SYM_ABSOLUTE
1-
シンボルには絶対 (再割り当て不可) 値があり、アドレスではありません。
IMAGE_SYM_DEBUG
2-
シンボルは、一般的な型またはデバッグ情報を提供しますが、セクションには対応していません。 Microsoft ツールでは、この設定を .file レコード (ストレージ クラス FILE) と共に使用します。

 

型の表現

シンボル テーブル エントリの Type フィールドには 2 バイトが含まれています。各バイトは型情報を表します。 LSB は単純 (基本) データ型を表し、MSB は複合型 (存在する場合) を表します。

MSB LSB
複合型: none、pointer、function、array。
基本型: 整数、浮動小数点など。

 

基本型には次の値が定義されていますが、Microsoft ツールでは通常、このフィールドを使用せず、LSB を 0 に設定します。 代わりに、Visual C++ デバッグ情報を使用して型を示します。 ただし、完成度を高める目的で、可能な COFF 値を次に示します。

定数 説明
IMAGE_SYM_TYPE_NULL
0
型情報または不明な基本型はありません。 Microsoft ツールでは、この設定を使用します
IMAGE_SYM_TYPE_VOID
1
有効な型がありません。void ポインターと関数と共に使用されます
IMAGE_SYM_TYPE_CHAR
2
文字 (符号付きバイト)
IMAGE_SYM_TYPE_SHORT
3
2 バイト符号付き整数
IMAGE_SYM_TYPE_INT
4
自然な整数型 (通常、Windows では 4 バイト)
IMAGE_SYM_TYPE_LONG
5
4 バイト符号付き整数
IMAGE_SYM_TYPE_FLOAT
6
4 バイトの浮動小数点数
IMAGE_SYM_TYPE_DOUBLE
7
8 バイトの浮動小数点数
IMAGE_SYM_TYPE_STRUCT
8
構造
IMAGE_SYM_TYPE_UNION
9
和集合
IMAGE_SYM_TYPE_ENUM
10
列挙型
IMAGE_SYM_TYPE_MOE
11
列挙体のメンバー (特定の値)
IMAGE_SYM_TYPE_BYTE
12
バイト、符号なし 1 バイト整数
IMAGE_SYM_TYPE_WORD
13
単語、符号なし 2 バイト整数
IMAGE_SYM_TYPE_UINT
14
自然サイズの符号なし整数 (通常は 4 バイト)
IMAGE_SYM_TYPE_DWORD
15
4 バイトの符号なし整数

 

最上位バイトは、シンボルが LSB で指定された基本型のポインター、関数を返す、または配列であるかどうかを指定します。 Microsoft ツールは、シンボルが関数であるかどうかを示すためにのみこのフィールドを使用するため、結果として得られる値は Type フィールドの 0x0 と 0x20 の 2 つだけです。 ただし、他のツールでは、このフィールドを使用して詳細情報を伝えることができます。

関数属性を正しく指定することは非常に重要です。 この情報は、インクリメンタル リンクが正しく機能するために必要です。 アーキテクチャによっては、他の目的で情報が必要になる場合があります。

定数 説明
IMAGE_SYM_DTYPE_NULL
0
派生型がありません。シンボルは単純なスカラー変数です。
IMAGE_SYM_DTYPE_POINTER
1
シンボルは基本型へのポインターです。
IMAGE_SYM_DTYPE_FUNCTION
2
シンボルは、基本型を返す関数です。
IMAGE_SYM_DTYPE_ARRAY
3
シンボルは基本型の配列です。

 

ストレージ クラス

シンボル テーブルの StorageClass フィールドは、シンボルが表す定義の種類を示します。 指定可能な値を次の表に示します。 StorageClass フィールドは符号なし 1 バイト整数であることに注意してください。 したがって、特殊な値 -1 は、符号なし等価の 0xFF を意味する必要があります。

従来の COFF 形式では多くのストレージ クラス値が使用されますが、Microsoft ツールはほとんどのシンボリック情報について Visual C++ デバッグ形式に依存しており、通常は EXTERNAL (2)、STATIC (3)、FUNCTION (101)、および ファイル (103) の 4 つのストレージ クラス値のみを使用します。 以下の 2 番目の列の見出しを除き、「値」はシンボル レコードの値フィールドを意味すると解釈してください (解釈はストレージ クラスとして見つかった数値によって異なります)。

定数 Value Value フィールドの説明/解釈
IMAGE_SYM_CLASS_END_OF_FUNCTION
-1 (0xFF)
デバッグ目的で、関数の終了を表す特別なシンボル。
IMAGE_SYM_CLASS_NULL
0
割り当てられたストレージ クラスがありません。
IMAGE_SYM_CLASS_AUTOMATIC
1
自動 (スタック) 変数。 Value フィールドは、スタック フレームオフセットを指定します。
IMAGE_SYM_CLASS_EXTERNAL
2
Microsoft ツールが外部シンボルに使用する値。 Value フィールドは、セクション番号が IMAGE_SYM_UNDEFINED (0) の場合のサイズを示します。 セクション番号が 0 でない場合、Value フィールドはセクション内のオフセットを指定します。
IMAGE_SYM_CLASS_STATIC
3
断面図内のシンボルのオフセット。 Value フィールドが 0 の場合、記号はセクション名を表します。
IMAGE_SYM_CLASS_REGISTER
4
レジスタ変数。 Value フィールドはレジスタ番号を指定します。
IMAGE_SYM_CLASS_EXTERNAL_DEF
5
外部で定義されているシンボル。
IMAGE_SYM_CLASS_LABEL
6
モジュール内で定義されているコード ラベル。 Value フィールドは、セクション内のシンボルのオフセットを指定します。
IMAGE_SYM_CLASS_UNDEFINED_LABEL
7
定義されていないコード ラベルへの参照。
IMAGE_SYM_CLASS_MEMBER_OF_STRUCT
8
構造体のメンバー。 Value フィールドは n 番目のメンバーを指定します。
IMAGE_SYM_CLASS_ARGUMENT
9
関数の仮引数 (パラメーター)。 Value フィールドは n 番目の引数を指定します。
IMAGE_SYM_CLASS_STRUCT_TAG
10
構造体タグ名エントリ。
IMAGE_SYM_CLASS_MEMBER_OF_UNION
11
共用体メンバー。 Value フィールドは n 番目のメンバーを指定します。
IMAGE_SYM_CLASS_UNION_TAG
12
共用体タグ名エントリ。
IMAGE_SYM_CLASS_TYPE_DEFINITION
13
Typedef エントリ。
IMAGE_SYM_CLASS_UNDEFINED_STATIC
14
静的データ宣言。
IMAGE_SYM_CLASS_ENUM_TAG
15
列挙型のタグ名エントリ。
IMAGE_SYM_CLASS_MEMBER_OF_ENUM
16
列挙体のメンバー。 Value フィールドは n 番目のメンバーを指定します。
IMAGE_SYM_CLASS_REGISTER_PARAM
17
レジスタ パラメーター。
IMAGE_SYM_CLASS_BIT_FIELD
18
ビット フィールド参照。 Value フィールドは、ビット フィールド内の n 番目のビットを指定します。
IMAGE_SYM_CLASS_BLOCK
100
.bb (ブロックの先頭) または .eb (ブロックの終わり) レコード。 Value フィールドは、コードの場所の再配置可能なアドレスです。
IMAGE_SYM_CLASS_FUNCTION
101
Microsoft ツールが関数の範囲を定義するシンボル レコードに使用する値: begin function (.bf)、end function (.ef)、および関数内の行 (.lf)。 .lf レコードの場合、Value フィールドには関数内のソース行の数が表示されます。 .ef レコードの場合、Value フィールドには関数コードのサイズが表示されます。
IMAGE_SYM_CLASS_END_OF_STRUCT
102
構造の終わりのエントリ。
IMAGE_SYM_CLASS_FILE
103
Microsoft が従来の COFF 形式と同様に、ソース ファイルのシンボル レコードに使用する値。 シンボルの後に、ファイルに名前を付けた補助レコードが続きます。
IMAGE_SYM_CLASS_SECTION
104
セクションの定義 (Microsoft ツールでは代わりに STATIC ストレージ クラスを使用します)。
IMAGE_SYM_CLASS_WEAK_EXTERNAL
105
弱い外部。 詳細については、「補助フォーマット 3: 弱い外部」を参照してください。
IMAGE_SYM_CLASS_CLR_TOKEN
107
CLR トークン シンボル。 この名前は、トークンの 16 進値で構成される ASCII 文字列です。 詳細については、「CLR トークン定義 (オブジェクトのみ)」を参照してください。

 

補助記号レコード

補助シンボル テーブル レコードは、常に標準シンボル テーブル レコードに従って適用されます。 補助レコードには、ツールが認識できる任意の形式を指定できますが、シンボル テーブルが通常のサイズの配列として維持されるように、補助レコードに 18 バイトを割り当てる必要があります。 現在、Microsoft ツールは、関数定義、関数の開始記号と終了記号 (.bf および .ef)、弱い外部ファイル、ファイル名、およびセクション定義の種類のレコードの補助形式を認識します。

従来の COFF 設計には、配列と構造体の補助レコード形式も含まれています。 Microsoft ツールはこれらを使用せず、代わりにそのシンボリック情報を Visual C++ デバッグ形式でデバッグ セクションに配置します。

補助形式 1: 関数定義

シンボル テーブル レコードは、EXTERNAL (2) のストレージ クラス、関数であることを示す Type 値 (0x20)、および 0 より大きいセクション番号をすべて備えている場合、関数定義の開始をマークします。 セクション番号が UNDEFINED (0) のシンボル テーブル レコードは関数を定義しておらず、補助レコードも持たないことに注意してください。 関数定義シンボル レコードの後には、次に説明する形式の補助レコードが続きます。

オフセット サイズ フィールド 説明
0
4
TagIndex
対応する .bf (begin 関数) シンボル レコードのシンボル テーブル インデックス。
4
4
TotalSize
関数自体の実行可能コードのサイズ。 関数が独自のセクションにある場合、セクション ヘッダーの SizeOfRawData は、配置の考慮事項に応じて、このフィールド以上になります。
8
4
PointerToLinenumber
関数の最初の COFF 行番号エントリのファイル オフセット。存在しない場合は 0。 詳細については、「COFF 行番号 (非推奨)」を参照してください。
12
4
PointerToNextFunction
次の関数のレコードのシンボル テーブル インデックス。 関数がシンボル テーブルの最後の場合、このフィールドは 0 に設定されます。
16
2
未使用

 

補助形式 2: .bf および .ef 記号

シンボル テーブル内の各関数定義について、3 つの項目で開始、終了、および行数が記述されます。 これらのシンボルにはそれぞれ、ストレージ クラス FUNCTION (101) があります。

.bf (begin 関数) という名前のシンボル レコード。 Value フィールドは未使用です。

.lf という名前のシンボル レコード (関数内の行)。 Value フィールドには、関数内の行数が表示されます。

.ef (関数の末尾) という名前のシンボル レコード。 Value フィールドの数値は、関数定義シンボル レコードの Total Size フィールドと同じです。

.bf および .ef シンボル レコード (.lf レコードではない) の後に、次の形式の補助レコードが続きます。

オフセット サイズ フィールド 説明
0
4
未使用
4
2
Linenumber
.bf または .ef レコードに対応するソース ファイル内の実際の序数 (1、2、3 など)。
6
6
未使用
12
4
PointerToNextFunction (.bf のみ)
次の .bf シンボル レコードのシンボル テーブル インデックス。 関数がシンボル テーブルの最後の場合、このフィールドは 0 に設定されます。 .ef レコードには使用されません。
16
2
未使用

 

補助フォーマット 3: 弱い外部

「弱い外部」は、リンク時の柔軟性を可能にするオブジェクト ファイルのメカニズムです。 モジュールには未解決の外部シンボル (sym1) を含めることができますが、リンク時に sym1 が存在しない場合、代わりに別の外部シンボル (sym2) を使用して参照を解決することを示す補助レコードを含めることもできます。

sym1 の定義がリンクされている場合、シンボルへの外部参照は通常どおりに解決されます。 sym1 の定義がリンクされていない場合、sym1 の弱い外部へのすべての参照は代わりに sym2 を参照します。 外部シンボル sym2 は常にリンクされている必要があります。通常は、sym1 への弱い参照を含むモジュールで定義されます。

弱い外部は、EXTERNAL ストレージ クラス、UNDEF セクション番号、および 0 の値を持つシンボル テーブル レコードによって表されます。 弱外部シンボル レコードの後に、次の形式の補助レコードが続きます。

オフセット サイズ フィールド 説明
0
4
TagIndex
sym2 のシンボル テーブル インデックス。sym1 が見つからない場合にリンクされるシンボル。
4
4
特性
IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY の値は、sym1 のライブラリ検索を実行する必要がないことを示します。
IMAGE_WEAK_EXTERN_SEARCH_LIBRARY の値は、sym1 のライブラリ検索を実行する必要があることを示します。
IMAGE_WEAK_EXTERN_SEARCH_ALIAS の値は、sym1 が sym2 のエイリアスであることを示します。
8
10
未使用

 

特性フィールドは WINNT.H で定義されていないことに注意してください。代わりに、Total Size フィールドが使用されます。

補助形式 4: ファイル

この形式は、ストレージ クラス FILE (103) のシンボル テーブル レコードに従います。 シンボル名自体は .file である必要があり、それに続く補助レコードはソース コード ファイルの名前を示します。

オフセット サイズ フィールド 説明
0
18
File Name
ソース ファイルの名前を指定する ANSI 文字列。 これは、最大長より小さい場合は null で埋め込まれます。

 

補助形式 5: セクション定義

この形式は、セクションを定義するシンボル テーブル レコードに従います。 このようなレコードには、セクションの名前であるシンボル名 (.text や .drectve など) があり、ストレージ クラス STATIC (3) があります。 補助レコードは、それが参照するセクションに関する情報を提供します。 したがって、セクション ヘッダーの情報の一部が複製されます。

オフセット サイズ フィールド 説明
0
4
長さ
セクション データのサイズ。セクション ヘッダーの SizeOfRawData と同じです。
4
2
NumberOfRelocations
セクションの再配置エントリの数。
6
2
NumberOfLinenumbers
セクションの行番号エントリの数。
8
4
CheckSum
共同データのチェック数。 セクション ヘッダーに IMAGE_SCN_LNK_COMDAT フラグが設定されている場合に適用されます。 詳細については、「COMDAT セクション (オブジェクトのみ)」を参照してください。
12
2
番号
関連付けられているセクションのセクション テーブルへの 1 から始まるインデックス。 これは、COMDAT の選択設定が 5 の場合に使用されます。
14
1
選択(S)
COMDAT の選択番号。 これは、セクションが COMDAT セクションの場合に適用されます。
15
3
未使用

 

COMDAT セクション (オブジェクトのみ)

セクション定義補助形式の選択フィールドは、セクションが COMDAT セクションの場合に適用できます。 COMDAT セクションは、複数のオブジェクト ファイルで定義できるセクションです。 (フラグ IMAGE_SCN_LNK_COMDAT は、セクション ヘッダーの Section Flags フィールドに設定されます。) 選択フィールドは、リンカーが COMDAT セクションの複数の定義を解決する方法を決定します。

COMDAT セクションのセクション値を持つ最初のシンボルは、セクションシンボルである必要があります。 このシンボルには、セクションの名前、0 に等しい Value フィールド、問題の COMDAT セクションのセクション番号、IMAGE_SYM_TYPE_NULL に等しい Type フィールド、IMAGE_SYM_CLASS_STATIC に等しい Class フィールド、および 1 つの補助レコードがあります。 2 番目のシンボルは「COMDAT シンボル」と呼ばれ、リンカーによって選択フィールドと組み合わせて使用されます。

選択フィールドの値を次に示します。

定数 説明
IMAGE_COMDAT_SELECT_NODUPLICATES
1
このシンボルが既に定義されている場合、リンカーは「定義されたシンボルの乗算」エラーを発行します。
IMAGE_COMDAT_SELECT_ANY
2
同じ COMDAT シンボルを定義する任意のセクションをリンクできます。残りは削除されます。
IMAGE_COMDAT_SELECT_SAME_SIZE
3
リンカーは、このシンボルの定義の中から任意のセクションを選択します。 すべての定義が同じサイズでない場合は、「定義されたシンボルの乗算」エラーが発行されます。
IMAGE_COMDAT_SELECT_EXACT_MATCH
4
リンカーは、このシンボルの定義の中から任意のセクションを選択します。 すべての定義が完全に一致しない場合は、「定義されたシンボルの乗算」エラーが発行されます。
IMAGE_COMDAT_SELECT_ASSOCIATIVE
5
特定の他の COMDAT セクションがリンクされている場合、セクションはリンクされます。 この他のセクションは、セクション定義の補助記号レコードの Number フィールドで示されます。 この設定は、複数のセクションにコンポーネントがある定義 (たとえば、あるセクションにコード、別のセクションにデータ) があり、すべてをセットとしてリンクまたは破棄する必要がある場合に便利です。 このセクションに関連付けられているもう 1 つのセクションは COMDAT セクションである必要があります。これは、もう 1 つの連想 COMDAT セクションである可能性があります。 連想 COMDAT セクションのセクション関連付けチェーンはループを形成できません。 セクションの関連付けチェーンは、最終的に、IMAGE_COMDAT_Standard Edition LECT_ASSOCIATIVE が設定されていない COMDAT セクションに来る必要があります。
IMAGE_COMDAT_SELECT_LARGEST
6
リンカーは、このシンボルのすべての定義の中から最大の定義を選択します。 複数の定義にこのサイズが設定されている場合、それらの定義の選択は任意です。

 

CLR トークン定義 (オブジェクトのみ)

この補助記号は、一般に IMAGE_SYM_CLASS_CLR_TOKEN に従います。 トークンを COFF シンボル テーブルの名前空間に関連付けるために使用されます。

オフセット サイズ フィールド 説明
0
1
bAuxType
IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF (1) にする必要があります。
1
1
bReserved
予約済み、0 でなければなりません。
2
4
SymbolTableIndex
この CLR トークン定義が参照する COFF シンボルのシンボル インデックス。
6
12
予約済み、0 でなければなりません。

 

COFF 文字列テーブル

COFF シンボル テーブルの直後に、COFF 文字列テーブルがあります。 このテーブルの位置は、COFF ヘッダー内のシンボル テーブル アドレスを取得し、シンボルの数とシンボルのサイズを掛け合わせた値を加算することによって求められます。

COFF 文字列テーブルの先頭には、文字列テーブルの残りの部分の合計サイズ (バイト単位) を含む 4 バイトがあります。 このサイズには size フィールド自体が含まれているため、文字列が存在しない場合、この場所の値は 4 になります。

サイズの後には、COFF シンボル テーブル内のシンボルが指す null 終了文字列が続きます。

属性証明書テーブル (イメージのみ)

属性証明書テーブルを追加することで、属性証明書をイメージに関連付けることができます。 属性証明書テーブルは、クワッドワードでアラインされた連続した属性証明書エントリのセットで構成されます。 この位置合わせを実現するために、ファイルの元の終わりと属性証明書テーブルの始まりの間にゼロ パディングが挿入されます。 各属性証明書エントリには、次のフィールドが含まれています。

オフセット サイズ フィールド 説明
0
4
dwLength
属性証明書エントリの長さを指定します。
4
2
wRevision
証明書のバージョン番号を格納します。 詳細については、次の本文を参照してください。
6
2
wCertificateType
bCertificate のコンテンツの種類を指定します。 詳細については、次の本文を参照してください。
8
参考資料
bCertificate
Authenticode 署名などの証明書が含まれています。 詳細については、次の本文を参照してください。

 

オプションのヘッダー データ ディレクトリの証明書テーブル エントリの仮想アドレス値は、最初の属性証明書エントリへのファイル オフセットです。 後続のエントリには、現在の属性証明書エントリの先頭からそのエントリの dwLength バイト (8 バイトの倍数に切り上げ) を進めることによってアクセスします。 これは、丸められた dwLength 値の合計が、オプションのヘッダー データ ディレクトリの証明書テーブル エントリの Size 値と等しくなるまで続きます。 丸められた dwLength 値の合計が Size 値と等しくない場合は、属性証明書テーブルまたは Size フィールドのいずれかが破損しています。

たとえば、省略可能なヘッダー データ ディレクトリの証明書テーブル エントリに次のものが含まれている場合です。

virtual address = 0x5000
size = 0x1000

最初の証明書は、ディスク上のファイルの先頭からオフセット 0x5000 で開始されます。 すべての属性証明書エントリを進めるには、次の手順を実行します。

  1. 最初の属性証明書の dwLength 値を開始オフセットに追加します。
  2. 手順 1 の値を最も近い 8 バイトの倍数に丸め、2 番目の属性証明書エントリのオフセットを見つけます。
  3. 手順 2 のオフセット値を 2 番目の属性証明書エントリの dwLength 値に加算し、最も近い 8 バイトの倍数に切り上げて、3 番目の属性証明書エントリのオフセットを決定します。
  4. 計算されたオフセットが 0x6000 (開始サイズ 0x5000 + 合計サイズ 0x1000) になるまで、連続する証明書ごとに手順 3 を繰り返します。これは、テーブル全体を調べたことを示します。

または、Win32 ImageEnumerateCertificates 関数をループで呼び出して、証明書エントリを列挙することもできます。 関数の参照ページへのリンクについては、「参照」を参照してください。

属性証明書テーブル エントリには、エントリに正しい dwLength 値、一意の wRevision 値、および一意の wCertificateType 値がある限り、任意の証明書タイプを含めることができます。 証明書テーブルエントリの最も一般的な種類は、wintrust.h に記載され、このセクションのメインで説明されている WIN_CERTIFICATE 構造です。

WIN_CERTIFICATE wRevision メンバーのオプションには、次のものが含まれます (ただし、これらに限定されません)。

Value 名前 メモ
0x0100
WIN_CERT_REVISION_1_0
バージョン 1、Win_Certificate 構造のレガシ バージョン。 従来の Authenticode 署名を検証する目的でのみサポートされます
0x0200
WIN_CERT_REVISION_2_0
バージョン 2 は、Win_Certificate 構造体の現在のバージョンです。

 

WIN_CERTIFICATE wCertificateType メンバーのオプションには、次の表の項目が含まれます (ただし、これらに限定されません)。 一部の値は現在サポートされていないことに注意してください。

Value 名前 メモ
0x0001
WIN_CERT_TYPE_X509
bCertificate には X.509 証明書が含まれています
サポートされていません
0x0002
WIN_CERT_TYPE_PKCS_SIGNED_DATA
bCertificate に PKCS#7 SignedData 構造体が含まれています
0x0003
WIN_CERT_TYPE_RESERVED_1
予約済み
0x0004
WIN_CERT_TYPE_TS_STACK_SIGNED
ターミナル サーバー プロトコル スタック証明書の署名
サポートされていません

 

WIN_CERTIFICATE構造体の bCertificate メンバーには、wCertificateType 指定されたコンテンツ タイプを持つ可変長バイト配列が含まれています。 Authenticode でサポートされる型は、PKCS#7 SignedData 構造体である WIN_CERT_TYPE_PKCS_SIGNED_DATA です。 Authenticode デジタル署名形式の詳細については、「Windows Authenticode Portable Executable Signature Format」を参照してください。

bCertificate コンテンツがクワッドワード境界で終わらない場合、属性証明書エントリは、bCertificate の末尾から次のクワッドワード境界まで、0 で埋め込まれます。

dwLength 値は、最終的な WIN_CERTIFICATE 構造体の長さであり、次のように計算されます。

dwLength = offsetof(WIN_CERTIFICATE, bCertificate) + (size of the variable-length binary array contained within bCertificate)

この長さは、各 WIN_CERTIFICATE 構造体がクワッドワードアラインされるという要件を満たすために使用されるパディングのサイズを含める必要があります。

dwLength += (8 - (dwLength & 7)) & 7;

省略可能なヘッダー データ ディレクトリ (イメージのみ)[証明書テーブル] エントリで指定された証明書テーブルのサイズには、パディングが含まれます。

ImageHlp API を使用して PE ファイルの証明書を列挙、追加、削除する方法の詳細については、「ImageHlp 関数」を参照してください。

証明書データ

前のセクションで説明したように、属性証明書テーブルの証明書には任意の種類の証明書を含めることができます。 PE ファイルの整合性を保証する証明書には、PE イメージ ハッシュが含まれる場合があります。

PE イメージ ハッシュ (またはファイル ハッシュ) は、ハッシュ アルゴリズムがファイルの整合性に関連するメッセージ ダイジェストを生成するという点で、ファイル チェックに似ています。 ただし、チェックサムは単純なアルゴリズムによって生成され、主にディスク上のメモリ ブロックが不良になり、保存されている値が破損したかどうかを検出するために使用されます。 ファイル ハッシュは、ファイルの破損も検出するという点で、チェックに似ています。 ただし、ほとんどのチェックサム アルゴリズムとは異なり、ファイル ハッシュを元の未変更の値から変更せずにファイルを変更することは非常に困難です。 したがって、ファイル ハッシュを使用して、ウイルス、ハッカー、トロイの木馬プログラムによって導入されたファイルなど、ファイルに対する意図的でわずかな変更を検出できます。

証明書に含まれる場合、イメージ ダイジェストは、オプションのヘッダー データ ディレクトリのチェックサムと証明書テーブルのエントリなど、PE イメージ内の特定のフィールドを除外する必要があります。 これは、証明書を追加する操作によってこれらのフィールドが変更され、別のハッシュ値が計算されるためです。

Win32 ImageGetDigestStream 関数は、関数のハッシュに使用するターゲット PE ファイルからのデータ ストリームを提供します。 このデータ ストリームはメイン PE ファイルへの証明書の追加または PE ファイルからの削除時に一貫性が保たれます。 ImageGetDigestStream に渡されるパラメーターに基づいて、PE イメージの他のデータをハッシュ計算から省略できます。 関数の参照ページへのリンクについては、「参照」を参照してください。

インポート テーブルの遅延読み込み (イメージのみ)

これらのテーブルは、アプリケーションが DLL を最初に呼び出すまで DLL の読み込みを遅らせる統一メカニズムをサポートするためにイメージに追加されました。 テーブルのレイアウトは、セクション 6.4 の .idata セクションで説明されている従来のインポート テーブルのレイアウトと一致します。ここでは、いくつかの詳細について説明します。

遅延読み込みディレクトリ テーブル

遅延読み込みディレクトリ テーブルは、インポート ディレクトリ テーブルに対応します。 これは、オプションのヘッダー データ ディレクトリ リスト (オフセット 200) の [遅延インポート記述子] エントリを使用して取得できます。 テーブルは次のように配置されます。

オフセット サイズ フィールド 説明
0
4
属性
ゼロを指定してください。
4
4
名前
読み込まれる DLL の名前の RVA。 この名前は、イメージの読み取り専用データ セクションに存在します。
8
4
モジュール ハンドル
遅延読み込みされる DLL のモジュール ハンドル (イメージのデータ セクション内) の RVA。 遅延読み込みを管理するために提供されるルーチンによってストレージに使用されます。
12
4
遅延インポート アドレス テーブル
遅延読み込みインポート アドレス テーブルの RVA。 詳細については、「遅延インポート アドレス テーブル (IAT)」を参照してください。
16
4
インポート名テーブルの遅延
読み込む必要がある可能性があるインポートの名前を含む遅延読み込み名テーブルの RVA。 これは、インポート名テーブルのレイアウトと一致します。 詳細については、「ヒント/名前テーブル」を参照してください。
20
4
連結遅延インポート テーブル
バインドされた遅延読み込みアドレス テーブルの RVA (存在する場合)。
24
4
遅延インポート テーブルのアンロード
アンロード遅延ロード アドレス テーブルの RVA (存在する場合)。 これは、遅延インポート アドレス テーブルの正確なコピーです。 呼び出し元が DLL をアンロードする場合は、後続の DLL 呼び出しでサンキング メカニズムが引き続き正しく使用されるように、このテーブルを遅延インポート アドレス テーブルにコピーして戻す必要があります。
28
4
タイム スタンプ
このイメージがバインドされている DLL のタイムスタンプ。

 

このデータ構造で参照されるテーブルは、対応するテーブルが従来のインポートの場合と同様に整理および並べ替えられます。 詳細については、「.idata セクション」を参照してください。

属性

まだ、属性フラグは定義されていません。 リンカーは、このフィールドをイメージ内の 0 に設定します。 このフィールドは、新しいフィールドの存在を示してレコードを拡張するために使用できます。また、遅延またはアンロード ヘルパー関数の動作を示すために使用することもできます。

名前

遅延読み込みされる DLL の名前は、イメージの読み取り専用データ セクションに存在します。 szName フィールドを介して参照されます。

モジュール ハンドル

遅延読み込みされる DLL のハンドルは、イメージのデータ セクションにあります。 phmod フィールドはハンドルを指します。 指定された遅延読み込みヘルパーは、この場所を使用して、読み込まれた DLL へのハンドルを格納します。

遅延インポート アドレス テーブル

遅延インポート アドレス テーブル (IAT) は、pIAT フィールドを介して遅延インポート記述子によって参照されます。 遅延読み込みヘルパーは、サンクが呼び出し元のループでなくなったように、これらのポインターを実際のエントリ ポイントで更新します。 関数ポインターには、式 pINT->u1.Function を使用してアクセスします。

インポート名テーブルの遅延

遅延インポート名テーブル (INT) には、読み込みが必要になる可能性があるインポートの名前が含まれています。 これらは、IAT の関数ポインターと同じ方法で順序付けられます。 これらは標準 INT と同じ構造で構成され、式 pINT->u1.AddressOfData->Name[0] を使用してアクセスされます。

遅延バインド インポート アドレス テーブルとタイム スタンプ

遅延制限インポート アドレス テーブル (BIAT) は、後処理バインディング フェーズで遅延ロード ディレクトリ テーブルのタイムスタンプ フィールドとともに使用される IMAGE_THUNK_DATA 項目のオプションのテーブルです。

インポート アドレス テーブルの遅延アンロード

遅延アンロード インポート アドレス テーブル (UIAT) は、アンロード コードが明示的なアンロード要求を処理するために使用する IMAGE_THUNK_DATA 項目のオプションのテーブルです。 これは、遅延読み込みサンクにコードを参照した元の IAT の正確なコピーである、読み取り専用セクションの初期化されたデータで構成されます。 アンロード要求では、ライブラリを解放し、*phmod をクリアし、IAT 経由で書き込まれた UIAT を使用して、すべてをプリロード状態に復元できます。

特別セクション

一般的な COFF セクションには、リンカーと Microsoft Win32 ローダーがセクションの内容に関する特別な知識なしに処理するコードまたはデータが含まれています。 コンテンツは、リンクまたは実行されているアプリケーションにのみ関連します。

ただし、一部の COFF セクションは、オブジェクト ファイルまたはイメージ ファイルで見つかった場合に特別な意味を持ちます。 ツールとローダーがこれらのセクションを認識するのは、セクション ヘッダーに特別なフラグが設定されているため、イメージのオプション ヘッダー内の特別な場所がそれらを指しているため、またはセクション名自体がセクションの特別な機能を示しているためです。 (セクション名自体がそのセクションの特別な機能を示していない場合でも、セクション名は慣例によって決定されるため、この仕様の作成者はあらゆる場合にセクション名を参照できます。)

以下の表では、予約セクションとその属性について説明し、その後、実行可能ファイルに永続化されるセクション タイプと拡張機能のメタデータを含むセクション タイプについて詳しく説明します。

セクション名 コンテンツ 特性
.bss
初期化されていないデータ (自由形式)
IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
.cormeta
オブジェクト ファイルにマネージド コードが含まれていることを示す CLR メタデータ
IMAGE_SCN_LNK_INFO
.data
初期化されているデータ (自由形式)
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
.debug$F
生成された FPO デバッグ情報 (オブジェクトのみ、x86 アーキテクチャのみ、現在は廃止)
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
.debug$P
プリコンパイル済みデバッグの種類 (オブジェクトのみ)
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
.debug$S
デバッグ シンボル (オブジェクトのみ)
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
.debug$T
デバッグ型 (オブジェクトのみ)
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
.drective
リンカー オプション
IMAGE_SCN_LNK_INFO
.edata
エクスポート テーブル
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
.idata
テーブルをインポートする
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
.idlsym
IDL 属性をサポートするために登録された SEH (イメージのみ) が含まれます。 詳細については、このトピックの最後にあるリファレンスの「IDL 属性」を参照してください。
IMAGE_SCN_LNK_INFO
.pdata
例外情報
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
.rdata
読み取り専用で初期化されたデータ
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
.reloc
イメージの再配置
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
.rsrc
リソース ディレクトリ
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
.sbss
GP 相対初期化されていないデータ (自由形式)
IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE _SCN_GPREL IMAGE_SCN_GPREL フラグは IA64 アーキテクチャにのみ設定する必要があります。このフラグは、他のアーキテクチャでは無効です。 IMAGE_SCN_GPREL フラグはオブジェクト ファイル専用です。このセクションの種類がイメージ ファイルに表示される場合は、IMAGE_SCN_GPREL フラグを設定しないでください。
.sdata
GP 相対初期化されているデータ (自由形式)
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE _SCN_GPREL IMAGE_SCN_GPREL フラグは IA64 アーキテクチャにのみ設定する必要があります。このフラグは、他のアーキテクチャでは無効です。 IMAGE_SCN_GPREL フラグはオブジェクト ファイル専用です。このセクションの種類がイメージ ファイルに表示される場合は、IMAGE_SCN_GPREL フラグを設定しないでください。
.srdata
GP 相対読み取り専用データ (自由形式)
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE _SCN_GPREL IMAGE_SCN_GPREL フラグは IA64 アーキテクチャにのみ設定する必要があります。このフラグは、他のアーキテクチャでは無効です。 IMAGE_SCN_GPREL フラグはオブジェクト ファイル専用です。このセクションの種類がイメージ ファイルに表示される場合は、IMAGE_SCN_GPREL フラグを設定しないでください。
.sxdata
登録済みの例外ハンドラー データ (フリー形式と x86/object のみ)
IMAGE_SCN_LNK_INFO そのオブジェクト ファイル内のコードによって参照されている各例外ハンドラーのシンボル インデックスが含まれます。 このシンボルは、UNDEF シンボル、またはそのモジュールで定義されているシンボルに対して指定できます。
.text
実行可能コード (自由形式)
IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IIMAGE_SCN_MEM_READ
.tls
スレッド ローカル ストレージ (オブジェクトのみ)
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
.tls$
スレッド ローカル ストレージ (オブジェクトのみ)
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
.vsdata
GP 関連の初期化されたデータ (自由形式、ARM、SH4、および Thumb アーキテクチャのみ)
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
.xdata
例外情報 (自由形式)
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ

 

ここにリストされているセクションの一部には、その特殊なセマンティクスがそれぞれオブジェクト ファイルまたはイメージ ファイルにのみ関連していることを示すために、「オブジェクトのみ」または「イメージのみ」とマークされています。 「イメージのみ」とマークされたセクションは、イメージ ファイルにアクセスする方法としてオブジェクト ファイル内に表示される場合がありますが、このセクションはリンカーにとって特別な意味はなく、イメージ ファイル ローダーにとってのみ特別な意味を持ちます。

.debug セクション

.debug セクションは、コンパイラによって生成されたデバッグ情報を含めるためにオブジェクト ファイルで使用され、生成されたすべてのデバッグ情報を含めるためにイメージ ファイルで使用されます。 このセクションでは、オブジェクト ファイルとイメージ ファイル内のデバッグ情報のパッケージ化について説明します。

次のセクションでは、デバッグ ディレクトリの形式について説明します。この形式は、イメージ内の任意の場所に置くことができます。 以降のセクションでは、デバッグ情報を含むオブジェクト ファイルの「グループ」について説明します。

リンカーの既定値は、デバッグ情報がイメージのアドレス空間にマップされないことです。 .debug セクションは、デバッグ情報がアドレス空間にマップされている場合にのみ存在します。

デバッグ ディレクトリ (イメージのみ)

イメージ ファイルには、デバッグ情報の形式とその場所を示すオプションのデバッグ ディレクトリが含まれています。 このディレクトリは、イメージの省略可能なヘッダーに場所とサイズが示されているデバッグ ディレクトリ エントリの配列で構成されます。

デバッグ ディレクトリは、disカードable .debug セクション (存在する場合) に入れるか、イメージ ファイル内の他のセクションに含めることができるか、セクションに含めないようにすることができます。

各デバッグ ディレクトリ エントリは、デバッグ情報のブロックの場所とサイズを識別します。 デバッグ情報がセクション ヘッダーでカバーされていない (つまり、イメージ ファイルに存在し、実行時アドレス空間にマップされていない) 場合、指定された RVA は 0 にすることができます。 マップされている場合、RVA はそのアドレスです。

デバッグ ディレクトリ エントリの形式は次のとおりです。

オフセット サイズ フィールド 説明
0
4
特性
予約済み、0 でなければなりません。
4
4
TimeDateStamp
デバッグ データが作成された日時。
8
2
MajorVersion
デバッグ データ形式のメジャー バージョン番号。
10
2
MinorVersion
デバッグ データ形式のマイナー バージョン番号。
12
4

デバッグ情報の形式。 このフィールドでは、複数のデバッガーをサポートできます。 詳細については、デバッグの種類に関するページを参照してください。
16
4
SizeOfData
デバッグ データのサイズ (デバッグ ディレクトリ自体は含まれません)。
20
4
AddressOfRawData
読み込み時に、イメージ ベースに相対的なデバッグ データのアドレス。
24
4
PointerToRawData
デバッグ データへのファイル ポインター。

 

デバッグの種類

デバッグ ディレクトリ エントリの Type フィールドには、次の値が定義されています。

定数 説明
IMAGE_DEBUG_TYPE_UNKNOWN
0
すべてのツールで無視される不明な値。
IMAGE_DEBUG_TYPE_COFF
1
COFF デバッグ情報 (行番号、シンボル テーブル、および文字列テーブル)。 この種のデバッグ情報はまた、ファイル ヘッダー内のフィールドによって指し示されます。
IMAGE_DEBUG_TYPE_CODEVIEW
2
Visual C++ デバッグ情報。
IMAGE_DEBUG_TYPE_FPO
3
フレーム ポインター省略 (FPO) 情報。 この情報は、フレーム ポインタとして以外の目的で EBP レジスタを使用する非標準スタック フレームを解釈する方法をデバッガに指示します。
IMAGE_DEBUG_TYPE_MISC
4
DBG ファイルの場所。
IMAGE_DEBUG_TYPE_EXCEPTION
5
.pdata セクションのコピー。
IMAGE_DEBUG_TYPE_FIXUP
6
予約済み。
IMAGE_DEBUG_TYPE_OMAP_TO_SRC
7
イメージの RVA からソース イメージの RVA へのマッピング。
IMAGE_DEBUG_TYPE_OMAP_FROM_SRC
8
ソース イメージの RVA からイメージの RVA へのマッピング。
IMAGE_DEBUG_TYPE_BORLAND
9
ボーランドのために予約されています。
IMAGE_DEBUG_TYPE_RESERVED10
10
予約済み。
IMAGE_DEBUG_TYPE_CLSID
11
予約済み。
IMAGE_DEBUG_TYPE_REPRO
16
PE の決定性または再現性。
Undefined
17
デバッグ情報は、PointerToRawData で指定された場所にある PE ファイルに埋め込まれます。
Undefined
19
PE/COFF ファイルのビルドに使用されるシンボル ファイルの内容の暗号化ハッシュを格納します。
IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS 20 拡張 DLL 特性ビット。

 

Type フィールドが IMAGE_DEBUG_TYPE_FPO に設定されている場合、デバッグ生データは、各メンバーが関数のスタック フレームを記述する配列になります。 デバッグの種類が FPO であっても、イメージ ファイル内のすべての関数に FPO 情報が定義されている必要があるわけではありません。 FPO 情報を持たない関数は、通常のスタック フレームを持つものと見なされます。 FPO 情報の形式は次のとおりです。

#define FRAME_FPO   0
#define FRAME_TRAP  1
#define FRAME_TSS   2

typedef struct _FPO_DATA {
    DWORD       ulOffStart;            // offset 1st byte of function code
    DWORD       cbProcSize;            // # bytes in function
    DWORD       cdwLocals;             // # bytes in locals/4
    WORD        cdwParams;             // # bytes in params/4
    WORD        cbProlog : 8;          // # bytes in prolog
    WORD        cbRegs   : 3;          // # regs saved
    WORD        fHasSEH  : 1;          // TRUE if SEH in func
    WORD        fUseBP   : 1;          // TRUE if EBP has been allocated
    WORD        reserved : 1;          // reserved for future use
    WORD        cbFrame  : 2;          // frame type
} FPO_DATA;

IMAGE_DEBUG_TYPE_REPRO 型のエントリの存在は、PE ファイルが決定性または再現性を達成する方法で構築されていることを示します。 入力が変更されない場合、出力 PE ファイルは、PE が生成されるタイミングや場所に関係なく、ビット単位で同一であることが保証されます。 PE ファイル内のさまざまな日付/時刻スタンプ フィールドは、PE ファイルのコンテンツを入力として使用する計算されたハッシュ値の一部またはすべてのビットで埋められているため、PE ファイルまたは PE 内の関連する特定のデータが生成された実際の日時を表すものではなくなっています。 このデバッグ エントリの生データは空である場合もあれば、計算されたハッシュ値の前にハッシュ値の長さを表す 4 バイトの値が含まれている場合もあります。

Type フィールドが IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS に設定されている場合、デバッグ生データには、イメージのオプションのヘッダーに設定できる拡張 DLL 特性ビットに加えて、拡張 DLL 特性ビットが含まれます。 「省略可能なヘッダー Windows 固有のフィールド (画像のみ)」セクションの「DLL の特性」を参照してください.

拡張 DLL の特性

拡張 DLL 特性ビットには、次の値が定義されています。

定数 説明
IMAGE_DLLCHARACTERISTICS_EX_CET_COMPAT 0x0001 イメージは Control-flow Enforcement Technology (CET) シャドウスタックと互換性があります。
IMAGE_DLLCHARACTERISTICS_EX_FORWARD_CFI_COMPAT 0x0040 すべてのイメージ コード セクションのすべての分岐ターゲットには、x86 CET 間接分岐追跡 (IBT) 命令や ARM 分岐ターゲット識別 (BTI) 命令などのフォワード エッジ制御フロー整合性ガード命令の注釈が付けられます。 このビットは、Windows では使用されません。

.debug$F (オブジェクトのみ)

このセクションのデータは、Visual C++ バージョン 7.0 以降では、.debug$S サブセクションに出力されるより広範なデータ セットに置き換わりました。

オブジェクト ファイルには、内容が 1 つ以上の FPO_DATA レコード (フレーム ポインターの省略情報) である .debug$F セクションを含めることができます。 「デバッグの種類」の「IMAGE_DEBUG_TYPE_FPO」を参照してください。

リンカーはこれらの .debug$F レコードを認識します。 デバッグ情報が生成されている場合、リンカーはプロシージャ RVA によって FPO_DATA レコードを並べ替え、それらのデバッグ ディレクトリ エントリを生成します。

コンパイラは、標準フレーム形式を持つプロシージャの FPO レコードを生成すべきではありません。

.debug$S (オブジェクトのみ)

このセクションには、Visual C++ デバッグ情報 (シンボリック情報) が含まれています。

.debug$P (オブジェクトのみ)

このセクションには、Visual C++ のデバッグ情報 (プリコンパイルされた情報) が含まれています。 これらは、このオブジェクトで生成されたプリコンパイル済みヘッダーを使用してコンパイルされたすべてのオブジェクト間で共有される型です。

.debug$T (オブジェクトのみ)

このセクションには、Visual C++ のデバッグ情報 (型情報) が含まれています。

Microsoft デバッグ情報のリンカー サポート

デバッグ情報をサポートするために、リンカーは次の手順を実行します。

  • .debug$Fdebug$S.debug$P、および .debug$Tセクションから関連するすべてのデバッグ データを収集します。

  • リンカーによって生成されたデバッグ情報と共にそのデータを PDB ファイルに処理し、それを参照するデバッグ ディレクトリ エントリを作成します。

.drectve セクション (オブジェクトのみ)

セクション ヘッダーに IMAGE_SCN_LNK_INFO フラグが設定され、.drectve セクション名を持つセクションはディレクティブ セクションです。 リンカーは、情報の処理後に .drectve セクションを削除するため、リンクされているイメージ ファイルにセクションは表示されません。

.drectve セクションは、ANSI または UTF-8 としてエンコードできるテキストの文字列で構成されます。 UTF-8 バイト オーダー マーカー (BOM、0xEF、0xBB、および 0xBF で構成される 3 バイトのプレフィックス) が存在しない場合、ディレクティブ文字列は ANSI として解釈されます。 ディレクティブ文字列は、スペースで区切られた一連のリンカー オプションです。 各オプションには、ハイフン、オプション名、および適切な属性が含まれています。 オプションにスペースが含まれている場合は、オプションを引用符で囲む必要があります。 .drectve セクションには再配置や行番号を含めてはなりません。

.edata セクション (イメージのみ)

.edata という名前のエクスポート データ セクションには、動的リンクを介して他の画像がアクセスできるシンボルに関する情報が含まれています。 エクスポートされたシンボルは、一般に DLL で見つかりますが、DLL はシンボルをインポートすることもできます。

エクスポート セクションの一般的な構造の概要を以下に示します。 説明されているテーブルは、通常、ファイル内で示されている順序で連続しています (ただし、これは必須ではありません)。 シンボルを序数としてエクスポートするには、エクスポート ディレクトリ テーブルとエクスポート アドレス テーブルのみが必要です。 (序数は、エクスポート アドレス テーブルインデックスによって直接アクセスされるエクスポートです)。名前ポインター テーブル、序数テーブル、エクスポート名テーブルはすべて、エクスポート名の使用をサポートするために存在します。

テーブル名 説明
エクスポート ディレクトリ テーブル
(デバッグ ディレクトリとは異なり) 行が 1 つだけのテーブル。 このテーブルは、他のエクスポート テーブルの場所とサイズを示します。
アドレス テーブルのエクスポート
エクスポートされたシンボルの RVA の配列。 これらは、実行可能コードおよびデータ セクション内のエクスポートされた関数とデータの実際のアドレスです。 他のイメージ ファイルは、このテーブルのインデックス (序数) を使用するか、オプションで、パブリック名が定義されている場合は序数に対応するパブリック名を使用して、シンボルをインポートできます。
名前ポインター テーブル
パブリック エクスポート名へのポインターの配列。昇順で並べ替えられます。
序数テーブル
名前ポインター テーブルのメンバーに対応する序数の配列。 対応は位置別です。そのため、名前ポインター テーブルと序数テーブルは、同じ数のメンバーを持つ必要があります。 各序数は、エクスポート アドレス テーブルのインデックスです。
名前テーブルのエクスポート
null で終わる一連の ASCII 文字列。 名前ポインター テーブルのメンバーは、この領域を指します。 これらの名前は、シンボルのインポートおよびエクスポートに使用される公開名です。これらは、イメージ ファイル内で使用されるプライベート名と必ずしも同じではありません。

 

別のイメージ ファイルが名前でシンボルをインポートすると、Win32 ローダーは名前ポインター テーブルで一致する文字列を検索します。 一致する文字列が見つかった場合、順序テーブル内の対応するメンバー (つまり、名前ポインター テーブルにある文字列ポインターと同じインデックスを持つ順序テーブルのメンバー) を検索することによって、関連付けられた順序が識別されます。 結果として得られる序数は、エクスポート アドレス テーブルへのインデックスであり、目的のシンボルの実際の位置を示します。 すべてのエクスポート シンボルには序数でアクセスできます。

別のイメージ ファイルが序数でシンボルをインポートする場合、名前ポインター テーブルで一致する文字列を検索する必要はありません。 したがって、序数を直接使用する方が効率的です。 ただし、エクスポート名は覚えやすく、シンボルのテーブル インデックスをユーザーに知る必要はありません。

エクスポート ディレクトリ テーブル

エクスポート シンボル情報は、エクスポート ディレクトリ テーブルで始まり、エクスポート シンボル情報の残りの部分が記述されます。 エクスポート ディレクトリ テーブルには、このイメージ内のエントリ ポイントへのインポートを解決するために使用されるアドレス情報が含まれています。

オフセット サイズ フィールド 説明
0
4
エクスポート フラグ
予約済み、0 である必要があります
4
4
時刻/日付スタンプ
エクスポート データが作成された日時。
8
2
メジャー バージョン
メジャー バージョン番号。 メジャー バージョン番号とマイナー バージョン番号は、ユーザーが設定できます。
10
2
マイナー バージョン
マイナー バージョン番号。
12
4
名前 RVA
DLL の名前を含む ASCII 文字列のアドレス。 このアドレスは、イメージ ベースを基準にしています。
16
4
序数ベース
このイメージ内のエクスポートの開始序数。 このフィールドは、エクスポート アドレス テーブルの開始序数を指定します。 通常は 1 に設定されます。
20
4
アドレス テーブルのエントリ
エクスポート アドレス テーブル内のエントリの数。
24
4
名前ポインターの数
名前ポインタ テーブル内のエントリの数。 これは、序数テーブル内のエントリの数でもあります。
28
4
アドレス テーブル RVA のエクスポート
イメージ ベースを基準にしたエクスポート アドレス テーブルのアドレス。
32
4
名前ポインター RVA
イメージ ベースを基準としたエクスポート名ポインター テーブルのアドレス。 テーブルのサイズは、Number of Name Pointers フィールドで指定します。
36
4
序数テーブル RVA
イメージ ベースを基準とした序数テーブルのアドレス。

 

アドレス テーブルのエクスポート

エクスポート アドレス テーブルには、エクスポートされたエントリ ポイントとエクスポートされたデータと絶対のアドレスが含まれています。 序数は、エクスポート アドレス テーブルのインデックスとして使用されます。

エクスポート アドレス テーブルの各エントリは、次の表の 2 つの形式のいずれかを使用するフィールドです。 指定されたアドレスがエクスポート セクション (オプションのヘッダーに示されるアドレスと長さによって定義される) 内にない場合、フィールドはエクスポート RVA であり、コードまたはデータ内の実際のアドレスです。 それ以外の場合、フィールドはフォワーダー RVA であり、別の DLL 内のシンボルに名前を付けます。

オフセット サイズ フィールド 説明
0
4
RVA のエクスポート
イメージ ベースを基準にして、メモリに読み込まれるときにエクスポートされたシンボルのアドレス。 たとえば、エクスポートされた関数のアドレスです。
0
4
フォワーダー RVA
エクスポート セクションの null で終わる ASCII 文字列へのポインター。 この文字列は、エクスポート テーブル データ ディレクトリ エントリで指定された範囲内にある必要があります。 「省略可能なヘッダー データ ディレクトリ (イメージのみ)」を参照してください。 この文字列は、DLL 名とエクスポートの名前 (たとえば、「MYDLL.expfunc」)、または DLL 名とエクスポートの序数 (たとえば、「MYDLL.#27」) を示します。

 

フォワーダー RVA は他のイメージから定義をエクスポートし、現在のイメージによってエクスポートされているかのように見えます。 したがって、シンボルは同時にインポートおよびエクスポートされます。

たとえば、Windows XP の Kernel32.dll では、「HeapAlloc」という名前のエクスポートが文字列「NTDLL.RtlAllocateHeap」に転送されます。これにより、アプリケーションは、実際にインポート参照を含めることなく、Windows XP 固有のモジュール Ntdll.dll を使用できるようになります。 アプリケーションのインポート テーブルは、Kernel32.dll のみを参照します。 したがって、アプリケーションは Windows XP に固有ではなく、任意の Win32 システムで実行できます。

名前ポインター テーブルのエクスポート

エクスポート名ポインター テーブルは、エクスポート名テーブルへのアドレス (RVA) の配列です。 ポインターはそれぞれ 32 ビットで、イメージ ベースを基準にしています。 ポインターは、バイナリ検索を可能にするために字句的に並べ替えされます。

エクスポート名は、エクスポート名ポインター テーブルにポインターが含まれている場合にのみ定義されます。

序数テーブルのエクスポート

エクスポート序数テーブルは、エクスポート アドレス テーブルへの 16 ビットの偏りのないインデックスの配列です。 序数は、エクスポート ディレクトリ テーブルの Ordinal Base フィールドによって偏っています。 つまり、エクスポート アドレス テーブルに真のインデックスを取得するには、序数から序数を減算する必要があります。

エクスポート名ポインター テーブルとエクスポート序数テーブルは、自然なフィールドの配置を可能にするために区切られた 2 つの並列配列を形成します。 これら 2 つのテーブルは実際には 1 つのテーブルとして動作し、エクスポート名ポインタ列がパブリック (エクスポートされた) 名を指し、エクスポート順序列がそのパブリック名に対応する序数を示します。 エクスポート名ポインター テーブルのメンバーとエクスポート順序テーブルのメンバーは、それぞれの配列内で同じ位置 (インデックス) を持つことによって関連付けられます。

したがって、エクスポート名ポインター テーブルが検索され、一致する文字列が位置 i で見つかった場合、シンボルの RVA とバイアス順序を見つけるためのアルゴリズムは次のようになります。

i = Search_ExportNamePointerTable (name);
ordinal = ExportOrdinalTable [i];

rva = ExportAddressTable [ordinal];
biased_ordinal = ordinal + OrdinalBase;

(偏った) 序数でシンボルを検索する場合、シンボルの RVA と名前を見つけるためのアルゴリズムは次のようになります。

ordinal = biased_ordinal - OrdinalBase;
i = Search_ExportOrdinalTable (ordinal);

rva = ExportAddressTable [ordinal];
name = ExportNameTable [i];

名前テーブルのエクスポート

エクスポート名テーブルには、エクスポート名ポインター テーブルによって指された実際の文字列データが含まれています。 この表の文字列は、他のイメージがシンボルのインポートに使用できるパブリック名です。 これらのパブリック エクスポート名は、シンボルが独自のイメージ ファイルやソース コード内で持つプライベート シンボル名と同じである可能性はありますが、必ずしも同じである必要はありません。

エクスポートされるすべてのシンボルには序数値があり、これはエクスポート アドレス テーブルへのインデックスにすぎません。 ただし、エクスポート名の使用は省略可能です。 エクスポートされたシンボルの一部、すべて、またはいずれもエクスポート名を持つことができません。 エクスポート名を持つエクスポートされたシンボルの場合、エクスポート名ポインター テーブルとエクスポート序数テーブルの対応するエントリが連携して、各名前を序数に関連付けます。

エクスポート名テーブルの構造は、可変長の null で終わる一連の ASCII 文字列です。

.idata セクション

シンボルをインポートするすべてのイメージ ファイル (ほぼすべての実行可能ファイル (EXE) ファイルを含む) には、.idata セクションがあります。 インポート情報の一般的なファイル レイアウトは次のとおりです。

  • ディレクトリ テーブル

    Null ディレクトリ エントリ

  • DLL1 参照テーブルのインポート

    [Null]

  • DLL2 参照テーブルのインポート

    [Null]

  • DLL3 参照テーブルのインポート

    [Null]

  • ヒント/名前テーブル

ディレクトリ テーブルのインポート

インポート情報はインポート ディレクトリ テーブルで始まり、インポート情報の残りの部分が説明されます。 インポート ディレクトリ テーブルには、DLL イメージ内のエントリ ポイントへの修正参照を解決するために使用されるアドレス情報が含まれています。 インポート ディレクトリ テーブルはインポート ディレクトリ エントリの配列で構成され、イメージが参照する DLL ごとに 1 つのエントリが含まれます。 ディレクトリ テーブルの末尾を示す、最後のディレクトリ エントリが空 (null 値で埋められます) です。

各インポート ディレクトリ エントリの形式は次のとおりです。

オフセット サイズ フィールド 説明
0
4
参照テーブル RVA のインポート (特性)
インポート参照テーブルの RVA。 このテーブルには、インポートごとに名前または序数が含まれています。 (「Characteristics」という名前は Winnt.h で使用されていますが、このフィールドについては説明されていません。)
4
4
時刻/日付スタンプ
イメージがバインドされるまで 0 に設定されるスタンプ。 イメージがバインドされると、このフィールドは DLL の時刻/データ スタンプに設定されます。
8
4
フォワーダー チェーン
最初のフォワーダー参照のインデックス。
12
4
名前 RVA
DLL の名前を含む ASCII 文字列のアドレス。 このアドレスは、イメージ ベースを基準にしています。
16
4
インポート アドレス テーブル RVA (サンク テーブル)
インポート アドレス テーブルの RVA。 このテーブルの内容は、イメージがバインドされるまでインポート 参照テーブルの内容と同じです。

 

参照テーブルのインポート

インポート 参照テーブルは、PE32 の場合は 32 ビット数値の配列、PE32 以降では 64 ビット数値の配列です。 各エントリは、次の表で説明されているビットフィールド形式を使用します。 この形式では、PE32 ではビット 31 が最も重要なビットであり、ビット 63 は PE32 以降で最も重要なビットです。 これらのエントリのコレクションは、特定の DLL からのすべてのインポートを記述します。 最後のエントリは、テーブルの末尾を示す 0 (NULL) に設定されます。

ビット サイズ ビット フィールド 説明
31/63
1
序数/名前フラグ
このビットが設定されている場合は、序数でインポートします。 それ以外の場合は、名前でインポートします。 ビットは、PE32 の場合は 0x80000000、PE32+ の場合は 0x8000000000000000 としてマスクされます。
15-0
16
序数
16 ビットの序数。 このフィールドは、Ordinal/Name Flag bit フィールドが 1 (序数によるインポート) の場合にのみ使用されます。 ビット 30 ~ 15 または 62 ~ 15 は 0 でなければなりません。
30-0
31
ヒント/名前テーブル RVA
ヒント/名前テーブル エントリの 31 ビット RVA。 このフィールドは、Ordinal/Name Flag bit フィールドが 0 (名前によるインポート) の場合にのみ使用されます。 PE32+ の場合、ビット 62 ~ 31 は 0 でなければなりません。

 

ヒント/名前テーブル

インポート セクション全体で 1 つのヒント/名前テーブルで十分です。 ヒント/名前テーブルの各エントリの形式は次のとおりです。

オフセット サイズ フィールド 説明
0
2
ヒント
エクスポート名ポインター テーブルへのインデックス。 この値で最初に一致が試行されます。 失敗した場合は、DLL のエクスポート名ポインター テーブルでバイナリ検索が実行されます。
2
変数
名前
インポートする名前を含む ASCII 文字列。 これは、DLL 内のパブリック名と一致する必要がある文字列です。 この文字列では大文字と小文字が区別され、null バイトで終了します。
*
0 または 1
Pad
必要に応じて、後続の null バイトの後に出現する末尾のゼロパッド バイトで、次のエントリを偶数境界に配置します。

 

インポート アドレス テーブル

インポート アドレス テーブルの構造と内容は、ファイルがバインドされるまで、インポート 参照テーブルの構造と内容と同じです。 バインド中、インポートアドレステーブルのエントリは、インポートされるシンボルの 32 ビット (PE32 の場合) または 64 ビット (PE32 以降の場合) アドレスで上書きされます。 これらのアドレスはシンボルの実際のメモリ アドレスですが、専門的には依然として「仮想アドレス」と呼ばれます。通常、ローダーはバインディングを処理します。

.pdata セクション

.pdata セクションには、例外処理に使用される関数テーブル エントリの配列が含まれています。 これは、イメージ データ ディレクトリ内の例外表項目によって指されます。 エントリは、最終イメージに出力される前に、関数アドレス (各構造体の最初のフィールド) に従ってソートする必要があります。 ターゲット プラットフォームによって、以下で説明する 3 つの関数テーブル エントリ形式のバリエーションのうちどれが使用されるかが決まります。

32 ビット MIPS イメージの場合、関数テーブルのエントリの形式は次のとおりです。

オフセット サイズ フィールド 説明
0
4
開始アドレス
対応する関数の VA。
4
4
終了アドレス
関数の終了時の VA。
8
4
例外ハンドラー
実行する例外ハンドラーへのポインター。
12
4
ハンドラー データ
ハンドラーに渡される追加情報へのポインター。
16
4
Prolog の終了アドレス
関数のプロローグの末尾のVA。

 

ARM、PowerPC、SH3、SH4 Windows CE プラットフォームの場合、関数テーブルエントリの形式は次のとおりです。

オフセット サイズ フィールド 説明
0
4
開始アドレス
対応する関数の VA。
4
8 ビット
プロローグの長さ
関数のプロローグ内の命令の数。
4
22 ビット
関数の長さ
関数内の命令の数。
4
1 ビット
32 ビット フラグ
設定すると、関数は 32 ビット命令で構成されます。 クリアすると、関数は 16 ビット命令で構成されます。
4
1 ビット
例外フラグ
設定すると、関数の例外ハンドラーが存在します。 それ以外の場合、例外ハンドラーは存在しません。

 

x64 および Itanium プラットフォームの場合、関数テーブルエントリの形式は次のとおりです。

オフセット サイズ フィールド 説明
0
4
開始アドレス
対応する関数の RVA。
4
4
終了アドレス
関数の終了時の RVA。
8
4
アンワインド情報
アンワインド情報の RVA。

 

.reloc セクション (イメージのみ)

ベース再配置テーブルには、イメージ内のすべてのベース再配置のエントリが含まれています。 オプションのヘッダー データ ディレクトリの Base Relocation Table フィールドには、ベース再配置テーブルのバイト数が示されます。 詳細については、「省略可能なヘッダー データ ディレクトリ (イメージのみ)」を参照してください。 ベース再配置テーブルはブロックに分割されます。 各ブロックは、4K ページのベース再配置を表します。 各ブロックは、32 ビット境界で開始する必要があります。

PE ヘッダーで指定されているイメージ ベースでロード イメージをロードできない場合を除き、ローダーはリンカーによって解決されるベースの再配置を処理する必要はありません。

ベース再配置ブロック

各ベース再配置ブロックは、次の構造で始まります。

オフセット サイズ フィールド 説明
0
4
ページ RVA
イメージ ベースとページ RVA が各オフセットに追加され、ベース再配置を適用する必要がある VA が作成されます。
4
4
ブロック サイズ
ベース再配置ブロックの合計バイト数 (Page RVA フィールド、Block Size フィールド、後続の Type/Offset フィールドを含む)。

 

Block Size フィールドの後に、任意の数の Type フィールドまたはOffset フィールドエントリが続きます。 各エントリは WORD (2 バイト) であり、次の構造を持ちます。

オフセット サイズ フィールド 説明
0
4 ビット

適用する基本再配置の種類を示す値である、WORD の上位 4 ビットに格納されます。 詳細については、「ベース再配置の種類」を参照してください。
0
12 ビット
オフセット
WORD の再メイン 12 ビットに格納されます。これは、ブロックのページ RVA フィールドで指定された開始アドレスからのオフセットです。 このオフセットは、ベース再配置を適用する場所を指定します。

 

ベース再配置を適用するには、優先ベース アドレスとイメージが実際にロードされるベースとの差が計算されます。 イメージが優先ベースで読み込まれる場合、違いは 0 であるため、ベース再配置を適用する必要はありません。

基本再配置の種類

定数 説明
IMAGE_REL_BASED_ABSOLUTE
0
ベース再配置はスキップされます。 このタイプは、ブロックを埋め込むのに使用できます。
IMAGE_REL_BASED_HIGH
1
ベース再配置では、オフセットの 16 ビット フィールドに差の上位 16 ビットが追加されます。 16 ビット フィールドは、32 ビット ワードの高い値を表します。
IMAGE_REL_BASED_LOW
2
ベース再配置では、オフセットの 16 ビット フィールドに差の下位 16 ビットが追加されます。 16 ビット フィールドは、32 ビット ワードの下位半分を表します。
IMAGE_REL_BASED_HIGHLOW
3
ベース再配置では、差分の 32 ビットすべてがオフセットの 32 ビット フィールドに適用されます。
IMAGE_REL_BASED_HIGHADJ
4
ベース再配置では、オフセットの 16 ビット フィールドに差の上位 16 ビットが追加されます。 16 ビット フィールドは、32 ビット ワードの高い値を表します。 32 ビット値の下位 16 ビットは、このベース再配置に続く 16 ビット ワードに格納されます。 これは、このベース再配置が 2 つのスロットを占有することを意味します。
IMAGE_REL_BASED_MIPS_JMPADDR
5
再配置の解釈は、マシンの種類によって異なります。
マシンの種類が MIPS の場合、基本再配置は MIPS ジャンプ命令に適用されます。
IMAGE_REL_BASED_ARM_MOV32
5
この再配置は、マシンの種類が ARM または Thumb の場合にのみ意味があります。 ベース再配置は、連続する MOVW/MOVT 命令ペア全体でシンボルの 32 ビット・アドレスを適用します。
IMAGE_REL_BASED_RISCV_HIGH20
5
この再配置は、マシンの種類が RISC-V の場合にのみ意味があります。 ベース再配置は、32 ビット絶対アドレスの上位 20 ビットに適用されます。
6
予約済み、0 でなければなりません。
IMAGE_REL_BASED_THUMB_MOV32
7
この再配置は、マシンの種類がThumb の場合にのみ意味があります。 ベース再配置は、連続する MOVW/MOVT 命令ペアでシンボルの 32 ビット・アドレスを適用します。
IMAGE_REL_BASED_RISCV_LOW12I
7
この再配置は、マシンの種類が RISC-V の場合にのみ意味があります。 ベース再配置は、RISC-V I 型命令形式で形成された 32 ビット絶対アドレスの下位 12 ビットに適用されます。
IMAGE_REL_BASED_RISCV_LOW12S
8
この再配置は、マシンの種類が RISC-V の場合にのみ意味があります。 ベース再配置は、ISC-V S 型命令形式で形成された 32 ビット絶対アドレスの下位 12 ビットに適用されます。
IMAGE_REL_BASED_LOONGARCH32_MARK_LA
8
この再配置は、マシンの種類が LoongArch 32 ビットの場合にのみ意味があります。 ベース再配置は、2 つの連続する命令で形成された 32 ビットの絶対アドレスに適用されます。
IMAGE_REL_BASED_LOONGARCH64_MARK_LA
8
この再配置は、マシンの種類が LoongArch 64 ビットの場合にのみ意味があります。 ベース再配置は、4 つの連続する命令で形成された 64 ビットの絶対アドレスに適用されます。
IMAGE_REL_BASED_MIPS_JMPADDR16
9
再配置は、マシンの種類が MIPS の場合にのみ意味があります。 ベース再配置は、MIPS16 ジャンプ命令に適用されます。
IMAGE_REL_BASED_DIR64
10
ベース再配置では、オフセットの 64 ビット フィールドに差が適用されます。

 

.tls セクション

.tls セクションでは、静的スレッド ローカル ストレージ (TLS) に対する PE と COFF の直接サポートが提供されます。 TLS は Windows がサポートする特別なストレージ クラスで、データ オブジェクトは自動 (スタック) 変数ではなく、コードを実行する個々のスレッドに対してローカルです。 したがって、各スレッドは、TLS を使用して宣言された変数に対して異なる値を維持できます。

API 呼び出し TlsAlloc、TlsFree、TlsSetValue、および TlsGetValue を使用して、任意の量の TLS データをサポートできることに注意してください。 PE または COFF 実装は、API を使用するための代替アプローチであり、高級言語プログラマの観点から見るとより簡単であるという利点があります。 この実装により、TLS データをプログラム内の通常の静的変数と同様に定義および初期化できます。 たとえば、Visual C++ では、Windows API を使用せずに、静的 TLS 変数を次のように定義できます。

__declspec (thread) int tlsFlag = 1;

このプログラミング構造をサポートするために、PE および COFF .tls セクションでは、初期化データ、スレッドごとに初期化と終了を実行するコールバック ルーチン、および TLS インデックスの情報を指定します。これらについては、次の説明で説明します。

Note

Windows Vista以前では、静的に宣言されたTLSデータオブジェクトは、静的にロードされたイメージファイルでのみ使用できます。 この事実から、DLL内での静的TLSデータの使用は信頼性の低下を招きます。ただし、DLLやそれと静的にリンクされたものが、LoadLibrary API関数を使用して動的にロードされないことがわかっている場合を除きます。 ただし、Windows Vista以降はWindowsローダーが改善され、静的TLSを持つDLLの動的な読み込みのサポートが向上しました。 この変更により、静的に宣言されたTLSデータオブジェクトを持つDLLは、LoadLibraryを使用して動的にロードされても、より信頼性の高い方法で使用できるようになりました。 ローダーは、これらのDLLのロード時にTLSスロットを割り当てることができ、Windowsの以前のバージョンで存在する制限を軽減します。

 

Note

32ビットアーキテクチャを持つシステムには、32ビットオフセットとインデックス乗数が適用されます。 64ビットアーキテクチャを持つシステムでは、必要に応じて調整してください。

実行可能コードは、静的TLSデータオブジェクトに以下の手順でアクセスします:

  1. リンク時に、リンカーは TLS ディレクトリの Address of Index フィールドを設定します。 このフィールドは、プログラムが TLS インデックスを受け取る予定の場所を指します。

    Microsoft ランタイム ライブラリは、TLS ディレクトリのメモリ イメージを定義し、特別な名前「__tls_used」(Intel x86 プラットフォーム) または「_tls_used」(その他のプラットフォーム) を付けることで、このプロセスを容易にします。 リンカーは、このメモリ イメージを検索し、そこでデータを使用して TLS ディレクトリを作成します。 TLS をサポートし、Microsoft リンカーと連携する他のコンパイラでも、この同じ手法を使用する必要があります。

  2. スレッドが作成されると、ローダーはスレッド環境ブロック (TEB) のアドレスを FS レジスタに配置することで、スレッドの TLS 配列のアドレスを通信します。 TLS 配列へのポインターは、TEB の先頭から 0x2C のオフセットにあります。 この動作は Intel x86 固有です。

  3. ローダーは、Address of Index フィールドで示された場所に TLS インデックスの値を割り当てます。

  4. 実行可能コードは、TLS インデックスと TLS 配列の場所も取得します。

  5. このコードは、TLS インデックスと TLS 配列の場所 (インデックスを 4 倍し、それを配列へのオフセットとして使用します) を使用して、指定されたプログラムとモジュールの TLS データ領域のアドレスを取得します。 各スレッドには独自の TLS データ領域がありますが、これはプログラムに対して透過的であり、個々のスレッドに対してデータがどのように割り当てられるかを知る必要はありません。

  6. 個々の TLS データ オブジェクトには、TLS データ領域への固定オフセットとしてアクセスされます。

TLS 配列は、システムが各スレッドに対して保持するアドレスの配列です。 この配列内の各アドレスは、プログラム内の特定のモジュール (EXE または DLL) の TLS データの場所を示します。 TLS インデックスは、使用する配列のメンバーを示します。 インデックスは、モジュールを識別する数値 (システムにとってのみ意味があります) です。

TLS ディレクトリ

TLS ディレクトリの形式は次のとおりです。

オフセット (PE32/PE32+) サイズ (PE32/PE32+) フィールド 説明
0
4/8
生データ開始 VA
TLS テンプレートの開始アドレス。 テンプレートは、TLS データの初期化に使用されるデータのブロックです。 システムは、スレッドが作成されるたびにこのデータをすべてコピーするため、破損しないようにする必要があります。 このアドレスは RVA ではないことに注意してください。これは、.reloc セクションにベース再配置が必要なアドレスです。
4/8
4/8
生データ終了 VA
ゼロフィルを除く TLS の最後のバイトのアドレス。 Raw Data Start VA フィールドと同様に、これは RVA ではなく VA です。
8/16
4/8
インデックスのアドレス
ローダーが割り当てる TLS インデックスを受信する場所。 この場所は通常のデータ セクション内に存在するため、プログラムからアクセスできるシンボリック名を指定できます。
12/24
4/8
コールバックのアドレス
TLS コールバック関数の配列へのポインター。 配列は null で終わるので、コールバック関数がサポートされていない場合、このフィールドは 4 バイトを 0 に設定することを指します。 これらの関数のプロトタイプについては、「TLS コールバック関数」を参照してください。
16/32
4
ゼロ フィルのサイズ
Raw Data Start VA フィールドと Raw Data End VA フィールドで区切られた初期化されたデータを超える、テンプレートのサイズ (バイト単位)。 テンプレートの合計サイズは、イメージ ファイル内の TLS データの合計サイズと同じである必要があります。 ゼロフィルは、初期化された 0 以外のデータの後に来るデータの量です。
20/36
4
特性
4 ビット [23:20] はアラインメント情報を記述します。 指定できる値は、IMAGE_SCN_ALIGN_* として定義されたもので、オブジェクト ファイル内のセクションの配置を記述するためにも使用されます。 残りの 28 ビットは、今後の使用のために予約されています。

 

TLS コールバック関数

プログラムは、TLS データ オブジェクトの追加の初期化と終了をサポートする 1 つ以上の TLS コールバック関数を提供できます。 このようなコールバック関数は、オブジェクトのコンストラクターとデストラクターを呼び出す場合に使用するのが一般的です。

通常、コールバック関数は 1 つだけですが、コールバックは配列として実装されており、必要に応じてコールバック関数を追加できます。 複数のコールバック関数がある場合、各関数は、そのアドレスが配列に表示される順序で呼び出されます。 null ポインターは配列を終了します。 空のリスト (コールバックはサポートされていない) を持つことは完全に有効であり、その場合、コールバック配列にはちょうど 1 つのメンバー (null ポインター) が含まれます。

コールバック関数 (PIMAGE_TLS_CALLBACK 型のポインターによって指される) のプロトタイプには、DLL エントリ ポイント関数と同じパラメーターがあります。

typedef VOID
(NTAPI *PIMAGE_TLS_CALLBACK) (
    PVOID DllHandle,
    DWORD Reason,
    PVOID Reserved
    );

Reserved パラメーターは 0 に設定する必要があります。 Reason パラメーターは次の値を取ることができます。

設定 説明
DLL_PROCESS_ATTACH
1
最初のスレッドを含む新しいプロセスが開始されました。
DLL_THREAD_ATTACH
2
新しいスレッドが作成されました。 この通知は、最初のスレッド以外のすべてのユーザーに送信されます。
DLL_THREAD_DETACH
3
スレッドを終了します。 この通知は、最初のスレッド以外のすべてのユーザーに送信されます。
DLL_PROCESS_DETACH
0
元のスレッドを含むプロセスを終了します。

 

構成構造体の読み込み (イメージのみ)

ロード構成構造体 (IMAGE_LOAD_CONFIG_DIRECTORY) はこれまで、難しすぎたり、大きすぎたりしてファイル ヘッダーやイメージのオプション ヘッダーに記述できないさまざまな機能を記述する場合など、Windows NT オペレーティング システム自体で非常に限られた用途で利用されていました。 現在のバージョンの Microsoft リンカーと Windows XP 以降のバージョンの Windows は、予約された SEH テクノロジを含む 32 ビット x86 ベース システム用のこの構造体の新しいバージョンを使用します。 これにより、オペレーティング システムが例外ディスパッチ中に使用する安全な構造化例外ハンドラーの一覧が提供されます。 ハンドラー アドレスがイメージの VA 範囲に存在し、予約済みの SEH 対応としてマークされている場合 (つまり、前述のように、省略可能なヘッダーの DllCharacteristics フィールドで IMAGE_DLLCHARACTERISTICS_NO_SEH がクリアされます)、ハンドラーはそのイメージの既知の安全なハンドラーの一覧に含まれている必要があります。 それ以外の場合、オペレーティング システムはアプリケーションを終了します。 これは、オペレーティング システムの制御を奪うために過去に使用された「x86 例外ハンドラー ハイジャック」エクスプロイトを防ぐのに役立ちます。

Microsoft リンカーは、予約された SEH データを含めるための既定のロード構成構造体を自動的に提供します。 ユーザー コードがすでにロード構成構造を提供している場合は、新しい予約済み SEH フィールドを含める必要があります。 それ以外の場合、リンカーは予約された SEH データを含めることができず、イメージには予約された SEH を含むものとしてマークされません。

構成ディレクトリの読み込み

事前予約された SEH ロード構成構造体のデータ ディレクトリ エントリでは、ロード構成構造体の特定のサイズを指定する必要があります。これは、オペレーティング システム ローダーが常に特定の値であることを期待しているためです。 その点、サイズは実際にはバージョンの確認にすぎません。 Windows XP および以前のバージョンの Windows との互換性を確保するには、x86 イメージのサイズは 64 である必要があります。

ロード構成体のレイアウト

ロード構成構造体には、32 ビットおよび 64 ビット PE ファイル用の次のレイアウトがあります。

オフセット サイズ フィールド 説明
0
4
特性
現在使用されていないファイルの属性を示すフラグ。
4
4
TimeDateStamp
日付と時刻のスタンプ値。 この値は、システム クロックに従って、協定世界時 1970 年 1 月 1 日の午前 0 時 (00:00:00) から経過した秒数で表されます。 タイム スタンプは、C ランタイム (CRT) 時間関数を使用して出力できます。
8
2
MajorVersion
メジャー バージョン番号。
10
2
MinorVersion
マイナー バージョン番号。
12
4
GlobalFlagsClear
ローダーがプロセスを開始すると、このプロセスをクリアするグローバル ローダー フラグ。
16
4
GlobalFlagsSet
ローダーがプロセスを開始するときにこのプロセスに設定するグローバル ローダー フラグ。
20
4
CriticalSectionDefaultTimeout
放棄されたこのプロセスのクリティカル セクションに使用する既定のタイムアウト値。
24
4/8
DeCommitFreeBlockThreshold
システムに返される前に解放する必要があるメモリ (バイト単位)。
28/32
4/8
DeCommitTotalFreeThreshold
空きメモリの合計量、バイト単位。
32/40
4/8
LockPrefixTable
[x86 のみ] LOCK プレフィックスを使用するアドレスの一覧の VA で、単一のプロセッサ マシンで NOP に置き換え可能。
36/48
4/8
MaximumAllocationSize
最大割り当てサイズ (バイト単位)。
40/56
4/8
VirtualMemoryThreshold
最大仮想メモリ サイズ (バイト単位)。
44/64
4/8
ProcessAffinityMask
このフィールドを 0 以外の値に設定すると、プロセスの起動時に値を指定して SetProcessAffinityMask を呼び出す必要がなくなります (.exe のみ)
48/72
4
ProcessHeapFlags
HeapCreate 関数の最初の引数に対応するプロセス ヒープ フラグ。 これらのフラグは、プロセスの起動時に作成されるプロセス ヒープに適用されます。
52/76
2
CSDVersion
Service Pack のバージョン識別子。
54/78
2
予約済み
ゼロを指定してください。
56/80
4/8
EditList
システムで使用するために予約されています。
60/88
4/8
SecurityCookie
Visual C++ または GS 実装で使用される Cookie へのポインター。
64/96
4/8
SEHandlerTable
[x86 のみ] イメージ内の有効な一意の各 SE ハンドラーの RVA がソートされたテーブルの VA。
68/104
4/8
SEHandlerCount
[x86 のみ] テーブル内の一意のハンドラーの数。
72/112
4/8
GuardCFCheckFunctionPointer
制御フロー ガードチェック関数ポインターが格納される VA。
76/120
4/8
GuardCFDispatchFunctionPointer
制御フロー ガードのディスパッチ関数ポインターが格納される VA。
80/128
4/8
GuardCFFunctionTable
イメージ内の各コントロール フロー ガード機能の RVA がソートされたテーブルの VA。
84/136
4/8
GuardCFFunctionCount
上記のテーブルの一意の RVA の数。
88/144
4
GuardFlags
制御フロー ガード フラグ。
92/148
12
CodeIntegrity
コード整合性情報。
104/160
4/8
GuardAddressTakenIatEntryTable
取得した制御フロー ガード アドレス IAT テーブルが格納される VA。
108/168
4/8
GuardAddressTakenIatEntryCount
上記のテーブルの一意の RVA の数。
112/176
4/8
GuardLongJumpTargetTable
制御フロー ガードのジャンプ ターゲット テーブルが格納される VA。
116/184
4/8
GuardLongJumpTargetCount
上記のテーブルの一意の RVA の数。

 

GuardFlags フィールドには、次のフラグとサブフィールドの 1 つ以上の組み合わせが含まれます。

  • モジュールは、システム提供のサポートを使用して制御フロー整合性チェックを実行します。

    #define IMAGE_GUARD_CF_INSTRUMENTED 0x00000100

  • モジュールは、制御フローと書き込みの整合性チェックを実行します。

    #define IMAGE_GUARD_CFW_INSTRUMENTED 0x00000200

  • モジュールには、有効な制御フロー ターゲット メタデータが含まれています。

    #define IMAGE_GUARD_CF_FUNCTION_TABLE_PRESENT 0x00000400

  • モジュールでは、/GS セキュリティ Cookie は使用されません。

    #define IMAGE_GUARD_SECURITY_COOKIE_UNUSED 0x00000800

  • モジュールでは、読み取り専用の遅延読み込み IAT がサポートされています。

    #define IMAGE_GUARD_PROTECT_DELAYLOAD_IAT 0x00001000

  • 自由に再保護できる (他に何も含まない) 独自の .didat セクションのインポート テーブルの遅延読み込み。

    #define IMAGE_GUARD_DELAYLOAD_IAT_IN_ITS_OWN_SECTION 0x00002000

  • モジュールには、抑制されたエクスポート情報が含まれています。 取得された IAT テーブルのアドレスが読み込み構成にも存在することを示唆します。

    #define IMAGE_GUARD_CF_EXPORT_SUPPRESSION_INFO_PRESENT 0x00004000

  • モジュールを使用すると、エクスポートを抑制できます。

    #define IMAGE_GUARD_CF_ENABLE_EXPORT_SUPPRESSION 0x00008000

  • モジュールには longjmp ターゲット情報が含まれています。

    #define IMAGE_GUARD_CF_LONGJUMP_TABLE_PRESENT 0x00010000

  • 制御フロー ガード関数テーブル エントリのストライド (つまり、テーブル エントリごとの追加バイト数) を含むサブフィールドのマスク。

    #define IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_MASK 0xF0000000

さらに、Windows SDK winnt.h ヘッダーは、制御フロー ガード関数テーブルのストライドを右揃えにするために GuardFlags 値を右シフトするビット量について次のマクロを定義します。

#define IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_SHIFT 28

.rsrc セクション

リソースは、複数レベルのバイナリ並べ替えツリー構造によってインデックスが作成されます。 一般的な設計には、2**31 レベルを組み込むことができます。 ただし、慣例により、Windows では次の 3 つのレベルが使用されます。

タイプ名言語

一連のリソース ディレクトリ テーブルは、次のようにすべてのレベルを関連付けます。各ディレクトリ テーブルの後には、そのレベル (タイプ、名前、または言語レベル) の名前または識別子 (ID) と、データ記述または別のディレクトリ テーブルのアドレスを示す一連のディレクトリ エントリが続きます。 アドレスがデータの説明を指している場合、データはツリー内のリーフになります。 アドレスが別のディレクトリ テーブルを指している場合、そのテーブルには次のレベルのディレクトリ エントリが一覧表示されます。

リーフの型、名前、および言語 ID は、リーフに到達するためにディレクトリ テーブルを通過するパスによって決まります。 最初のテーブルはタイプ ID を決定し、2 番目のテーブル (最初のテーブルのディレクトリ エントリによって示される) は名前 ID を決定し、3 番目のテーブルは言語 ID を決定します。

.rsrc セクションの一般的な構造は次のとおりです。

データ​​ 説明
リソース ディレクトリ テーブル (およびリソース ディレクトリ エントリ)
ツリー内のノードのグループごとに 1 つずつ、一連のテーブル。 すべての最上位 (種類) ノードが最初の表に一覧表示されます。 このテーブルのエントリは、第 2 レベルのテーブルを指します。 各第 2 レベル ツリーの型 ID は同じですが、名前 ID は異なります。 第 3 レベルのツリーの種類 ID と名前 ID は同じですが、言語 ID は異なります。
個々のテーブルの直後にはディレクトリ エントリが続き、各エントリには名前または数値識別子と、データ記述または次の下位レベルのテーブルへのポインターが含まれます。
リソース ディレクトリ文字列
2 バイトアライン Unicode 文字列。ディレクトリ エントリによって指される文字列データとして機能します。
リソースデータの説明
リソース データの実際のサイズと場所を表す、テーブルが指すレコードの配列。 これらのレコードは、リソース記述ツリー内のリーフです。
リソース データ
リソース セクションの生データ。 Resource Data Descriptions フィールドのサイズと場所の情報は、リソース データの個々の領域を区切ります。

 

リソース ディレクトリ テーブル

各リソース ディレクトリ テーブルの形式は次のとおりです。 テーブルは実際にはディレクトリ エントリ (セクション 6.9.2「リソース ディレクトリ エントリ」で説明) と次の構造で構成されているため、このデータ構造はテーブルの見出しであると考える必要があります。

オフセット サイズ フィールド 説明
0
4
特性
リソース フラグ。 このフィールドは今後使用するために予約されています。 現在は 0 に設定されています。
4
4
時刻/日付スタンプ
リソース コンパイラによってリソース データが作成された時刻。
8
2
メジャー バージョン
ユーザーによって設定されたメジャー バージョン番号。
10
2
マイナー バージョン
ユーザーによって設定されたマイナー バージョン番号。
12
2
名前エントリの数
文字列を使用してタイプ、名前、または言語エントリを識別する、テーブルの直後にあるディレクトリ エントリの数 (テーブルのレベルに応じて異なります)。
14
2
ID エントリの数
Type、Name、または Language エントリに数値 ID を使用する Name エントリの直後のディレクトリ エントリの数。

 

リソース ディレクトリ エントリ

ディレクトリ エントリは、テーブルの行を構成します。 各リソース ディレクトリ エントリの形式は次のとおりです。 エントリが名前エントリであるか ID エントリであるかは、後続の名前エントリと ID エントリの数も含めリソース ディレクトリ テーブルに示されます (テーブルではすべての名前エントリがすべての ID エントリより前にあることに注意してください)。 テーブルのすべてのエントリは昇順で並べ替えられます。名前エントリは大文字と小文字を区別する文字列で、ID エントリは数値で並べられます。 オフセットは、IMAGE_DIRECTORY_ENTRY_RESOURCE DataDirectory 内のアドレスに対して相対的です。 詳細については、「PE 内のピアリング: Win32 ポータブル実行可能ファイル形式のツアー」を参照してください。

オフセット サイズ フィールド 説明
0
4
名前オフセット
テーブルのレベルに応じて、Type、Name、または Language ID エントリを指定する文字列のオフセット。
0
4
整数 ID
Type、Name、または Language ID エントリを識別する 32 ビット整数。
4
4
データ 入力オフセット
上位ビット 0。 リソース データ エントリ (リーフ) のアドレス。
4
4
サブディレクトリ オフセット
上位ビット 1。 下位 31 ビットは、別のリソース ディレクトリ テーブルのアドレスです (次のレベル下)。

 

リソース ディレクトリ文字列

リソース ディレクトリ文字列領域は、単語でアラインされた Unicode 文字列で構成されます。 これらの文字列は、最後の Resource Directory エントリの後、および最初のリソース データ エントリの前にまとめて格納されます。 これにより、固定サイズのディレクトリ エントリの配置に対するこれらの可変長文字列の影響が最小限に抑えられます。 各リソース ディレクトリ 文字列の形式は次のとおりです。

オフセット サイズ フィールド 説明
0
2
長さ
長さフィールド自体を含まない文字列のサイズ。
2
変数
Unicode 文字列
ワードアラインメントされた可変長 Unicode 文字列データ。

 

リソース データ エントリ

各リソース データ エントリには、リソース データ領域の生データの実際の単位が記述されます。 リソース データ エントリ の形式は次のとおりです。

オフセット サイズ フィールド 説明
0
4
データ RVA
リソース データ領域のリソース データの単位のアドレス。
4
4
サイズ
Data RVA フィールドが指すリソース データのサイズ (バイト単位)。
8
4
Codepage
リソース データ内のコード ポイント値をデコードするために使用されるコード ページ。 通常、コード ページは Unicode コード ページです。
12
4
予約済み、0 である必要があります

 

.cormeta セクション (オブジェクトのみ)

CLR メタデータは、このセクションに格納されます。 これは、オブジェクト ファイルにマネージド コードが含まれていることを示すために使用されます。 メタデータの形式は文書化されていませんが、メタデータを処理するために CLR インターフェイスに渡すことができます。

.sxdata セクション

オブジェクトの有効な例外ハンドラーは、そのオブジェクトの .sxdata セクションに一覧表示されます。 このセクションは IMAGE_SCN_LNK_INFO とマークされています。 これには、有効な各ハンドラーの COFF シンボル インデックスが含まれています。インデックスあたり 4 バイトを使用します。

さらに、コンパイラは、値フィールドの LSB が 1 に設定された絶対シンボル「@feat.00」を発行することにより、COFF オブジェクトを登録済み SEH としてマークします。 SEH ハンドラーが登録されていない COFF オブジェクトには、「@feat.00」シンボルが付きまが、.sxdata セクションはありません。

アーカイブ (ライブラリ) ファイル形式

COFF アーカイブ形式は、オブジェクト ファイルのコレクションを格納するための標準的なメカニズムを提供します。 これらのコレクションは、プログラミング ドキュメントでは一般的にライブラリと呼ばれます。

アーカイブの最初の 8 バイトは、ファイル署名で構成されます。 アーカイブの残りの部分は、次のような一連のアーカイブ メンバーで構成されます。

  • 1 番目と 2 番目のメンバーは「リンカー メンバー」です。これらの各メンバーは、「インポート名の種類」セクションの説明に従って、独自の形式を持ちます。 通常、リンカーはこれらのアーカイブ メンバーに情報を配置します。 リンカー メンバーには、アーカイブのディレクトリが含まれています。

  • 3 番目のメンバーは「longnames」メンバーです。 この省略可能なメンバーは、各文字列が別のアーカイブ メンバーの名前である一連の null で終わる ASCII 文字列で構成されます。

  • アーカイブの残りの部分は、標準 (オブジェクト ファイル) メンバーで構成されます。 これらの各メンバーには、1 つのオブジェクト ファイル全体の内容が含まれています。

アーカイブ メンバー ヘッダーは、各メンバーの前にあります。 次のリストは、アーカイブの一般的な構造を示しています。

サイン :"!<arch>\n"
ヘッダー
最初のリンカー メンバー
ヘッダー
2 番目のリンカー メンバー
ヘッダー
Longnames メンバー
ヘッダー
OBJ ファイル 1 の内容
(COFF 形式)
ヘッダー
OBJ ファイル 2 の内容
(COFF 形式)

...

ヘッダー
OBJ ファイル N の内容
(COFF 形式)

ファイル署名のアーカイブ

アーカイブ ファイル署名は、ファイルの種類を識別します。 入力としてアーカイブ ファイルを受け取るユーティリティ (リンカーなど) は、この署名を読み取ることでファイルの種類をチェックできます。 署名は次の ASCII 文字で構成され、改行 (\n) 文字を除き、以下の各文字がリテラルで表されます。

!<arch>\n

Windows SDK winnt.h ヘッダーは、次のマクロを定義します。

#define IMAGE_ARCHIVE_START_SIZE             8
#define IMAGE_ARCHIVE_START                  "!<arch>\n"
#define IMAGE_ARCHIVE_END                    "`\n"
#define IMAGE_ARCHIVE_PAD                    "\n"
#define IMAGE_ARCHIVE_LINKER_MEMBER          "/               "
#define IMAGE_ARCHIVE_LONGNAMES_MEMBER       "//              "
#define IMAGE_ARCHIVE_HYBRIDMAP_MEMBER       "/<HYBRIDMAP>/   "

メンバー ヘッダーのアーカイブ

各メンバー (リンカー、longnames、またはオブジェクト ファイル メンバー) の前にヘッダーが付きます。 アーカイブ メンバー ヘッダーの形式は次のとおりです。各フィールドは ASCII テキスト文字列であり、両端揃えのままで、フィールドの末尾にスペースが埋め込まれます。 これらのいずれのフィールドにも終端の null 文字はありません。

各メンバー ヘッダーは、前のアーカイブ メンバーの終了後の最初の偶数アドレスで始まります。アーカイブ メンバーの後に 1 バイト '\n' (IMAGE_ARCHIVE_PAD) を挿入して、次のメンバーを偶数アドレスで開始することができます。

オフセット サイズ フィールド 説明
0
16
名前
アーカイブ メンバーの名前。名前を終了するためにスラッシュ (/) が追加されています。 最初の文字がスラッシュの場合、次の表に示すように、名前には特別な解釈があります。
16
12
日付
アーカイブ メンバーが作成された日時: これは、UCT 1970 年 1 月 1 日からの秒数を ASCII 10 進数で表したものです。
28
6
ユーザー ID
ユーザー ID の ASCII 10 進表現。 Microsoft ツールではすべての空白が出力されるため、このフィールドには Windows プラットフォームでは意味のある値は含まれません。
34
6
グループ ID
グループ ID の ASCII 10 進表現。 Microsoft ツールではすべての空白が出力されるため、このフィールドには Windows プラットフォームでは意味のある値は含まれません。
40
8
モード
メンバーのファイル モードの ASCII 8 進数表現。 これは、C ランタイム関数 _wstat からの ST_MODE 値です。
48
10
サイズ
ヘッダーのサイズを含まない、アーカイブ メンバーの合計サイズの ASCII 10 進表現。
58
2
ヘッダーの末尾
C 文字列「`\n」(IMAGE_ARCHIVE_END) の 2 バイト (0x60 0x0A)。

Name フィールドには、次の表に示すいずれかの形式があります。 前述したように、これらの各文字列は左寄せされ、16 バイトのフィールド内で末尾のスペースが埋め込まれます。

Name フィールドの内容 説明
name/
アーカイブの名前を変更します。
/
アーカイブ メンバーは、2 つのリンカー メンバーのいずれかです。 どちらのリンカー メンバーにもこの名前が付けられます。
//
アーカイブ メンバーは longnames メンバーであり、一連の null で終わる ASCII 文字列で構成されます。 longnames メンバーは 3 番目のアーカイブ メンバーであり、省略可能です。
/n
アーカイブ メンバーの名前は、longnames メンバー内のオフセット n にあります。 数値 n はオフセットの 10 進表現です。 たとえば、「/26」は、アーカイブ メンバーの名前が、ロングネーム メンバーの内容の先頭から 26 バイト離れたところにあることを示します。

 

最初のリンカー メンバー

最初のリンカー メンバーの名前は「/」 (IMAGE_ARCHIVE_LINKER_MEMBER) です。 最初のリンカー メンバーは、下位互換性のために含まれています。 現在のリンカーでは使用されませんが、その形式は正しい必要があります。 このリンカー メンバーは、2 番目のリンカー メンバーと同様に、シンボル名のディレクトリを提供します。 各シンボルの情報は、シンボルを含むアーカイブ メンバーを検索する場所を示します。

最初のリンカー メンバーの形式は次のとおりです。 この情報は、ヘッダーの後に表示されます。

オフセット サイズ フィールド 説明
0
4
シンボルの数
インデックス付きシンボルの数を含む符号なし long。 この数値はビッグ エンディアン形式で格納されます。 通常、各オブジェクト ファイル メンバーは 1 つ以上の外部シンボルを定義します。
4
4 * n
オフセット
アーカイブ メンバー ヘッダーへのファイル オフセットの配列。n は Number of Symbols フィールドと等しくなります。 配列内の各数値は、ビッグ エンディアン形式で格納された符号なし long です。 文字列テーブルに名前が付けられたシンボルごとに、offsets 配列内の対応する要素によって、シンボルを含むアーカイブ メンバーの場所が指定されます。
*
*
文字列テーブル
ディレクトリ内のすべてのシンボルに名前を付けた一連の null で終わる文字列。 各文字列は、前の文字列の null 文字の直後から始まります。 文字列の数は、Number of Symbols フィールドの値と等しい必要があります。

 

オフセット配列内の要素は昇順に配置する必要があります。 これは、文字列テーブル内のシンボルをアーカイブ メンバーの順序に従って配置する必要があることを意味します。 たとえば、最初のオブジェクト ファイル メンバー内のすべてのシンボルは、2 番目のオブジェクト ファイル内のシンボルの前に一覧表示する必要があります。

2 番目のリンカー メンバー

最初のリンカー メンバーと同様に、2 番目のリンカー メンバーの名前は「/」 (IMAGE_ARCHIVE_LINKER_MEMBER) です。 どちらのリンカー メンバーもシンボルのディレクトリと、それらを含むアーカイブ メンバーを提供しますが、現在のすべてのリンカーでは 2 番目のリンカー メンバーが最初のリンカー メンバーよりも優先して使用されます。 2 番目のリンカー メンバーには、字句順にシンボル名が含まれているため、名前による検索が高速になります。

2 番目のメンバーの形式は次のとおりです。 この情報は、ヘッダーの後に表示されます。

オフセット サイズ フィールド 説明
0
4
メンバーの数
アーカイブ メンバーの数を含む符号なし long。
4
4 * m
オフセット
アーカイブ メンバー ヘッダーへのファイル オフセットの配列。昇順に配置されます。 各オフセットは符号なし long です。 数値 m は、Number of Members フィールドの値と等しくなります。
*
4
シンボルの数
インデックス付けされたシンボルの数を含む符号なし long。 通常、各オブジェクト ファイル メンバーは 1 つ以上の外部シンボルを定義します。
*
2 * n
インデックス
シンボル名をアーカイブ メンバー オフセットにマップする 1 から始まるインデックス (符号なし short) の配列。 数値 n は、Number of Symbols フィールドと等しくなります。 文字列テーブルに名前が付けられたシンボルごとに、Indexs 配列内の対応する要素がオフセット配列にインデックスを与えます。 オフセット配列は、シンボルを含むアーカイブ メンバーの位置を示します。
*
*
文字列テーブル
ディレクトリ内のすべてのシンボルに名前を付けた一連の null で終わる文字列。 各文字列は、前の文字列の null バイトの直後から始まります。 文字列の数は、Number of Symbols フィールドの値と等しい必要があります。 次の表に、すべてのシンボル名を構文の昇順で示します。

 

Longnames メンバー

ロングネームメンバーの名前は「//」(IMAGE_ARCHIVE_LONGNAMES_MEMBER) です。 longnames メンバーは、アーカイブ メンバー名の一連の文字列です。 名前は、Name フィールドに十分な空き領域がない場合にのみ表示されます (16 バイト)。 longnames メンバーは省略可能です。 ヘッダーのみで空にすることも、ヘッダーなしでも完全に存在しない場合もあります。

文字列は null で終わります。 各文字列は、前の文字列の null バイトの直後から始まります。

ライブラリ形式のインポート

従来のインポート ライブラリ、つまり、あるイメージからのエクスポートを別のイメージで使用するために記述するライブラリは、通常、セクション 7 の「アーカイブ (ライブラリ) ファイル形式」で説明されているレイアウトに従います。 主な違いは、インポート ライブラリ メンバーには実際のファイルではなく擬似オブジェクト ファイルが含まれていることです。このファイルには、セクション 6.4「.idata セクション」で説明されているインポート テーブルのビルドに必要なセクション コントリビューションが各メンバーに含まれています。リンカーは、エクスポート アプリケーションのビルド中にこのアーカイブを生成します。

インポートに対するセクションの寄与は、少数の情報セットから推測できます。 リンカーは、ライブラリの作成時に各メンバーのインポート ライブラリに完全な詳細情報を生成することも、正規の情報のみをライブラリに書き込んで、後でそれを使用するアプリケーションが必要なデータをオンザフライで生成できるようにすることもできます。

長い形式のインポート ライブラリでは、1 つのメンバーに次の情報が含まれます。

  • メンバー ヘッダーのアーカイブ
  • ファイル ヘッダー
  • セクション ヘッダー
  • 各セクション ヘッダーに対応するデータ
  • COFF シンボル テーブル
  • 文字列

これに対し、短いインポート ライブラリは次のように記述されます。

  • メンバー ヘッダーのアーカイブ
  • ヘッダーのインポート
  • Null で終わるインポート名の文字列
  • Null で終了する DLL 名文字列

これは、使用時にメンバーのコンテンツ全体を正確に再構成するのに十分な情報です。

ヘッダーのインポート

インポート ヘッダーには、次のフィールドとオフセットが含まれています。

オフセット サイズ フィールド 説明
0
2
Sig1
IMAGE_FILE_MACHINE_UNKNOWN である必要があります。 詳細については、「メッセージの種類」を参照してください。
2
2
Sig2
0xFFFF である必要があります。
4
2
バージョン
構造体バージョン。
6
2
機械
ターゲット マシンのタイプを識別する番号。 詳細については、「メッセージの種類」を参照してください。
8
4
日付/時刻スタンプ
ファイルが作成された時刻と日付。
12
4
データのサイズ
ヘッダーの後に続く文字列のサイズ。
16
2
序数/ヒント
Name Type フィールドの値によって決定されるインポートの序数またはヒント。
18
2 ビット
種類
インポートの種類。 特定の値と説明については、「インポートの種類」を参照してください。
3 ビット
名前の種類
インポート名の種類。 詳細については、「インポート名の種類」を参照してください。
11 ビット
予約済み
予約済み、0 である必要があります

 

この構造体の後には、インポートされたシンボルの名前とその元の DLL を説明する 2 つの null で終わる文字列が続きます。

インポートの種類

インポート ヘッダーの [Type] フィールドには、次の値が定義されています。

定数 説明
IMPORT_OBJECT_CODE
0
実行可能なコード。
IMPORT_OBJECT_DATA
1
データ。
IMPORT_OBJECT_CONST
2
.def ファイルで CONST として指定されます。

これらの値は、ライブラリを使用するツールがそのデータにアクセスする必要がある場合に、どのセクションの寄与を生成する必要があるかを決定するために使用されます。

インポート名の種類

null で終わるインポート シンボル名は、関連付けられているインポート ヘッダーの直後にあります。 インポート ヘッダーの [Name Type] フィールドには、次の値が定義されています。 これらは、インポートを表す正しいシンボルを生成するために名前を使用する方法を示します。

定数 説明
IMPORT_OBJECT_ORDINAL 0 インポートは序数で行います。 これは、インポート ヘッダーの [Ordinal/Hint] フィールドの値がインポートの序数であることを示します。 この定数が指定されていない場合、[Ordinal/Hint] フィールドは常にインポートのヒントとして解釈される必要があります。
IMPORT_OBJECT_NAME 1 インポート名は、パブリック シンボル名と同じです。
IMPORT_OBJECT_NAME_NOPREFIX 2 インポート名はパブリック シンボル名ですが、先頭の ?、@、またはオプションで _ を省略します。
IMPORT_OBJECT_NAME_UNDECORATE 3 インポート名はパブリック シンボル名ですが、先頭の ?、@、またはオプションで _ をスキップし、最初の @ で切り捨てられます。

付録 A: Authenticode PE イメージ ハッシュの計算

イメージの整合性を検証するために、いくつかの属性証明書が使用されることが想定されています。 ただし、最も一般的なのは Authenticode 署名です。 Authenticode 署名を使用すると、PE イメージ ファイルの関連セクションがファイルの元の形式からまったく変更されていないことを確認できます。 このタスクを実行するために、Authenticode 署名には PE イメージ ハッシュと呼ばれるものが含まれています

Authenticode PE イメージ ハッシュとは

Authenticode PE イメージ ハッシュ (略してファイル ハッシュ) は、ファイルの整合性に関連する小さな値を生成するという点でファイル チェックサムに似ています。 チェックサムは単純なアルゴリズムによって生成され、主にメモリ障害を検出するために使用されます。 つまり、ディスク上のメモリのブロックが不良になり、そこに保存されている値が破損したかどうかを検出するために使用されます。 ファイル ハッシュは、ファイルの破損も検出するという点で、チェックに似ています。 ただし、ほとんどのチェックサム アルゴリズムとは異なり、元の (変更されていない) 形式と同じファイル ハッシュになるようにファイルを変更することは非常に困難です。 つまり、チェックサムは破損につながる単純なメモリ障害を検出することを目的としていますが、ファイル ハッシュを使用すると、ウイルス、ハッカー、またはトロイの木馬プログラムによって加えられたファイルへの意図的な変更や微妙な変更さえも検出できます。

Authenticode 署名では、ファイルの署名者だけが知っている秘密キーを使用して、ファイル ハッシュがデジタル署名されます。 ソフトウェア利用者は、ファイルのハッシュ値を計算し、それを Authenticode デジタル署名に含まれる署名付きハッシュの値と比較することで、ファイルの整合性を検証できます。 ファイル ハッシュが一致しない場合は、PE イメージ ハッシュの対象となるファイルの一部が変更されています。

Authenticode PE イメージ ハッシュでカバーされる内容

PE イメージ ハッシュの計算にすべてのイメージ ファイル データを含めることは不可能であり、望ましいことでもありません。 場合によっては、単に望ましくない特性を示す場合もあります (たとえば、公開されたファイルからデバッグ情報を削除できないなど)。単に不可能な場合もあります。 たとえば、イメージ ファイル内のすべての情報を Authenticode 署名に含めてから、その PE イメージ ハッシュを含む Authenticode 署名を PE イメージに挿入し、後ですべての情報を含めることで同一の PE イメージ ハッシュを生成することはできません。ファイルには元々存在しなかった Authenticode 署名が含まれるため、イメージ ファイル データが再度計算に含まれます。

Authenticode PE イメージ ハッシュを生成するプロセス

このセクションでは、PE イメージ ハッシュの計算方法と、Authenticode 署名を無効にすることなく PE イメージのどの部分を変更できるかについて説明します。

特定のファイルの PE イメージ ハッシュは、ハッシュ ファイル内に属性証明書を含めずに、別のカタログ ファイルに含めることができます。 実際には Authenticode 署名が含まれていない PE イメージを変更することで、Authenticode 署名付きカタログ ファイル内の PE イメージ ハッシュを無効にすることが可能になるため、これは重要です。

セクション テーブルで指定された PE イメージのセクション内のすべてのデータは、次の除外範囲を除いて全体的にハッシュされます。

  • 省略可能なヘッダーの Windows 固有のフィールドのファイル CheckSum フィールド。 このチェックサムには、ファイル全体 (ファイル内の属性証明書を含む) が含まれます。 ほとんどの場合、Authenticode 署名を挿入した後のチェックサムは元の値とは異なります。

  • 属性証明書に関連する情報。 Authenticode 署名は、イメージ全体の整合性に影響を与えることなくイメージに追加または削除できるため、Authenticode 署名に関連する PE イメージの領域は、PE イメージ ハッシュの計算には含まれません。 PE イメージの再署名やタイムスタンプの追加に依存するユーザー シナリオがあるため、これは問題ではありません。 Authenticode では、ハッシュ計算から次の情報が除外されます。

    • オプションのヘッダー データ ディレクトリの証明書テーブル フィールド。

    • 証明書テーブルと、すぐ上にリストされている証明書テーブル フィールドによって指定される対応する証明書。

    PE イメージ ハッシュを計算するために、Authenticode はセクション テーブルで指定されたセクションをアドレス範囲ごとに順序付けし、除外範囲を超えて結果のバイト シーケンスをハッシュします。

  • 最後のセクション終了時点以降の情報です。 最後のセクションを超えた領域 (最も高いオフセットで定義) はハッシュされません。 この領域には、通常、デバッグ情報が含まれています。 デバッグ情報は通常、デバッガに対する助言であると考えられます。実行可能プログラムの実際の整合性には影響しません。 製品の納品後に、プログラムの機能に影響を与えずに、イメージからデバッグ情報を削除することは文字通り可能です。 実際、これはディスク節約の手段として行われることがあります。 PE イメージの指定されたセクションに含まれるデバッグ情報は、Authenticode 署名を無効にしない限り削除できないことに注意してください。

Windows プラットフォーム SDK で提供される makecert ツールと Signtool ツールを使用して、Authenticode 署名の作成と検証を試すことができます。 詳細については、以下の「参考資料」を参照してください。

参考資料

Windows 用のダウンロードとツール (Windows SDK を含む)

証明書の作成、表示、管理

カーネル モード コード署名のチュートリアル (.doc)

SignTool

Windows Authenticode ポータブル実行可能署名形式 (.docx)

ImageHlp 関数