PE 形式

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

Note

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

Microsoft ポータブル実行可能ファイルおよび共通オブジェクト ファイル形式仕様のこのリビジョンは、この仕様の以前のすべてのリビジョンに置き換えられます。

一般的な概念

このドキュメントでは、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 と同じですが、イメージ ファイルのベース アドレスは減算されません。 Windowsは物理メモリに関係なく、プロセスごとに個別の VA 領域を作成するため、アドレスは VA と呼ばれます。 ほぼすべての目的で、VA は単なるアドレスと見なす必要があります。 VA は RVA ほど予測できないので、ローダーは推奨される場所にイメージを読み込まない可能性があります。

概要

次の一覧では、Microsoft PE 実行可能ファイルの形式について説明します。画像ヘッダーの先頭にベースが付きます。 MS-DOS 2.0 互換 EXE ヘッダーから、PE ヘッダーの直前の未使用セクションまでのセクションは MS-DOS 2.0 セクションであり、MS-DOS の互換性にのみ使用されます。

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

  • 未使用

  • OEM 識別子

    OEM 情報

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

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

  • 未使用

  • PE ヘッダー (8 バイト境界に配置)

  • セクション ヘッダー

  • イメージ ページ:

    情報のインポート

    エクスポート情報

    基本再配置

    リソース情報

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

  • Microsoft COFF ヘッダー

  • セクション ヘッダー

  • 生データ:

    code

    data

    デバッグ情報

    リロケーション

ファイル ヘッダー

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

MS-DOS スタブ (画像のみ)

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

場所0x3cでは、スタブには PE 署名へのファイル オフセットがあります。 この情報により、WINDOWSには MS-DOS スタブがある場合でも、イメージ ファイルを適切に実行できます。 このファイル オフセットは、リンク時に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。 イメージの場合、この値は 0 にする必要があります。これは、COFF デバッグ情報が非推奨になるためです。
12
4
NumberOfSymbols
シンボル テーブル内のエントリの数。 このデータを使用すれば、シンボル テーブルのすぐ後に続く文字列テーブルを検索することができます。 イメージの場合、この値は 0 にする必要があります。これは、COFF デバッグ情報が非推奨になるためです。
16
2
SizeOfOptionalHeader
省略可能なヘッダーのサイズ。実行可能ファイルには必要ですが、オブジェクト ファイルには必要ありません。 オブジェクト ファイルの場合、この値は 0 とする必要があります。 ヘッダー形式の説明については、「 省略可能なヘッダー (イメージのみ)」を参照してください。
18
2
特性
ファイルの属性を示すフラグ。 特定のフラグ値については、「 特性」を参照してください。

マシンの種類

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

定数 説明
IMAGE_FILE_MACHINE_UNKNOWN
0x0
このフィールドの内容は、任意のコンピューターの種類に適用されるものと見なされます
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_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
浮動小数点サポートを備えた Power 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 以降では非推奨であり、0 である必要があります。
IMAGE_FILE_LARGE_ADDRESS_対応
0x0020
アプリケーションは 2 GB のアドレスを処理 > できます。
0x0040
このフラグは、今後使用するために予約されています。
IMAGE_FILE_BYTES_REVERSED_LO
0x0080
リトル エンディアン: 最下位ビット (LSB) は、メモリ内の最も重要なビット (MSB) の前に置きます。 このフラグは非推奨であり、ゼロにする必要があります。
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 の累乗である必要があります(両端を含む)。 既定値は 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_ ドライバー
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
構造化例外 (Standard Edition) 処理は使用しません。 このイメージでは、Standard Edition ハンドラーが呼び出されない場合があります。
IMAGE_DLLCHARACTERISTICS_ NO_BIND
0x0800
イメージをバインドしないでください。
IMAGE_DLLCHARACTERISTICS_APPCONTAINER
0x1000
イメージは AppContainer で実行する必要があります。
IMAGE_DLLCHARACTERISTICS_ WDM_DRIVER
0x2000
WDM ドライバー。
IMAGE_DLLCHARACTERISTICS_GUARD_CF
0x4000
Image では、Control Flow Guard がサポートされています。
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
Architecture
予約済み、0 である必要があります
160/176
8
Global Ptr
グローバル ポインター レジスタに格納される値の RVA。 この構造体のサイズ メンバーは 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 値の倍数である必要があります。

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

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

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

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

オブジェクト セクションの内容を含むイメージ セクションを決定すると、リンカーは "$" を破棄しますか? とそれに続くすべての文字。 したがって、という名前のオブジェクト セクションです。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 ビットはゼロであり、格納されません。
この再配置は、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
シフトゼロの命令 ADD/ADDS (イミディエイト) のターゲットの 12 ビット ページ オフセット。
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
ターゲットのセクション オフセットのビット 0:11。命令 LDR の場合 (インデックス付き、符号なしイミディエイト)。
IMAGE_REL_ARM64_TOKEN
0x000C
CLR トークン。
IMAGE_REL_ARM64_SECTION
0x000D
ターゲットを含むセクションの 16 ビット セクション インデックス。 これは、デバッグ情報をサポートするために使用されます。
IMAGE_REL_ARM64_ADDR64
0x000E
再配置ターゲットの 64 ビット VA。
IMAGE_REL_ARM64_BRANCH19
0x000F
条件付き B 命令の再配置ターゲットへの 19 ビット オフセット。
IMAGE_REL_ARM64_BRANCH14
0x0010
命令 TBZ および TBNZ の再配置ターゲットへの 14 ビット オフセット。
IMAGE_REL_ARM64_REL32
0x0011
再配置後のバイトからの 32 ビット相対アドレス。
日立スーパーHプロセッサ

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

定数 説明
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 命令シーケンスの最初の命令に使用されます。 この再配置の直後に、SymbolTableIndex に符号付き 16 ビットのディスプレイスメントが含まれ、再配置される場所から取得された上位 16 ビットに追加される PAIR 再配置が続く必要があります。
IMAGE_REL_PPC_REFLO
0x0011
ターゲットの VA の下位 16 ビット。
IMAGE_REL_PPC_PAIR
0x0012
REFHI または SECRELHI 再配置の直後にのみ有効な再配置。 SymbolTableIndex には、シンボル テーブルへのインデックスではなく、ディスプレイスメントが含まれています。
IMAGE_REL_PPC_SECRELLO
0x0013
セクションの先頭からのターゲットの 32 ビット オフセットの下位 16 ビット。
IMAGE_REL_PPC_GPREL
0x0015
GP レジスタに対するターゲットの 16 ビット符号付き変位。
IMAGE_REL_PPC_TOKEN
0x0016
CLR トークン。

 

Intel 386 プロセッサ

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

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

 

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

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

定数 説明
IMAGE_REL_IA64_ABSOLUTE
0x0000
再配置は無視されます。
IMAGE_REL_IA64_IMM14
0x0001
命令再配置の後に、IMM14 バンドル内の指定されたスロットに挿入される前にターゲット・アドレスに値が追加される ADDEND 再配置が続く場合があります。 再配置ターゲットは絶対パスであるか、イメージを固定する必要があります。
IMAGE_REL_IA64_IMM22
0x0002
命令再配置の後に、IMM22 バンドル内の指定されたスロットに挿入される前にターゲット・アドレスに値が追加される ADDEND 再配置が続く場合があります。 再配置ターゲットは絶対パスであるか、イメージを固定する必要があります。
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 ビット オフセットで固定されます。 この再配置の直後に、Value フィールドにセクションの先頭からのターゲットの 32 ビット符号なしオフセットが含まれる 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 つの最下位ビットすべて 0 およびドロップ) BR 命令。
IMAGE_REL_IA64_PCREL60I
0x0018
60 ビット PC 相対修正。 ターゲットの変位が符号付き 25 ビット フィールドに収まる場合は、バンドル全体を NOP を持つ MIB バンドルに変換します。スロット 1 の I と、スロット 2 の 25 ビット (4 つの最下位ビットすべて 0 およびドロップ) BR 命令。
IMAGE_REL_IA64_PCREL60M
0x0019
60 ビット PC 相対修正。 ターゲットの変位が符号付き 25 ビット フィールドに収まる場合は、バンドル全体を NOP を使用して MMB バンドルに変換します。スロット 1 の M と、スロット 2 の 25 ビット (4 つの最小ビットすべて 0 およびドロップ) 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 ビットに追加される符号付き 16 ビットの変位が含まれる PAIR 再配置が続く必要があります。
IMAGE_REL_MIPS_REFLO
0x0005
ターゲットの VA の下位 16 ビット。
IMAGE_REL_MIPS_GPREL
0x0006
GP レジスタに対するターゲットの 16 ビット符号付き変位。
IMAGE_REL_MIPS_LITERAL
0x0007
IMAGE_REL_MIPS_GPRELと同じです。
IMAGE_REL_MIPS_SECTION
0x000A
セクションの 16 ビット セクション インデックスには、ターゲットが含まれています。 これは、デバッグ情報をサポートするために使用されます。
IMAGE_REL_MIPS_SECREL
0x000B
セクションの先頭からのターゲットの 32 ビット オフセット。 これは、デバッグ情報と静的スレッド ローカル ストレージをサポートするために使用されます。
IMAGE_REL_MIPS_SECRELLO
0x000C
ターゲットのセクションの先頭からの 32 ビット オフセットの下位 16 ビット。
IMAGE_REL_MIPS_SECRELHI
0x000D
ターゲットのセクションの先頭からの 32 ビット オフセットの上位 16 ビット。 IMAGE_REL_MIPS_PAIR再配置は、この後すぐに実行する必要があります。 PAIR 再配置の SymbolTableIndex には、再配置される場所から取得された上位 16 ビットに追加される符号付き 16 ビットの変位が含まれています。
IMAGE_REL_MIPS_JMPADDR16
0x0010
ターゲットの VA の下位 26 ビット。 MIPS16 JAL命令に対応しています。
IMAGE_REL_MIPS_REFWORDNB
0x0022
ターゲットの 32 ビット RVA。
IMAGE_REL_MIPS_PAIR
0x0025
再配置は、REFHI または SECRELHI 再配置の直後にある場合にのみ有効です。 SymbolTableIndex には、シンボル テーブルへのインデックスではなく、ディスプレイスメントが含まれています。

 

三菱 M32R

次の再配置タイプ標識は、三菱 M32R プロセッサーに対して定義されています。

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

 

COFF 行番号 (非推奨)

COFF 行番号は生成されなくなり、今後は使用されません。

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

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

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
ストレージ クラスを表す列挙値。 詳細については、「Storage クラス」を参照してください。
17
1
NumberOfAuxSymbols
このレコードの後に続く補助シンボル・テーブル項目の数。

 

0 個以上の補助シンボル テーブル レコードは、各標準シンボル テーブル レコードのすぐ後に続きます。 ただし、通常、標準のシンボル テーブル レコードに従う補助シンボル テーブル レコードは 1 つではありません (長いファイル名を持つ .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
単語。符号なし 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 でない場合は、[値] フィールドでセクション内のオフセットを指定します。
IMAGE_SYM_CLASS_STATIC
3
セクション内のシンボルのオフセット。 [値] フィールドが 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
列挙型のタグ名エントリ。
IMAGE_SYM_CLASS_MEMBER_OF_ENUM
16
列挙体のメンバー。 Value フィールドは、n 番目のメンバーを指定します。
IMAGE_SYM_CLASS_REGISTER_PARAM
17
レジスタ パラメーター。
IMAGE_SYM_CLASS_BIT_FIELD
18
ビット フィールド参照。 Value フィールドは、ビット フィールドの n 番目のビットを指定します。
IMAGE_SYM_CLASS_BLOCK
100
.bb (ブロックの先頭) または .eb (ブロックの終わり) レコード。 [値] フィールドは、コードの場所の再配置可能なアドレスです。
IMAGE_SYM_CLASS_FUNCTION
101
関数の範囲を定義するシンボル レコードに Microsoft ツールが使用する値: begin 関数 (.bf)、end function (.ef)、および関数内の行 (.lf)。 .lf レコードの場合、[値] フィールドには、関数内のソース行の数が指定されます。 .ef レコードの場合、[値] フィールドには関数コードのサイズが表示されます。
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
ソース ファイル内の実際の序数 (1、2、3 など) (.bf または .ef レコードに対応)。
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
sym2 のシンボル テーブル インデックス。sym1 が見つからない場合にリンクされるシンボル。
4
4
特性
IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARYの値は、sym1 のライブラリ検索を実行する必要がないことを示します。
IMAGE_WEAK_EXTERN_SEARCH_LIBRARYの値は、sym1 のライブラリ検索を実行する必要があることを示します。
IMAGE_WEAK_EXTERN_SEARCH_ALIASの値は、sym1 が sym2 のエイリアスであることを示します。
8
10
未使用

 

特性フィールドは WINNT で定義されていないことに注意してください。H;代わりに、[合計サイズ] フィールドが使用されます。

補助形式 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 セクション (オブジェクトのみ)

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

COMDAT セクションのセクション値を持つ最初のシンボルは、セクションシンボルである必要があります。 このシンボルには、セクションの名前、値フィールドが 0、問題の 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 で終わる文字列です。

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

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

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

 

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

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

virtual address = 0x5000
size = 0x1000

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

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

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

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

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

名前 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 デジタル署名形式の詳細については、「Authenticode ポータブル実行可能ファイル署名形式Windows」を参照してください。

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

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

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

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

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

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

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

証明書データ

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

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

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

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

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。 詳細については、「 遅延インポート アドレス テーブル (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 セクションは、オブジェクト ファイルまたはイメージ ファイルで見つかった場合に特別な意味を持ちます。 ツールとローダーは、セクション ヘッダーに特別なフラグが設定されているため、これらのセクションを認識します。これは、イメージの省略可能なヘッダー内の特別な場所がそれらのセクションを指しているため、またはセクション名自体がセクションの特殊な関数を示しているためです。 (セクション名自体がセクションの特別な機能を示していない場合でも、セクション名は規則によって規定されるため、この仕様の作成者はすべてのケースでセクション名を参照できます)。

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

セクション名 Content 特性
.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 相対初期化データ (FREE 形式、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

 

ここに記載されているセクションの中には、特殊なセマンティクスがオブジェクト ファイルまたはイメージ ファイルにのみ関連することを示すために、"オブジェクトのみ" または "イメージのみ" とマークされているものがあります。 "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 が生成されるタイミングや場所に関係なく、ビット for ビットの同一であることが保証されます。 PE ファイル内のさまざまな日付/時刻スタンプ フィールドには、PE ファイルの内容を入力として使用する計算ハッシュ値の一部またはすべてのビットが格納されるため、PE ファイルまたは PE 内の関連する特定のデータが生成される実際の日時は表されなくなります。 このデバッグ エントリの生データは空であるか、ハッシュ値の長さを表す 4 バイトの値の前に計算されたハッシュ値を含む場合があります。

Type フィールドが 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$Fdebug$S.debug$P、および .debug$T セクションから関連するすべてのデバッグ データを収集します。

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

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

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

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

.edata セクション (画像のみ)

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

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

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

 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

.idata セクション

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

  • ディレクトリ テーブル

    Null ディレクトリ エントリ

  • DLL1 Import Lookup Table

    Null

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

    Null

  • DLL3 Import Lookup Table

    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。 このフィールドは、序数/名前フラグ ビット フィールドが 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 ビット命令で構成されます。 オフの場合、関数は 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 フィールドを含みます。

 

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

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

 

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

基本再配置の種類

定数 説明
IMAGE_REL_BASED_ABSOLUTE
0
基本再配置はスキップされます。 この型は、ブロックを埋め込むのに使用できます。
IMAGE_REL_BASED_HIGH
1
ベース再配置では、オフセット時の 16 ビット フィールドに差分の上位 16 ビットが追加されます。 16 ビット フィールドは、32 ビット ワードの高い値を表します。
IMAGE_REL_BASED_LOW
2
基本再配置では、オフセット時の 16 ビット フィールドに差分の下位 16 ビットが追加されます。 16 ビット フィールドは、32 ビット ワードの下位半分を表します。
IMAGE_REL_BASED_HIGHLOW
3
基本再配置では、オフセット時の 32 ビット フィールドに差分のすべての 32 ビットが適用されます。
IMAGE_REL_BASED_HIGHADJ
4
ベース再配置では、オフセット時の 16 ビット フィールドに差分の上位 16 ビットが追加されます。 16 ビット フィールドは、32 ビット ワードの高い値を表します。 32 ビット値の下位 16 ビットは、この基本再配置の後の 16 ビット ワードに格納されます。 これは、この基本再配置が 2 つのスロットを占有することを意味します。
IMAGE_REL_BASED_MIPS_JMPADDR
5
再配置の解釈は、マシンの種類によって異なります。
マシンの種類が MIPS の場合、基本再配置は MIPS ジャンプ命令に適用されます。
IMAGE_REL_BASED_ARM_MOV32
5
この再配置は、マシンの種類が ARM または Thumb の場合にのみ意味があります。 基本再配置は、連続する MOVW/MOVT 命令ペアにシンボルの 32 ビット・アドレスを適用します。
IMAGE_REL_BASED_RISCV_HIGH20
5
この再配置は、マシンの種類が RISC-V の場合にのみ意味があります。 基本再配置は、32 ビット絶対アドレスの上位 20 ビットに適用されます。
6
予約済み。0 である必要があります。
IMAGE_REL_BASED_THUMB_MOV32
7
この再配置は、マシンの種類が Thumb の場合にのみ意味があります。 基本再配置は、シンボルの 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 を使用して宣言された変数に対して異なる値を保持できます。

任意の量の TLS データは、API 呼び出し TlsAlloc、TlsFree、TlsSetValue、および TlsGetValue を使用してサポートできることに注意してください。 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 で終わるので、コールバック関数がサポートされていない場合、このフィールドは 4 バイトを 0 に設定します。 これらの関数のプロトタイプについては、「 TLS コールバック関数」を参照してください。
16/32
4
0 の塗りつぶしのサイズ
Raw Data Start VA フィールドと Raw Data End 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
元のスレッドを含め、プロセスが終了しようとしています。

 

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

ロード構成構造 (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 のみ]単一のプロセッサ マシンで NOP に置き換えることができるように、LOCK プレフィックスが使用されるアドレスの一覧の 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 のみ]イメージ内の有効な一意の各Standard Edition ハンドラーの RVA の並べ替えられたテーブルの VA。
68/104
4/8
SEHandlerCount
[x86 のみ]テーブル内の一意のハンドラーの数。
72/112
4/8
GuardCFCheckFunctionPointer
Control Flow Guard check-function ポインターが格納される VA。
76/120
4/8
GuardCFDispatchFunctionPointer
Control Flow Guard ディスパッチ関数ポインターが格納される VA。
80/128
4/8
GuardCFFunctionTable
イメージ内の各 Control Flow Guard 関数の RVA の並べ替えられたテーブルの VA。
84/136
4/8
GuardCFFunctionCount
上記の表の一意の RVA の数。
88/144
4
GuardFlags
Guard 関連フラグFlow制御します。
92/148
12
CodeIntegrity
コードの整合性情報。
104/160
4/8
GuardAddressTakenIatEntryTable
Control Flow Guard アドレス取得 IAT テーブルが格納される VA。
108/168
4/8
GuardAddressTakenIatEntryCount
上記の表の一意の RVA の数。
112/176
4/8
GuardLongJumpTargetTable
Control Flow Guard のロング ジャンプ ターゲット テーブルが格納されている 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) (種類、名前、または言語レベル) と、データ記述または別のディレクトリ テーブルのアドレスを指定する一連のディレクトリ エントリが続きます。 アドレスがデータの説明を指している場合、データはツリー内のリーフになります。 アドレスが別のディレクトリ テーブルを指している場合、そのテーブルには次のレベルのディレクトリ エントリが一覧表示されます。

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

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

Data 説明
リソース ディレクトリ テーブル (および 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 を使用する名前エントリの直後のディレクトリ エントリの数。

 

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

ディレクトリ エントリは、テーブルの行を構成します。 各リソース ディレクトリ エントリの形式は次のとおりです。 エントリが名前エントリであるか ID エントリであるかは、リソース ディレクトリ テーブルによって示されます。これは、その後に続く名前と ID のエントリの数を示します (テーブルのすべての ID エントリの前にすべての 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 エントリの後、および最初のリソース データ エントリの前にまとめて格納されます。 これにより、固定サイズのディレクトリ エントリの配置に対するこれらの可変長文字列の影響が最小限に抑えられます。 各リソース ディレクトリ文字列の形式は次のとおりです。

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

 

リソース データエントリ

各リソース データ エントリは、[リソース データ] 領域の生データの実際の単位を表します。 リソース データ エントリの形式は次のとおりです。

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 シンボル インデックスが含まれています。

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

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

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

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

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

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

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

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

署名 :"!<アーチ>\n"
Header
1 番目のリンカー メンバー
Header
2 番目のリンカー メンバー
Header
Longnames メンバー
Header
OBJ ファイル 1 の内容
(COFF 形式)
Header
OBJ ファイル 2 の内容
(COFF 形式)

...

Header
OBJ ファイル N の内容
(COFF 形式)

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

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

!<arch>\n

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

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

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

Offset サイズ フィールド 説明
0
16
名前
アーカイブ メンバーの名前。名前を終了するためにスラッシュ (/) が追加されます。 最初の文字がスラッシュの場合、次の表に示すように、名前には特別な解釈があります。
16
12
日付
アーカイブ メンバーが作成された日時: これは、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 バイトのフィールド内に末尾のスペースが埋め込まれます。

[名前] フィールドの内容 説明
name/
アーカイブ メンバーの名前。
/
アーカイブ メンバーは、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 文字の直後に開始されます。 文字列の数は、[シンボルの数] フィールドの値と等しい必要があります。

 

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

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

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

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

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

 

Longnames メンバー

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

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

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

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

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

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

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

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

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

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

ヘッダーのインポート

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

Offset サイズ フィールド 説明
0
2
Sig1
IMAGE_FILE_MACHINE_UNKNOWNする必要があります。 詳細については、「マシンの 種類」を参照してください
2
2
Sig2
0xFFFFする必要があります。
4
2
Version
構造体のバージョン。
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 署名の作成と検証を試すことができます。 詳細については、以下のリファレンスを参照してください。

リファレンス

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

証明書の作成、表示、および管理

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

SignTool

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

ImageHlp 関数