PE 形式

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

Note

このドキュメントは、Windows 用のツールとアプリケーションの開発に役立ちますが、すべての点で完全な仕様であるとは限りません。 Microsoft は、このドキュメントを予告なしに変更する権利を留保します。

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

一般的な概念

このドキュメントでは、オペレーティング システムの Microsoft Windows ファミリの下にある実行可能ファイル (イメージ) ファイルとオブジェクト ファイルの構造を指定します。 これらのファイルは、それぞれポータブル実行可能ファイル (PE) ファイルと共通オブジェクト ファイル形式 (COFF) ファイルと呼ばれます。 "ポータブル実行可能ファイル" という名前は、形式がアーキテクチャ固有ではないという事実を指します。

この仕様全体で使用される特定の概念を次の表に示します。

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

  • セクション ヘッダー

  • 生データ:

    code

    data

    デバッグ情報

    リロケーション

ファイル ヘッダー

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 に制限されることに注意してください。

Offset サイズ フィールド 説明
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
特性
ファイルの属性を示すフラグ。 特定のフラグ値については、「 特性」を参照してください。

マシンの種類

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

定数 説明
IMAGE_FILE_MACHINE_UNKNOWN
0x0
このフィールドの内容は、任意のコンピューターの種類に適用されるものと見なされます
IMAGE_FILE_MACHINE_ALPHA
0x184
Alpha AXP、32 ビット アドレス空間
IMAGE_FILE_MACHINE_ALPHA64
0x284
アルファ 64、64 ビットアドレス空間
IMAGE_FILE_MACHINE_AM33
0x1d3
松下 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
日立 SH3
IMAGE_FILE_MACHINE_SH3DSP
0x1a3
日立 SH3 DSP
IMAGE_FILE_MACHINE_SH4
0x1a6
日立 SH4
IMAGE_FILE_MACHINE_SH5
0x1a8
日立 SH5
IMAGE_FILE_MACHINE_THUMB
0x1c2
つまみ
IMAGE_FILE_MACHINE_WCEMIPSV2
0x169
MIPS リトル エンディアン WCE v2

特性

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

フラグ 説明
IMAGE_FILE_RELOCS_STRIPPED
0x0001
イメージのみ、Windows CE、Microsoft Windows NT以降。 これは、ファイルにベース再配置が含まれていないため、優先ベース アドレスで読み込む必要があることを示します。 ベース アドレスが使用できない場合、ローダーはエラーを報告します。 リンカーの既定の動作では、実行可能ファイル (EXE) からベース再配置を削除します。
IMAGE_FILE_EXECUTABLE_IMAGE
0x0002
画像のみ。 これは、イメージ ファイルが有効であり、実行できることを示します。 このフラグが設定されていない場合は、リンカー エラーを示します。
IMAGE_FILE_LINE_NUMS_STRIPPED
0x0004
COFF 行番号が削除されました。 このフラグは非推奨であり、ゼロにする必要があります。
IMAGE_FILE_LOCAL_SYMS_STRIPPED
0x0008
ローカル シンボルの COFF シンボル テーブルエントリが削除されました。 このフラグは非推奨であり、ゼロにする必要があります。
IMAGE_FILE_AGGRESSIVE_WS_TRIM
0x0010
互換性のために残されています。 作業セットを積極的にトリミングします。 このフラグは、Windows 2000 以降では非推奨であり、ゼロである必要があります。
IMAGE_FILE_LARGE_ADDRESS_ AWARE
0x0020
アプリケーションは 2 GB のアドレスを処理 > できます。
0x0040
このフラグは、今後使用するために予約されています。
IMAGE_FILE_BYTES_REVERSED_LO
0x0080
リトル エンディアン: メモリ内の最下位ビット (MSB) の前に最下位ビット (LSB) が付きます。 このフラグは非推奨であり、ゼロにする必要があります。
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 の前にあります。 このフラグは非推奨であり、ゼロにする必要があります。

省略可能なヘッダー (画像のみ)

すべてのイメージ ファイルには、ローダーに情報を提供する省略可能なヘッダーがあります。 このヘッダーは、一部のファイル (具体的にはオブジェクト ファイル) に存在しないという意味では省略可能です。 イメージ ファイルの場合は、このヘッダーが必要です。 オブジェクト ファイルには省略可能なヘッダーを指定できますが、通常、このヘッダーには、サイズを大きくする以外に、オブジェクト ファイルに関数はありません。

省略可能なヘッダーのサイズは固定されていないことに注意してください。 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 以降の形式では変更されません。

Offset サイズ フィールド 説明
0
2
マジック
イメージ ファイルの状態を識別する符号なし整数。 最も一般的な数値は、通常の実行可能ファイルとして識別される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 以降に存在しないこの追加フィールドが含まれています。

Offset サイズ フィールド 説明
24
4
BaseOfData
メモリに読み込まれるときに、データの先頭セクションのイメージ ベースに対する相対アドレス。

省略可能なヘッダー Windows-Specific フィールド (画像のみ)

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

オフセット (PE32/PE32 以降) サイズ (PE32/PE32+) フィールド 説明
28/24
4/8
ImageBase
メモリに読み込まれるときのイメージの最初のバイトの優先アドレス。は 64 K の倍数である必要があります。DLL の既定値は0x10000000です。 Windows CE EXEs の既定値は 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 の累乗である必要があります。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
MS-DOS スタブ、PE ヘッダー、セクション ヘッダーの合計サイズは、FileAlignment の倍数に切り上げられます。
64/64
4
チェックサム
イメージ ファイルのチェックサム。 チェックサムを計算するためのアルゴリズムは、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
テーブルのエクスポート
エクスポート テーブルのアドレスとサイズ。 詳細については、「 .edata セクション (画像のみ)」を参照してください。
104/120
8
テーブルのインポート
インポート テーブルのアドレスとサイズ。 詳細については、「 .idata セクション」を参照してください。
112/128
8
リソース テーブル
リソース テーブルのアドレスとサイズ。 詳細については、「 .rsrc セクション」を参照してください。
120/136
8
例外テーブル
例外テーブルのアドレスとサイズ。 詳細については、「 .pdata セクション」を参照してください。
128/144
8
証明書テーブル
属性証明書テーブルのアドレスとサイズ。 詳細については、「 属性証明書テーブル (イメージのみ)」を参照してください。
136/152
8
ベース再配置テーブル
ベース再配置テーブルのアドレスとサイズ。 詳細については、「 .reloc セクション (イメージのみ)」を参照してください。
144/160
8
デバッグ
デバッグ データの開始アドレスとサイズ。 詳細については、「 .debug セクション」を参照してください。
152/168
8
アーキテクチャ
予約済み、0 である必要があります
160/176
8
Global Ptr
グローバル ポインター レジスタに格納される値の RVA。 この構造体の size メンバーは 0 に設定する必要があります。
168/184
8
TLS テーブル
スレッド ローカル ストレージ (TLS) テーブルのアドレスとサイズ。 詳細については、「 .tls セクション」を参照してください。
176/192
8
構成テーブルの読み込み
ロード構成テーブルのアドレスとサイズ。 詳細については、「 Load Configuration Structure (イメージのみ)」を参照してください。
184/200
8
バインドされたインポート
バインドされたインポート テーブルのアドレスとサイズ。
192/208
8
Iat
インポート アドレス テーブルのアドレスとサイズ。 詳細については、「 アドレス テーブルのインポート」を参照してください。
200/216
8
インポート記述子の遅延
遅延インポート記述子のアドレスとサイズ。 詳細については、「 インポート テーブルの遅延読み込み (イメージのみ)」を参照してください。
208/224
8
CLR ランタイム ヘッダー
CLR ランタイム ヘッダーのアドレスとサイズ。 詳細については、「 .cormeta セクション (オブジェクトのみ)」を参照してください。
216/232
8
予約済み、0 にする必要があります

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

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

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

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

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

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

Offset サイズ フィールド 説明
0
8
名前
8 バイトの null 埋め込み UTF-8 エンコード文字列。 文字列の長さがちょうど 8 文字の場合、終了 null は発生しません。 長い名前の場合、このフィールドにはスラッシュ (/) が含まれます。その後に、文字列テーブルへのオフセットである 10 進数の ASCII 表現が続きます。 実行可能イメージは文字列テーブルを使用せず、8 文字を超えるセクション名をサポートしていません。 オブジェクト ファイル内の長い名前は、実行可能ファイルに出力されると切り捨てられます。
8
4
VirtualSize
メモリに読み込まれた場合のセクションの合計サイズ。 この値が SizeOfRawData より大きい場合、セクションはゼロ埋め込みになります。 このフィールドは実行可能イメージに対してのみ有効であり、オブジェクト ファイルの場合は 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
特性
セクションの特性を説明するフラグ。 詳細については、「 セクション フラグ」を参照してください。

 

セクション フラグ

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

フラグ 説明
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
0x00000200
セクションには、コメントまたはその他の情報が含まれています。 .drectve セクションには、この型があります。 これはオブジェクト ファイルに対してのみ有効です。
0x00000400
将来利用するために予約されています。
IMAGE_SCN_LNK_REMOVE
0x00000800
セクションはイメージの一部になりません。 これは、オブジェクト ファイルに対してのみ有効です。
IMAGE_SCN_LNK_COMDAT
0x00001000
セクションには COMDAT データが含まれています。 詳細については、「 COMDAT セクション (オブジェクトのみ)」を参照してください。 これは、オブジェクト ファイルに対してのみ有効です。
IMAGE_SCN_GPREL
0x00008000
セクションには、グローバル ポインター (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未満の場合は、エラーです。

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

"$"? character (ドル記号) には、オブジェクト ファイル内のセクション名に特別な解釈があります。

オブジェクト セクションの内容を含むイメージ セクションを決定すると、リンカーは "$" を破棄しますか? およびそれに続くすべての文字。 したがって、 という名前のオブジェクト セクション。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 より小さい場合、剰余はゼロで埋められます。

イメージ ファイルでは、省略可能なヘッダーの FileAlignment フィールドで指定された境界にセクション データを配置する必要があります。 セクション データは、対応するセクションの RVA 値の順序で表示する必要があります (セクション テーブルの個々のセクション ヘッダーと同様)。

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

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

オブジェクト ファイルには COFF 再配置が含まれています。これは、イメージ ファイルに配置した後にメモリに読み込むときにセクション データを変更する方法を指定します。

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

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

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

 

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

型インジケーター

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

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 ビットは 0 であり、格納されません。
この再配置は、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
B 命令と BL 命令の場合、ターゲットに対する 26 ビットの相対変位。
IMAGE_REL_ARM64_PAGEBASE_REL21
0x0004
ADRP 命令のターゲットのページ ベース。
IMAGE_REL_ARM64_REL21
0x0005
命令 ADR のターゲットに対する 12 ビットの相対変位
IMAGE_REL_ARM64_PAGEOFFSET_12A
0x0006
ターゲットの 12 ビット ページ オフセット。手順 ADD/ADDS (イミディエイト) (シフトゼロ)。
IMAGE_REL_ARM64_PAGEOFFSET_12L
0x0007
命令 LDR (インデックス付き、符号なしイミディエイト) のターゲットの 12 ビット ページ オフセット。
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
命令 LDR (インデックス付き、符号なしイミディエイト) のターゲットのセクション オフセットのビット 0:11。
IMAGE_REL_ARM64_TOKEN
0x000C
CLR トークン。
IMAGE_REL_ARM64_SECTION
0x000D
ターゲットを含むセクションの 16 ビット セクション インデックス。 これは、デバッグ情報をサポートするために使用されます。
IMAGE_REL_ARM64_ADDR64
0x000E
再配置ターゲットの 64 ビット VA。
IMAGE_REL_ARM64_BRANCH19
0x000F
条件付き B 命令の再配置ターゲットへの 19 ビット オフセット。
IMAGE_REL_ARM64_BRANCH14
0x0010
命令 TBZ と TBNZ の場合、再配置ターゲットへの 14 ビット オフセット。
IMAGE_REL_ARM64_REL32
0x0011
再配置後のバイトからの 32 ビット相対アドレス。
日立スーパーHプロセッサ

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 命令シーケンスの最初の命令に使用されます。 この再配置の直後に PAIR 再配置が行われ、その後に SymbolTableIndex に、再配置される場所から取得された上位 16 ビットに追加される符号付き 16 ビットの変位が含まれている必要があります。
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 である必要があります。 再配置の後に、IMM64 バンドルの 3 つのスロットすべてに格納される前に、ターゲット アドレスに値が追加される ADDEND 再配置を実行できます。
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 再配置と、計算されて GPREL22 バンドルに適用される 22 ビットの GP 相対オフセットを指定できます。
IMAGE_REL_IA64_LTOFF22
0x000A
この命令は、ターゲット シンボルのリテラル テーブル エントリに対する 22 ビット GP 相対オフセットで修正されます。 リンカーは、この再配置と後に続く可能性がある ADDEND 再配置に基づいて、このリテラル テーブル エントリを作成します。
IMAGE_REL_IA64_SECTION
0x000B
セクションの 16 ビット セクション インデックスには、ターゲットが含まれています。 これは、デバッグ情報をサポートするために使用されます。
IMAGE_REL_IA64_SECREL22
0x000C
命令は、セクションの先頭からターゲットの 22 ビット オフセットで固定されます。 この再配置の直後に ADDEND 再配置が行われ、その Value フィールドにはセクションの先頭からのターゲットの 32 ビット符号なしオフセットが含まれます。
IMAGE_REL_IA64_SECREL64I
0x000D
この再配置のスロット番号は 1 である必要があります。 命令は、セクションの先頭からターゲットの 64 ビット オフセットで固定されます。 この再配置の直後には、セクションの先頭からターゲットの 32 ビット符号なしオフセットが Value フィールドに含まれる ADDEND 再配置が続きます。
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 ビット フィールドに収まる場合は、バンドル全体を NOP を使用して MBB バンドルに変換します。スロット 1 の B とスロット 2 の 25 ビット BR 命令 (4 つの最低ビットはすべてゼロおよびドロップ) です。
IMAGE_REL_IA64_PCREL60F
0x0017
60 ビット PC 相対修正。 ターゲット変位が符号付き 25 ビット フィールドに収まる場合は、バンドル全体を NOP を使用して MFB バンドルに変換します。スロット 1 の F と、スロット 2 の 25 ビット (4 つの最低ビットすべてゼロおよびドロップされた) BR 命令。
IMAGE_REL_IA64_PCREL60I
0x0018
60 ビット PC 相対修正。 ターゲット変位が符号付き 25 ビット フィールドに収まる場合は、バンドル全体を NOP を使用して MIB バンドルに変換します。スロット 1 の I と、スロット 2 の 25 ビット (最低 4 ビットすべてゼロおよびドロップ) BR 命令。
IMAGE_REL_IA64_PCREL60M
0x0019
60 ビット PC 相対修正。 ターゲット変位が符号付き 25 ビット フィールドに収まる場合は、バンドル全体を NOP を使用して MMB バンドルに変換します。スロット 1 の M と、スロット 2 の 25 ビット (最低 4 ビットすべてゼロおよびドロップ) BR 命令。
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 命令シーケンスの最初の命令に使用されます。 この再配置の直後に、SymbolTableIndex に符号付き 16 ビットの変位が含まれている PAIR 再配置が続く必要があります。これは、再配置される場所から取得された上位 16 ビットに追加されます。
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 MB。
IMAGE_REL_M32R_REFHI
0x0009
LSB 符号拡張用に調整されたターゲット VA の 16 MSB。 これは、完全な 32 ビット アドレスを読み込む 2 命令シーケンスの最初の命令に使用されます。 この再配置の直後に、SymbolTableIndex に符号付き 16 ビットの変位が含まれている PAIR 再配置が続く必要があります。これは、再配置される場所から取得された上位 16 ビットに追加されます。
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 行番号は、固定長レコードの配列で構成されます。 配列の場所 (ファイル オフセット) とサイズは、セクション ヘッダーで指定します。 各行番号レコードの形式は次のとおりです。

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

 

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

Offset サイズ フィールド 説明
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 バイトの長さのレコードの配列です。 各レコードは、標準または補助シンボル・テーブル・レコードです。 標準レコードは、シンボルまたは名前を定義し、次の形式を持っています。

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

シンボルに関連付けられている値。 このフィールドの解釈は、SectionNumber と StorageClass によって異なります。 一般的な意味は、再配置可能なアドレスです。
12
2
SectionNumber
セクション テーブルに 1 から始まるインデックスを使用してセクションを識別する符号付き整数。 セクション 5.4.2「セクション番号値」で定義されているように、一部の値は特別な意味を持ちます。
14
2
Type
型を表す数値。 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 でエンコードされた文字列として扱われます。

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

 

セクション番号の値

通常、シンボル テーブル エントリの [セクション値] フィールドは、セクション テーブルへの 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
単語。unsigned 2 バイト整数
IMAGE_SYM_TYPE_UINT
14
自然サイズの符号なし整数 (通常は 4 バイト)
IMAGE_SYM_TYPE_DWORD
15
符号なし 4 バイト整数

 

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

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

定数 説明
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)、FILE (103) の 4 つのストレージ クラス値のみを使用します。 以下の 2 番目の列見出しを除き、"Value" はシンボル レコードの Value フィールドを意味するように取得する必要があります (その解釈はストレージ クラスとして見つかった数値によって異なります)。

定数 [値] フィールドの説明/解釈
IMAGE_SYM_CLASS_END_OF_FUNCTION
-1 (0xFF)
デバッグ目的で関数の終了を表す特別なシンボル。
IMAGE_SYM_CLASS_NULL
0
ストレージ クラスが割り当てされていません。
IMAGE_SYM_CLASS_AUTOMATIC
1
自動 (スタック) 変数。 [値] フィールドは、スタック フレームオフセットを指定します。
IMAGE_SYM_CLASS_EXTERNAL
2
Microsoft ツールが外部シンボルに使用する値。 [値] フィールドは、セクション番号がIMAGE_SYM_UNDEFINED (0) の場合のサイズを示します。 セクション番号が 0 でない場合、Value フィールドはセクション内のオフセットを指定します。
IMAGE_SYM_CLASS_STATIC
3
セクション内のシンボルのオフセット。 Value フィールドが 0 の場合、記号はセクション名を表します。
IMAGE_SYM_CLASS_REGISTER
4
レジスタ変数。 [値] フィールドには、レジスタ番号を指定します。
IMAGE_SYM_CLASS_EXTERNAL_DEF
5
外部で定義されているシンボル。
IMAGE_SYM_CLASS_LABEL
6
モジュール内で定義されているコード ラベル。 [値] フィールドは、セクション内のシンボルのオフセットを指定します。
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
Union タグ名エントリ。
IMAGE_SYM_CLASS_TYPE_DEFINITION
13
Typedef エントリ。
IMAGE_SYM_CLASS_UNDEFINED_STATIC
14
静的データ宣言。
IMAGE_SYM_CLASS_ENUM_TAG
15
列挙型の tagname エントリ。
IMAGE_SYM_CLASS_MEMBER_OF_ENUM
16
列挙体のメンバー。 Value フィールドは、n 番目のメンバーを指定します。
IMAGE_SYM_CLASS_REGISTER_PARAM
17
register パラメーター。
IMAGE_SYM_CLASS_BIT_FIELD
18
ビット フィールド参照。 Value フィールドは、ビット フィールドの n 番目のビットを指定します。
IMAGE_SYM_CLASS_BLOCK
100
.bb (ブロックの先頭) または .eb (ブロックの末尾) レコード。 [値] フィールドは、コードの場所の再配置可能なアドレスです。
IMAGE_SYM_CLASS_FUNCTION
101
関数の範囲を定義するシンボル レコードに Microsoft ツールが使用する値: begin 関数 (.bf)、end function ( .ef )、および function ( .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) のストレージ クラス、関数 (0x20) であることを示す Type 値、および 0 より大きいセクション番号を持つ場合、シンボル テーブル レコードは関数定義の先頭をマークします。 セクション番号 UNDEFINED (0) を持つシンボル テーブル レコードは、関数を定義せず、補助レコードを持たないことに注意してください。 関数定義シンボル・レコードの後に、以下に示す形式の補助レコードが続きます。

Offset サイズ フィールド 説明
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 関数) という名前のシンボル レコード。 [値] フィールドは使用されません。

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

.ef (関数の末尾) という名前のシンボル レコード。 [値] フィールドの数値は、関数定義シンボル レコードの [合計サイズ] フィールドと同じです。

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

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

 

補助形式 3: 弱い外部

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

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

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

Offset サイズ フィールド 説明
0
4
TagIndex
sym1 が見つからない場合にリンクされるシンボルである sym2 のシンボル テーブル インデックス。
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;代わりに、[合計サイズ] フィールドが使用されます。

補助形式 4: ファイル

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

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

 

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

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

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

 

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

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

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

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

定数 説明
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 つのセクションのコードや別のセクションのデータなど) で、すべてのコンポーネントをセットとしてリンクまたは破棄する必要がある場合に便利です。 このセクションに関連付けられているもう 1 つのセクションは COMDAT セクションである必要があります。これは、別の連想 COMDAT セクションにすることができます。 連想 COMDAT セクションのセクション関連付けチェーンはループを形成できません。 セクション関連付けチェーンは、最終的に、IMAGE_COMDAT_SELECT_ASSOCIATIVE設定されていない COMDAT セクションにアクセスする必要があります。
IMAGE_COMDAT_SELECT_LARGEST
6
リンカーは、このシンボルのすべての定義の中から最大の定義を選択します。 複数の定義にこのサイズがある場合は、その間の選択肢は任意です。

 

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

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

Offset サイズ フィールド 説明
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 バイトがあります。 このサイズにはサイズ フィールド自体が含まれているため、文字列が存在しない場合、この場所の値は 4 になります。

次のサイズは、COFF シンボル テーブル内のシンボルによって指される null で終わる文字列です。

属性証明書テーブル (画像のみ)

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

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

 

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

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

virtual address = 0x5000
size = 0x1000

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

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

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

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

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

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

 

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

名前 Notes
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 コンテンツが quadword 境界で終わらない場合、属性証明書エントリは、bCertificate の末尾から次の quadword 境界まで、ゼロで埋め込まれます。

dwLength 値は、ファイナライズされたWIN_CERTIFICATE構造体の長さであり、次のように計算されます。

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

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

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

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

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

証明書データ

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

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

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

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

Delay-Load テーブルのインポート (イメージのみ)

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

Delay-Load ディレクトリ テーブル

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

Offset サイズ フィールド 説明
0
4
属性
ゼロを指定してください。
4
4
名前
読み込む DLL の名前の RVA。 名前は、イメージの読み取り専用データ セクションに存在します。
8
4
モジュール ハンドル
遅延読み込みされる DLL のモジュール ハンドル (イメージのデータ セクション内) の RVA。 遅延読み込みを管理するために提供されるルーチンによってストレージに使用されます。
12
4
遅延インポート アドレス テーブル
遅延読み込みインポート アドレス テーブルの RVA。 詳細については、「 Delay Import Address Table (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

 

ここに記載されているセクションの中には、特別なセマンティクスがオブジェクト ファイルまたはイメージ ファイルにのみ関連していることを示すために、"object only" または "image only" とマークされているものがあります。 "image only" とマークされているセクションは、イメージ ファイルに入る方法としてオブジェクト ファイルに引き続き表示されることがありますが、このセクションはリンカーにとって特別な意味を持たず、イメージ ファイル ローダーに対してのみ特別な意味を持ちます。

.debug セクション

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

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

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

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

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

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

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

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

Offset サイズ フィールド 説明
0
4
特性
予約済み。 は 0 である必要があります。
4
4
TimeDateStamp
デバッグ データが作成された日時。
8
2
MajorVersion
デバッグ データ形式のメジャー バージョン番号。
10
2
MinorVersion
デバッグ データ形式のマイナー バージョン番号。
12
4
Type
デバッグ情報の形式。 このフィールドを使用すると、複数のデバッガーをサポートできます。 詳細については、「デバッグの 種類」を参照してください。
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 の決定性または再現性。
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 バイト値の前に計算されたハッシュ値を含む場合があります。

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

拡張 DLL の特性

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

定数 説明
IMAGE_DLLCHARACTERISTICS_EX_CET_COMPAT 0x0001 イメージは CET と互換性があります。

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

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

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

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

Offset サイズ フィールド 説明
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
イメージ ベースを基準としたエクスポート名ポインター テーブルのアドレス。 テーブルのサイズは、[名前ポインターの数] フィールドで指定します。
36
4
序数テーブル RVA
イメージ ベースを基準とした序数テーブルのアドレス。

 

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

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

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

Offset サイズ フィールド 説明
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 つのテーブルとして動作します。このテーブルでは、エクスポート名ポインター列がパブリック (エクスポート) 名を指し、Export Ordinal 列がそのパブリック名に対応する序数を指定します。 エクスポート名ポインター テーブルのメンバーとエクスポート序数テーブルのメンバーは、それぞれの配列内で同じ位置 (インデックス) を持つことによって関連付けられます。

したがって、エクスポート名ポインター テーブルが検索され、一致する文字列が位置 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]

  • Hint-Name テーブル

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

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

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

Offset サイズ フィールド 説明
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 ビット数値の配列です。 各エントリは、次の表に示すビット フィールド形式を使用します。 この形式では、ビット 31 は PE32 の最上位ビットであり、ビット 63 は PE32 以降の最も重要なビットです。 これらのエントリのコレクションは、特定の DLL からのすべてのインポートについて説明します。 最後のエントリは、テーブルの末尾を示す 0 (NULL) に設定されます。

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

 

ヒント/名前テーブル

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

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

 

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

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

.pdata セクション

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

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

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

 

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

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

 

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

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

 

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

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

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

基本再配置ブロック

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

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

 

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

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

 

ベース再配置を適用するために、優先ベース アドレスと、イメージが実際に読み込まれるベースとの差が計算されます。 イメージが優先ベースで読み込まれる場合、違いは 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 の場合にのみ意味があります。 基本再配置は、シンボルの 32 ビット・アドレスを連続する MOVW/MOVT 命令ペアに適用します。
IMAGE_REL_BASED_RISCV_LOW12I
7
この再配置は、マシンの種類が RISC-V の場合にのみ意味があります。 ベース再配置は、RISC-V I 型命令形式で形成された 32 ビット絶対アドレスの下位 12 ビットに適用されます。
IMAGE_REL_BASED_RISCV_LOW12S
8
この再配置は、マシンの種類が RISC-V の場合にのみ意味があります。 ベース再配置は、RISC-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

静的に宣言された TLS データ オブジェクトは、静的に読み込まれたイメージ ファイルでのみ使用できます。 この事実により、DLL または DLL に静的にリンクされているものが LoadLibrary API 関数で動的に読み込まれることはないことがわかっている場合を除き、DLL で静的 TLS データを使用することは信頼性が低くなります。

 

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

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

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

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

  3. ローダーは、[インデックスのアドレス] フィールドで示された場所に 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 の最後のバイトのアドレス。 生データ開始 VA フィールドと同様に、これは RVA ではなく VA です。
8/16
4/8
インデックスのアドレス
ローダーによって割り当てられる TLS インデックスを受信する場所。 この場所は通常のデータ セクション内にあります。そのため、プログラムからアクセスできるシンボリック名を指定できます。
12/24
4/8
コールバックのアドレス
TLS コールバック関数の配列へのポインター。 配列は null で終了するため、コールバック関数がサポートされていない場合、このフィールドは 0 に設定された 4 バイトを指します。 これらの関数のプロトタイプの詳細については、「 TLS コールバック関数」を参照してください。
16/32
4
0 の塗りつぶしのサイズ
[生データ開始 VA] フィールドと [生データ終了 VA] フィールドで区切られた初期化されたデータを超える、テンプレートのサイズ (バイト単位)。 テンプレートの合計サイズは、イメージ ファイル内の TLS データの合計サイズと同じである必要があります。 ゼロフィルは、初期化された 0 以外のデータの後に来るデータの量です。
20/36
4
特性
4 つのビット [23:20] は、アラインメント情報を記述します。 指定できる値は、IMAGE_SCN_ALIGN_* として定義されたもので、オブジェクト ファイル内のセクションの配置を記述するためにも使用されます。 他の 28 ビットは、将来の使用のために予約されています。

 

TLS コールバック関数

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

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

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

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

予約済みパラメーターは 0 に設定する必要があります。 Reason パラメーターは、次の値を受け取ることができます。

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

 

Load Configuration Structure (イメージのみ)

ロード構成構造 (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 ファイル用の次のレイアウトがあります。

Offset サイズ フィールド 説明
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 プレフィックスが使用され、単一のプロセッサ マシンで NOP に置き換えられるアドレスの一覧の VA。
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
Flow Guard に関連するフラグを制御します。
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

  • Control Flow Guard 関数テーブル エントリのストライドを含むサブフィールド (つまり、テーブル エントリあたりのバイト数の追加数) をマスクします。

    #define IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_MASK 0xF0000000

さらに、Windows SDK winnt.h ヘッダーは、GuardFlags 値を右シフトして Control Flow Guard 関数テーブルのストライドを右揃えするビット数に対して、このマクロを定義します。

#define IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_SHIFT 28

.rsrc セクション

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

型名の言語

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

リーフの Type、Name、Language ID は、リーフに到達するためにディレクトリ テーブルを介して取得されるパスによって決まります。 最初のテーブルは型 ID を決定し、2 番目のテーブル (最初のテーブルのディレクトリ エントリによって指されます) が名前 ID を決定し、3 番目のテーブルが言語 ID を決定します。

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

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

 

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

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

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

 

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

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

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

 

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

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

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

 

リソース データエントリ

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

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

 

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

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

.sxdata セクション

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

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

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

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

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

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

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

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

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

シグネチャ :"!<アーチ>\n"
ヘッダー
1 番目のリンカー メンバー
ヘッダー
2 番目のリンカー メンバー
ヘッダー
Longnames メンバー
ヘッダー
OBJ ファイル 1 の内容
(COFF 形式)
ヘッダー
OBJ ファイル 2 の内容
(COFF 形式)

...

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

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

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

!<arch>\n

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

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

各メンバー ヘッダーは、前のアーカイブ メンバーの末尾の後の最初の偶数アドレスで開始されます。

Offset サイズ フィールド 説明
0
16
名前
アーカイブ メンバーの名前。名前を終了するためにスラッシュ (/) を追加します。 最初の文字がスラッシュの場合、次の表に示すように、名前には特別な解釈があります。
16
12
Date
アーカイブ・メンバーが作成された日時: これは、1970 年 1 月 1 日 UCT 以降の秒数の ASCII 10 進数表記です。
28
6
User 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" の 2 バイト (0x60 0x0A)。

 

[名前] フィールドには、次の表に示すいずれかの形式があります。 前述のように、これらの各文字列は両端揃えのままで、16 バイトのフィールド内に末尾のスペースが埋め込まれます。

[名前] フィールドの内容 説明
名前/
アーカイブ メンバーの名前。
/
アーカイブ メンバーは、2 つのリンカー メンバーのいずれかです。 どちらのリンカー メンバーも、この名前を持ちます。
//
アーカイブ メンバーは longnames メンバーであり、一連の null で終わる ASCII 文字列で構成されます。 longnames メンバーは 3 番目のアーカイブ メンバーであり、省略可能です。
/n
アーカイブ・メンバーの名前は、longnames メンバー内のオフセット n にあります。 数値 n はオフセットの 10 進表現です。 例: "/26" は、アーカイブ・メンバーの名前が longnames メンバー・コンテンツの先頭を 26 バイト超えて配置されていることを示します。

 

最初のリンカー メンバー

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

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

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

 

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

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

2 番目のリンカー メンバーの名前は、最初のリンカー メンバーと同様に "/" です。 両方のリンカー メンバーは、シンボルのディレクトリと、それらを含むアーカイブ メンバーを提供しますが、2 番目のリンカー メンバーは、現在のすべてのリンカーによって 1 つ目のリンカーより優先して使用されます。 2 番目のリンカー メンバーには、構文順のシンボル名が含まれています。これにより、名前による高速な検索が可能になります。

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

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

 

Longnames メンバー

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

文字列は null で終わる。 各文字列は、前の文字列の null バイトの直後に開始されます。

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

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

インポートのセクションコントリビューションは、小さな情報セットから推測できます。 リンカーは、ライブラリの作成時に各メンバーのインポート ライブラリに完全で詳細な情報を生成するか、ライブラリに正規情報のみを書き込み、後で使用するアプリケーションに必要なデータを即座に生成させることができます。

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

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

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

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

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

ヘッダーのインポート

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

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

 

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

インポートの種類

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

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

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

インポート名の種類

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

定数 説明
IMPORT_ORDINAL 0 インポートは序数で行います。 これは、インポート ヘッダーの Ordinal/Hint フィールドの値がインポートの序数であることを示します。 この定数を指定しない場合、Ordinal/Hint フィールドは常にインポートのヒントとして解釈されます。
IMPORT_NAME 1 インポート名は、パブリック シンボル名と同じです。
IMPORT_NAME_NOPREFIX 2 インポート名はパブリック シンボル名ですが、先頭の ?、@、または必要に応じて _をスキップします。
IMPORT_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 イメージの部分を変更する方法について説明します。

Note

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

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

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

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

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

    • 直前の [証明書テーブル] フィールドが指す証明書テーブルと対応する証明書。

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

  • 最後のセクションの最後を過ぎた情報。 最後のセクションを超えた領域 (最も高いオフセットで定義) はハッシュされません。 この領域には、一般的にデバッグ情報が含まれています。 デバッグ情報は通常、デバッガーのアドバイザリと見なすことができます。実行可能プログラムの実際の整合性には影響しません。 製品が配信された後にイメージからデバッグ情報を削除することは、文字通り可能であり、プログラムの機能には影響しません。 実際、これはディスク節約の手段として行われる場合があります。 PE イメージの指定されたセクションに含まれるデバッグ情報は、Authenticode 署名を無効にしないと削除できないことに注意してください。

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

References

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

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

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

SignTool

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

ImageHlp 関数