PE 形式
この仕様では、オペレーティング システムの Windows ファミリの下にある実行可能ファイル (イメージ) ファイルとオブジェクト ファイルの構造について説明します。 これらのファイルは、それぞれポータブル実行可能ファイル (PE) ファイルと共通オブジェクト ファイル形式 (COFF) ファイルと呼ばれます。
Note
このドキュメントは、Windows 用のツールとアプリケーションの開発に役立ちますが、すべての点で完全な仕様であるとは限りません。 Microsoft は、このドキュメントを予告なしに変更する権利を留保します。
Microsoft Portable Executable および Common Object File Format Specification のこのリビジョンは、この仕様の以前のリビジョンをすべて置き換えます。
一般的な概念
このドキュメントでは、オペレーティング システムの Microsoft Windows ファミリの下にある実行可能ファイル (イメージ) ファイルとオブジェクト ファイルの構造を指定します。 これらのファイルは、それぞれポータブル実行可能ファイル (PE) ファイルと共通オブジェクト ファイル形式 (COFF) ファイルと呼ばれます。 "ポータブル実行可能ファイル" という名前は、形式がアーキテクチャ固有ではないという事実を指します。
この仕様全体で使用される特定の概念を次の表に示します。
名前 | 説明 |
---|---|
属性証明書 |
検証可能なステートメントをイメージに関連付けるために使用される証明書。 さまざまな検証可能なステートメントをファイルに関連付けることができます。最も便利なものの 1 つは、イメージのメッセージ ダイジェストが期待される内容を示すソフトウェア製造元の声明です。 メッセージ ダイジェストはチェックサムに似ていますが、偽造は非常に困難です。 したがって、元のファイルと同じメッセージ ダイジェストを持つファイルを変更することは非常に困難です。 ステートメントは、公開キーまたは秘密キー暗号化スキームを使用して、製造元によって作成されたと確認できます。 このドキュメントでは、イメージ ファイルへの挿入を許可する以外の属性証明書の詳細について説明します。 |
日付/タイム スタンプ |
PE または COFF ファイル内のいくつかの場所で異なる目的で使用されるスタンプ。 ほとんどの場合、各スタンプの形式は、C ランタイム ライブラリのタイム関数で使用される形式と同じです。 例外については、「デバッグの種類」のIMAGE_DEBUG_TYPE_REPROの説明を参照 してください。 スタンプ値が 0 または0xFFFFFFFFの場合、実際または意味のある日付/タイム スタンプは表されません。 |
ファイル ポインター |
リンカー (オブジェクト ファイルの場合) またはローダー (イメージ ファイルの場合) によって処理される前の、ファイル自体内の項目の場所。 つまり、これはディスクに格納されているファイル内の位置です。 |
リンカー |
Microsoft Visual Studio で提供されるリンカーへの参照。 |
オブジェクト ファイル |
リンカーへの入力として指定されたファイル。 リンカーによってイメージ ファイルが生成され、ローダーによる入力として使用されます。 "object file" という用語は、必ずしもオブジェクト指向プログラミングへの接続を意味するとは限りません。 |
予約済み、0 である必要があります |
ジェネレーターの場合はフィールドの値を 0 にする必要があり、コンシューマーはフィールドを無視する必要があることを示すフィールドの説明。 |
相対仮想アドレス (RVA) |
イメージ ファイルでは、これはメモリに読み込まれた後の項目のアドレスであり、イメージ ファイルのベース アドレスはそこから差し引かれます。 アイテムの RVA は、ほとんどの場合、ディスク上のファイル内の位置 (ファイル ポインター) と異なります。 オブジェクト ファイルでは、メモリの場所が割り当てられないため、RVA はあまり意味がありません。 この場合、RVA はセクション (この表で後述) 内のアドレスであり、後でリンク中に再配置が適用されます。 わかりやすくするために、コンパイラは各セクションの最初の RVA を 0 に設定する必要があります。 |
section |
PE または COFF ファイル内のコードまたはデータの基本単位。 たとえば、オブジェクト ファイル内のすべてのコードを 1 つのセクション内で結合することも、(コンパイラの動作に応じて) 各関数が独自のセクションを占有することもできます。 より多くのセクションを使用すると、より多くのファイル オーバーヘッドが発生しますが、リンカーはコード内でより選択的にリンクできます。 セクションは、Intel 8086 アーキテクチャのセグメントに似ています。 セクション内のすべての生データを連続して読み込む必要があります。 さらに、イメージ ファイルには、特別な目的を持つ .tls や .reloc などのいくつかのセクションを含めることができます。 |
仮想アドレス (VA) |
RVA と同じですが、イメージ ファイルのベース アドレスが減算されないことを除きます。 アドレスは VA と呼ばれます。これは、物理メモリに関係なく、Windows によってプロセスごとに個別の VA 領域が作成されるためです。 ほぼすべての目的で、VA はアドレスと見なす必要があります。 ローダーが推奨される場所にイメージを読み込まない可能性があるため、VA は RVA ほど予測できません。 |
概要
次の一覧では、イメージ ヘッダーのベースを先頭に配置した Microsoft PE 実行可能形式について説明します。 MS-DOS 2.0 互換 EXE ヘッダーから、PE ヘッダーの直前にある未使用のセクションまでのセクションは MS-DOS 2.0 セクションであり、MS-DOS の互換性にのみ使用されます。
MS-DOS 2.0 互換 EXE ヘッダー
未使用
OEM 識別子
OEM 情報
PE ヘッダーへのオフセット
MS-DOS 2.0 スタブ プログラムと再配置テーブル
未使用
PE ヘッダー (8 バイト境界に配置)
セクション ヘッダー
イメージ ページ:
インポート情報
情報をエクスポートする
基本再配置
リソース情報
次の一覧では、Microsoft COFF オブジェクト モジュール形式について説明します。
Microsoft COFF ヘッダー
セクション ヘッダー
生データ:
code
data
デバッグ情報
リロケーション
ファイル ヘッダー
PE ファイル ヘッダーは、Microsoft MS-DOS スタブ、PE 署名、COFF ファイル ヘッダー、および省略可能なヘッダーで構成されます。 COFF オブジェクト ファイル ヘッダーは、COFF ファイル ヘッダーと省略可能なヘッダーで構成されます。 どちらの場合も、ファイル ヘッダーの直後にセクション ヘッダーが続きます。
MS-DOS スタブ (イメージのみ)
MS-DOS スタブは、MS-DOS で実行される有効なアプリケーションです。 EXE イメージの前面に配置されます。 リンカーによって既定のスタブがここに配置され、イメージが MS-DOS で実行されると"このプログラムを DOS モードで実行できません" というメッセージが出力されます。 ユーザーは、/STUB リンカー オプションを使用して別のスタブを指定できます。
場所0x3cでは、スタブには PE 署名へのファイル オフセットがあります。 この情報により、MS-DOS スタブがある場合でも、Windows はイメージ ファイルを適切に実行できます。 このファイル オフセットは、リンク時に0x3c位置に配置されます。
署名 (イメージのみ)
MS-DOS スタブの後、オフセット 0x3cで指定されたファイル オフセットで、ファイルを PE 形式のイメージ ファイルとして識別する 4 バイトの署名です。 このシグネチャは "PE\0\0" です (文字 "P" と "E" の後に 2 つの null バイトが続きます)。
COFF ファイル ヘッダー (オブジェクトとイメージ)
オブジェクト ファイルの先頭、またはイメージ ファイルの署名の直後は、次の形式の標準 COFF ファイル ヘッダーです。 Windows ローダーでは、セクションの数が 96 に制限されることに注意してください。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
2 |
Machine |
ターゲット コンピューターの種類を識別する番号。 詳細については、「マシンの 種類」を参照してください。 |
2 |
2 |
NumberOfSections |
セクションの数。 これは、ヘッダーのすぐ後に続くセクション テーブルのサイズを示します。 |
4 |
4 |
TimeDateStamp |
ファイルが作成された日時を示す、1970 年 1 月 1 日 00:00 以降の秒数の下位 32 ビット (C ランタイム time_t値)。 |
8 |
4 |
PointerToSymbolTable |
COFF シンボル テーブルのファイル オフセット。COFF シンボル テーブルがない場合は 0。 COFF デバッグ情報は非推奨であるため、イメージの場合、この値は 0 にする必要があります。 |
12 |
4 |
NumberOfSymbols |
シンボル テーブル内のエントリの数。 このデータを使用すれば、シンボル テーブルのすぐ後に続く文字列テーブルを検索することができます。 COFF デバッグ情報は非推奨であるため、イメージの場合、この値は 0 にする必要があります。 |
16 |
2 |
SizeOfOptionalHeader |
省略可能なヘッダーのサイズ。実行可能ファイルには必要ですが、オブジェクト ファイルには必要ありません。 オブジェクト ファイルの場合、この値は 0 とする必要があります。 ヘッダー形式の説明については、「 省略可能なヘッダー (画像のみ)」を参照してください。 |
18 |
2 |
特性 |
ファイルの属性を示すフラグ。 特定のフラグ値については、「 特性」を参照してください。 |
マシンの種類
[マシン] フィールドには、CPU の種類を指定する次のいずれかの値があります。 イメージ ファイルは、指定したコンピューターまたは指定したコンピューターをエミュレートするシステムでのみ実行できます。
定数 | 値 | 説明 |
---|---|---|
IMAGE_FILE_MACHINE_UNKNOWN |
0x0 |
このフィールドの内容は、任意のコンピューターの種類に適用されるものと見なされます |
IMAGE_FILE_MACHINE_ALPHA |
0x184 |
Alpha AXP、32 ビット アドレス空間 |
IMAGE_FILE_MACHINE_ALPHA64 |
0x284 |
アルファ 64、64 ビットアドレス空間 |
IMAGE_FILE_MACHINE_AM33 |
0x1d3 |
松下 AM33 |
IMAGE_FILE_MACHINE_AMD64 |
0x8664 |
X64 |
IMAGE_FILE_MACHINE_ARM |
0x1c0 |
ARM リトル エンディアン |
IMAGE_FILE_MACHINE_ARM64 |
0xaa64 |
ARM64 リトル エンディアン |
IMAGE_FILE_MACHINE_ARMNT |
0x1c4 |
ARM Thumb-2 リトル エンディアン |
IMAGE_FILE_MACHINE_AXP64 |
0x284 |
AXP 64 (アルファ 64 と同じ) |
IMAGE_FILE_MACHINE_EBC |
0xebc |
EFI バイト コード |
IMAGE_FILE_MACHINE_I386 |
0x14c |
Intel 386 以降のプロセッサと互換性のあるプロセッサ |
IMAGE_FILE_MACHINE_IA64 |
0x200 |
Intel Itanium プロセッサ ファミリ |
IMAGE_FILE_MACHINE_LOONGARCH32 |
0x6232 |
LoongArch 32 ビット プロセッサ ファミリ |
IMAGE_FILE_MACHINE_LOONGARCH64 |
0x6264 |
LoongArch 64 ビット プロセッサ ファミリ |
IMAGE_FILE_MACHINE_M32R |
0x9041 |
三菱M32Rリトルエンディアン |
IMAGE_FILE_MACHINE_MIPS16 |
0x266 |
MIPS16 |
IMAGE_FILE_MACHINE_MIPSFPU |
0x366 |
FPU を使用した MIPS |
IMAGE_FILE_MACHINE_MIPSFPU16 |
0x466 |
FPU を使用した MIPS16 |
IMAGE_FILE_MACHINE_POWERPC |
0x1f0 |
Power PC リトル エンディアン |
IMAGE_FILE_MACHINE_POWERPCFP |
0x1f1 |
浮動小数点サポート付き電源 PC |
IMAGE_FILE_MACHINE_R4000 |
0x166 |
MIPS リトル エンディアン |
IMAGE_FILE_MACHINE_RISCV32 |
0x5032 |
RISC-V 32 ビット アドレス空間 |
IMAGE_FILE_MACHINE_RISCV64 |
0x5064 |
RISC-V 64 ビット アドレス空間 |
IMAGE_FILE_MACHINE_RISCV128 |
0x5128 |
RISC-V 128 ビット アドレス空間 |
IMAGE_FILE_MACHINE_SH3 |
0x1a2 |
日立 SH3 |
IMAGE_FILE_MACHINE_SH3DSP |
0x1a3 |
日立 SH3 DSP |
IMAGE_FILE_MACHINE_SH4 |
0x1a6 |
日立 SH4 |
IMAGE_FILE_MACHINE_SH5 |
0x1a8 |
日立 SH5 |
IMAGE_FILE_MACHINE_THUMB |
0x1c2 |
つまみ |
IMAGE_FILE_MACHINE_WCEMIPSV2 |
0x169 |
MIPS リトル エンディアン WCE v2 |
特性
[特性] フィールドには、オブジェクトまたはイメージ ファイルの属性を示すフラグが含まれています。 現在、次のフラグが定義されています。
フラグ | 値 | 説明 |
---|---|---|
IMAGE_FILE_RELOCS_STRIPPED |
0x0001 |
イメージのみ、Windows CE、Microsoft Windows NT以降。 これは、ファイルにベース再配置が含まれていないため、優先ベース アドレスで読み込む必要があることを示します。 ベース アドレスが使用できない場合、ローダーはエラーを報告します。 リンカーの既定の動作では、実行可能ファイル (EXE) からベース再配置を削除します。 |
IMAGE_FILE_EXECUTABLE_IMAGE |
0x0002 |
画像のみ。 これは、イメージ ファイルが有効であり、実行できることを示します。 このフラグが設定されていない場合は、リンカー エラーを示します。 |
IMAGE_FILE_LINE_NUMS_STRIPPED |
0x0004 |
COFF 行番号が削除されました。 このフラグは非推奨であり、ゼロにする必要があります。 |
IMAGE_FILE_LOCAL_SYMS_STRIPPED |
0x0008 |
ローカル シンボルの COFF シンボル テーブルエントリが削除されました。 このフラグは非推奨であり、ゼロにする必要があります。 |
IMAGE_FILE_AGGRESSIVE_WS_TRIM |
0x0010 |
互換性のために残されています。 作業セットを積極的にトリミングします。 このフラグは、Windows 2000 以降では非推奨であり、ゼロである必要があります。 |
IMAGE_FILE_LARGE_ADDRESS_ AWARE |
0x0020 |
アプリケーションは 2 GB のアドレスを処理 > できます。 |
0x0040 |
このフラグは、今後使用するために予約されています。 |
|
IMAGE_FILE_BYTES_REVERSED_LO |
0x0080 |
リトル エンディアン: メモリ内の最下位ビット (MSB) の前に最下位ビット (LSB) が付きます。 このフラグは非推奨であり、ゼロにする必要があります。 |
IMAGE_FILE_32BIT_MACHINE |
0x0100 |
マシンは、32 ビットワード アーキテクチャに基づいています。 |
IMAGE_FILE_DEBUG_STRIPPED |
0x0200 |
デバッグ情報がイメージ ファイルから削除されます。 |
IMAGE_FILE_REMOVABLE_RUN_ FROM_SWAP |
0x0400 |
イメージがリムーバブル メディア上にある場合は、イメージを完全に読み込み、スワップ ファイルにコピーします。 |
IMAGE_FILE_NET_RUN_FROM_SWAP |
0x0800 |
イメージがネットワーク メディア上にある場合は、イメージを完全に読み込み、スワップ ファイルにコピーします。 |
IMAGE_FILE_SYSTEM |
0x1000 |
イメージ ファイルはシステム ファイルであり、ユーザー プログラムではありません。 |
IMAGE_FILE_DLL |
0x2000 |
イメージ ファイルはダイナミック リンク ライブラリ (DLL) です。 このようなファイルは、ほぼすべての目的で実行可能ファイルと見なされますが、直接実行することはできません。 |
IMAGE_FILE_UP_SYSTEM_ONLY |
0x4000 |
ファイルは、ユニプロセッサ コンピューターでのみ実行する必要があります。 |
IMAGE_FILE_BYTES_REVERSED_HI |
0x8000 |
ビッグ エンディアン: MSB はメモリ内の LSB の前にあります。 このフラグは非推奨であり、ゼロにする必要があります。 |
省略可能なヘッダー (画像のみ)
すべてのイメージ ファイルには、ローダーに情報を提供する省略可能なヘッダーがあります。 このヘッダーは、一部のファイル (具体的にはオブジェクト ファイル) に存在しないという意味では省略可能です。 イメージ ファイルの場合は、このヘッダーが必要です。 オブジェクト ファイルには省略可能なヘッダーを指定できますが、通常、このヘッダーには、サイズを大きくする以外に、オブジェクト ファイルに関数はありません。
省略可能なヘッダーのサイズは固定されていないことに注意してください。 COFF ヘッダー の SizeOfOptionalHeader フィールドを使用して、特定のデータ ディレクトリのファイルへのプローブが SizeOfOptionalHeader を超えていないことを検証する必要があります。 詳細については、「 COFF ファイル ヘッダー (オブジェクトとイメージ)」を参照してください。
また、省略可能なヘッダーの NumberOfRvaAndSizes フィールドを使用して、特定のデータ ディレクトリ エントリのプローブが省略可能なヘッダーを超えないことを確認する必要があります。 また、書式の互換性のために、オプションのヘッダー マジック番号を検証することが重要です。
オプションのヘッダー マジック番号は、イメージが PE32 または PE32 以降の実行可能ファイルであるかどうかを決定します。
マジックナンバー | PE 形式 |
---|---|
0x10b |
PE32 |
0x20b |
PE32 以降 |
PE32 以降のイメージでは、イメージ サイズを 2 ギガバイトに制限しながら、64 ビットのアドレス空間を使用できます。 その他の PE32 以降の変更は、それぞれのセクションで対処されています。
省略可能なヘッダー自体には、3 つの主要な部分があります。
オフセット (PE32/PE32+) | サイズ (PE32/PE32 以降) | ヘッダー パーツ | 説明 |
---|---|---|---|
0 |
28/24 |
標準フィールド |
UNIX を含む COFF のすべての実装に対して定義されているフィールド。 |
28/24 |
68/88 |
Windows 固有のフィールド |
Windows の特定の機能 (サブシステムなど) をサポートするための追加フィールド。 |
96/112 |
変数 |
データ ディレクトリ |
イメージ ファイルで見つかり、オペレーティング システム (インポート テーブルやエクスポート テーブルなど) で使用される特殊なテーブルのアドレスとサイズのペア。 |
省略可能なヘッダー標準フィールド (画像のみ)
省略可能なヘッダーの最初の 8 つのフィールドは、COFF の実装ごとに定義される標準フィールドです。 これらのフィールドには、実行可能ファイルの読み込みと実行に役立つ一般的な情報が含まれています。 PE32 以降の形式では変更されません。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
2 |
マジック |
イメージ ファイルの状態を識別する符号なし整数。 最も一般的な数値は、通常の実行可能ファイルとして識別される0x10Bです。 0x107は ROM イメージとして識別し、0x20Bは PE32+ 実行可能ファイルとして識別します。 |
2 |
1 |
MajorLinkerVersion |
リンカーのメジャー バージョン番号。 |
3 |
1 |
MinorLinkerVersion |
リンカーのマイナー バージョン番号。 |
4 |
4 |
SizeOfCode |
コード (テキスト) セクションのサイズ、または複数のセクションがある場合は、すべてのコード セクションの合計。 |
8 |
4 |
SizeOfInitializedData |
初期化されたデータ セクションのサイズ。複数のデータ セクションがある場合は、そのようなすべてのセクションの合計。 |
12 |
4 |
SizeOfUninitializedData |
初期化されていないデータ セクション (BSS) のサイズ。複数の BSS セクションがある場合は、そのようなすべてのセクションの合計。 |
16 |
4 |
AddressOfEntryPoint |
実行可能ファイルがメモリに読み込まれるときのイメージ ベースに対する相対エントリ ポイントのアドレス。 プログラム イメージの場合、これは開始アドレスです。 デバイス ドライバーの場合、これは初期化関数のアドレスです。 DLL のエントリ ポイントは省略可能です。 エントリ ポイントが存在しない場合、このフィールドは 0 である必要があります。 |
20 |
4 |
BaseOfCode |
コードの先頭セクションがメモリに読み込まれるときのイメージ ベースに対する相対アドレス。 |
PE32 には、BaseOfCode に続く PE32 以降に存在しないこの追加フィールドが含まれています。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
24 |
4 |
BaseOfData |
メモリに読み込まれるときに、データの先頭セクションのイメージ ベースに対する相対アドレス。 |
省略可能なヘッダー Windows-Specific フィールド (画像のみ)
次の 21 個のフィールドは、COFF オプションのヘッダー形式の拡張です。 Windows のリンカーとローダーに必要な追加情報が含まれています。
オフセット (PE32/PE32 以降) | サイズ (PE32/PE32+) | フィールド | 説明 |
---|---|---|---|
28/24 |
4/8 |
ImageBase |
メモリに読み込まれるときのイメージの最初のバイトの優先アドレス。は 64 K の倍数である必要があります。DLL の既定値は0x10000000です。 Windows CE EXEs の既定値は 0x00010000 です。 Windows NT、Windows 2000、Windows XP、Windows 95、Windows 98、および Windows Me の既定値は0x00400000。 |
32/32 |
4 |
SectionAlignment |
セクションがメモリに読み込まれるときのその配置 (バイト単位)。 FileAlignment 以上である必要があります。 既定値は、アーキテクチャのページ サイズです。 |
36/36 |
4 |
FileAlignment |
イメージ ファイル内のセクションの生データを揃えるために使用される配置係数 (バイト単位)。 値は、512 から 64 K の間の 2 の累乗である必要があります。2 を含みます。 既定値は 512 です。 SectionAlignment がアーキテクチャのページ サイズより小さい場合、FileAlignment は SectionAlignment と一致する必要があります。 |
40/40 |
2 |
MajorOperatingSystemVersion |
必要なオペレーティング システムのメジャー バージョン番号。 |
42/42 |
2 |
MinorOperatingSystemVersion |
必要なオペレーティング システムのマイナー バージョン番号。 |
44/44 |
2 |
MajorImageVersion |
イメージのメジャー バージョン番号。 |
46/46 |
2 |
MinorImageVersion |
イメージのマイナー バージョン番号。 |
48/48 |
2 |
MajorSubsystemVersion |
サブアセンブリのメジャー バージョン番号。 |
50/50 |
2 |
MinorSubsystemVersion |
サブアセンブリのマイナー バージョン番号。 |
52/52 |
4 |
Win32VersionValue |
予約済み。 は 0 である必要があります。 |
56/56 |
4 |
SizeOfImage |
イメージがメモリに読み込まれるときの、すべてのヘッダーを含むイメージのサイズ (バイト単位)。 SectionAlignment の倍数である必要があります。 |
60/60 |
4 |
SizeOfHeaders |
MS-DOS スタブ、PE ヘッダー、セクション ヘッダーの合計サイズは、FileAlignment の倍数に切り上げられます。 |
64/64 |
4 |
チェックサム |
イメージ ファイルのチェックサム。 チェックサムを計算するためのアルゴリズムは、IMAGHELP.DLLに組み込まれます。 読み込み時に検証が確認されます。すべてのドライバー、起動時に読み込まれた DLL、および重要な Windows プロセスに読み込まれる DLL。 |
68/68 |
2 |
Subsystem |
このイメージを実行するために必要なサブシステム。 詳細については、「 Windows サブシステム」を参照してください。 |
70/70 |
2 |
DllCharacteristics |
詳細については、この仕様の後半の 「DLL の特性 」を参照してください。 |
72/72 |
4/8 |
SizeOfStackReserve |
予約するスタックのサイズ。 SizeOfStackCommit のみがコミットされます。残りは、予約サイズに達するまで一度に 1 ページずつ使用できます。 |
76/80 |
4/8 |
SizeOfStackCommit |
コミットするスタックのサイズ。 |
80/88 |
4/8 |
SizeOfHeapReserve |
予約するローカル ヒープ領域のサイズ。 SizeOfHeapCommit のみがコミットされます。残りは、予約サイズに達するまで一度に 1 ページずつ使用できます。 |
84/96 |
4/8 |
SizeOfHeapCommit |
コミットするローカル ヒープ領域のサイズ。 |
88/104 |
4 |
LoaderFlags |
予約済み。 は 0 である必要があります。 |
92/108 |
4 |
NumberOfRvaAndSizes |
省略可能なヘッダーの残りのデータ ディレクトリ エントリの数。 それぞれによって、場所とサイズが記述されます。 |
Windows サブシステム
省略可能なヘッダーの Subsystem フィールドに対して定義されている次の値によって、イメージを実行するために必要な Windows サブシステム (存在する場合) が決まります。
定数 | 値 | 説明 |
---|---|---|
IMAGE_SUBSYSTEM_UNKNOWN |
0 |
不明なサブシステム |
IMAGE_SUBSYSTEM_NATIVE |
1 |
デバイス ドライバーとネイティブ Windows プロセス |
IMAGE_SUBSYSTEM_WINDOWS_GUI |
2 |
Windows グラフィカル ユーザー インターフェイス (GUI) サブシステム |
IMAGE_SUBSYSTEM_WINDOWS_CUI |
3 |
Windows 文字サブシステム |
IMAGE_SUBSYSTEM_OS2_CUI |
5 |
OS/2 文字サブシステム |
IMAGE_SUBSYSTEM_POSIX_CUI |
7 |
Posix 文字サブシステム |
IMAGE_SUBSYSTEM_NATIVE_WINDOWS |
8 |
ネイティブ Win9x ドライバー |
IMAGE_SUBSYSTEM_WINDOWS_CE_GUI |
9 |
Windows CE |
IMAGE_SUBSYSTEM_EFI_APPLICATION |
10 |
拡張ファームウェア インターフェイス (EFI) アプリケーション |
IMAGE_SUBSYSTEM_EFI_BOOT_ SERVICE_DRIVER |
11 |
ブート サービスを備えた EFI ドライバー |
IMAGE_SUBSYSTEM_EFI_RUNTIME_ DRIVER |
12 |
ランタイム サービスを備えた EFI ドライバー |
IMAGE_SUBSYSTEM_EFI_ROM |
13 |
EFI ROM イメージ |
IMAGE_SUBSYSTEM_XBOX |
14 |
XBOX |
IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION |
16 |
Windows ブート アプリケーション。 |
DLL の特性
省略可能なヘッダーの DllCharacteristics フィールドには、次の値が定義されています。
定数 | 値 | 説明 |
---|---|---|
0x0001 |
予約済み。 は 0 である必要があります。 |
|
0x0002 |
予約済み。 は 0 である必要があります。 |
|
0x0004 |
予約済み。 は 0 である必要があります。 |
|
0x0008 |
予約済み。 は 0 である必要があります。 |
|
IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA |
0x0020 |
イメージは、高エントロピの 64 ビット仮想アドレス空間を処理できます。 |
IMAGE_DLLCHARACTERISTICS_ DYNAMIC_BASE |
0x0040 |
DLL は読み込み時に再配置できます。 |
IMAGE_DLLCHARACTERISTICS_ FORCE_INTEGRITY |
0x0080 |
コードの整合性チェックが適用されます。 |
IMAGE_DLLCHARACTERISTICS_ NX_COMPAT |
0x0100 |
画像は NX 互換です。 |
IMAGE_DLLCHARACTERISTICS_ NO_ISOLATION |
0x0200 |
分離は認識されますが、イメージは分離されません。 |
IMAGE_DLLCHARACTERISTICS_ NO_SEH |
0x0400 |
構造化例外 (SE) 処理は使用しません。 このイメージでは SE ハンドラーが呼び出されません。 |
IMAGE_DLLCHARACTERISTICS_ NO_BIND |
0x0800 |
イメージをバインドしないでください。 |
IMAGE_DLLCHARACTERISTICS_APPCONTAINER |
0x1000 |
イメージは AppContainer で実行する必要があります。 |
IMAGE_DLLCHARACTERISTICS_ WDM_DRIVER |
0x2000 |
WDM ドライバー。 |
IMAGE_DLLCHARACTERISTICS_GUARD_CF |
0x4000 |
イメージでは、制御フロー ガードがサポートされています。 |
IMAGE_DLLCHARACTERISTICS_ TERMINAL_SERVER_AWARE |
0x8000 |
ターミナル サーバー対応。 |
省略可能なヘッダー データ ディレクトリ (イメージのみ)
各データ ディレクトリには、Windows で使用されるテーブルまたは文字列のアドレスとサイズが指定されます。 これらのデータ ディレクトリ エントリはすべてメモリに読み込まれるため、システムは実行時にそれらを使用できます。 データ ディレクトリは、次の宣言を持つ 8 バイトフィールドです。
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;
DWORD Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
最初のフィールド VirtualAddress は、実際にはテーブルの RVA です。 RVA は、テーブルが読み込まれるときのイメージのベース アドレスを基準としたテーブルのアドレスです。 2 番目のフィールドでは、サイズをバイト単位で指定します。 省略可能なヘッダーの最後の部分を形成するデータ ディレクトリを次の表に示します。
ディレクトリの数は固定されていないことに注意してください。 特定のディレクトリを探す前に、省略可能なヘッダーの NumberOfRvaAndSizes フィールドを確認します。
また、このテーブルの RVA がセクションの先頭を指していること、または特定のテーブルを含むセクションに特定の名前があることを想定しないでください。
オフセット (PE/PE32+) | サイズ | フィールド | 説明 |
---|---|---|---|
96/112 |
8 |
テーブルのエクスポート |
エクスポート テーブルのアドレスとサイズ。 詳細については、「 .edata セクション (画像のみ)」を参照してください。 |
104/120 |
8 |
テーブルのインポート |
インポート テーブルのアドレスとサイズ。 詳細については、「 .idata セクション」を参照してください。 |
112/128 |
8 |
リソース テーブル |
リソース テーブルのアドレスとサイズ。 詳細については、「 .rsrc セクション」を参照してください。 |
120/136 |
8 |
例外テーブル |
例外テーブルのアドレスとサイズ。 詳細については、「 .pdata セクション」を参照してください。 |
128/144 |
8 |
証明書テーブル |
属性証明書テーブルのアドレスとサイズ。 詳細については、「 属性証明書テーブル (イメージのみ)」を参照してください。 |
136/152 |
8 |
ベース再配置テーブル |
ベース再配置テーブルのアドレスとサイズ。 詳細については、「 .reloc セクション (イメージのみ)」を参照してください。 |
144/160 |
8 |
デバッグ |
デバッグ データの開始アドレスとサイズ。 詳細については、「 .debug セクション」を参照してください。 |
152/168 |
8 |
アーキテクチャ |
予約済み、0 である必要があります |
160/176 |
8 |
Global Ptr |
グローバル ポインター レジスタに格納される値の RVA。 この構造体の size メンバーは 0 に設定する必要があります。 |
168/184 |
8 |
TLS テーブル |
スレッド ローカル ストレージ (TLS) テーブルのアドレスとサイズ。 詳細については、「 .tls セクション」を参照してください。 |
176/192 |
8 |
構成テーブルの読み込み |
ロード構成テーブルのアドレスとサイズ。 詳細については、「 Load Configuration Structure (イメージのみ)」を参照してください。 |
184/200 |
8 |
バインドされたインポート |
バインドされたインポート テーブルのアドレスとサイズ。 |
192/208 |
8 |
Iat |
インポート アドレス テーブルのアドレスとサイズ。 詳細については、「 アドレス テーブルのインポート」を参照してください。 |
200/216 |
8 |
インポート記述子の遅延 |
遅延インポート記述子のアドレスとサイズ。 詳細については、「 インポート テーブルの遅延読み込み (イメージのみ)」を参照してください。 |
208/224 |
8 |
CLR ランタイム ヘッダー |
CLR ランタイム ヘッダーのアドレスとサイズ。 詳細については、「 .cormeta セクション (オブジェクトのみ)」を参照してください。 |
216/232 |
8 |
予約済み、0 にする必要があります |
[証明書テーブル] エントリは、属性証明書のテーブルを指します。 これらの証明書は、イメージの一部としてメモリに読み込まれません。 そのため、通常は RVA であるこのエントリの最初のフィールドは、代わりにファイル ポインターです。
セクション テーブル (セクション ヘッダー)
セクション テーブルの各行は、実質的にはセクション ヘッダーです。 このテーブルは、省略可能なヘッダー (存在する場合) の直後に表示されます。 ファイル ヘッダーにセクション テーブルへの直接ポインターが含まれていないため、この配置が必要です。 代わりに、セクション テーブルの場所は、ヘッダーの後の最初のバイトの位置を計算することによって決定されます。 ファイル ヘッダーで指定されている省略可能なヘッダーのサイズを必ず使用してください。
セクション テーブル内のエントリの数は、ファイル ヘッダーの NumberOfSections フィールドによって指定されます。 セクション テーブルのエントリには、1 から始まる番号が付けられます。 コードとデータ メモリ セクションのエントリは、リンカーによって選択された順序で行われます。
イメージ ファイルでは、セクションの VA がリンカーによって割り当てられ、それらが昇順で隣接するようにする必要があります。また、省略可能なヘッダーの SectionAlignment 値の倍数である必要があります。
各セクション ヘッダー (セクション テーブル エントリ) の形式は、1 エントリあたり合計 40 バイトです。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
8 |
名前 |
8 バイトの null 埋め込み UTF-8 エンコード文字列。 文字列の長さがちょうど 8 文字の場合、終了 null は発生しません。 長い名前の場合、このフィールドにはスラッシュ (/) が含まれます。その後に、文字列テーブルへのオフセットである 10 進数の ASCII 表現が続きます。 実行可能イメージは文字列テーブルを使用せず、8 文字を超えるセクション名をサポートしていません。 オブジェクト ファイル内の長い名前は、実行可能ファイルに出力されると切り捨てられます。 |
8 |
4 |
VirtualSize |
メモリに読み込まれた場合のセクションの合計サイズ。 この値が SizeOfRawData より大きい場合、セクションはゼロ埋め込みになります。 このフィールドは実行可能イメージに対してのみ有効であり、オブジェクト ファイルの場合は 0 に設定する必要があります。 |
12 |
4 |
VirtualAddress |
実行可能イメージの場合、セクションがメモリに読み込まれるときのイメージ ベースに対するセクションの最初のバイトのアドレス。 オブジェクト ファイルの場合、このフィールドは再配置が適用される前の最初のバイトのアドレスです。わかりやすくするために、コンパイラはこれをゼロに設定する必要があります。 それ以外の場合は、再配置中にオフセットから減算される任意の値です。 |
16 |
4 |
SizeOfRawData |
セクションのサイズ (オブジェクト ファイルの場合) またはディスク上の初期化されたデータのサイズ (イメージ ファイルの場合)。 実行可能イメージの場合、これは省略可能なヘッダーからの FileAlignment の倍数である必要があります。 これが VirtualSize より小さい場合、セクションの残りの部分は 0 で塗りつぶされます。 SizeOfRawData フィールドは丸められますが、VirtualSize フィールドは指定されていないため、SizeOfRawData も VirtualSize より大きくなる可能性があります。 セクションに初期化されていないデータのみが含まれている場合、このフィールドは 0 にする必要があります。 |
20 |
4 |
PointerToRawData |
COFF ファイル内のセクションの最初のページへのファイル ポインター。 実行可能イメージの場合、これは省略可能なヘッダーからの FileAlignment の倍数である必要があります。 オブジェクト ファイルの場合は、最適なパフォーマンスを得るための値を 4 バイト境界に配置する必要があります。 セクションに初期化されていないデータのみが含まれている場合、このフィールドは 0 にする必要があります。 |
24 |
4 |
PointerToRelocations |
セクションの再配置エントリの先頭へのファイル ポインター。 実行可能イメージの場合、または再配置がない場合、これは 0 に設定されます。 |
28 |
4 |
PointerToLinenumbers |
セクションの行番号エントリの先頭へのファイル ポインター。 COFF 行番号がない場合、これは 0 に設定されます。 COFF デバッグ情報は非推奨であるため、イメージの場合、この値は 0 にする必要があります。 |
32 |
2 |
NumberOfRelocations |
セクションの再配置エントリの数。 実行可能イメージの場合、これは 0 に設定されます。 |
34 |
2 |
NumberOfLinenumbers |
セクションの行番号エントリの数。 COFF デバッグ情報は非推奨であるため、イメージの場合、この値は 0 にする必要があります。 |
36 |
4 |
特性 |
セクションの特性を説明するフラグ。 詳細については、「 セクション フラグ」を参照してください。 |
セクション フラグ
セクション ヘッダーの [特性] フィールドのセクション フラグは、セクションの特性を示します。
フラグ | 値 | 説明 |
---|---|---|
0x00000000 |
将来利用するために予約されています。 |
|
0x00000001 |
将来利用するために予約されています。 |
|
0x00000002 |
将来利用するために予約されています。 |
|
0x00000004 |
将来利用するために予約されています。 |
|
IMAGE_SCN_TYPE_NO_PAD |
0x00000008 |
セクションを次の境界に埋め込むべきではありません。 このフラグは廃止され、IMAGE_SCN_ALIGN_1BYTESに置き換えられます。 これは、オブジェクト ファイルに対してのみ有効です。 |
0x00000010 |
将来利用するために予約されています。 |
|
IMAGE_SCN_CNT_CODE |
0x00000020 |
セクションには実行可能コードが含まれています。 |
IMAGE_SCN_CNT_INITIALIZED_DATA |
0x00000040 |
セクションには、初期化されたデータが含まれています。 |
IMAGE_SCN_CNT_UNINITIALIZED_ DATA |
0x00000080 |
セクションには、初期化されていないデータが含まれています。 |
IMAGE_SCN_LNK_OTHER |
0x00000100 |
将来利用するために予約されています。 |
IMAGE_SCN_LNK_INFO |
0x00000200 |
セクションには、コメントまたはその他の情報が含まれています。 .drectve セクションには、この型があります。 これはオブジェクト ファイルに対してのみ有効です。 |
0x00000400 |
将来利用するために予約されています。 |
|
IMAGE_SCN_LNK_REMOVE |
0x00000800 |
セクションはイメージの一部になりません。 これは、オブジェクト ファイルに対してのみ有効です。 |
IMAGE_SCN_LNK_COMDAT |
0x00001000 |
セクションには COMDAT データが含まれています。 詳細については、「 COMDAT セクション (オブジェクトのみ)」を参照してください。 これは、オブジェクト ファイルに対してのみ有効です。 |
IMAGE_SCN_GPREL |
0x00008000 |
セクションには、グローバル ポインター (GP) を介して参照されるデータが含まれています。 |
IMAGE_SCN_MEM_PURGEABLE |
0x00020000 |
将来利用するために予約されています。 |
IMAGE_SCN_MEM_16BIT |
0x00020000 |
将来利用するために予約されています。 |
IMAGE_SCN_MEM_LOCKED |
0x00040000 |
将来利用するために予約されています。 |
IMAGE_SCN_MEM_PRELOAD |
0x00080000 |
将来利用するために予約されています。 |
IMAGE_SCN_ALIGN_1BYTES |
0x00100000 |
1 バイト境界にデータを配置します。 オブジェクト ファイルに対してのみ有効です。 |
IMAGE_SCN_ALIGN_2BYTES |
0x00200000 |
2 バイト境界にデータを配置します。 オブジェクト ファイルに対してのみ有効です。 |
IMAGE_SCN_ALIGN_4BYTES |
0x00300000 |
4 バイト境界にデータを配置します。 オブジェクト ファイルに対してのみ有効です。 |
IMAGE_SCN_ALIGN_8BYTES |
0x00400000 |
8 バイト境界にデータを配置します。 オブジェクト ファイルに対してのみ有効です。 |
IMAGE_SCN_ALIGN_16BYTES |
0x00500000 |
16 バイト境界にデータを配置します。 オブジェクト ファイルに対してのみ有効です。 |
IMAGE_SCN_ALIGN_32BYTES |
0x00600000 |
32 バイト境界にデータを配置します。 オブジェクト ファイルに対してのみ有効です。 |
IMAGE_SCN_ALIGN_64BYTES |
0x00700000 |
64 バイト境界にデータを配置します。 オブジェクト ファイルに対してのみ有効です。 |
IMAGE_SCN_ALIGN_128BYTES |
0x00800000 |
128 バイト境界にデータを配置します。 オブジェクト ファイルに対してのみ有効です。 |
IMAGE_SCN_ALIGN_256BYTES |
0x00900000 |
256 バイト境界にデータを配置します。 オブジェクト ファイルに対してのみ有効です。 |
IMAGE_SCN_ALIGN_512BYTES |
0x00A00000 |
512 バイト境界にデータを配置します。 オブジェクト ファイルに対してのみ有効です。 |
IMAGE_SCN_ALIGN_1024BYTES |
0x00B00000 |
1024 バイト境界にデータを配置します。 オブジェクト ファイルに対してのみ有効です。 |
IMAGE_SCN_ALIGN_2048BYTES |
0x00C00000 |
2048 バイト境界にデータを配置します。 オブジェクト ファイルに対してのみ有効です。 |
IMAGE_SCN_ALIGN_4096BYTES |
0x00D00000 |
4096 バイト境界にデータを配置します。 オブジェクト ファイルに対してのみ有効です。 |
IMAGE_SCN_ALIGN_8192BYTES |
0x00E00000 |
8192 バイト境界にデータを配置します。 オブジェクト ファイルに対してのみ有効です。 |
IMAGE_SCN_LNK_NRELOC_OVFL |
0x01000000 |
セクションには、拡張再配置が含まれています。 |
IMAGE_SCN_MEM_DISCARDABLE |
0x02000000 |
セクションは必要に応じて破棄できます。 |
IMAGE_SCN_MEM_NOT_CACHED |
0x04000000 |
セクションをキャッシュできません。 |
IMAGE_SCN_MEM_NOT_PAGED |
0x08000000 |
セクションはページングできません。 |
IMAGE_SCN_MEM_SHARED |
0x10000000 |
セクションはメモリ内で共有できます。 |
IMAGE_SCN_MEM_EXECUTE |
0x20000000 |
セクションはコードとして実行できます。 |
IMAGE_SCN_MEM_READ |
0x40000000 |
セクションは読み取ることができます。 |
IMAGE_SCN_MEM_WRITE |
0x80000000 |
セクションは に書き込むことができます。 |
IMAGE_SCN_LNK_NRELOC_OVFLは、セクションの再配置の数が、セクション ヘッダーで予約されている 16 ビットを超えていることを示します。 ビットが設定され、セクション ヘッダーの NumberOfRelocations フィールドが0xffff場合、実際の再配置数は、最初の再配置の 32 ビット VirtualAddress フィールドに格納されます。 IMAGE_SCN_LNK_NRELOC_OVFLが設定されていて、セクション内の再配置が0xffff未満の場合は、エラーです。
グループ化されたセクション (オブジェクトのみ)
"$"? character (ドル記号) には、オブジェクト ファイル内のセクション名に特別な解釈があります。
オブジェクト セクションの内容を含むイメージ セクションを決定すると、リンカーは "$" を破棄しますか? およびそれに続くすべての文字。 したがって、 という名前のオブジェクト セクション。text$X は、実際には画像の .text セクションに寄与します。
ただし、"$" に続く文字は? 画像セクションへのコントリビューションの順序を決定します。 同じオブジェクト セクション名を持つすべてのコントリビューションがイメージ内で連続して割り当てられ、コントリビューションのブロックはオブジェクト セクション名で構文順に並べ替えられます。 したがって、セクション名 が .text$X のオブジェクト ファイル内のすべてが、 .text$W コントリビューションの後、および .text$Y コントリビューションの前にまとめて終了します。
イメージ ファイル内のセクション名に "$" が含まれることはありませんか? 文字。
ファイルのその他の内容
- セクション データ
- COFF 再配置 (オブジェクトのみ)
- COFF 行番号 (非推奨)
- COFF シンボル テーブル
- 補助記号レコード
- COFF 文字列テーブル
- 属性証明書テーブル (イメージのみ)
- インポート テーブルの遅延読み込み (イメージのみ)
これまでに説明したデータ構造 (省略可能なヘッダーを含む) はすべて、ファイルの先頭からの固定オフセット (またはファイルが MS-DOS スタブを含むイメージの場合は PE ヘッダーから) に配置されます。
COFF オブジェクトまたはイメージ ファイルの残りの部分には、特定のファイル オフセットとは限らないデータブロックが含まれています。 代わりに、場所は省略可能なヘッダーまたはセクション ヘッダー内のポインターによって定義されます。
例外は、SectionAlignment 値がアーキテクチャのページ サイズより小さいイメージの場合です (Intel x86 および MIPS の場合は 4 K、Itanium の場合は 8 K)。 SectionAlignment の説明については、「 省略可能なヘッダー (イメージのみ)」を参照してください。 この場合、セクション 5.1「セクション データ」で説明されているように、セクション データのファイル オフセットに制約があります。もう 1 つの例外は、イメージ ファイルの末尾に属性証明書とデバッグ情報を配置する必要があり、ローダーはこれらをメモリにマップしないため、デバッグ セクションの直前に属性証明書テーブルを配置する必要がある点です。 ただし、属性証明書とデバッグ情報に関する規則は、オブジェクト ファイルには適用されません。
セクション データ
セクションの初期化されたデータは、単純なバイト ブロックで構成されます。 ただし、ゼロをすべて含むセクションの場合、セクション データを含める必要はありません。
各セクションのデータは、セクション ヘッダーの PointerToRawData フィールドによって指定されたファイル オフセットにあります。 ファイル内のこのデータのサイズは、SizeOfRawData フィールドによって示されます。 SizeOfRawData が VirtualSize より小さい場合、剰余はゼロで埋められます。
イメージ ファイルでは、省略可能なヘッダーの FileAlignment フィールドで指定された境界にセクション データを配置する必要があります。 セクション データは、対応するセクションの RVA 値の順序で表示する必要があります (セクション テーブルの個々のセクション ヘッダーと同様)。
省略可能なヘッダーの SectionAlignment 値がアーキテクチャのページ サイズより小さい場合、イメージ ファイルには追加の制限があります。 このようなファイルの場合、ファイル内のセクション データの場所は、イメージが読み込まれるときにメモリ内の場所と一致する必要があります。これにより、セクション データの物理オフセットは RVA と同じになります。
COFF 再配置 (オブジェクトのみ)
オブジェクト ファイルには COFF 再配置が含まれています。これは、イメージ ファイルに配置した後にメモリに読み込むときにセクション データを変更する方法を指定します。
イメージ ファイルには COFF 再配置が含まれていません。参照されているすべてのシンボルには、フラット アドレス空間にアドレスが既に割り当てられているためです。 イメージには、.reloc セクションの基本再配置の形式で再配置情報が含まれます (イメージに IMAGE_FILE_RELOCS_STRIPPED 属性がない限り)。 詳細については、「 .reloc セクション (イメージのみ)」を参照してください。
オブジェクト ファイル内の各セクションについて、固定長レコードの配列はセクションの COFF 再配置を保持します。 配列の位置と長さはセクション ヘッダーで指定します。 配列の各要素の形式は次のとおりです。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
4 |
VirtualAddress |
再配置が適用されるアイテムのアドレス。 これは、セクションの先頭からのオフセットと、セクションの RVA/Offset フィールドの値です。 セクション テーブル (セクション ヘッダー) を参照してください。 たとえば、セクションの最初のバイトに 0x10 のアドレスがある場合、3 番目のバイトのアドレスは 0x12 です。 |
4 |
4 |
SymbolTableIndex |
シンボル テーブルへの 0 から始まるインデックス。 このシンボルは、再配置に使用されるアドレスを示します。 指定したシンボルにセクション ストレージ クラスがある場合、シンボルのアドレスは、同じ名前の最初のセクションを持つアドレスです。 |
8 |
2 |
Type |
実行する必要がある再配置の種類を示す 値。 有効な再配置の種類は、コンピューターの種類によって異なります。 「型インジケーター」を参照してください。 |
SymbolTableIndex フィールドによって参照されるシンボルにストレージ クラスIMAGE_SYM_CLASS_SECTIONがある場合、シンボルのアドレスは セクションの先頭になります。 オブジェクト ファイルがアーカイブ (ライブラリ) の一部である場合を除き、セクションは通常同じファイル内にあります。 その場合、現在のオブジェクト ファイルと同じアーカイブ メンバー名を持つアーカイブ内の他のオブジェクト ファイルでセクションを見つけることができます。 (アーカイブ メンバー名とのリレーションシップは、インポート テーブルのリンク 、つまり .idata セクションで使用されます)。
型インジケーター
再配置レコードの Type フィールドは、実行する必要がある再配置の種類を示します。 マシンの種類ごとに異なる再配置の種類が定義されています。
x64 プロセッサ
x64 および互換性のあるプロセッサに対して、次の再配置タイプ インジケーターが定義されています。
定数 | 値 | 説明 |
---|---|---|
IMAGE_REL_AMD64_ABSOLUTE |
0x0000 |
再配置は無視されます。 |
IMAGE_REL_AMD64_ADDR64 |
0x0001 |
再配置ターゲットの 64 ビット VA。 |
IMAGE_REL_AMD64_ADDR32 |
0x0002 |
再配置ターゲットの 32 ビット VA。 |
IMAGE_REL_AMD64_ADDR32NB |
0x0003 |
イメージ ベース (RVA) のない 32 ビット アドレス。 |
IMAGE_REL_AMD64_REL32 |
0x0004 |
再配置後のバイトからの 32 ビット相対アドレス。 |
IMAGE_REL_AMD64_REL32_1 |
0x0005 |
再配置からのバイト距離 1 に対する 32 ビット アドレス。 |
IMAGE_REL_AMD64_REL32_2 |
0x0006 |
再配置からのバイト距離 2 に対する 32 ビット アドレス。 |
IMAGE_REL_AMD64_REL32_3 |
0x0007 |
再配置からのバイト距離 3 に対する 32 ビット アドレス。 |
IMAGE_REL_AMD64_REL32_4 |
0x0008 |
再配置からのバイト距離 4 に対する 32 ビット アドレス。 |
IMAGE_REL_AMD64_REL32_5 |
0x0009 |
再配置からのバイト距離 5 に対する 32 ビット アドレス。 |
IMAGE_REL_AMD64_SECTION |
0x000A |
ターゲットを含むセクションの 16 ビット セクション インデックス。 これは、デバッグ情報をサポートするために使用されます。 |
IMAGE_REL_AMD64_SECREL |
0x000B |
セクションの先頭からのターゲットの 32 ビット オフセット。 これは、デバッグ情報と静的スレッド ローカル ストレージをサポートするために使用されます。 |
IMAGE_REL_AMD64_SECREL7 |
0x000C |
ターゲットを含むセクションのベースからの 7 ビット符号なしオフセット。 |
IMAGE_REL_AMD64_TOKEN |
0x000D |
CLR トークン。 |
IMAGE_REL_AMD64_SREL32 |
0x000E |
オブジェクトに出力される 32 ビット符号付きスパン依存値。 |
IMAGE_REL_AMD64_PAIR |
0x000F |
スパンに依存するすべての値の直後に続く必要があるペア。 |
IMAGE_REL_AMD64_SSPAN32 |
0x0010 |
リンク時に適用される 32 ビット符号付きスパン依存値。 |
ARM プロセッサ
ARM プロセッサには、次の再配置タイプ インジケーターが定義されています。
定数 | 値 | 説明 |
---|---|---|
IMAGE_REL_ARM_ABSOLUTE |
0x0000 |
再配置は無視されます。 |
IMAGE_REL_ARM_ADDR32 |
0x0001 |
ターゲットの 32 ビット VA。 |
IMAGE_REL_ARM_ADDR32NB |
0x0002 |
ターゲットの 32 ビット RVA。 |
IMAGE_REL_ARM_BRANCH24 |
0x0003 |
ターゲットに対する 24 ビットの相対変位。 |
IMAGE_REL_ARM_BRANCH11 |
0x0004 |
サブルーチン呼び出しへの参照。 このリファレンスは、11 ビット オフセットを持つ 2 つの 16 ビット命令で構成されます。 |
IMAGE_REL_ARM_REL32 |
0x000A |
再配置後のバイトからの 32 ビット相対アドレス。 |
IMAGE_REL_ARM_SECTION |
0x000E |
ターゲットを含むセクションの 16 ビット セクション インデックス。 これは、デバッグ情報をサポートするために使用されます。 |
IMAGE_REL_ARM_SECREL |
0x000F |
セクションの先頭からのターゲットの 32 ビット オフセット。 これは、デバッグ情報と静的スレッド ローカル ストレージをサポートするために使用されます。 |
IMAGE_REL_ARM_MOV32 |
0x0010 |
ターゲットの 32 ビット VA。 この再配置は、下位 16 ビットの MOVW 命令と、上位 16 ビットの MOVT を使用して適用されます。 |
IMAGE_REL_THUMB_MOV32 |
0x0011 |
ターゲットの 32 ビット VA。 この再配置は、下位 16 ビットの MOVW 命令と、上位 16 ビットの MOVT を使用して適用されます。 |
IMAGE_REL_THUMB_BRANCH20 |
0x0012 |
命令は、2 バイトアラインターゲットに対する 21 ビットの相対変位で固定されます。 変位の最下位ビットは常に 0 であり、格納されません。 この再配置は、Thumb-2 32 ビットの条件付き B 命令に対応します。 |
未使用 |
0x0013 |
|
IMAGE_REL_THUMB_BRANCH24 |
0x0014 |
命令は、2 バイトアラインターゲットに対する 25 ビットの相対変位で固定されます。 変位の最下位ビットは 0 であり、格納されません。この再配置は、Thumb-2 B 命令に対応します。 |
IMAGE_REL_THUMB_BLX23 |
0x0015 |
命令は、4 バイトのアラインターゲットに対する 25 ビットの相対変位で固定されます。 変位の下位 2 ビットは 0 であり、格納されません。 この再配置は、Thumb-2 BLX 命令に対応します。 |
IMAGE_REL_ARM_PAIR |
0x0016 |
再配置は、ARM_REFHIまたはTHUMB_REFHIの直後にある場合にのみ有効です。 SymbolTableIndex には、シンボル テーブルへのインデックスではなく、変位が含まれています。 |
ARM64 プロセッサ
ARM64 プロセッサには、次の再配置タイプ インジケーターが定義されています。
定数 | 値 | 説明 |
---|---|---|
IMAGE_REL_ARM64_ABSOLUTE |
0x0000 |
再配置は無視されます。 |
IMAGE_REL_ARM64_ADDR32 |
0x0001 |
ターゲットの 32 ビット VA。 |
IMAGE_REL_ARM64_ADDR32NB |
0x0002 |
ターゲットの 32 ビット RVA。 |
IMAGE_REL_ARM64_BRANCH26 |
0x0003 |
B 命令と BL 命令の場合、ターゲットに対する 26 ビットの相対変位。 |
IMAGE_REL_ARM64_PAGEBASE_REL21 |
0x0004 |
ADRP 命令のターゲットのページ ベース。 |
IMAGE_REL_ARM64_REL21 |
0x0005 |
命令 ADR のターゲットに対する 12 ビットの相対変位 |
IMAGE_REL_ARM64_PAGEOFFSET_12A |
0x0006 |
ターゲットの 12 ビット ページ オフセット。手順 ADD/ADDS (イミディエイト) (シフトゼロ)。 |
IMAGE_REL_ARM64_PAGEOFFSET_12L |
0x0007 |
命令 LDR (インデックス付き、符号なしイミディエイト) のターゲットの 12 ビット ページ オフセット。 |
IMAGE_REL_ARM64_SECREL |
0x0008 |
セクションの先頭からのターゲットの 32 ビット オフセット。 これは、デバッグ情報と静的スレッド ローカル ストレージをサポートするために使用されます。 |
IMAGE_REL_ARM64_SECREL_LOW12A |
0x0009 |
ターゲットのセクション オフセットのビット 0:11。手順 ADD/ADDS (イミディエイト) (シフトゼロ)。 |
IMAGE_REL_ARM64_SECREL_HIGH12A |
0x000A |
ターゲットのセクション オフセットのビット 12:23(シフトゼロの命令 ADD/ADDS (イミディエイト) 用)。 |
IMAGE_REL_ARM64_SECREL_LOW12L |
0x000B |
命令 LDR (インデックス付き、符号なしイミディエイト) のターゲットのセクション オフセットのビット 0:11。 |
IMAGE_REL_ARM64_TOKEN |
0x000C |
CLR トークン。 |
IMAGE_REL_ARM64_SECTION |
0x000D |
ターゲットを含むセクションの 16 ビット セクション インデックス。 これは、デバッグ情報をサポートするために使用されます。 |
IMAGE_REL_ARM64_ADDR64 |
0x000E |
再配置ターゲットの 64 ビット VA。 |
IMAGE_REL_ARM64_BRANCH19 |
0x000F |
条件付き B 命令の再配置ターゲットへの 19 ビット オフセット。 |
IMAGE_REL_ARM64_BRANCH14 |
0x0010 |
命令 TBZ と TBNZ の場合、再配置ターゲットへの 14 ビット オフセット。 |
IMAGE_REL_ARM64_REL32 |
0x0011 |
再配置後のバイトからの 32 ビット相対アドレス。 |
日立スーパーHプロセッサ
SH3 および SH4 プロセッサーには、次の再配置タイプ・インディケーターが定義されています。 SH5 固有の再配置は、SHM (SH メディア) として示されます。
定数 | 値 | 説明 |
---|---|---|
IMAGE_REL_SH3_ABSOLUTE |
0x0000 |
再配置は無視されます。 |
IMAGE_REL_SH3_DIRECT16 |
0x0001 |
ターゲット シンボルの VA を含む 16 ビットの場所への参照。 |
IMAGE_REL_SH3_DIRECT32 |
0x0002 |
ターゲット シンボルの 32 ビット VA。 |
IMAGE_REL_SH3_DIRECT8 |
0x0003 |
ターゲット シンボルの VA を含む 8 ビットの場所への参照。 |
IMAGE_REL_SH3_DIRECT8_WORD |
0x0004 |
ターゲット シンボルの有効な 16 ビット VA を含む 8 ビット命令への参照。 |
IMAGE_REL_SH3_DIRECT8_LONG |
0x0005 |
ターゲット シンボルの有効な 32 ビット VA を含む 8 ビット命令への参照。 |
IMAGE_REL_SH3_DIRECT4 |
0x0006 |
下位 4 ビットにターゲット シンボルの VA が含まれる 8 ビット位置への参照。 |
IMAGE_REL_SH3_DIRECT4_WORD |
0x0007 |
下位 4 ビットにターゲット シンボルの有効な 16 ビット VA が含まれる 8 ビット命令への参照。 |
IMAGE_REL_SH3_DIRECT4_LONG |
0x0008 |
下位 4 ビットにターゲット シンボルの有効な 32 ビット VA が含まれている 8 ビット命令への参照。 |
IMAGE_REL_SH3_PCREL8_WORD |
0x0009 |
ターゲット シンボルの有効な 16 ビット相対オフセットを含む 8 ビット命令への参照。 |
IMAGE_REL_SH3_PCREL8_LONG |
0x000A |
ターゲット シンボルの有効な 32 ビット相対オフセットを含む 8 ビット命令への参照。 |
IMAGE_REL_SH3_PCREL12_WORD |
0x000B |
下位 12 ビットにターゲット シンボルの有効な 16 ビット相対オフセットが含まれる 16 ビット命令への参照。 |
IMAGE_REL_SH3_STARTOF_SECTION |
0x000C |
ターゲット シンボルを含むセクションの VA である 32 ビットの場所への参照。 |
IMAGE_REL_SH3_SIZEOF_SECTION |
0x000D |
ターゲット シンボルを含むセクションのサイズである 32 ビットの場所への参照。 |
IMAGE_REL_SH3_SECTION |
0x000E |
ターゲットを含むセクションの 16 ビット セクション インデックス。 これは、デバッグ情報をサポートするために使用されます。 |
IMAGE_REL_SH3_SECREL |
0x000F |
セクションの先頭からのターゲットの 32 ビット オフセット。 これは、デバッグ情報と静的スレッド ローカル ストレージをサポートするために使用されます。 |
IMAGE_REL_SH3_DIRECT32_NB |
0x0010 |
ターゲット シンボルの 32 ビット RVA。 |
IMAGE_REL_SH3_GPREL4_LONG |
0x0011 |
GP 相対。 |
IMAGE_REL_SH3_TOKEN |
0x0012 |
CLR トークン。 |
IMAGE_REL_SHM_PCRELPT |
0x0013 |
longwords の現在の命令からのオフセット。 NOMODE ビットが設定されていない場合は、下位ビットの逆ビットをビット 32 に挿入して、PTA または PTB を選択します。 |
IMAGE_REL_SHM_REFLO |
0x0014 |
32 ビット アドレスの下位 16 ビット。 |
IMAGE_REL_SHM_REFHALF |
0x0015 |
32 ビット アドレスの上位 16 ビット。 |
IMAGE_REL_SHM_RELLO |
0x0016 |
相対アドレスの下位 16 ビット。 |
IMAGE_REL_SHM_RELHALF |
0x0017 |
相対アドレスの上位 16 ビット。 |
IMAGE_REL_SHM_PAIR |
0x0018 |
再配置は、REFHALF、RELHALF、または RELLO の再配置の直後にある場合にのみ有効です。 再配置の SymbolTableIndex フィールドには、シンボル テーブルへのインデックスではなく、ディスプレイスメントが含まれています。 |
IMAGE_REL_SHM_NOMODE |
0x8000 |
再配置はセクション モードを無視します。 |
IBM PowerPC プロセッサ
PowerPC プロセッサには、次の再配置タイプ インジケーターが定義されています。
定数 | 値 | 説明 |
---|---|---|
IMAGE_REL_PPC_ABSOLUTE |
0x0000 |
再配置は無視されます。 |
IMAGE_REL_PPC_ADDR64 |
0x0001 |
ターゲットの 64 ビット VA。 |
IMAGE_REL_PPC_ADDR32 |
0x0002 |
ターゲットの 32 ビット VA。 |
IMAGE_REL_PPC_ADDR24 |
0x0003 |
ターゲットの VA の下位 24 ビット。 これは、ターゲット シンボルが絶対であり、元の値に符号拡張できる場合にのみ有効です。 |
IMAGE_REL_PPC_ADDR16 |
0x0004 |
ターゲットの VA の下位 16 ビット。 |
IMAGE_REL_PPC_ADDR14 |
0x0005 |
ターゲットの VA の下位 14 ビット。 これは、ターゲット シンボルが絶対であり、元の値に符号拡張できる場合にのみ有効です。 |
IMAGE_REL_PPC_REL24 |
0x0006 |
シンボルの位置に対する 24 ビット PC 相対オフセット。 |
IMAGE_REL_PPC_REL14 |
0x0007 |
シンボルの位置に対する 14 ビット PC 相対オフセット。 |
IMAGE_REL_PPC_ADDR32NB |
0x000A |
ターゲットの 32 ビット RVA。 |
IMAGE_REL_PPC_SECREL |
0x000B |
セクションの先頭からのターゲットの 32 ビット オフセット。 これは、デバッグ情報と静的スレッド ローカル ストレージをサポートするために使用されます。 |
IMAGE_REL_PPC_SECTION |
0x000C |
ターゲットを含むセクションの 16 ビット セクション インデックス。 これは、デバッグ情報をサポートするために使用されます。 |
IMAGE_REL_PPC_SECREL16 |
0x000F |
セクションの先頭からのターゲットの 16 ビット オフセット。 これは、デバッグ情報と静的スレッド ローカル ストレージをサポートするために使用されます。 |
IMAGE_REL_PPC_REFHI |
0x0010 |
ターゲットの 32 ビット VA の上位 16 ビット。 これは、完全なアドレスを読み込む 2 命令シーケンスの最初の命令に使用されます。 この再配置の直後に PAIR 再配置が行われ、その後に SymbolTableIndex に、再配置される場所から取得された上位 16 ビットに追加される符号付き 16 ビットの変位が含まれている必要があります。 |
IMAGE_REL_PPC_REFLO |
0x0011 |
ターゲットの VA の下位 16 ビット。 |
IMAGE_REL_PPC_PAIR |
0x0012 |
REFHI または SECRELHI 再配置の直後にだけ有効な再配置。 SymbolTableIndex には、シンボル テーブルへのインデックスではなく、ディスプレイスメントが含まれています。 |
IMAGE_REL_PPC_SECRELLO |
0x0013 |
セクションの先頭からのターゲットの 32 ビット オフセットの下位 16 ビット。 |
IMAGE_REL_PPC_GPREL |
0x0015 |
GP レジスタに対するターゲットの 16 ビット符号付き変位。 |
IMAGE_REL_PPC_TOKEN |
0x0016 |
CLR トークン。 |
Intel 386 プロセッサ
Intel 386 および互換性のあるプロセッサでは、次の再配置タイプ インジケーターが定義されています。
定数 | 値 | 説明 |
---|---|---|
IMAGE_REL_I386_ABSOLUTE |
0x0000 |
再配置は無視されます。 |
IMAGE_REL_I386_DIR16 |
0x0001 |
サポートされていません。 |
IMAGE_REL_I386_REL16 |
0x0002 |
サポートされていません。 |
IMAGE_REL_I386_DIR32 |
0x0006 |
ターゲットの 32 ビット VA。 |
IMAGE_REL_I386_DIR32NB |
0x0007 |
ターゲットの 32 ビット RVA。 |
IMAGE_REL_I386_SEG12 |
0x0009 |
サポートされていません。 |
IMAGE_REL_I386_SECTION |
0x000A |
ターゲットを含むセクションの 16 ビット セクション インデックス。 これは、デバッグ情報をサポートするために使用されます。 |
IMAGE_REL_I386_SECREL |
0x000B |
セクションの先頭からのターゲットの 32 ビット オフセット。 これは、デバッグ情報と静的スレッド ローカル ストレージをサポートするために使用されます。 |
IMAGE_REL_I386_TOKEN |
0x000C |
CLR トークン。 |
IMAGE_REL_I386_SECREL7 |
0x000D |
ターゲットを含むセクションのベースからの 7 ビット オフセット。 |
IMAGE_REL_I386_REL32 |
0x0014 |
ターゲットに対する 32 ビットの相対変位。 これにより、x86 相対ブランチと呼び出し命令がサポートされます。 |
Intel Itanium プロセッサ ファミリ (IPF)
Intel Itanium プロセッサ ファミリと互換性のあるプロセッサに対して、次の再配置タイプ インジケーターが定義されています。 命令の再配置では、再配置オフセットにバンドルのオフセットとスロット番号が使用されることに注意してください。
定数 | 値 | 説明 |
---|---|---|
IMAGE_REL_IA64_ABSOLUTE |
0x0000 |
再配置は無視されます。 |
IMAGE_REL_IA64_IMM14 |
0x0001 |
命令の再配置の後に ADDEND 再配置が行われ、その値は IMM14 バンドル内の指定されたスロットに挿入される前にターゲット・アドレスに追加されます。 再配置先は絶対であるか、イメージを固定する必要があります。 |
IMAGE_REL_IA64_IMM22 |
0x0002 |
命令再配置の後に ADDEND 再配置が行われ、その値は IMM22 バンドル内の指定されたスロットに挿入される前にターゲット・アドレスに追加されます。 再配置先は絶対であるか、イメージを固定する必要があります。 |
IMAGE_REL_IA64_IMM64 |
0x0003 |
この再配置のスロット番号は 1 である必要があります。 再配置の後に、IMM64 バンドルの 3 つのスロットすべてに格納される前に、ターゲット アドレスに値が追加される ADDEND 再配置を実行できます。 |
IMAGE_REL_IA64_DIR32 |
0x0004 |
ターゲットの 32 ビット VA。 これは、/LARGEADDRESSAWARE:NO イメージでのみサポートされます。 |
IMAGE_REL_IA64_DIR64 |
0x0005 |
ターゲットの 64 ビット VA。 |
IMAGE_REL_IA64_PCREL21B |
0x0006 |
命令は、16 ビットアラインターゲットに対する 25 ビットの相対変位で固定されます。 変位の下位 4 ビットはゼロであり、格納されません。 |
IMAGE_REL_IA64_PCREL21M |
0x0007 |
命令は、16 ビットアラインターゲットに対する 25 ビットの相対変位で固定されます。 ディスプレイスメントの下位 4 ビット (ゼロ) は格納されません。 |
IMAGE_REL_IA64_PCREL21F |
0x0008 |
この再配置のオフセットの LSB にはスロット番号を含める必要があります。残りはバンドル アドレスです。 バンドルは、16 ビットアラインターゲットに対する 25 ビットの相対変位で固定されます。 変位の下位 4 ビットはゼロであり、格納されません。 |
IMAGE_REL_IA64_GPREL22 |
0x0009 |
命令の再配置の後に、ターゲット アドレスに値が追加された ADDEND 再配置と、計算されて GPREL22 バンドルに適用される 22 ビットの GP 相対オフセットを指定できます。 |
IMAGE_REL_IA64_LTOFF22 |
0x000A |
この命令は、ターゲット シンボルのリテラル テーブル エントリに対する 22 ビット GP 相対オフセットで修正されます。 リンカーは、この再配置と後に続く可能性がある ADDEND 再配置に基づいて、このリテラル テーブル エントリを作成します。 |
IMAGE_REL_IA64_SECTION |
0x000B |
セクションの 16 ビット セクション インデックスには、ターゲットが含まれています。 これは、デバッグ情報をサポートするために使用されます。 |
IMAGE_REL_IA64_SECREL22 |
0x000C |
命令は、セクションの先頭からターゲットの 22 ビット オフセットで固定されます。 この再配置の直後に ADDEND 再配置が行われ、その Value フィールドにはセクションの先頭からのターゲットの 32 ビット符号なしオフセットが含まれます。 |
IMAGE_REL_IA64_SECREL64I |
0x000D |
この再配置のスロット番号は 1 である必要があります。 命令は、セクションの先頭からターゲットの 64 ビット オフセットで固定されます。 この再配置の直後には、セクションの先頭からターゲットの 32 ビット符号なしオフセットが Value フィールドに含まれる ADDEND 再配置が続きます。 |
IMAGE_REL_IA64_SECREL32 |
0x000E |
セクションの先頭からターゲットの 32 ビット オフセットで固定されるデータのアドレス。 |
IMAGE_REL_IA64_DIR32NB |
0x0010 |
ターゲットの 32 ビット RVA。 |
IMAGE_REL_IA64_SREL14 |
0x0011 |
これは、2 つの再配置可能なターゲット間の差を含む符号付き 14 ビットイミディエイトに適用されます。 これは、コンパイラがこの値を既に出力していることを示すリンカーの宣言型フィールドです。 |
IMAGE_REL_IA64_SREL22 |
0x0012 |
これは、2 つの再配置可能なターゲット間の差を含む符号付き 22 ビットイミディエイトに適用されます。 これは、コンパイラがこの値を既に出力していることを示すリンカーの宣言型フィールドです。 |
IMAGE_REL_IA64_SREL32 |
0x0013 |
これは、2 つの再配置可能な値の差を含む符号付き 32 ビットイミディエイトに適用されます。 これは、コンパイラがこの値を既に出力していることを示すリンカーの宣言型フィールドです。 |
IMAGE_REL_IA64_UREL32 |
0x0014 |
これは、2 つの再配置可能な値の差を含む符号なし 32 ビットイミディエイトに適用されます。 これは、コンパイラがこの値を既に出力していることを示すリンカーの宣言型フィールドです。 |
IMAGE_REL_IA64_PCREL60X |
0x0015 |
MLX バンドルの BRL 命令として常に維持される 60 ビット PC 相対修正。 |
IMAGE_REL_IA64_PCREL60B |
0x0016 |
60 ビット PC 相対修正。 ターゲットの変位が符号付き 25 ビット フィールドに収まる場合は、バンドル全体を NOP を使用して MBB バンドルに変換します。スロット 1 の B とスロット 2 の 25 ビット BR 命令 (4 つの最低ビットはすべてゼロおよびドロップ) です。 |
IMAGE_REL_IA64_PCREL60F |
0x0017 |
60 ビット PC 相対修正。 ターゲット変位が符号付き 25 ビット フィールドに収まる場合は、バンドル全体を NOP を使用して MFB バンドルに変換します。スロット 1 の F と、スロット 2 の 25 ビット (4 つの最低ビットすべてゼロおよびドロップされた) BR 命令。 |
IMAGE_REL_IA64_PCREL60I |
0x0018 |
60 ビット PC 相対修正。 ターゲット変位が符号付き 25 ビット フィールドに収まる場合は、バンドル全体を NOP を使用して MIB バンドルに変換します。スロット 1 の I と、スロット 2 の 25 ビット (最低 4 ビットすべてゼロおよびドロップ) BR 命令。 |
IMAGE_REL_IA64_PCREL60M |
0x0019 |
60 ビット PC 相対修正。 ターゲット変位が符号付き 25 ビット フィールドに収まる場合は、バンドル全体を NOP を使用して MMB バンドルに変換します。スロット 1 の M と、スロット 2 の 25 ビット (最低 4 ビットすべてゼロおよびドロップ) BR 命令。 |
IMAGE_REL_IA64_IMMGPREL64 |
0x001a |
64 ビット GP 相対修正。 |
IMAGE_REL_IA64_TOKEN |
0x001b |
CLR トークン。 |
IMAGE_REL_IA64_GPREL32 |
0x001c |
32 ビット GP 相対修正。 |
IMAGE_REL_IA64_ADDEND |
0x001F |
再配置が有効になるのは、IMM14、IMM22、IMM64、GPREL22、LTOFF22、LTOFF64、SECREL22、SECREL64I、または SECREL32 のいずれかです。 その値には、データではなく、バンドル内の命令に適用するアドオンが含まれています。 |
MIPS プロセッサ
MIPS プロセッサには、次の再配置タイプ インジケーターが定義されています。
定数 | 値 | 説明 |
---|---|---|
IMAGE_REL_MIPS_ABSOLUTE |
0x0000 |
再配置は無視されます。 |
IMAGE_REL_MIPS_REFHALF |
0x0001 |
ターゲットの 32 ビット VA の上位 16 ビット。 |
IMAGE_REL_MIPS_REFWORD |
0x0002 |
ターゲットの 32 ビット VA。 |
IMAGE_REL_MIPS_JMPADDR |
0x0003 |
ターゲットの VA の下位 26 ビット。 これにより、MIPS J および JAL 命令がサポートされます。 |
IMAGE_REL_MIPS_REFHI |
0x0004 |
ターゲットの 32 ビット VA の上位 16 ビット。 これは、完全なアドレスを読み込む 2 命令シーケンスの最初の命令に使用されます。 この再配置の直後に、SymbolTableIndex に符号付き 16 ビットの変位が含まれている PAIR 再配置が続く必要があります。これは、再配置される場所から取得された上位 16 ビットに追加されます。 |
IMAGE_REL_MIPS_REFLO |
0x0005 |
ターゲットの VA の下位 16 ビット。 |
IMAGE_REL_MIPS_GPREL |
0x0006 |
GP レジスタに対するターゲットの 16 ビット符号付き変位。 |
IMAGE_REL_MIPS_LITERAL |
0x0007 |
IMAGE_REL_MIPS_GPRELと同じです。 |
IMAGE_REL_MIPS_SECTION |
0x000A |
セクションの 16 ビット セクション インデックスには、ターゲットが含まれています。 これは、デバッグ情報をサポートするために使用されます。 |
IMAGE_REL_MIPS_SECREL |
0x000B |
セクションの先頭からのターゲットの 32 ビット オフセット。 これは、デバッグ情報と静的スレッド ローカル ストレージをサポートするために使用されます。 |
IMAGE_REL_MIPS_SECRELLO |
0x000C |
セクションの先頭からのターゲットの 32 ビット オフセットの下位 16 ビット。 |
IMAGE_REL_MIPS_SECRELHI |
0x000D |
セクションの先頭からのターゲットの 32 ビット オフセットの上位 16 ビット。 IMAGE_REL_MIPS_PAIR再配置は、この後すぐに行う必要があります。 PAIR 再配置の SymbolTableIndex には、再配置される場所から取得された上位 16 ビットに追加される符号付き 16 ビットの変位が含まれています。 |
IMAGE_REL_MIPS_JMPADDR16 |
0x0010 |
ターゲットの VA の下位 26 ビット。 MIPS16 JAL命令に対応しています。 |
IMAGE_REL_MIPS_REFWORDNB |
0x0022 |
ターゲットの 32 ビット RVA。 |
IMAGE_REL_MIPS_PAIR |
0x0025 |
再配置は、REFHI または SECRELHI 再配置の直後にある場合にのみ有効です。 SymbolTableIndex には、シンボル テーブルへのインデックスではなく、ディスプレイスメントが含まれています。 |
三菱 M32R
三菱M32Rプロセッサには、以下の再配置タイプ区分が定義されています。
定数 | 値 | 説明 |
---|---|---|
IMAGE_REL_M32R_ABSOLUTE |
0x0000 |
再配置は無視されます。 |
IMAGE_REL_M32R_ADDR32 |
0x0001 |
ターゲットの 32 ビット VA。 |
IMAGE_REL_M32R_ADDR32NB |
0x0002 |
ターゲットの 32 ビット RVA。 |
IMAGE_REL_M32R_ADDR24 |
0x0003 |
ターゲットの 24 ビット VA。 |
IMAGE_REL_M32R_GPREL16 |
0x0004 |
ターゲットの GP レジスタからの 16 ビット オフセット。 |
IMAGE_REL_M32R_PCREL24 |
0x0005 |
プログラム カウンター (PC) からのターゲットの 24 ビット オフセットを 2 ビットずつ左にシフトし、符号拡張 |
IMAGE_REL_M32R_PCREL16 |
0x0006 |
ターゲットの PC からの 16 ビット オフセットが 2 ビットずつ左にシフトされ、符号が拡張されました |
IMAGE_REL_M32R_PCREL8 |
0x0007 |
ターゲットの PC からの 8 ビット オフセット(2 ビットずつ左にシフトし、符号拡張) |
IMAGE_REL_M32R_REFHALF |
0x0008 |
ターゲット VA の 16 MB。 |
IMAGE_REL_M32R_REFHI |
0x0009 |
LSB 符号拡張用に調整されたターゲット VA の 16 MSB。 これは、完全な 32 ビット アドレスを読み込む 2 命令シーケンスの最初の命令に使用されます。 この再配置の直後に、SymbolTableIndex に符号付き 16 ビットの変位が含まれている PAIR 再配置が続く必要があります。これは、再配置される場所から取得された上位 16 ビットに追加されます。 |
IMAGE_REL_M32R_REFLO |
0x000A |
ターゲット VA の 16 LSB。 |
IMAGE_REL_M32R_PAIR |
0x000B |
再配置は、REFHI 再配置に従う必要があります。 SymbolTableIndex には、シンボル テーブルへのインデックスではなく、ディスプレイスメントが含まれています。 |
IMAGE_REL_M32R_SECTION |
0x000C |
ターゲットを含むセクションの 16 ビット セクション インデックス。 これは、デバッグ情報をサポートするために使用されます。 |
IMAGE_REL_M32R_SECREL |
0x000D |
セクションの先頭からのターゲットの 32 ビット オフセット。 これは、デバッグ情報と静的スレッド ローカル ストレージをサポートするために使用されます。 |
IMAGE_REL_M32R_TOKEN |
0x000E |
CLR トークン。 |
COFF 行番号 (非推奨)
COFF 行番号は生成されなくなり、将来的には使用されません。
COFF 行番号は、ソース ファイル内のコードと行番号の関係を示します。 COFF 行番号の Microsoft 形式は標準の COFF に似ていますが、1 つのセクションが複数のソース ファイルの行番号に関連付けることができるように拡張されています。
COFF 行番号は、固定長レコードの配列で構成されます。 配列の場所 (ファイル オフセット) とサイズは、セクション ヘッダーで指定します。 各行番号レコードの形式は次のとおりです。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
4 |
型 (*) |
これは、SymbolTableIndex と VirtualAddress という 2 つのフィールドの和集合です。 SymbolTableIndex と RVA のどちらを使用するかは、Linenumber の値によって異なります。 |
4 |
2 |
Linenumber |
0 以外の場合、このフィールドは 1 から始まる行番号を指定します。 0 の場合、Type フィールドは関数のシンボル テーブル インデックスとして解釈されます。 |
Type フィールドは、SymbolTableIndex と VirtualAddress という 2 つの 4 バイト フィールドの和集合です。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
4 |
SymbolTableIndex |
Linenumber が 0 の場合に使用されます。関数のテーブル エントリをシンボル化するためのインデックス。 この形式は、行番号レコードのグループが参照する関数を示すために使用されます。 |
0 |
4 |
VirtualAddress |
Linenumber が 0 以外の場合に使用されます。指定されたソース行に対応する実行可能コードの RVA。 オブジェクト ファイルでは、これには セクション内の VA が含まれます。 |
行番号レコードは、Linenumber フィールドを 0 に設定し、シンボル テーブルの関数定義をポイントするか、オブジェクト コードで正の整数 (行番号) と対応するアドレスを指定することで、標準の行番号エントリとして機能します。
行番号エントリのグループは、常に最初の形式 (関数シンボルのインデックス) で始まります。 これがセクションの最初の行番号レコードである場合、セクションの COMDAT フラグが設定されている場合は、関数の COMDAT シンボル名でもあります。 「COMDAT セクション (オブジェクトのみ)」を参照してください。 シンボル テーブル内の関数の補助レコードには、この同じ行番号レコードを指す Linenumber フィールドへのポインターがあります。
関数を識別するレコードの後に、実際の行番号情報を提供する任意の数の行番号エントリ (つまり、Linenumber が 0 より大きいエントリ) が続きます。 これらのエントリは、関数の先頭を基準にして 1 から始まり、最初の行を除く関数内のすべてのソース行を表します。
たとえば、次の例の最初の行番号レコードでは、ReverseSign 関数 (ReverseSign の SymbolTableIndex と Linenumber を 0 に設定) を指定します。 次に、Linenumber 値が 1、2、3 のレコードは、次のようにソース行に対応します。
// some code precedes ReverseSign function
int ReverseSign(int i)
1: {
2: return -1 * i;
3: }
COFF シンボル テーブル
このセクションのシンボル テーブルは、従来の COFF 形式から継承されます。 デバッグ情報Microsoft Visual C++とは異なります。 ファイルには COFF シンボル テーブルと Visual C++ デバッグ情報の両方を含めることができます。2 つのデバッグ情報は別々に保持されます。 一部の Microsoft ツールでは、リンカーに COMDAT 情報を伝達するなど、限られた重要な目的でシンボル テーブルを使用します。 セクション名とファイル名、およびコードとデータ シンボルは、シンボル テーブルに一覧表示されます。
シンボル テーブルの場所は COFF ヘッダーに示されます。
シンボル テーブルは、18 バイトの長さのレコードの配列です。 各レコードは、標準または補助シンボル・テーブル・レコードです。 標準レコードは、シンボルまたは名前を定義し、次の形式を持っています。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
8 |
名前 (*) |
3 つの構造体の和集合で表されるシンボルの名前。 名前の長さが 8 バイト以下の場合は、8 バイトの配列が使用されます。 詳細については、「 シンボル名表現」を参照してください。 |
8 |
4 |
値 |
シンボルに関連付けられている値。 このフィールドの解釈は、SectionNumber と StorageClass によって異なります。 一般的な意味は、再配置可能なアドレスです。 |
12 |
2 |
SectionNumber |
セクション テーブルに 1 から始まるインデックスを使用してセクションを識別する符号付き整数。 セクション 5.4.2「セクション番号値」で定義されているように、一部の値は特別な意味を持ちます。 |
14 |
2 |
Type |
型を表す数値。 Microsoft ツールでは、このフィールドを 0x20 (関数) または0x0 (関数ではありません) に設定します。 詳細については、「 型表現」を参照してください。 |
16 |
1 |
StorageClass |
ストレージ クラスを表す列挙値。 詳細については、「 ストレージ クラス」を参照してください。 |
17 |
1 |
NumberOfAuxSymbols |
このレコードの後に続く補助シンボル・テーブル項目の数。 |
0 個以上の補助シンボル テーブル レコードは、各標準シンボル テーブル レコードの直後にあります。 ただし、通常、標準のシンボル テーブル レコードの後に続く補助シンボル テーブル レコードは複数ありません (長いファイル名を持つ .file レコードを除く)。 各補助レコードのサイズは、標準シンボル テーブル レコード (18 バイト) と同じですが、新しいシンボルを定義するのではなく、補助レコードは、定義された最後のシンボルに関する追加情報を提供します。 使用する複数の形式のうちどれを選択するかは、StorageClass フィールドによって異なります。 補助シンボル テーブル レコードの現在定義されている形式は、「補助シンボル レコード」セクション 5.5 に示されています。
COFF シンボル テーブルを読み取るツールでは、解釈が不明な補助シンボル レコードを無視する必要があります。 これにより、シンボル テーブルの形式を拡張して、既存のツールを壊すことなく、新しい補助レコードを追加できます。
シンボル名表現
シンボル テーブルの ShortName フィールドは、名前自体を含む 8 バイトで構成されます。長さが 8 バイト以下の場合、または ShortName フィールドが文字列テーブルにオフセットを与えます。 名前自体またはオフセットが指定されているかどうかを判断するには、最初の 4 バイトの等価性を 0 にテストします。
規則により、名前は 0 で終わる UTF-8 でエンコードされた文字列として扱われます。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
8 |
ShortName |
8 バイトの配列。 名前の長さが 8 バイト未満の場合、この配列には右側に null が埋め込まれます。 |
0 |
4 |
ゼロ |
名前が 8 バイトを超える場合に、すべてのゼロに設定されるフィールド。 |
4 |
4 |
Offset |
文字列テーブルへのオフセット。 |
セクション番号の値
通常、シンボル テーブル エントリの [セクション値] フィールドは、セクション テーブルへの 1 から始まるインデックスです。 ただし、このフィールドは符号付き整数であり、負の値を取ることができます。 次の値は 1 未満で、特別な意味を持ちます。
定数 | 値 | 説明 |
---|---|---|
IMAGE_SYM_UNDEFINED |
0 |
シンボル レコードにセクションがまだ割り当てられません。 値 0 は、外部シンボルへの参照が他の場所で定義されていることを示します。 0 以外の値は、値で指定されたサイズを持つ一般的なシンボルです。 |
IMAGE_SYM_ABSOLUTE |
-1 |
シンボルには絶対 (再割り当て不可) 値があり、アドレスではありません。 |
IMAGE_SYM_DEBUG |
-2 |
シンボルは、一般的な型またはデバッグ情報を提供しますが、セクションには対応していません。 Microsoft ツールでは、この設定を .file レコード (ストレージ クラス FILE) と共に使用します。 |
型表現
シンボル テーブル エントリの Type フィールドには 2 バイトが含まれています。各バイトは型情報を表します。 LSB は単純 (基本) データ型を表し、MSB は複合型 (存在する場合) を表します。
Msb | Lsb |
---|---|
複合型: none、pointer、function、array。 |
基本型: 整数、浮動小数点など。 |
基本型には次の値が定義されていますが、Microsoft ツールでは通常、このフィールドを使用せず、LSB を 0 に設定します。 代わりに、Visual C++ デバッグ情報を使用して型を示します。 ただし、可能な COFF 値は、完全のためにここに一覧表示されます。
定数 | 値 | 説明 |
---|---|---|
IMAGE_SYM_TYPE_NULL |
0 |
型情報または不明な基本型はありません。 Microsoft ツールでは、この設定を使用します |
IMAGE_SYM_TYPE_VOID |
1 |
有効な型はありません。void ポインターと関数と共に使用されます |
IMAGE_SYM_TYPE_CHAR |
2 |
文字 (符号付きバイト) |
IMAGE_SYM_TYPE_SHORT |
3 |
2 バイト符号付き整数 |
IMAGE_SYM_TYPE_INT |
4 |
自然整数型 (Windows では通常 4 バイト) |
IMAGE_SYM_TYPE_LONG |
5 |
4 バイト符号付き整数 |
IMAGE_SYM_TYPE_FLOAT |
6 |
4 バイト浮動小数点数 |
IMAGE_SYM_TYPE_DOUBLE |
7 |
8 バイト浮動小数点数 |
IMAGE_SYM_TYPE_STRUCT |
8 |
構造体 |
IMAGE_SYM_TYPE_UNION |
9 |
共用体 |
IMAGE_SYM_TYPE_ENUM |
10 |
列挙型 |
IMAGE_SYM_TYPE_MOE |
11 |
列挙体のメンバー (特定の値) |
IMAGE_SYM_TYPE_BYTE |
12 |
バイト。符号なし 1 バイト整数 |
IMAGE_SYM_TYPE_WORD |
13 |
単語。unsigned 2 バイト整数 |
IMAGE_SYM_TYPE_UINT |
14 |
自然サイズの符号なし整数 (通常は 4 バイト) |
IMAGE_SYM_TYPE_DWORD |
15 |
符号なし 4 バイト整数 |
最も重要なバイトは、シンボルが LSB で指定された基本型のポインター、関数の戻り値、または配列であるかどうかを指定します。 Microsoft のツールでは、このフィールドを使用して、シンボルが関数であるかどうかを示すだけで、結果として得られる 2 つの値のみが [型] フィールドに0x0され、0x20されます。 ただし、他のツールでは、このフィールドを使用して詳細情報を伝えることができます。
関数属性を正しく指定することは非常に重要です。 この情報は、インクリメンタル リンクが正しく機能するために必要です。 一部のアーキテクチャでは、他の目的で情報が必要になる場合があります。
定数 | 値 | 説明 |
---|---|---|
IMAGE_SYM_DTYPE_NULL |
0 |
派生型はありません。シンボルは単純なスカラー変数です。 |
IMAGE_SYM_DTYPE_POINTER |
1 |
シンボルは基本型へのポインターです。 |
IMAGE_SYM_DTYPE_FUNCTION |
2 |
シンボルは、基本型を返す関数です。 |
IMAGE_SYM_DTYPE_ARRAY |
3 |
シンボルは基本型の配列です。 |
ストレージ クラス
シンボル テーブルの StorageClass フィールドは、シンボルが表す定義の種類を示します。 次の表に、使用可能な値を示します。 StorageClass フィールドは符号なし 1 バイトの整数であることに注意してください。 したがって、特殊な値 -1 は、符号なし等価の0xFFを意味するように取得する必要があります。
従来の COFF 形式では多くのストレージ クラス値が使用されていますが、Microsoft ツールはほとんどのシンボリック情報に Visual C++ デバッグ形式を使用し、一般に、EXTERNAL (2)、STATIC (3)、FUNCTION (101)、FILE (103) の 4 つのストレージ クラス値のみを使用します。 以下の 2 番目の列見出しを除き、"Value" はシンボル レコードの Value フィールドを意味するように取得する必要があります (その解釈はストレージ クラスとして見つかった数値によって異なります)。
定数 | 値 | [値] フィールドの説明/解釈 |
---|---|---|
IMAGE_SYM_CLASS_END_OF_FUNCTION |
-1 (0xFF) |
デバッグ目的で関数の終了を表す特別なシンボル。 |
IMAGE_SYM_CLASS_NULL |
0 |
ストレージ クラスが割り当てされていません。 |
IMAGE_SYM_CLASS_AUTOMATIC |
1 |
自動 (スタック) 変数。 [値] フィールドは、スタック フレームオフセットを指定します。 |
IMAGE_SYM_CLASS_EXTERNAL |
2 |
Microsoft ツールが外部シンボルに使用する値。 [値] フィールドは、セクション番号がIMAGE_SYM_UNDEFINED (0) の場合のサイズを示します。 セクション番号が 0 でない場合、Value フィールドはセクション内のオフセットを指定します。 |
IMAGE_SYM_CLASS_STATIC |
3 |
セクション内のシンボルのオフセット。 Value フィールドが 0 の場合、記号はセクション名を表します。 |
IMAGE_SYM_CLASS_REGISTER |
4 |
レジスタ変数。 [値] フィールドには、レジスタ番号を指定します。 |
IMAGE_SYM_CLASS_EXTERNAL_DEF |
5 |
外部で定義されているシンボル。 |
IMAGE_SYM_CLASS_LABEL |
6 |
モジュール内で定義されているコード ラベル。 [値] フィールドは、セクション内のシンボルのオフセットを指定します。 |
IMAGE_SYM_CLASS_UNDEFINED_LABEL |
7 |
定義されていないコード ラベルへの参照。 |
IMAGE_SYM_CLASS_MEMBER_OF_STRUCT |
8 |
構造体メンバー。 Value フィールドは、n 番目のメンバーを指定します。 |
IMAGE_SYM_CLASS_ARGUMENT |
9 |
関数の仮引数 (パラメーター)。 Value フィールドは、n 番目の引数を指定します。 |
IMAGE_SYM_CLASS_STRUCT_TAG |
10 |
構造体タグ名エントリ。 |
IMAGE_SYM_CLASS_MEMBER_OF_UNION |
11 |
共用体メンバー。 Value フィールドは、n 番目のメンバーを指定します。 |
IMAGE_SYM_CLASS_UNION_TAG |
12 |
Union タグ名エントリ。 |
IMAGE_SYM_CLASS_TYPE_DEFINITION |
13 |
Typedef エントリ。 |
IMAGE_SYM_CLASS_UNDEFINED_STATIC |
14 |
静的データ宣言。 |
IMAGE_SYM_CLASS_ENUM_TAG |
15 |
列挙型の tagname エントリ。 |
IMAGE_SYM_CLASS_MEMBER_OF_ENUM |
16 |
列挙体のメンバー。 Value フィールドは、n 番目のメンバーを指定します。 |
IMAGE_SYM_CLASS_REGISTER_PARAM |
17 |
register パラメーター。 |
IMAGE_SYM_CLASS_BIT_FIELD |
18 |
ビット フィールド参照。 Value フィールドは、ビット フィールドの n 番目のビットを指定します。 |
IMAGE_SYM_CLASS_BLOCK |
100 |
.bb (ブロックの先頭) または .eb (ブロックの末尾) レコード。 [値] フィールドは、コードの場所の再配置可能なアドレスです。 |
IMAGE_SYM_CLASS_FUNCTION |
101 |
関数の範囲を定義するシンボル レコードに Microsoft ツールが使用する値: begin 関数 (.bf)、end function ( .ef )、および function ( .lf ) 内の行。 .lf レコードの場合、Value フィールドには関数内のソース行の数が表示されます。 .ef レコードの場合、Value フィールドは関数コードのサイズを示します。 |
IMAGE_SYM_CLASS_END_OF_STRUCT |
102 |
構造の終わりのエントリ。 |
IMAGE_SYM_CLASS_FILE |
103 |
Microsoft が従来の COFF 形式と同様にソース ファイルシンボル レコードに使用する値。 シンボルの後に、ファイルに名前を付けた補助レコードが続きます。 |
IMAGE_SYM_CLASS_SECTION |
104 |
セクションの定義 (Microsoft ツールでは代わりに STATIC ストレージ クラスを使用します)。 |
IMAGE_SYM_CLASS_WEAK_EXTERNAL |
105 |
弱い外部。 詳細については、「 補助形式 3: 弱い外部」を参照してください。 |
IMAGE_SYM_CLASS_CLR_TOKEN |
107 |
CLR トークン シンボル。 名前は、トークンの 16 進値で構成される ASCII 文字列です。 詳細については、「 CLR トークン定義 (オブジェクトのみ)」を参照してください。 |
補助記号レコード
補助シンボル テーブル レコードは常に一部の標準シンボル テーブル レコードに従って適用されます。 補助レコードは、ツールで認識できる任意の形式を持つことができますが、シンボル テーブルが通常のサイズの配列として維持されるように、それらに 18 バイトを割り当てる必要があります。 現在、Microsoft ツールは、関数定義、関数の開始記号と終了記号 (.bf および .ef)、弱い外部、ファイル名、セクション定義などのレコードの補助形式を認識しています。
従来の COFF 設計には、配列と構造体の補助レコード形式も含まれています。 Microsoft ツールではこれらを使用するのではなく、そのシンボリック情報を Visual C++ デバッグ形式でデバッグ セクションに配置します。
補助形式 1: 関数定義
関数定義の先頭が、EXTERNAL (2) のストレージ クラス、関数 (0x20) であることを示す Type 値、および 0 より大きいセクション番号を持つ場合、シンボル テーブル レコードは関数定義の先頭をマークします。 セクション番号 UNDEFINED (0) を持つシンボル テーブル レコードは、関数を定義せず、補助レコードを持たないことに注意してください。 関数定義シンボル・レコードの後に、以下に示す形式の補助レコードが続きます。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
4 |
TagIndex |
対応する .bf (begin 関数) シンボル レコードのシンボル テーブル インデックス。 |
4 |
4 |
TotalSize |
関数自体の実行可能コードのサイズ。 関数が独自のセクションにある場合、配置に関する考慮事項に応じて、セクション ヘッダーの SizeOfRawData がこのフィールド以上になります。 |
8 |
4 |
PointerToLinenumber |
関数の最初の COFF 行番号エントリのファイル オフセット。存在しない場合は 0。 詳細については、「 COFF 行番号 (非推奨)」を参照してください。 |
12 |
4 |
PointerToNextFunction |
次の関数のレコードのシンボル テーブル インデックス。 関数がシンボル テーブルの最後の場合、このフィールドは 0 に設定されます。 |
16 |
2 |
未使用 |
補助形式 2: .bf および .ef シンボル
シンボル テーブル内の各関数定義について、3 つの項目で開始、終了、および行数が記述されます。 これらの各シンボルには、ストレージ クラス FUNCTION (101) があります。
.bf (begin 関数) という名前のシンボル レコード。 [値] フィールドは使用されません。
.lf という名前のシンボル レコード (関数内の行)。 [値] フィールドには、関数内の行数が表示されます。
.ef (関数の末尾) という名前のシンボル レコード。 [値] フィールドの数値は、関数定義シンボル レコードの [合計サイズ] フィールドと同じです。
.bf および .ef シンボル レコード (.lf レコードではなく) の後に、次の形式の補助レコードが続きます。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
4 |
未使用 |
|
4 |
2 |
Linenumber |
.bf または .ef レコードに対応する、ソース ファイル内の実際の序数 (1、2、3 など)。 |
6 |
6 |
未使用 |
|
12 |
4 |
PointerToNextFunction ( .bf のみ) |
次の .bf シンボル レコードのシンボル テーブル インデックス。 関数がシンボル テーブルの最後の場合、このフィールドは 0 に設定されます。 .ef レコードには使用されません。 |
16 |
2 |
未使用 |
補助形式 3: 弱い外部
"弱い外部" は、リンク時の柔軟性を可能にするオブジェクト ファイルのメカニズムです。 モジュールには未解決の外部シンボル (sym1) を含めることができますが、シンボリック 1 がリンク時に存在しない場合は、代わりに別の外部シンボル (sym2) を使用して参照を解決することを示す補助レコードを含めることもできます。
sym1 の定義がリンクされている場合、シンボルへの外部参照は正常に解決されます。 sym1 の定義がリンクされていない場合、sym1 の弱い外部へのすべての参照は代わりに sym2 を参照します。 外部シンボル sym2 は常にリンクされている必要があります。通常は、sym1 への弱い参照を含むモジュールで定義されます。
弱い外部は、EXTERNAL ストレージ クラス、UNDEF セクション番号、および 0 の値を持つシンボル テーブル レコードによって表されます。 弱外部シンボル レコードの後に、次の形式の補助レコードが続きます。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
4 |
TagIndex |
sym1 が見つからない場合にリンクされるシンボルである sym2 のシンボル テーブル インデックス。 |
4 |
4 |
特性 |
IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY の値は、sym1 のライブラリ検索を実行する必要がないことを示します。 IMAGE_WEAK_EXTERN_SEARCH_LIBRARY の値は、sym1 のライブラリ検索を実行する必要があることを示します。 IMAGE_WEAK_EXTERN_SEARCH_ALIAS の値は、sym1 が sym2 のエイリアスであることを示します。 |
8 |
10 |
未使用 |
特性フィールドは WINNT では定義されていないことに注意してください。H;代わりに、[合計サイズ] フィールドが使用されます。
補助形式 4: ファイル
この形式は、ストレージ クラス FILE (103) を持つシンボル テーブル レコードに従います。 シンボル名自体は .file にする必要があり、それに続く補助レコードはソース コード ファイルの名前を示します。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
18 |
ファイル名 |
ソース ファイルの名前を示す ANSI 文字列。 これは、最大長より小さい場合は null で埋め込まれます。 |
補助形式 5: セクション定義
この形式は、セクションを定義するシンボル テーブル レコードに従います。 このようなレコードには、セクションの名前であるシンボル名 (.text や .drectve など) があり、ストレージ クラス STATIC (3) があります。 補助レコードは、それが参照するセクションに関する情報を提供します。 したがって、セクション ヘッダーの情報の一部が複製されます。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
4 |
長さ |
セクション データのサイズ。セクション ヘッダーの SizeOfRawData と同じです。 |
4 |
2 |
NumberOfRelocations |
セクションの再配置エントリの数。 |
6 |
2 |
NumberOfLinenumbers |
セクションの行番号エントリの数。 |
8 |
4 |
チェックサム |
共同データのチェックサム。 セクション ヘッダーに IMAGE_SCN_LNK_COMDAT フラグが設定されている場合に適用されます。 詳細については、「 COMDAT セクション (オブジェクトのみ)」を参照してください。 |
12 |
2 |
数値 |
関連付けられたセクションのセクション テーブルへの 1 から始まるインデックス。 これは、COMDAT の選択設定が 5 の場合に使用されます。 |
14 |
1 |
[選択] |
COMDAT の選択番号。 これは、セクションが COMDAT セクションの場合に適用されます。 |
15 |
3 |
未使用 |
COMDAT セクション (オブジェクトのみ)
セクション定義補助形式の Selection フィールドは、セクションが COMDAT セクションの場合に適用できます。 COMDAT セクションは、複数のオブジェクト ファイルで定義できるセクションです。 (フラグ IMAGE_SCN_LNK_COMDATは、セクション ヘッダーの [セクション フラグ] フィールドで設定されます)。[選択] フィールドは、リンカーが COMDAT セクションの複数の定義を解決する方法を決定します。
COMDAT セクションのセクション値を持つ最初のシンボルは、セクションシンボルである必要があります。 このシンボルには、セクションの名前、0 に等しい Value フィールド、問題の COMDAT セクションのセクション番号、IMAGE_SYM_TYPE_NULLと等しい Type フィールド、IMAGE_SYM_CLASS_STATICと等しい Class フィールド、および 1 つの補助レコードがあります。 2 番目のシンボルは "COMDAT シンボル" と呼ばれ、リンカーによって Selection フィールドと組み合わせて使用されます。
[選択] フィールドの値を次に示します。
定数 | 値 | 説明 |
---|---|---|
IMAGE_COMDAT_SELECT_NODUPLICATES |
1 |
このシンボルが既に定義されている場合、リンカーは "定義されたシンボルの乗算" エラーを発行します。 |
IMAGE_COMDAT_SELECT_ANY |
2 |
同じ COMDAT シンボルを定義する任意のセクションをリンクできます。残りは削除されます。 |
IMAGE_COMDAT_SELECT_SAME_SIZE |
3 |
リンカーは、このシンボルの定義の中から任意のセクションを選択します。 すべての定義が同じサイズでない場合は、"乗算定義シンボル" エラーが発行されます。 |
IMAGE_COMDAT_SELECT_EXACT_MATCH |
4 |
リンカーは、このシンボルの定義の中から任意のセクションを選択します。 すべての定義が完全に一致しない場合は、"乗算定義シンボル" エラーが発行されます。 |
IMAGE_COMDAT_SELECT_ASSOCIATIVE |
5 |
特定の他の COMDAT セクションがリンクされている場合、セクションはリンクされます。 この他のセクションは、セクション定義の補助シンボル・レコードの Number フィールドによって示されます。 この設定は、複数のセクションにコンポーネントがある定義 (1 つのセクションのコードや別のセクションのデータなど) で、すべてのコンポーネントをセットとしてリンクまたは破棄する必要がある場合に便利です。 このセクションに関連付けられているもう 1 つのセクションは COMDAT セクションである必要があります。これは、別の連想 COMDAT セクションにすることができます。 連想 COMDAT セクションのセクション関連付けチェーンはループを形成できません。 セクション関連付けチェーンは、最終的に、IMAGE_COMDAT_SELECT_ASSOCIATIVE設定されていない COMDAT セクションにアクセスする必要があります。 |
IMAGE_COMDAT_SELECT_LARGEST |
6 |
リンカーは、このシンボルのすべての定義の中から最大の定義を選択します。 複数の定義にこのサイズがある場合は、その間の選択肢は任意です。 |
CLR トークン定義 (オブジェクトのみ)
通常、この補助記号はIMAGE_SYM_CLASS_CLR_TOKENに従います。 トークンを COFF シンボル テーブルの名前空間に関連付けるために使用されます。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
1 |
bAuxType |
IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEFにする必要があります (1)。 |
1 |
1 |
bReserved |
予約済み。 は 0 である必要があります。 |
2 |
4 |
SymbolTableIndex |
この CLR トークン定義が参照する COFF シンボルのシンボル インデックス。 |
6 |
12 |
予約済み。 は 0 である必要があります。 |
COFF 文字列テーブル
COFF シンボル テーブルの直後に COFF 文字列テーブルがあります。 このテーブルの位置は、COFF ヘッダーでシンボル テーブルのアドレスを取得し、シンボルの数にシンボルのサイズを乗算して追加することによって見つかります。
COFF 文字列テーブルの先頭には、文字列テーブルの残りの部分の合計サイズ (バイト単位) を含む 4 バイトがあります。 このサイズにはサイズ フィールド自体が含まれているため、文字列が存在しない場合、この場所の値は 4 になります。
次のサイズは、COFF シンボル テーブル内のシンボルによって指される null で終わる文字列です。
属性証明書テーブル (画像のみ)
属性証明書は、属性証明書テーブルを追加することで、イメージに関連付けることができます。 属性証明書テーブルは、連続する quadword でアラインされた属性証明書エントリのセットで構成されます。 この配置を実現するために、ファイルの元の末尾と属性証明書テーブルの先頭の間にゼロパディングが挿入されます。 各属性証明書エントリには、次のフィールドが含まれています。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
4 |
dwLength |
属性証明書エントリの長さを指定します。 |
4 |
2 |
wRevision |
証明書のバージョン番号が含まれています。 詳細については、次のテキストを参照してください。 |
6 |
2 |
wCertificateType |
bCertificate 内のコンテンツの種類を指定します。 詳細については、次のテキストを参照してください。 |
8 |
参考資料 |
bCertificate |
Authenticode 署名などの証明書が含まれます。 詳細については、次のテキストを参照してください。 |
省略可能なヘッダー データ ディレクトリの証明書テーブル エントリの仮想アドレス値は、最初の属性証明書エントリへのファイル オフセットです。 後続のエントリは、現在の属性証明書エントリの先頭から 8 バイトの倍数に切り上げられた、そのエントリの dwLength バイトを進めることによってアクセスされます。 これは、丸められた dwLength 値の合計が、省略可能なヘッダー データ ディレクトリの Certificates Table エントリの Size 値と等しくなるまで続きます。 丸められた dwLength 値の合計が Size 値と等しくない場合は、属性証明書テーブルまたは Size フィールドのいずれかが破損しています。
たとえば、省略可能なヘッダー データ ディレクトリの証明書テーブル エントリに次のものが含まれている場合です。
virtual address = 0x5000
size = 0x1000
最初の証明書は、ディスク上のファイルの先頭から0x5000オフセットで開始されます。 すべての属性証明書エントリを進める方法:
- 最初の属性証明書の dwLength 値を開始オフセットに追加します。
- 手順 1 の値を最も近い 8 バイトの倍数に丸め、2 番目の属性証明書エントリのオフセットを見つけます。
- 手順 2 のオフセット値を 2 番目の属性証明書エントリの dwLength 値に追加し、最も近い 8 バイトの倍数に切り上げて、3 番目の属性証明書エントリのオフセットを決定します。
- 計算されたオフセットが0x6000 (開始 + 合計サイズ0x1000 0x5000) になるまで、連続する証明書ごとに手順 3 を繰り返します。これは、テーブル全体を歩いたことを示します。
または、Win32 ImageEnumerateCertificates 関数をループで呼び出して、証明書エントリを列挙することもできます。 関数の参照ページへのリンクについては、「 参照」を参照してください。
属性証明書テーブルのエントリには、エントリに正しい dwLength 値、一意の wRevision 値、および一意の wCertificateType 値がある限り、任意の証明書の種類を含めることができます。 証明書テーブル エントリの最も一般的な種類は、wintrust.h に記載されているWIN_CERTIFICATE構造であり、このセクションの残りの部分で説明します。
WIN_CERTIFICATE wRevision メンバーのオプションには、次のものが含まれます (ただし、これらに限定されません)。
値 | 名前 | Notes |
---|---|---|
0x0100 |
WIN_CERT_REVISION_1_0 |
バージョン 1、Win_Certificate構造のレガシ バージョン。 従来の Authenticode 署名を検証する目的でのみサポートされます |
0x0200 |
WIN_CERT_REVISION_2_0 |
バージョン 2 は、Win_Certificate構造の現在のバージョンです。 |
WIN_CERTIFICATE wCertificateType メンバーのオプションには、次の表の項目が含まれます (ただし、これらに限定されません)。 一部の値は現在サポートされていないことに注意してください。
値 | 名前 | Notes |
---|---|---|
0x0001 |
WIN_CERT_TYPE_X509 |
bCertificate に X.509 証明書が含まれている サポートされていません |
0x0002 |
WIN_CERT_TYPE_PKCS_SIGNED_DATA |
bCertificate には PKCS#7 SignedData 構造体が含まれています |
0x0003 |
WIN_CERT_TYPE_RESERVED_1 |
予約されています。 |
0x0004 |
WIN_CERT_TYPE_TS_STACK_SIGNED |
ターミナル サーバー プロトコル スタック証明書の署名 サポートされていません |
WIN_CERTIFICATE構造体の bCertificate メンバーには、wCertificateType で指定されたコンテンツ タイプを持つ可変長バイト配列 が含まれています。 Authenticode でサポートされる型は、PKCS#7 SignedData 構造体WIN_CERT_TYPE_PKCS_SIGNED_DATAです。 Authenticode デジタル署名形式の詳細については、「 Windows Authenticode Portable Executable Signature Format」を参照してください。
bCertificate コンテンツが quadword 境界で終わらない場合、属性証明書エントリは、bCertificate の末尾から次の quadword 境界まで、ゼロで埋め込まれます。
dwLength 値は、ファイナライズされたWIN_CERTIFICATE構造体の長さであり、次のように計算されます。
dwLength = offsetof(WIN_CERTIFICATE, bCertificate) + (size of the variable-length binary array contained within bCertificate)
この長さは、各WIN_CERTIFICATE構造体が quadword アラインされるという要件を満たすために使用されるパディングのサイズを含める必要があります。
dwLength += (8 - (dwLength & 7)) & 7;
省略可能なヘッダー データ ディレクトリ (イメージのみ) の [証明書テーブル] エントリで指定された証明書テーブルのサイズには、埋め込みが含まれます。
ImageHlp API を使用して PE ファイルから証明書を列挙、追加、および削除する方法の詳細については、「 ImageHlp Functions」を参照してください。
証明書データ
前のセクションで説明したように、属性証明書テーブルの証明書には任意の証明書の種類を含めることができます。 PE ファイルの整合性を保証する証明書には、PE イメージ ハッシュが含まれる場合があります。
PE イメージ ハッシュ (またはファイル ハッシュ) は、ハッシュ アルゴリズムがファイルの整合性に関連するメッセージ ダイジェストを生成するという点で、ファイル チェックサムに似ています。 ただし、チェックサムは単純なアルゴリズムによって生成され、主にディスク上のメモリ ブロックが正しくなくなり、そこに格納されている値が破損しているかどうかを検出するために使用されます。 ファイル ハッシュは、ファイルの破損も検出するという点でチェックサムに似ています。 ただし、ほとんどのチェックサム アルゴリズムとは異なり、元の変更されていない値からファイル ハッシュを変更せずにファイルを変更することは非常に困難です。 したがって、ファイル ハッシュを使用して、ウイルス、ハッカー、トロイの木馬プログラムによって導入されたものなど、ファイルに対する意図的かつ微妙な変更を検出できます。
証明書に含まれる場合、イメージ ダイジェストでは、オプションのヘッダー データ ディレクトリのチェックサムと証明書テーブルエントリなど、PE イメージ内の特定のフィールドを除外する必要があります。 これは、証明書を追加するとこれらのフィールドが変更され、別のハッシュ値が計算されるためです。
Win32 ImageGetDigestStream 関数は、関数をハッシュするターゲット PE ファイルからのデータ ストリームを提供します。 証明書が PE ファイルに追加または PE ファイルから削除される場合、このデータ ストリームは一貫性を保ちます。 ImageGetDigestStream に渡されるパラメーターに基づいて、PE イメージの他のデータをハッシュ計算から省略できます。 関数の参照ページへのリンクについては、「 参照」を参照してください。
Delay-Load テーブルのインポート (イメージのみ)
これらのテーブルは、アプリケーションがその DLL への最初の呼び出しまで DLL の読み込みを遅延させる均一なメカニズムをサポートするために、イメージに追加されました。 テーブルのレイアウトは、セクション 6.4「 .idata セクション」で説明されている従来のインポート テーブルのレイアウトと一致します。ここでは、いくつかの詳細について説明します。
Delay-Load ディレクトリ テーブル
遅延読み込みディレクトリ テーブルは、インポート ディレクトリ テーブルに対応します。 これは、オプションのヘッダー データ ディレクトリ リスト (オフセット 200) の [Delay Import Descriptor]\(遅延インポート記述子\) エントリを使用して取得できます。 テーブルは次のように配置されます。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
4 |
属性 |
ゼロを指定してください。 |
4 |
4 |
名前 |
読み込む DLL の名前の RVA。 名前は、イメージの読み取り専用データ セクションに存在します。 |
8 |
4 |
モジュール ハンドル |
遅延読み込みされる DLL のモジュール ハンドル (イメージのデータ セクション内) の RVA。 遅延読み込みを管理するために提供されるルーチンによってストレージに使用されます。 |
12 |
4 |
遅延インポート アドレス テーブル |
遅延読み込みインポート アドレス テーブルの RVA。 詳細については、「 Delay Import Address Table (IAT)」を参照してください。 |
16 |
4 |
遅延インポート名テーブル |
読み込む必要がある可能性があるインポートの名前を含む遅延読み込み名テーブルの RVA。 これは、インポート名テーブルのレイアウトと一致します。 詳細については、「 ヒント/名前テーブル」を参照してください。 |
20 |
4 |
連結遅延インポート テーブル |
バインドされた遅延読み込みアドレス テーブルの RVA (存在する場合)。 |
24 |
4 |
遅延インポート テーブルのアンロード |
アンロード遅延読み込みアドレス テーブルの RVA (存在する場合)。 これは、遅延インポート アドレス テーブルの正確なコピーです。 呼び出し元が DLL をアンロードする場合は、DLL への後続の呼び出しでサンキング メカニズムが引き続き正しく使用されるように、遅延インポート アドレス テーブルの上にこのテーブルをコピーし直す必要があります。 |
28 |
4 |
タイム スタンプ |
このイメージがバインドされている DLL のタイムスタンプ。 |
このデータ構造で参照されるテーブルは、従来のインポートに対応するテーブルと同様に整理および並べ替えられます。 詳細については、「 .idata セクション」を参照してください。
属性
まだ、属性フラグは定義されていません。 リンカーは、このフィールドをイメージの 0 に設定します。 このフィールドは、新しいフィールドの存在を示すことによってレコードを拡張するために使用できます。または、遅延ヘルパー関数またはアンロード ヘルパー関数の動作を示すために使用できます。
名前
遅延読み込みされる DLL の名前は、イメージの読み取り専用データ セクションに存在します。 szName フィールドを介して参照されます。
モジュール ハンドル
遅延読み込みされる DLL のハンドルは、イメージのデータ セクションにあります。 phmod フィールドはハンドルを指します。 指定された遅延読み込みヘルパーは、この場所を使用して、読み込まれた DLL へのハンドルを格納します。
遅延インポート アドレス テーブル
遅延インポート アドレス テーブル (IAT) は、pIAT フィールドを介して遅延インポート記述子によって参照されます。 遅延読み込みヘルパーは、サンクが呼び出しループに入らなくなったように、これらのポインターを実際のエントリ ポイントで更新します。 関数ポインターには、 式 pINT->u1.Function
を使用してアクセスします。
遅延インポート名テーブル
遅延インポート名テーブル (INT) には、読み込みが必要になる可能性があるインポートの名前が含まれています。 これらは、IAT の関数ポインターと同じ方法で順序付けされます。 これらは標準の INT と同じ構造で構成され、 式 pINT->u1.AddressOfData->Name[0]
を使用してアクセスされます。
遅延バインドされたインポート アドレス テーブルとタイム スタンプ
遅延バインド インポート アドレス テーブル (BIAT) は、プロセス後のバインド フェーズによって遅延読み込みディレクトリ テーブルのタイムスタンプ フィールドと共に使用される、IMAGE_THUNK_DATA項目の省略可能なテーブルです。
遅延アンロード インポート アドレス テーブル
遅延アンロード インポート アドレス テーブル (UIAT) は、アンロード コードが明示的なアンロード要求を処理するために使用するIMAGE_THUNK_DATA項目の省略可能なテーブルです。 これは、遅延読み込みサンクにコードを参照した元の IAT の正確なコピーである、読み取り専用セクションの初期化されたデータで構成されます。 アンロード要求では、ライブラリを解放し、*phmod をクリアし、IAT 経由で書き込まれた UIAT を使用して、すべてをプリロード状態に復元できます。
特別なセクション
- .debug セクション
- .drectve セクション (オブジェクトのみ)
- .edata セクション (イメージのみ)
- .idata セクション
- .pdata セクション
- .reloc セクション (イメージのみ)
- .tls セクション
- 読み込み構成構造 (イメージのみ)
- .rsrc セクション
- .cormeta セクション (オブジェクトのみ)
- .sxdata セクション
一般的な COFF セクションには、リンカーと Microsoft Win32 ローダーがセクションの内容に関する特別な知識なしに処理するコードまたはデータが含まれています。 コンテンツは、リンクまたは実行されているアプリケーションにのみ関連します。
ただし、一部の COFF セクションは、オブジェクト ファイルまたはイメージ ファイルで見つかった場合に特別な意味を持ちます。 ツールとローダーは、セクション ヘッダーに特別なフラグが設定されているため、これらのセクションを認識します。これは、イメージの省略可能なヘッダー内の特別な場所がそれらを指しているため、またはセクション名自体がセクションの特別な関数を示しているためです。 (セクション名自体がセクションの特別な機能を示していない場合でも、セクション名は規則によって規定されるため、この仕様の作成者はすべてのケースでセクション名を参照できます)。
予約済みセクションとその属性については、次の表で説明します。続いて、実行可能ファイルに永続化されるセクションの種類と、拡張機能のメタデータを含むセクションの種類について詳しく説明します。
セクション名 | コンテンツ | 特性 |
---|---|---|
.bss |
初期化されていないデータ (フリー形式) |
IMAGE_SCN_CNT_UNINITIALIZED_DATA |IMAGE_SCN_MEM_READ |IMAGE_SCN_MEM_WRITE |
.cormeta |
オブジェクト ファイルにマネージド コードが含まれていることを示す CLR メタデータ |
IMAGE_SCN_LNK_INFO |
.data |
初期化されたデータ (自由形式) |
IMAGE_SCN_CNT_INITIALIZED_DATA |IMAGE_SCN_MEM_READ |IMAGE_SCN_MEM_WRITE |
.debug$F |
生成された FPO デバッグ情報 (オブジェクトのみ、x86 アーキテクチャのみ、現在は廃止) |
IMAGE_SCN_CNT_INITIALIZED_DATA |IMAGE_SCN_MEM_READ |IMAGE_SCN_MEM_DISCARDABLE |
.debug$P |
プリコンパイル済みデバッグ型 (オブジェクトのみ) |
IMAGE_SCN_CNT_INITIALIZED_DATA |IMAGE_SCN_MEM_READ |IMAGE_SCN_MEM_DISCARDABLE |
.debug$S |
デバッグ シンボル (オブジェクトのみ) |
IMAGE_SCN_CNT_INITIALIZED_DATA |IMAGE_SCN_MEM_READ |IMAGE_SCN_MEM_DISCARDABLE |
.debug$T |
デバッグ型 (オブジェクトのみ) |
IMAGE_SCN_CNT_INITIALIZED_DATA |IMAGE_SCN_MEM_READ |IMAGE_SCN_MEM_DISCARDABLE |
.drective |
リンカー オプション |
IMAGE_SCN_LNK_INFO |
.edata |
テーブルのエクスポート |
IMAGE_SCN_CNT_INITIALIZED_DATA |IMAGE_SCN_MEM_READ |
.idata |
テーブルのインポート |
IMAGE_SCN_CNT_INITIALIZED_DATA |IMAGE_SCN_MEM_READ |IMAGE_SCN_MEM_WRITE |
.idlsym |
IDL 属性をサポートするために登録された SEH (イメージのみ) が含まれます。 詳細については、このトピックの最後にある 「リファレンス 」の「IDL 属性」を参照してください。 |
IMAGE_SCN_LNK_INFO |
.pdata |
例外情報 |
IMAGE_SCN_CNT_INITIALIZED_DATA |IMAGE_SCN_MEM_READ |
.rdata |
読み取り専用で初期化されたデータ |
IMAGE_SCN_CNT_INITIALIZED_DATA |IMAGE_SCN_MEM_READ |
.reloc |
イメージの再配置 |
IMAGE_SCN_CNT_INITIALIZED_DATA |IMAGE_SCN_MEM_READ |IMAGE_SCN_MEM_DISCARDABLE |
.rsrc |
リソース ディレクトリ |
IMAGE_SCN_CNT_INITIALIZED_DATA |IMAGE_SCN_MEM_READ |
.sbss |
GP 相対初期化されていないデータ (自由形式) |
IMAGE_SCN_CNT_UNINITIALIZED_DATA |IMAGE_SCN_MEM_READ |IMAGE_SCN_MEM_WRITE |IMAGE _SCN_GPREL IMAGE_SCN_GPREL フラグは、IA64 アーキテクチャにのみ設定する必要があります。このフラグは、他のアーキテクチャでは無効です。 IMAGE_SCN_GPREL フラグはオブジェクト ファイル専用です。このセクションの種類がイメージ ファイルに表示される場合は、IMAGE_SCN_GPREL フラグを設定しないでください。 |
.sdata |
GP 相対初期化データ (自由形式) |
IMAGE_SCN_CNT_INITIALIZED_DATA |IMAGE_SCN_MEM_READ |IMAGE_SCN_MEM_WRITE |IMAGE _SCN_GPREL IMAGE_SCN_GPREL フラグは、IA64 アーキテクチャにのみ設定する必要があります。このフラグは、他のアーキテクチャでは無効です。 IMAGE_SCN_GPREL フラグはオブジェクト ファイル専用です。このセクションの種類がイメージ ファイルに表示される場合は、IMAGE_SCN_GPREL フラグを設定しないでください。 |
.srdata |
GP 相対読み取り専用データ (自由形式) |
IMAGE_SCN_CNT_INITIALIZED_DATA |IMAGE_SCN_MEM_READ |IMAGE _SCN_GPREL IMAGE_SCN_GPREL フラグは、IA64 アーキテクチャにのみ設定する必要があります。このフラグは、他のアーキテクチャでは無効です。 IMAGE_SCN_GPREL フラグはオブジェクト ファイル専用です。このセクションの種類がイメージ ファイルに表示される場合は、IMAGE_SCN_GPREL フラグを設定しないでください。 |
.sxdata |
登録された例外ハンドラー データ (フリー形式と x86/object のみ) |
IMAGE_SCN_LNK_INFO オブジェクト ファイル内のコードによって参照される各例外ハンドラーのシンボル インデックスが含まれます。 シンボルは、UNDEF シンボル、またはそのモジュールで定義されているシンボルに使用できます。 |
.text |
実行可能コード (自由形式) |
IMAGE_SCN_CNT_CODE |IMAGE_SCN_MEM_EXECUTE |IIMAGE_SCN_MEM_READ |
。Tls |
スレッド ローカル ストレージ (オブジェクトのみ) |
IMAGE_SCN_CNT_INITIALIZED_DATA |IMAGE_SCN_MEM_READ |IMAGE_SCN_MEM_WRITE |
.tls$ |
スレッド ローカル ストレージ (オブジェクトのみ) |
IMAGE_SCN_CNT_INITIALIZED_DATA |IMAGE_SCN_MEM_READ |IMAGE_SCN_MEM_WRITE |
.vsdata |
GP 相対初期化データ (自由形式と ARM、SH4、Thumb アーキテクチャのみ) |
IMAGE_SCN_CNT_INITIALIZED_DATA |IMAGE_SCN_MEM_READ |IMAGE_SCN_MEM_WRITE |
.xdata |
例外情報 (自由形式) |
IMAGE_SCN_CNT_INITIALIZED_DATA |IMAGE_SCN_MEM_READ |
ここに記載されているセクションの中には、特別なセマンティクスがオブジェクト ファイルまたはイメージ ファイルにのみ関連していることを示すために、"object only" または "image only" とマークされているものがあります。 "image only" とマークされているセクションは、イメージ ファイルに入る方法としてオブジェクト ファイルに引き続き表示されることがありますが、このセクションはリンカーにとって特別な意味を持たず、イメージ ファイル ローダーに対してのみ特別な意味を持ちます。
.debug セクション
.debug セクションは、コンパイラによって生成されたデバッグ情報を含むオブジェクト ファイルと、生成されるすべてのデバッグ情報を含むイメージ ファイルで使用されます。 このセクションでは、オブジェクト ファイルとイメージ ファイル内のデバッグ情報のパッケージ化について説明します。
次のセクションでは、イメージ内の任意の場所で使用できるデバッグ ディレクトリの形式について説明します。 以降のセクションでは、デバッグ情報を含むオブジェクト ファイル内の "グループ" について説明します。
リンカーの既定値は、デバッグ情報がイメージのアドレス空間にマップされないことです。 .debug セクションは、デバッグ情報がアドレス空間にマップされている場合にのみ存在します。
デバッグ ディレクトリ (イメージのみ)
イメージ ファイルには、デバッグ情報の形式とその場所を示すオプションのデバッグ ディレクトリが含まれています。 このディレクトリは、イメージの省略可能なヘッダーに場所とサイズが示されているデバッグ ディレクトリ エントリの配列で構成されます。
デバッグ ディレクトリは、破棄可能な .debug セクション (存在する場合) に入れるか、イメージ ファイル内の他のセクションに含めることができるか、セクションに含めないようにすることができます。
各デバッグ ディレクトリ エントリは、デバッグ情報のブロックの場所とサイズを識別します。 デバッグ情報がセクション ヘッダーでカバーされていない (つまり、イメージ ファイルに存在し、実行時アドレス空間にマップされていない) 場合、指定された RVA は 0 になる可能性があります。 マップされている場合、RVA はそのアドレスです。
デバッグ ディレクトリ エントリの形式は次のとおりです。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
4 |
特性 |
予約済み。 は 0 である必要があります。 |
4 |
4 |
TimeDateStamp |
デバッグ データが作成された日時。 |
8 |
2 |
MajorVersion |
デバッグ データ形式のメジャー バージョン番号。 |
10 |
2 |
MinorVersion |
デバッグ データ形式のマイナー バージョン番号。 |
12 |
4 |
Type |
デバッグ情報の形式。 このフィールドを使用すると、複数のデバッガーをサポートできます。 詳細については、「デバッグの 種類」を参照してください。 |
16 |
4 |
SizeOfData |
デバッグ データのサイズ (デバッグ ディレクトリ自体は含まれません)。 |
20 |
4 |
AddressOfRawData |
イメージ ベースに対する相対的な読み込み時のデバッグ データのアドレス。 |
24 |
4 |
PointerToRawData |
デバッグ データへのファイル ポインター。 |
デバッグの種類
デバッグ ディレクトリ エントリの Type フィールドには、次の値が定義されています。
定数 | 値 | 説明 |
---|---|---|
IMAGE_DEBUG_TYPE_UNKNOWN |
0 |
すべてのツールで無視される不明な値。 |
IMAGE_DEBUG_TYPE_COFF |
1 |
COFF デバッグ情報 (行番号、シンボル テーブル、および文字列テーブル)。 この種のデバッグ情報はまた、ファイル ヘッダー内のフィールドによって指し示されます。 |
IMAGE_DEBUG_TYPE_CODEVIEW |
2 |
Visual C++ デバッグ情報。 |
IMAGE_DEBUG_TYPE_FPO |
3 |
フレーム ポインター省略 (FPO) 情報。 この情報は、フレーム ポインターとして以外の目的で EBP レジスタを使用する非標準スタック フレームを解釈する方法をデバッガーに指示します。 |
IMAGE_DEBUG_TYPE_MISC |
4 |
DBG ファイルの場所。 |
IMAGE_DEBUG_TYPE_EXCEPTION |
5 |
.pdata セクションのコピー。 |
IMAGE_DEBUG_TYPE_FIXUP |
6 |
予約済み。 |
IMAGE_DEBUG_TYPE_OMAP_TO_SRC |
7 |
イメージ内の RVA からソース イメージの RVA へのマッピング。 |
IMAGE_DEBUG_TYPE_OMAP_FROM_SRC |
8 |
ソース イメージの RVA からイメージ内の RVA へのマッピング。 |
IMAGE_DEBUG_TYPE_BORLAND |
9 |
ボーランドのために予約されています。 |
IMAGE_DEBUG_TYPE_RESERVED10 |
10 |
予約済み。 |
IMAGE_DEBUG_TYPE_CLSID |
11 |
予約済み。 |
IMAGE_DEBUG_TYPE_REPRO |
16 |
PE の決定性または再現性。 |
IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS | 20 | 拡張 DLL 特性ビット。 |
Type フィールドが IMAGE_DEBUG_TYPE_FPO に設定されている場合、デバッグ生データは、各メンバーが関数のスタック フレームを記述する配列です。 デバッグの種類が FPO であっても、イメージ ファイル内のすべての関数に FPO 情報が定義されている必要があるわけではありません。 FPO 情報を持たない関数は、通常のスタック フレームを持つものと見なされます。 FPO 情報の形式は次のとおりです。
#define FRAME_FPO 0
#define FRAME_TRAP 1
#define FRAME_TSS 2
typedef struct _FPO_DATA {
DWORD ulOffStart; // offset 1st byte of function code
DWORD cbProcSize; // # bytes in function
DWORD cdwLocals; // # bytes in locals/4
WORD cdwParams; // # bytes in params/4
WORD cbProlog : 8; // # bytes in prolog
WORD cbRegs : 3; // # regs saved
WORD fHasSEH : 1; // TRUE if SEH in func
WORD fUseBP : 1; // TRUE if EBP has been allocated
WORD reserved : 1; // reserved for future use
WORD cbFrame : 2; // frame type
} FPO_DATA;
IMAGE_DEBUG_TYPE_REPRO型のエントリが存在することは、PE ファイルが確定性または再現性を実現する方法で構築されていることを示します。 入力が変更されない場合、出力 PE ファイルは、PE が生成されるタイミングや場所に関係なく、ビット単位で同一であることが保証されます。 PE ファイル内のさまざまな日付/時刻スタンプ フィールドには、PE ファイルの内容を入力として使用する計算ハッシュ値の一部またはすべてのビットが入力されます。したがって、PE ファイルまたは PE 内の関連する特定のデータが生成された実際の日付と時刻は表されなくなります。 このデバッグ エントリの生データは空であるか、ハッシュ値の長さを表す 4 バイト値の前に計算されたハッシュ値を含む場合があります。
[種類] フィールドが IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS に設定されている場合、デバッグ生データには拡張 DLL 特性ビットが含まれます。このビットは、イメージの省略可能なヘッダーで設定できるビットに追加されます。 「省略可能なヘッダー Windows-Specific フィールド (画像のみ)」セクションの「DLL の特性」を参照してください。
拡張 DLL の特性
拡張 DLL 特性ビットには、次の値が定義されています。
定数 | 値 | 説明 |
---|---|---|
IMAGE_DLLCHARACTERISTICS_EX_CET_COMPAT | 0x0001 | イメージは CET と互換性があります。 |
.debug$F (オブジェクトのみ)
このセクションのデータは、Visual C++ バージョン 7.0 以降では、 .debug$S サブセクションに出力されるより広範なデータ セットによって置き換えられます。
オブジェクト ファイルには、内容が 1 つ以上のFPO_DATA レコード (フレーム ポインター省略情報) である .debug$F セクションを含めることができます。 「デバッグの種類」の「IMAGE_DEBUG_TYPE_FPO」を参照してください。
リンカーは、これらの .debug$F レコードを 認識します。 デバッグ情報が生成されている場合、リンカーはプロシージャ RVA でFPO_DATAレコードを並べ替え、それらのデバッグ ディレクトリ エントリを生成します。
コンパイラは、標準フレーム形式のプロシージャに対して FPO レコードを生成しないでください。
.debug$S (オブジェクトのみ)
このセクションには、Visual C++ デバッグ情報 (シンボリック情報) が含まれています。
.debug$P (オブジェクトのみ)
このセクションには、Visual C++ デバッグ情報 (プリコンパイル済み情報) が含まれています。 これらは、このオブジェクトで生成されたプリコンパイル済みヘッダーを使用してコンパイルされたすべてのオブジェクト間で共有型です。
.debug$T (オブジェクトのみ)
このセクションには、Visual C++ デバッグ情報 (型情報) が含まれています。
Microsoft デバッグ情報のリンカー サポート
デバッグ情報をサポートするために、リンカーは次の手順を実行します。
.debug$F、debug$S、.debug$P、および .debug$T セクションから関連するすべてのデバッグ データを収集します。
そのデータをリンカーによって生成されたデバッグ情報と共に PDB ファイルに処理し、それを参照するデバッグ ディレクトリ エントリを作成します。
.drectve セクション (オブジェクトのみ)
セクションヘッダーにIMAGE_SCN_LNK_INFOフラグが設定され、セクション名が .drectve の場合、セクションはディレクティブ セクションです。 リンカーは、情報の処理後 に .drectve セクションを削除するため、リンクされているイメージ ファイルにセクションは表示されません。
.drectve セクションは、ANSI または UTF-8 としてエンコードできるテキストの文字列で構成されます。 UTF-8 バイト順マーカー (BOM、0xEF、0xBB、および0xBFで構成される 3 バイトプレフィックス) が存在しない場合、ディレクティブ文字列は ANSI として解釈されます。 ディレクティブ文字列は、スペースで区切られた一連のリンカー オプションです。 各オプションには、ハイフン、オプション名、および適切な属性が含まれます。 オプションにスペースが含まれている場合は、オプションを引用符で囲む必要があります。 .drectve セクションに再配置または行番号を指定することはできません。
.edata セクション (画像のみ)
.edata という名前のエクスポート データ セクションには、動的リンクを使用して他の画像がアクセスできるシンボルに関する情報が含まれています。 エクスポートされたシンボルは一般に DLL にありますが、DLL はシンボルをインポートすることもできます。
エクスポート セクションの一般的な構造の概要を以下に示します。 説明されているテーブルは、通常、ファイル内で示されている順序で連続しています (ただし、これは必須ではありません)。 シンボルを序数としてエクスポートするには、エクスポート ディレクトリ テーブルとエクスポート アドレス テーブルのみが必要です。 (序数は、エクスポート アドレス テーブルインデックスによって直接アクセスされるエクスポートです)。名前ポインター テーブル、序数テーブル、およびエクスポート名テーブルはすべて、エクスポート名の使用をサポートするために存在します。
テーブル名 | 説明 |
---|---|
ディレクトリ テーブルのエクスポート |
1 行のみのテーブル (デバッグ ディレクトリとは異なります)。 このテーブルは、他のエクスポート テーブルの場所とサイズを示します。 |
アドレス テーブルのエクスポート |
エクスポートされたシンボルの RVA の配列。 これらは、実行可能コードとデータ セクション内のエクスポートされた関数とデータの実際のアドレスです。 他のイメージ ファイルでは、このテーブルのインデックス (序数) を使用してシンボルをインポートできます。また、必要に応じて、パブリック名が定義されている場合は序数に対応するパブリック名を使用します。 |
名前ポインター テーブル |
パブリック エクスポート名へのポインターの配列。昇順で並べ替えられます。 |
序数テーブル |
名前ポインター テーブルのメンバーに対応する序数の配列。 対応は位置別です。したがって、名前ポインター テーブルと序数テーブルのメンバー数は同じである必要があります。 各序数は、エクスポート アドレス テーブルのインデックスです。 |
エクスポート名テーブル |
null で終わる一連の ASCII 文字列。 名前ポインター テーブルのメンバーは、この領域を指します。 これらの名前は、シンボルがインポートおよびエクスポートされるパブリック名です。これらは、イメージ ファイル内で使用されるプライベート名と必ずしも同じとは限りません。 |
別のイメージ ファイルが名前でシンボルをインポートすると、Win32 ローダーは名前ポインター テーブルで一致する文字列を検索します。 一致する文字列が見つかった場合、関連付けられた序数は、序数テーブル内の対応するメンバー (つまり、名前ポインター テーブル内の文字列ポインターと同じインデックスを持つ序数テーブルのメンバー) を検索することによって識別されます。 結果の序数は、エクスポート アドレス テーブルへのインデックスであり、目的のシンボルの実際の場所を示します。 すべてのエクスポート シンボルには、序数でアクセスできます。
別のイメージ ファイルが序数でシンボルをインポートする場合、名前ポインター テーブルで一致する文字列を検索する必要は不要です。 したがって、序数を直接使用する方が効率的です。 ただし、エクスポート名は覚えやすく、シンボルのテーブル インデックスをユーザーに知る必要はありません。
ディレクトリ テーブルのエクスポート
エクスポート シンボル情報はエクスポート ディレクトリ テーブルで始まり、エクスポート シンボル情報の残りの部分が記述されます。 エクスポート ディレクトリ テーブルには、このイメージ内のエントリ ポイントへのインポートを解決するために使用されるアドレス情報が含まれています。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
4 |
エクスポート フラグ |
予約済み。0 である必要があります。 |
4 |
4 |
時刻/日付スタンプ |
エクスポート データが作成された日時。 |
8 |
2 |
メジャー バージョン |
メジャー バージョン番号。 メジャー バージョン番号とマイナー バージョン番号は、ユーザーが設定できます。 |
10 |
2 |
マイナー バージョン |
マイナー バージョン番号。 |
12 |
4 |
名前 RVA |
DLL の名前を含む ASCII 文字列のアドレス。 このアドレスは、イメージ ベースに対する相対アドレスです。 |
16 |
4 |
序数ベース |
このイメージ内のエクスポートの開始序数。 このフィールドは、エクスポート アドレス テーブルの開始序数を指定します。 通常は 1 に設定されます。 |
20 |
4 |
アドレス テーブルのエントリ |
エクスポート アドレス テーブル内のエントリの数。 |
24 |
4 |
名前ポインターの数 |
名前ポインター テーブル内のエントリの数。 これは、序数テーブル内のエントリの数でもあります。 |
28 |
4 |
エクスポート アドレス テーブル RVA |
イメージ ベースを基準としたエクスポート アドレス テーブルのアドレス。 |
32 |
4 |
名前ポインター RVA |
イメージ ベースを基準としたエクスポート名ポインター テーブルのアドレス。 テーブルのサイズは、[名前ポインターの数] フィールドで指定します。 |
36 |
4 |
序数テーブル RVA |
イメージ ベースを基準とした序数テーブルのアドレス。 |
アドレス テーブルのエクスポート
エクスポート アドレス テーブルには、エクスポートされたエントリ ポイントのアドレスと、エクスポートされたデータと絶対値が含まれます。 序数は、エクスポート アドレス テーブルのインデックスとして使用されます。
エクスポート アドレス テーブルの各エントリは、次の表の 2 つの形式のいずれかを使用するフィールドです。 指定されたアドレスがエクスポート セクション内にない場合 (省略可能なヘッダーに示されているアドレスと長さによって定義されます)、フィールドはエクスポート RVA です。これはコードまたはデータの実際のアドレスです。 それ以外の場合、フィールドはフォワーダー RVA で、別の DLL のシンボルに名前を付けます。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
4 |
RVA のエクスポート |
イメージ ベースを基準にしてメモリに読み込まれるときにエクスポートされたシンボルのアドレス。 たとえば、エクスポートされた関数のアドレスなどです。 |
0 |
4 |
フォワーダー RVA |
エクスポート セクションの null で終わる ASCII 文字列へのポインター。 この文字列は、エクスポート テーブルのデータ ディレクトリ エントリによって指定される範囲内である必要があります。 「省略可能なヘッダー データ ディレクトリ (イメージのみ)」を参照してください。 この文字列は、DLL 名とエクスポートの名前 ("MYDLL.expfunc" など) または DLL 名とエクスポートの序数 ("MYDLL.#27" など) を指定します。 |
フォワーダー RVA は他のイメージから定義をエクスポートし、現在のイメージによってエクスポートされているかのように見えます。 したがって、シンボルは同時にインポートおよびエクスポートされます。
たとえば、Windows XP のKernel32.dllでは、"HeapAlloc" という名前のエクスポートが文字列 "NTDLL" に転送されます。RtlAllocateHeap"これにより、アプリケーションは、Windows XP 固有のモジュールNtdll.dllを実際に含めることなく、そのモジュールへのインポート参照を使用できます。 アプリケーションのインポート テーブルは、Kernel32.dllのみを参照します。 したがって、アプリケーションは Windows XP に固有ではなく、任意の Win32 システムで実行できます。
名前ポインター テーブルのエクスポート
エクスポート名ポインター テーブルは、エクスポート名テーブルへのアドレス (RVA) の配列です。 ポインターはそれぞれ 32 ビットであり、イメージベースを基準にしています。 ポインターは、バイナリ検索を可能にするために構文的に並べ替えされます。
エクスポート名は、エクスポート名ポインター テーブルにポインターが含まれている場合にのみ定義されます。
序数テーブルのエクスポート
エクスポート序数テーブルは、エクスポート アドレス テーブルに 16 ビットの偏りのないインデックスの配列です。 序数は、エクスポート ディレクトリ テーブルの Ordinal Base フィールドによって偏っています。 つまり、エクスポート アドレス テーブルに真のインデックスを取得するには、序数から序数ベースを減算する必要があります。
エクスポート名ポインター テーブルとエクスポート序数テーブルは、自然なフィールドの配置を可能にするために区切られた 2 つの並列配列を形成します。 実際には、これら 2 つのテーブルは 1 つのテーブルとして動作します。このテーブルでは、エクスポート名ポインター列がパブリック (エクスポート) 名を指し、Export Ordinal 列がそのパブリック名に対応する序数を指定します。 エクスポート名ポインター テーブルのメンバーとエクスポート序数テーブルのメンバーは、それぞれの配列内で同じ位置 (インデックス) を持つことによって関連付けられます。
したがって、エクスポート名ポインター テーブルが検索され、一致する文字列が位置 i で見つかった場合、シンボルの RVA と偏った序数を検索するためのアルゴリズムは次のようになります。
i = Search_ExportNamePointerTable (name);
ordinal = ExportOrdinalTable [i];
rva = ExportAddressTable [ordinal];
biased_ordinal = ordinal + OrdinalBase;
(偏りのある) 序数でシンボルを検索する場合、シンボルの RVA と名前を検索するためのアルゴリズムは次のようになります。
ordinal = biased_ordinal - OrdinalBase;
i = Search_ExportOrdinalTable (ordinal);
rva = ExportAddressTable [ordinal];
name = ExportNameTable [i];
名前テーブルのエクスポート
エクスポート名テーブルには、エクスポート名ポインター テーブルによって指された実際の文字列データが含まれています。 この表の文字列は、他のイメージがシンボルのインポートに使用できるパブリック名です。 これらのパブリック エクスポート名は、シンボルが独自のイメージ ファイルとソース コードに含まれるプライベート シンボル名と必ずしも同じとは限りませんが、可能です。
エクスポートされたすべてのシンボルには、エクスポート アドレス テーブルのインデックスである序数値があります。 ただし、エクスポート名の使用は省略可能です。 エクスポートされたシンボルの一部、すべて、またはいずれもエクスポート名を持つことができません。 エクスポート名を持つエクスポートシンボルの場合、エクスポート名ポインター テーブルとエクスポート序数テーブルの対応するエントリが連携して、各名前を序数に関連付けます。
エクスポート名テーブルの構造は、可変長の null で終わる一連の ASCII 文字列です。
.idata セクション
シンボルをインポートするすべてのイメージ ファイル (ほぼすべての実行可能ファイル (EXE) ファイルを含む) には、.idata セクションがあります。 インポート情報の一般的なファイル レイアウトは次のとおりです。
ディレクトリ テーブル
Null ディレクトリ エントリ
DLL1 インポート参照テーブル
[Null]
DLL2 インポート参照テーブル
[Null]
DLL3 インポート参照テーブル
[Null]
Hint-Name テーブル
ディレクトリ テーブルのインポート
インポート情報は、インポート ディレクトリ テーブルから始まります。このテーブルには、インポート情報の残りの部分が記述されています。 インポート ディレクトリ テーブルには、DLL イメージ内のエントリ ポイントへの修正参照を解決するために使用されるアドレス情報が含まれています。 インポート ディレクトリ テーブルは、イメージが参照する DLL ごとに 1 つのエントリである、インポート ディレクトリ エントリの配列で構成されます。 最後のディレクトリ エントリは空です (null 値で塗りつぶされます)。これは、ディレクトリ テーブルの末尾を示します。
各インポート ディレクトリ エントリの形式は次のとおりです。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
4 |
ルックアップ テーブル RVA のインポート (特性) |
インポート参照テーブルの RVA。 このテーブルには、インポートごとに名前または序数が含まれています。 (名前 "Characteristics" は Winnt.h で使用されますが、このフィールドは説明されなくなりました)。 |
4 |
4 |
時刻/日付スタンプ |
イメージがバインドされるまで 0 に設定されるスタンプ。 イメージがバインドされると、このフィールドは DLL の時刻/データ スタンプに設定されます。 |
8 |
4 |
フォワーダー チェーン |
最初のフォワーダー参照のインデックス。 |
12 |
4 |
名前 RVA |
DLL の名前を含む ASCII 文字列のアドレス。 このアドレスは、イメージ ベースに対する相対アドレスです。 |
16 |
4 |
インポート アドレス テーブル RVA (サンク テーブル) |
インポート アドレス テーブルの RVA。 このテーブルの内容は、イメージがバインドされるまで、インポート参照テーブルの内容と同じです。 |
参照テーブルのインポート
インポート参照テーブルは、PE32 の場合は 32 ビット数値の配列、または PE32 以降の場合は 64 ビット数値の配列です。 各エントリは、次の表に示すビット フィールド形式を使用します。 この形式では、ビット 31 は PE32 の最上位ビットであり、ビット 63 は PE32 以降の最も重要なビットです。 これらのエントリのコレクションは、特定の DLL からのすべてのインポートについて説明します。 最後のエントリは、テーブルの末尾を示す 0 (NULL) に設定されます。
ビット | サイズ | ビット フィールド | 説明 |
---|---|---|---|
31/63 |
1 |
Ordinal/Name フラグ |
このビットが設定されている場合は、序数でインポートします。 それ以外の場合は、名前でインポートします。 ビットは PE32 の0x80000000としてマスクされ、PE32 以降の場合は0x8000000000000000されます。 |
15-0 |
16 |
序数 |
16 ビットの序数。 このフィールドは、Ordinal/Name Flag ビット フィールドが 1 (序数によるインポート) の場合にのみ使用されます。 ビット 30 から 15 または 62-15 は 0 である必要があります。 |
30-0 |
31 |
ヒント/名前テーブル RVA |
ヒント/名前テーブル エントリの 31 ビット RVA。 このフィールドは、Ordinal/Name Flag ビット フィールドが 0 (名前によるインポート) の場合にのみ使用されます。 PE32 以降のビット 62 から 31 は 0 である必要があります。 |
ヒント/名前テーブル
インポート セクション全体に 1 つのヒント/名前テーブルで十分です。 ヒント/名前テーブルの各エントリの形式は次のとおりです。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
2 |
ヒント |
エクスポート名ポインター テーブルのインデックス。 最初に、この値を使用して一致が試行されます。 失敗した場合は、DLL のエクスポート名ポインター テーブルでバイナリ検索が実行されます。 |
2 |
変数 |
名前 |
インポートする名前を含む ASCII 文字列。 これは、DLL 内のパブリック名と一致する必要がある文字列です。 この文字列では大文字と小文字が区別され、null バイトで終了します。 |
* |
0 または 1 |
Pad |
必要に応じて、後続の null バイトの後に出現する末尾のゼロパッド バイト。偶数境界に次のエントリを配置します。 |
インポート アドレス テーブル
インポート アドレス テーブルの構造と内容は、ファイルがバインドされるまで、インポート 参照テーブルの構造と内容は同じです。 バインド中に、インポート アドレス テーブル内のエントリは、インポートされるシンボルの 32 ビット (PE32 の場合) または 64 ビット (PE32 以降の場合) アドレスで上書きされます。 これらのアドレスはシンボルの実際のメモリ アドレスですが、技術的には"仮想アドレス" と呼ばれています。ローダーは通常、バインディングを処理します。
.pdata セクション
.pdata セクションには、例外処理に使用される関数テーブル エントリの配列が含まれています。 これは、イメージ データ ディレクトリ内の例外テーブル エントリによって指されます。 エントリは、最終的なイメージに出力される前に、関数アドレス (各構造体の最初のフィールド) に従って並べ替える必要があります。 ターゲット プラットフォームは、以下で説明する 3 つの関数テーブルエントリ形式のバリエーションのうちどれを使用するかを決定します。
32 ビット MIPS イメージの場合、関数テーブルのエントリの形式は次のとおりです。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
4 |
開始アドレス |
対応する関数の VA。 |
4 |
4 |
終了アドレス |
関数の末尾の VA。 |
8 |
4 |
例外ハンドラー |
実行する例外ハンドラーへのポインター。 |
12 |
4 |
ハンドラー データ |
ハンドラーに渡される追加情報へのポインター。 |
16 |
4 |
Prolog の終了アドレス |
関数のプロローグの末尾の VA。 |
ARM、PowerPC、SH3、SH4 Windows CE プラットフォームの場合、関数テーブルエントリの形式は次のとおりです。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
4 |
開始アドレス |
対応する関数の VA。 |
4 |
8 ビット |
Prolog の長さ |
関数のプロローグ内の命令の数。 |
4 |
22 ビット |
Function Length |
関数内の命令の数。 |
4 |
1 ビット |
32 ビット フラグ |
設定されている場合、関数は 32 ビット命令で構成されます。 clear の場合、関数は 16 ビット命令で構成されます。 |
4 |
1 ビット |
例外フラグ |
設定されている場合、関数の例外ハンドラーが存在します。 それ以外の場合、例外ハンドラーは存在しません。 |
x64 および Itanium プラットフォームの場合、関数テーブルエントリの形式は次のとおりです。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
4 |
開始アドレス |
対応する関数の RVA。 |
4 |
4 |
終了アドレス |
関数の末尾の RVA。 |
8 |
4 |
アンワインド情報 |
アンワインド情報の RVA。 |
.reloc セクション (イメージのみ)
基本再配置テーブルには、イメージ内のすべての基本再配置のエントリが含まれています。 省略可能なヘッダー データ ディレクトリの [基本再配置テーブル] フィールドには、ベース再配置テーブルのバイト数が表示されます。 詳細については、「 省略可能なヘッダー データ ディレクトリ (イメージのみ)」を参照してください。 基本再配置テーブルはブロックに分割されます。 各ブロックは、4K ページの基本再配置を表します。 各ブロックは、32 ビット境界で開始する必要があります。
ロード イメージを PE ヘッダーで指定されたイメージ ベースに読み込むことができない場合を除き、リンカーによって解決されるベース再配置を処理するためにローダーは必要ありません。
基本再配置ブロック
各基本再配置ブロックは、次の構造で始まります。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
4 |
ページ RVA |
イメージ ベースとページ RVA が各オフセットに追加され、ベース再配置を適用する必要がある VA が作成されます。 |
4 |
4 |
ブロック サイズ |
ページ RVA フィールドとブロック サイズ フィールド、続く Type/Offset フィールドなど、ベース再配置ブロックの合計バイト数。 |
次に、[ブロック サイズ] フィールドの後に任意の数の Type フィールドまたは Offset フィールド エントリが続きます。 各エントリは WORD (2 バイト) であり、次の構造を持ちます。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
4 ビット |
Type |
適用する基本再配置の種類を示す値である、WORD の上位 4 ビットに格納されます。 詳細については、「 基本再配置の種類」を参照してください。 |
0 |
12 ビット |
Offset |
ブロックの [ページ RVA] フィールドで指定された開始アドレスからのオフセットである、WORD の残りの 12 ビットに格納されます。 このオフセットは、基本再配置を適用する場所を指定します。 |
ベース再配置を適用するために、優先ベース アドレスと、イメージが実際に読み込まれるベースとの差が計算されます。 イメージが優先ベースで読み込まれる場合、違いは 0 であるため、ベースの再配置を適用する必要はありません。
基本再配置の種類
定数 | 値 | 説明 |
---|---|---|
IMAGE_REL_BASED_ABSOLUTE |
0 |
基本再配置はスキップされます。 この型を使用して、ブロックを埋め込むことができます。 |
IMAGE_REL_BASED_HIGH |
1 |
ベース再配置では、オフセット時の 16 ビット フィールドに高い 16 ビットの差が追加されます。 16 ビット フィールドは、32 ビット ワードの高い値を表します。 |
IMAGE_REL_BASED_LOW |
2 |
ベース再配置では、差分の下位 16 ビットがオフセットの 16 ビット フィールドに追加されます。 16 ビット フィールドは、32 ビット ワードの下位半分を表します。 |
IMAGE_REL_BASED_HIGHLOW |
3 |
基本再配置では、差分の 32 ビットすべてがオフセット時の 32 ビット フィールドに適用されます。 |
IMAGE_REL_BASED_HIGHADJ |
4 |
ベース再配置では、オフセット時の 16 ビット フィールドに高い 16 ビットの差が追加されます。 16 ビット フィールドは、32 ビット ワードの高い値を表します。 32 ビット値の下位 16 ビットは、この基本再配置に続く 16 ビットワードに格納されます。 これは、この基本再配置が 2 つのスロットを占めていることを意味します。 |
IMAGE_REL_BASED_MIPS_JMPADDR |
5 |
再配置の解釈は、マシンの種類によって異なります。 マシンの種類が MIPS の場合、基本再配置は MIPS ジャンプ命令に適用されます。 |
IMAGE_REL_BASED_ARM_MOV32 |
5 |
この再配置は、マシンの種類が ARM または Thumb の場合にのみ意味があります。 基本再配置では、連続する MOVW/MOVT 命令ペアにシンボルの 32 ビット・アドレスが適用されます。 |
IMAGE_REL_BASED_RISCV_HIGH20 |
5 |
この再配置は、マシンの種類が RISC-V の場合にのみ意味があります。 基本再配置は、32 ビット絶対アドレスの上位 20 ビットに適用されます。 |
6 |
予約済み。 は 0 である必要があります。 |
|
IMAGE_REL_BASED_THUMB_MOV32 |
7 |
この再配置は、マシンの種類が Thumb の場合にのみ意味があります。 基本再配置は、シンボルの 32 ビット・アドレスを連続する MOVW/MOVT 命令ペアに適用します。 |
IMAGE_REL_BASED_RISCV_LOW12I |
7 |
この再配置は、マシンの種類が RISC-V の場合にのみ意味があります。 ベース再配置は、RISC-V I 型命令形式で形成された 32 ビット絶対アドレスの下位 12 ビットに適用されます。 |
IMAGE_REL_BASED_RISCV_LOW12S |
8 |
この再配置は、マシンの種類が RISC-V の場合にのみ意味があります。 ベース再配置は、RISC-V S 型命令形式で形成された 32 ビット絶対アドレスの下位 12 ビットに適用されます。 |
IMAGE_REL_BASED_LOONGARCH32_MARK_LA |
8 |
この再配置は、マシンの種類が LoongArch 32 ビットの場合にのみ意味があります。 基本再配置は、2 つの連続する命令で形成された 32 ビットの絶対アドレスに適用されます。 |
IMAGE_REL_BASED_LOONGARCH64_MARK_LA |
8 |
この再配置は、マシンの種類が LoongArch 64 ビットの場合にのみ意味があります。 基本再配置は、4 つの連続する命令で形成された 64 ビットの絶対アドレスに適用されます。 |
IMAGE_REL_BASED_MIPS_JMPADDR16 |
9 |
再配置は、マシンの種類が MIPS の場合にのみ意味があります。 基本再配置は、MIPS16 ジャンプ命令に適用されます。 |
IMAGE_REL_BASED_DIR64 |
10 |
基本再配置では、オフセットの 64 ビット フィールドに差分が適用されます。 |
.tls セクション
.tls セクションでは、静的スレッド ローカル ストレージ (TLS) に対する PE と COFF の直接サポートを提供します。 TLS は、データ オブジェクトが自動 (スタック) 変数ではなく、コードを実行する個々のスレッドに対してローカルである Windows がサポートする特別なストレージ クラスです。 したがって、各スレッドは、TLS を使用して宣言された変数に対して異なる値を保持できます。
API 呼び出し TlsAlloc、TlsFree、TlsSetValue、および TlsGetValue を使用して、任意の量の TLS データをサポートできることに注意してください。 PE または COFF の実装は、API を使用するための代替アプローチであり、高レベルの言語プログラマの観点からより単純であるという利点があります。 この実装により、TLS データをプログラム内の通常の静的変数と同様に定義および初期化できます。 たとえば、Visual C++ では、Windows API を使用せずに、静的 TLS 変数を次のように定義できます。
__declspec (thread) int tlsFlag = 1;
このプログラミングコンストラクトをサポートするために、PE および COFF .tls セクションでは、初期化データ、スレッドごとの初期化と終了のためのコールバック ルーチン、TLS インデックスの情報を指定します。これについては、次の説明で説明します。
Note
静的に宣言された TLS データ オブジェクトは、静的に読み込まれたイメージ ファイルでのみ使用できます。 この事実により、DLL または DLL に静的にリンクされているものが LoadLibrary API 関数で動的に読み込まれることはないことがわかっている場合を除き、DLL で静的 TLS データを使用することは信頼性が低くなります。
実行可能コードは、次の手順で静的 TLS データ オブジェクトにアクセスします。
リンク時に、リンカーは TLS ディレクトリの [インデックスのアドレス] フィールドを設定します。 このフィールドは、プログラムが TLS インデックスを受け取ることを想定している場所を指します。
Microsoft ランタイム ライブラリでは、TLS ディレクトリのメモリ イメージを定義し、特別な名前 "__tls_used" (Intel x86 プラットフォーム) または "_tls_used" (その他のプラットフォーム) を指定することで、このプロセスを容易にします。 リンカーは、このメモリ イメージを検索し、そこでデータを使用して TLS ディレクトリを作成します。 TLS をサポートし、Microsoft リンカーと連携する他のコンパイラでも、この同じ手法を使用する必要があります。
スレッドが作成されると、ローダーはスレッド環境ブロック (TEB) のアドレスを FS レジスタに配置することで、スレッドの TLS 配列のアドレスを通信します。 TLS 配列へのポインターは、TEB の先頭から0x2Cのオフセットにあります。 この動作は Intel x86 固有です。
ローダーは、[インデックスのアドレス] フィールドで示された場所に TLS インデックスの値を割り当てます。
実行可能コードは、TLS インデックスと TLS 配列の場所も取得します。
このコードでは、TLS インデックスと TLS 配列の場所 (インデックスに 4 を掛けて配列へのオフセットとして使用) を使用して、指定されたプログラムとモジュールの TLS データ領域のアドレスを取得します。 各スレッドには独自の TLS データ領域がありますが、これはプログラムに対して透過的であり、個々のスレッドにデータがどのように割り当てられるかを知る必要はありません。
個々の TLS データ オブジェクトには、TLS データ領域への固定オフセットとしてアクセスされます。
TLS 配列は、システムが各スレッドに対して保持するアドレスの配列です。 この配列内の各アドレスは、プログラム内の特定のモジュール (EXE または DLL) の TLS データの場所を示します。 TLS インデックスは、使用する配列のメンバーを示します。 インデックスは、モジュールを識別する数値 (システムにとってのみ意味があります) です。
TLS ディレクトリ
TLS ディレクトリの形式は次のとおりです。
オフセット (PE32/PE32 以降) | サイズ (PE32/PE32+) | フィールド | 説明 |
---|---|---|---|
0 |
4/8 |
生データ開始 VA |
TLS テンプレートの開始アドレス。 テンプレートは、TLS データの初期化に使用されるデータのブロックです。 システムは、スレッドが作成されるたびにこのデータをすべてコピーするため、破損しないようにする必要があります。 このアドレスは RVA ではないことに注意してください。これは、.reloc セクションにベース再配置が必要なアドレスです。 |
4/8 |
4/8 |
生データの終了 VA |
ゼロフィルを除く TLS の最後のバイトのアドレス。 生データ開始 VA フィールドと同様に、これは RVA ではなく VA です。 |
8/16 |
4/8 |
インデックスのアドレス |
ローダーによって割り当てられる TLS インデックスを受信する場所。 この場所は通常のデータ セクション内にあります。そのため、プログラムからアクセスできるシンボリック名を指定できます。 |
12/24 |
4/8 |
コールバックのアドレス |
TLS コールバック関数の配列へのポインター。 配列は null で終了するため、コールバック関数がサポートされていない場合、このフィールドは 0 に設定された 4 バイトを指します。 これらの関数のプロトタイプの詳細については、「 TLS コールバック関数」を参照してください。 |
16/32 |
4 |
0 の塗りつぶしのサイズ |
[生データ開始 VA] フィールドと [生データ終了 VA] フィールドで区切られた初期化されたデータを超える、テンプレートのサイズ (バイト単位)。 テンプレートの合計サイズは、イメージ ファイル内の TLS データの合計サイズと同じである必要があります。 ゼロフィルは、初期化された 0 以外のデータの後に来るデータの量です。 |
20/36 |
4 |
特性 |
4 つのビット [23:20] は、アラインメント情報を記述します。 指定できる値は、IMAGE_SCN_ALIGN_* として定義されたもので、オブジェクト ファイル内のセクションの配置を記述するためにも使用されます。 他の 28 ビットは、将来の使用のために予約されています。 |
TLS コールバック関数
プログラムは、TLS データ オブジェクトの追加の初期化と終了をサポートするために、1 つ以上の TLS コールバック関数を提供できます。 このようなコールバック関数の一般的な用途は、オブジェクトのコンストラクターとデストラクターを呼び出す場合です。
通常は複数のコールバック関数はありませんが、必要に応じてコールバック関数を追加できるように、コールバックが配列として実装されます。 複数のコールバック関数がある場合、各関数は、そのアドレスが配列に表示される順序で呼び出されます。 null ポインターは配列を終了します。 空のリスト (コールバックがサポートされていません) を持つことは完全に有効です。その場合、コールバック配列にはメンバー a null ポインターが 1 つだけ含まれます。
コールバック関数 (PIMAGE_TLS_CALLBACK 型のポインターによって指される) のプロトタイプには、DLL エントリ ポイント関数と同じパラメーターがあります。
typedef VOID
(NTAPI *PIMAGE_TLS_CALLBACK) (
PVOID DllHandle,
DWORD Reason,
PVOID Reserved
);
予約済みパラメーターは 0 に設定する必要があります。 Reason パラメーターは、次の値を受け取ることができます。
設定 | 値 | 説明 |
---|---|---|
DLL_PROCESS_ATTACH |
1 |
最初のスレッドを含む新しいプロセスが開始されました。 |
DLL_THREAD_ATTACH |
2 |
新しいスレッドが作成されました。 この通知は、最初のスレッド以外のすべてのスレッドに対して送信されました。 |
DLL_THREAD_DETACH |
3 |
スレッドが終了しようとしています。 この通知は、最初のスレッド以外のすべてのスレッドに対して送信されました。 |
DLL_PROCESS_DETACH |
0 |
元のスレッドを含め、プロセスが終了しようとしています。 |
Load Configuration Structure (イメージのみ)
ロード構成構造 (IMAGE_LOAD_CONFIG_DIRECTORY) は、以前は、Windows NT オペレーティング システム自体で非常に限られたケースで使用されていました。これは、イメージのファイル ヘッダーまたは省略可能なヘッダーで記述するのが難しすぎる、または大きすぎるさまざまな機能を記述するために使用されていました。 現在のバージョンの Microsoft リンカーと Windows XP 以降のバージョンの Windows では、予約済みの SEH テクノロジを含む 32 ビット x86 ベースのシステムに対して、この構造体の新しいバージョンが使用されます。 これにより、オペレーティング システムが例外ディスパッチ時に使用する安全な構造化例外ハンドラーの一覧が提供されます。 ハンドラー アドレスがイメージの VA 範囲にあり、予約済みの SEH 対応としてマークされている場合 (つまり、前述のように、省略可能なヘッダーの DllCharacteristics フィールドでIMAGE_DLLCHARACTERISTICS_NO_SEHは明確です)、ハンドラーはそのイメージの既知の安全なハンドラーの一覧に含まれている必要があります。 それ以外の場合、オペレーティング システムはアプリケーションを終了します。 これは、オペレーティング システムを制御するために過去に使用されていた "x86 例外ハンドラーハイジャック" の悪用を防ぐのに役立ちます。
Microsoft リンカーは、予約済みの SEH データを含める既定の読み込み構成構造を自動的に提供します。 ユーザー コードが既に読み込み構成構造を提供している場合は、新しい予約済み SEH フィールドを含める必要があります。 それ以外の場合、リンカーは予約済みの SEH データを含むことができず、イメージは予約済み SEH を含んでいるとマークされません。
構成ディレクトリの読み込み
オペレーティング システム ローダーでは常に特定の値と見なされるため、事前予約済みの SEH 読み込み構成構造のデータ ディレクトリ エントリでは、特定のサイズの読み込み構成構造を指定する必要があります。 その点、サイズは実際にはバージョンチェックにすぎません。 Windows XP および以前のバージョンの Windows との互換性を保つには、x86 イメージのサイズを 64 にする必要があります。
構成レイアウトの読み込み
ロード構成構造には、32 ビットおよび 64 ビット PE ファイル用の次のレイアウトがあります。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
4 |
特性 |
現在使用されていないファイルの属性を示すフラグ。 |
4 |
4 |
TimeDateStamp |
日付と時刻のスタンプ値。 値は、システム クロックに従って、1970 年 1 月 1 日午前 0 時 (00:00:00)、世界協定時刻から経過した秒数で表されます。 タイム スタンプは、C ランタイム (CRT) 時間関数を使用して出力できます。 |
8 |
2 |
MajorVersion |
メジャー バージョン番号。 |
10 |
2 |
MinorVersion |
マイナー バージョン番号。 |
12 |
4 |
GlobalFlagsClear |
ローダーがプロセスを開始すると、このプロセスに対してクリアするグローバル ローダー フラグ。 |
16 |
4 |
GlobalFlagsSet |
ローダーがプロセスを開始すると、このプロセスに対して設定するグローバル ローダー フラグ。 |
20 |
4 |
CriticalSectionDefaultTimeout |
破棄されるこのプロセスの重要なセクションに使用する既定のタイムアウト値。 |
24 |
4/8 |
DeCommitFreeBlockThreshold |
システムに返される前に解放する必要があるメモリ (バイト単位)。 |
28/32 |
4/8 |
DeCommitTotalFreeThreshold |
空きメモリの合計量 (バイト単位)。 |
32/40 |
4/8 |
LockPrefixTable |
[x86 のみ]LOCK プレフィックスが使用され、単一のプロセッサ マシンで NOP に置き換えられるアドレスの一覧の VA。 |
36/48 |
4/8 |
MaximumAllocationSize |
最大割り当てサイズ (バイト単位)。 |
40/56 |
4/8 |
VirtualMemoryThreshold |
最大仮想メモリ サイズ (バイト単位)。 |
44/64 |
4/8 |
ProcessAffinityMask |
このフィールドを 0 以外の値に設定することは、プロセスの起動時にこの値を使用して SetProcessAffinityMask を呼び出すことと同じです (.exeのみ) |
48/72 |
4 |
ProcessHeapFlags |
HeapCreate 関数の最初の引数に対応するプロセス ヒープ フラグ。 これらのフラグは、プロセスの起動時に作成されるプロセス ヒープに適用されます。 |
52/76 |
2 |
CSDVersion |
Service Pack のバージョン識別子。 |
54/78 |
2 |
予約されています。 |
ゼロを指定してください。 |
56/80 |
4/8 |
EditList |
システムで使用するために予約されています。 |
60/88 |
4/8 |
SecurityCookie |
Visual C++ または GS 実装で使用される Cookie へのポインター。 |
64/96 |
4/8 |
SEHandlerTable |
[x86 のみ]イメージ内の有効な一意の SE ハンドラーごとの RVA の並べ替えられたテーブルの VA。 |
68/104 |
4/8 |
SEHandlerCount |
[x86 のみ]テーブル内の一意のハンドラーの数。 |
72/112 |
4/8 |
GuardCFCheckFunctionPointer |
制御フロー ガードのチェック関数ポインターが格納されている VA。 |
76/120 |
4/8 |
GuardCFDispatchFunctionPointer |
制御フロー ガードディスパッチ関数ポインターが格納される VA。 |
80/128 |
4/8 |
GuardCFFunctionTable |
イメージ内の各制御フロー ガード関数の RVA の並べ替えられたテーブルの VA。 |
84/136 |
4/8 |
GuardCFFunctionCount |
上の表の一意の RVA の数。 |
88/144 |
4 |
GuardFlags |
Flow Guard に関連するフラグを制御します。 |
92/148 |
12 |
CodeIntegrity |
コードの整合性情報。 |
104/160 |
4/8 |
GuardAddressTakenIatEntryTable |
制御フロー ガード アドレスが IAT テーブルを取得した VA が格納されます。 |
108/168 |
4/8 |
GuardAddressTakenIatEntryCount |
上の表の一意の RVA の数。 |
112/176 |
4/8 |
GuardLongJumpTargetTable |
制御フロー ガードの長いジャンプターゲット テーブルが格納されている VA。 |
116/184 |
4/8 |
GuardLongJumpTargetCount |
上の表の一意の RVA の数。 |
GuardFlags フィールドには、次のフラグとサブフィールドの 1 つ以上の組み合わせが含まれています。
モジュールは、システム提供のサポートを使用して制御フローの整合性チェックを実行します。
#define IMAGE_GUARD_CF_INSTRUMENTED 0x00000100
モジュールは、制御フローと書き込みの整合性チェックを実行します。
#define IMAGE_GUARD_CFW_INSTRUMENTED 0x00000200
モジュールには、有効な制御フロー ターゲット メタデータが含まれています。
#define IMAGE_GUARD_CF_FUNCTION_TABLE_PRESENT 0x00000400
モジュールでは、/GS セキュリティ Cookie は使用されません。
#define IMAGE_GUARD_SECURITY_COOKIE_UNUSED 0x00000800
モジュールでは、読み取り専用の遅延読み込み IAT がサポートされています。
#define IMAGE_GUARD_PROTECT_DELAYLOAD_IAT 0x00001000
自由に再保護できる独自の .didat セクション (他に何も含まない) にインポート テーブルを遅延読み込みます。
#define IMAGE_GUARD_DELAYLOAD_IAT_IN_ITS_OWN_SECTION 0x00002000
モジュールには、抑制されたエクスポート情報が含まれています。 これにより、IAT テーブルを取得したアドレスも読み込み構成に存在することが推測されます。
#define IMAGE_GUARD_CF_EXPORT_SUPPRESSION_INFO_PRESENT 0x00004000
モジュールを使用すると、エクスポートの抑制が可能になります。
#define IMAGE_GUARD_CF_ENABLE_EXPORT_SUPPRESSION 0x00008000
モジュールには longjmp ターゲット情報が含まれています。
#define IMAGE_GUARD_CF_LONGJUMP_TABLE_PRESENT 0x00010000
Control Flow Guard 関数テーブル エントリのストライドを含むサブフィールド (つまり、テーブル エントリあたりのバイト数の追加数) をマスクします。
#define IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_MASK 0xF0000000
さらに、Windows SDK winnt.h ヘッダーは、GuardFlags 値を右シフトして Control Flow Guard 関数テーブルのストライドを右揃えするビット数に対して、このマクロを定義します。
#define IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_SHIFT 28
.rsrc セクション
リソースは、複数レベルのバイナリ並べ替えツリー構造によってインデックスが作成されます。 一般的な設計では、2**31 レベルを組み込むことができます。 ただし、慣例により、Windows では次の 3 つのレベルが使用されます。
- 型名の言語
一連のリソース ディレクトリ テーブルは、すべてのレベルを次のように関連付けます。各ディレクトリ テーブルの後に、そのレベルの名前または識別子 (ID) と、データ記述または別のディレクトリ テーブルのアドレスを指定する一連のディレクトリ エントリが続きます。 アドレスがデータ記述を指している場合、データはツリー内のリーフになります。 アドレスが別のディレクトリ テーブルを指している場合、そのテーブルには次のレベルのディレクトリ エントリが一覧表示されます。
リーフの Type、Name、Language ID は、リーフに到達するためにディレクトリ テーブルを介して取得されるパスによって決まります。 最初のテーブルは型 ID を決定し、2 番目のテーブル (最初のテーブルのディレクトリ エントリによって指されます) が名前 ID を決定し、3 番目のテーブルが言語 ID を決定します。
.rsrc セクションの一般的な構造は次のとおりです。
Data | 説明 |
---|---|
Resource Directory テーブル (および Resource Directory エントリ) |
ツリー内のノードのグループごとに 1 つずつ、一連のテーブル。 すべての最上位 (種類) ノードが最初の表に一覧表示されます。 このテーブルのエントリは、第 2 レベルのテーブルを指します。 各 2 番目のレベルのツリーの型 ID は同じですが、名前 ID は異なります。 第 3 レベルのツリーの型 ID と名前 ID は同じですが、言語 ID は異なります。 各テーブルの直後にディレクトリ エントリが続きます。各エントリには、名前または数値識別子と、次の下位レベルのデータ記述またはテーブルへのポインターが含まれます。 |
リソース ディレクトリ文字列 |
ディレクトリ エントリが指す文字列データとして機能する 2 バイトアライン Unicode 文字列。 |
リソース データの説明 |
リソース データの実際のサイズと場所を表す、テーブルが指すレコードの配列。 これらのレコードは、リソース説明ツリーのリーフです。 |
リソース データ |
リソース セクションの生データ。 [リソース データの説明] フィールドのサイズと場所の情報は、リソース データの個々の領域を区切ります。 |
リソース ディレクトリ テーブル
各リソース ディレクトリ テーブルの形式は次のとおりです。 テーブルは実際にはディレクトリ エントリ (セクション 6.9.2「Resource Directory Entries」で説明) と次の構造で構成されているため、このデータ構造はテーブルの見出しと見なす必要があります。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
4 |
特性 |
リソース フラグ。 このフィールドは将来使用するために予約されています。 現在は 0 に設定されています。 |
4 |
4 |
時刻/日付スタンプ |
リソース コンパイラによってリソース データが作成された時刻。 |
8 |
2 |
メジャー バージョン |
ユーザーによって設定されたメジャー バージョン番号。 |
10 |
2 |
マイナー バージョン |
ユーザーによって設定されたマイナー バージョン番号。 |
12 |
2 |
名前エントリの数 |
文字列を使用して Type、Name、または Language エントリを識別するテーブルの直後のディレクトリ エントリの数 (テーブルのレベルに応じて)。 |
14 |
2 |
ID エントリの数 |
Type、Name、または Language エントリに数値 ID を使用する Name エントリの直後にあるディレクトリ エントリの数。 |
リソース ディレクトリ エントリ
ディレクトリ エントリは、テーブルの行を構成します。 各リソース ディレクトリ エントリの形式は次のとおりです。 エントリが Name エントリか ID エントリかは、リソース ディレクトリ テーブルによって示されます。これは、その後に続く名前と ID のエントリの数を示します (テーブルのすべての ID エントリの前にすべての Name エントリが先行していることを忘れないでください)。 テーブルのすべてのエントリは昇順で並べ替えられます。Name エントリは大文字と小文字を区別する文字列で、ID エントリは数値で並べ替えられます。 オフセットは、IMAGE_DIRECTORY_ENTRY_RESOURCE DataDirectory 内のアドレスに対して相対的です。 詳細については、「 PE 内のピアリング: Win32 ポータブル実行可能ファイル形式のツアー 」を参照してください。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
4 |
名前のオフセット |
テーブルのレベルに応じて、Type、Name、または Language ID エントリを指定する文字列のオフセット。 |
0 |
4 |
整数 ID |
Type、Name、または Language ID エントリを識別する 32 ビットの整数。 |
4 |
4 |
データ入力オフセット |
上位ビット 0。 リソース データ エントリ (リーフ) のアドレス。 |
4 |
4 |
サブディレクトリ オフセット |
上位ビット 1。 下位 31 ビットは、別のリソース ディレクトリ テーブルのアドレスです (次のレベルは下)。 |
リソース ディレクトリ文字列
リソース ディレクトリ文字列領域は、単語アラインメントされた Unicode 文字列で構成されます。 これらの文字列は、最後の Resource Directory エントリの後、および最初の Resource Data エントリの前にまとめて格納されます。 これにより、固定サイズのディレクトリ エントリの配置に対するこれらの可変長文字列の影響が最小限に抑えられます。 各リソース ディレクトリ文字列の形式は次のとおりです。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
2 |
長さ |
長さフィールド自体を含まない文字列のサイズ。 |
2 |
変数 |
Unicode 文字列 |
ワードアラインメントされた可変長 Unicode 文字列データ。 |
リソース データエントリ
各リソース データ エントリには、リソース データ領域の生データの実際の単位が記述されます。 Resource Data エントリの形式は次のとおりです。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
4 |
データ RVA |
[リソース データ] 領域のリソース データの単位のアドレス。 |
4 |
4 |
サイズ |
Data RVA フィールドが指すリソース データのサイズ (バイト単位)。 |
8 |
4 |
codepage |
リソース データ内のコード ポイント値をデコードするために使用されるコード ページ。 通常、コード ページは Unicode コード ページになります。 |
12 |
4 |
予約済み、0 である必要があります。 |
.cormeta セクション (オブジェクトのみ)
CLR メタデータは、このセクションに格納されます。 これは、オブジェクト ファイルにマネージド コードが含まれていることを示すために使用されます。 メタデータの形式は文書化されていませんが、メタデータを処理するために CLR インターフェイスに渡すことができます。
.sxdata セクション
オブジェクトの有効な例外ハンドラーは、そのオブジェクトの .sxdata セクションに一覧表示されます。 セクションはIMAGE_SCN_LNK_INFOマークされています。 インデックスごとに 4 バイトを使用して、有効な各ハンドラーの COFF シンボル インデックスが含まれています。
さらに、コンパイラは、VALUE フィールドの LSB を 1 に設定して絶対シンボル "@feat.00" を出力することで、COFF オブジェクトを登録済み SEH としてマークします。 SEH ハンドラーが登録されていない COFF オブジェクトには、"@feat.00" シンボルがありますが、 .sxdata セクションはありません。
アーカイブ (ライブラリ) ファイル形式
COFF アーカイブ形式は、オブジェクト ファイルのコレクションを格納するための標準的なメカニズムを提供します。 これらのコレクションは、プログラミング ドキュメントでは一般にライブラリと呼ばれます。
アーカイブの最初の 8 バイトは、ファイル署名で構成されます。 アーカイブの残りの部分は、次のように一連のアーカイブ メンバーで構成されます。
1 番目と 2 番目のメンバーは "リンカー メンバー" です。これらの各メンバーは、「 名前の種類のインポート」セクションで説明されているように、独自の形式を持ちます。 通常、リンカーはこれらのアーカイブ メンバーに情報を配置します。 リンカー メンバーには、アーカイブのディレクトリが含まれています。
3 番目のメンバーは "longnames" メンバーです。 この省略可能なメンバーは、各文字列が別のアーカイブ メンバーの名前である一連の null で終わる ASCII 文字列で構成されます。
アーカイブの残りの部分は、標準 (オブジェクト ファイル) メンバーで構成されます。 これらの各メンバーには、1 つのオブジェクト ファイルの内容全体が含まれます。
アーカイブ メンバー ヘッダーは、各メンバーの前にあります。 次の一覧は、アーカイブの一般的な構造を示しています。
シグネチャ :"!<アーチ>\n" |
---|
ヘッダー |
---|
1 番目のリンカー メンバー |
ヘッダー |
---|
2 番目のリンカー メンバー |
ヘッダー |
---|
Longnames メンバー |
ヘッダー |
---|
OBJ ファイル 1 の内容 (COFF 形式) |
ヘッダー |
---|
OBJ ファイル 2 の内容 (COFF 形式) |
...
ヘッダー |
---|
OBJ ファイル N の内容 (COFF 形式) |
アーカイブ ファイルの署名
アーカイブ ファイル署名は、ファイルの種類を識別します。 アーカイブ ファイルを入力として受け取るユーティリティ (リンカーなど) は、このシグネチャを読み取ることでファイルの種類を確認できます。 シグネチャは次の ASCII 文字で構成され、改行 (\n) 文字を除き、以下の各文字がリテラルで表されます。
!<arch>\n
アーカイブ メンバー ヘッダー
各メンバー (リンカー、longnames、またはオブジェクト ファイル メンバー) の前に ヘッダーが付きます。 アーカイブ メンバー ヘッダーの形式は次のとおりです。各フィールドは、両端揃えの ASCII テキスト文字列であり、フィールドの末尾にスペースが埋め込まれます。 これらのフィールドに終端の null 文字はありません。
各メンバー ヘッダーは、前のアーカイブ メンバーの末尾の後の最初の偶数アドレスで開始されます。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
16 |
名前 |
アーカイブ メンバーの名前。名前を終了するためにスラッシュ (/) を追加します。 最初の文字がスラッシュの場合、次の表に示すように、名前には特別な解釈があります。 |
16 |
12 |
Date |
アーカイブ・メンバーが作成された日時: これは、1970 年 1 月 1 日 UCT 以降の秒数の ASCII 10 進数表記です。 |
28 |
6 |
User ID |
ユーザー ID の ASCII 10 進数表現。 このフィールドには、Microsoft ツールによってすべての空白が出力されるため、Windows プラットフォームでは意味のある値は含まれません。 |
34 |
6 |
グループ ID |
グループ ID の ASCII 10 進数表現。 このフィールドには、Microsoft ツールによってすべての空白が出力されるため、Windows プラットフォームでは意味のある値は含まれません。 |
40 |
8 |
モード |
メンバーのファイル モードの ASCII 8 進数表現。 これは、C ランタイム関数_wstatからのST_MODE値です。 |
48 |
10 |
サイズ |
ヘッダーのサイズを含まない、アーカイブ メンバーの合計サイズの ASCII 10 進数表現。 |
58 |
2 |
ヘッダーの末尾 |
C 文字列 "̃\n" の 2 バイト (0x60 0x0A)。 |
[名前] フィールドには、次の表に示すいずれかの形式があります。 前述のように、これらの各文字列は両端揃えのままで、16 バイトのフィールド内に末尾のスペースが埋め込まれます。
[名前] フィールドの内容 | 説明 |
---|---|
名前/ |
アーカイブ メンバーの名前。 |
/ |
アーカイブ メンバーは、2 つのリンカー メンバーのいずれかです。 どちらのリンカー メンバーも、この名前を持ちます。 |
// |
アーカイブ メンバーは longnames メンバーであり、一連の null で終わる ASCII 文字列で構成されます。 longnames メンバーは 3 番目のアーカイブ メンバーであり、省略可能です。 |
/n |
アーカイブ・メンバーの名前は、longnames メンバー内のオフセット n にあります。 数値 n はオフセットの 10 進表現です。 例: "/26" は、アーカイブ・メンバーの名前が longnames メンバー・コンテンツの先頭を 26 バイト超えて配置されていることを示します。 |
最初のリンカー メンバー
最初のリンカー メンバーの名前は "/" です。 下位互換性のために、最初のリンカー メンバーが含まれています。 現在のリンカーでは使用されませんが、その形式は正しい必要があります。 このリンカー メンバーは、2 番目のリンカー メンバーと同様に、シンボル名のディレクトリを提供します。 シンボルごとに、シンボルを含むアーカイブ メンバーを検索する場所が情報に示されます。
最初のリンカー メンバーの形式は次のとおりです。 この情報は、ヘッダーの後に表示されます。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
4 |
記号の数 |
インデックス付きシンボルの数を含む符号なし long。 この数値は、ビッグ エンディアン形式で格納されます。 各オブジェクト ファイル メンバーは、通常、1 つ以上の外部シンボルを定義します。 |
4 |
4 * n |
オフセット |
アーカイブ メンバー ヘッダーへのファイル オフセットの配列。n は [シンボルの数] フィールドと等しくなります。 配列内の各数値は、ビッグ エンディアン形式で格納された符号なし long です。 文字列テーブルで名前が付けられたシンボルごとに、offsets 配列内の対応する要素によって、シンボルを含むアーカイブ メンバーの場所が指定されます。 |
* |
* |
文字列テーブル |
ディレクトリ内のすべてのシンボルに名前を付ける一連の null で終わる文字列。 各文字列は、前の文字列の null 文字の直後に開始されます。 文字列の数は、[シンボルの数] フィールドの値と等しい必要があります。 |
offsets 配列内の要素は昇順に配置する必要があります。 これは、文字列テーブル内のシンボルをアーカイブ メンバーの順序に従って配置する必要があることを意味します。 たとえば、最初のオブジェクト ファイル メンバーのすべてのシンボルは、2 番目のオブジェクト ファイル内のシンボルの前に一覧表示する必要があります。
2 番目のリンカー メンバー
2 番目のリンカー メンバーの名前は、最初のリンカー メンバーと同様に "/" です。 両方のリンカー メンバーは、シンボルのディレクトリと、それらを含むアーカイブ メンバーを提供しますが、2 番目のリンカー メンバーは、現在のすべてのリンカーによって 1 つ目のリンカーより優先して使用されます。 2 番目のリンカー メンバーには、構文順のシンボル名が含まれています。これにより、名前による高速な検索が可能になります。
2 番目のメンバーの形式は次のとおりです。 この情報は、ヘッダーの後に表示されます。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
4 |
メンバーの数 |
アーカイブ メンバーの数を含む符号なし long。 |
4 |
4 * m |
オフセット |
アーカイブ メンバー ヘッダーへのファイル オフセットの配列。昇順に配置されます。 各オフセットは、符号なし long です。 数値 m は、[メンバー数] フィールドの値と等しくなります。 |
* |
4 |
記号の数 |
インデックスが作成されたシンボルの数を含む符号なし long。 各オブジェクト ファイル メンバーは、通常、1 つ以上の外部シンボルを定義します。 |
* |
2 * n |
インデックス |
シンボル名をアーカイブ メンバー オフセットにマップする 1 から始まるインデックス (符号なし short) の配列。 数値 n は、[シンボルの数] フィールドと等しくなります。 文字列テーブルで名前が付けられたシンボルごとに、Indexs 配列内の対応する要素によって、オフセット配列にインデックスが渡されます。 offsets 配列は、シンボルを含むアーカイブ メンバーの場所を示します。 |
* |
* |
文字列テーブル |
ディレクトリ内のすべてのシンボルに名前を付ける一連の null で終わる文字列。 各文字列は、前の文字列の null バイトの直後に開始されます。 文字列の数は、[シンボルの数] フィールドの値と等しい必要があります。 次の表に、すべてのシンボル名を構文の昇順で示します。 |
Longnames メンバー
longnames メンバーの名前は "//" です。 longnames メンバーは、アーカイブ メンバー名の一連の文字列です。 Name フィールド (16 バイト) に十分な領域がない場合にのみ、名前がここに表示されます。 longnames メンバーは省略可能です。 ヘッダーのみで空にすることも、ヘッダーなしでも完全に存在しない場合があります。
文字列は null で終わる。 各文字列は、前の文字列の null バイトの直後に開始されます。
ライブラリ形式のインポート
従来のインポート ライブラリ、つまり、別のイメージからのエクスポートを記述するライブラリは、通常、セクション 7 の「 アーカイブ (ライブラリ) ファイル形式」で説明されているレイアウトに従います。 主な違いは、インポート ライブラリ メンバーには実際のファイルではなく擬似オブジェクト ファイルが含まれていることです。各メンバーには、セクション 6.4 で説明されているインポート テーブルの作成に必要なセクションコントリビューションが含まれています。 .idata セクション リンカーは 、エクスポート アプリケーションのビルド中にこのアーカイブを生成します。
インポートのセクションコントリビューションは、小さな情報セットから推測できます。 リンカーは、ライブラリの作成時に各メンバーのインポート ライブラリに完全で詳細な情報を生成するか、ライブラリに正規情報のみを書き込み、後で使用するアプリケーションに必要なデータを即座に生成させることができます。
long 形式のインポート ライブラリでは、1 つのメンバーに次の情報が含まれます。
- アーカイブ メンバー ヘッダー
- ファイル ヘッダー
- セクション ヘッダー
- 各セクション ヘッダーに対応するデータ
- COFF シンボル テーブル
- 文字列
これに対し、短いインポート ライブラリは次のように記述されます。
- アーカイブ メンバー ヘッダー
- ヘッダーのインポート
- Null で終わるインポート名の文字列
- NULL で終わる DLL 名の文字列
これは、使用時にメンバーの内容全体を正確に再構築するのに十分な情報です。
ヘッダーのインポート
インポート ヘッダーには、次のフィールドとオフセットが含まれています。
Offset | サイズ | フィールド | 説明 |
---|---|---|---|
0 |
2 |
Sig1 |
IMAGE_FILE_MACHINE_UNKNOWNする必要があります。 詳細については、「マシンの 種類」を参照してください。 |
2 |
2 |
Sig2 |
0xFFFFする必要があります。 |
4 |
2 |
バージョン |
構造体のバージョン。 |
6 |
2 |
Machine |
ターゲット コンピューターの種類を識別する番号。 詳細については、「マシンの 種類」を参照してください。 |
8 |
4 |
Time-Date スタンプ |
ファイルが作成された日時。 |
12 |
4 |
データのサイズ |
ヘッダーに続く文字列のサイズ。 |
16 |
2 |
序数/ヒント |
インポートの序数またはヒントのいずれか。[名前の種類] フィールドの値によって決まります。 |
18 |
2 ビット |
Type |
インポートの種類。 特定の値と説明については、「 インポートの種類」を参照してください。 |
3 ビット |
名前の種類 |
インポート名の種類。 詳細については、「 インポート名の種類」を参照してください。 |
|
11 ビット |
予約されています。 |
予約済み、0 である必要があります。 |
この構造体の後には、インポートされたシンボルの名前と、それが含まれる DLL を記述する 2 つの null で終わる文字列が続きます。
インポートの種類
インポート ヘッダーの Type フィールドには、次の値が定義されています。
定数 | 値 | 説明 |
---|---|---|
IMPORT_CODE |
0 |
実行可能コード。 |
IMPORT_DATA |
1 |
データ。 |
IMPORT_CONST |
2 |
.def ファイルで CONST として指定されます。 |
これらの値は、ライブラリを使用するツールがそのデータにアクセスする必要がある場合に、どのセクションコントリビューションを生成する必要があるかどうかを判断するために使用されます。
インポート名の種類
null で終わるインポート シンボル名は、関連付けられているインポート ヘッダーの直後にあります。 インポート ヘッダーの [名前の種類] フィールドには、次の値が定義されています。 これらは、インポートを表す正しいシンボルを生成するために名前を使用する方法を示します。
定数 | 値 | 説明 |
---|---|---|
IMPORT_ORDINAL | 0 | インポートは序数で行います。 これは、インポート ヘッダーの Ordinal/Hint フィールドの値がインポートの序数であることを示します。 この定数を指定しない場合、Ordinal/Hint フィールドは常にインポートのヒントとして解釈されます。 |
IMPORT_NAME | 1 | インポート名は、パブリック シンボル名と同じです。 |
IMPORT_NAME_NOPREFIX | 2 | インポート名はパブリック シンボル名ですが、先頭の ?、@、または必要に応じて _をスキップします。 |
IMPORT_NAME_UNDECORATE | 3 | インポート名はパブリック シンボル名ですが、先頭の ?、@、または必要に応じて _をスキップし、最初の @で切り捨てます。 |
付録 A: Authenticode PE イメージ ハッシュの計算
イメージの整合性を検証するために、いくつかの属性証明書が使用されることが想定されています。 ただし、最も一般的なのは Authenticode シグネチャです。 Authenticode 署名を使用して、PE イメージ ファイルの関連セクションがファイルの元の形式から変更されていないことを確認できます。 このタスクを実行するために、Authenticode 署名には PE イメージ ハッシュと呼ばれるものが含まれています
Authenticode PE イメージ ハッシュとは
Authenticode PE イメージ ハッシュ (略してファイル ハッシュ) は、ファイルの整合性に関連する小さな値を生成するという点で、ファイル チェックサムに似ています。 チェックサムは単純なアルゴリズムによって生成され、主にメモリ エラーを検出するために使用されます。 つまり、ディスク上のメモリ ブロックが正しくなくなり、そこに格納されている値が破損しているかどうかを検出するために使用されます。 ファイル ハッシュは、ファイルの破損も検出するという点でチェックサムに似ています。 ただし、ほとんどのチェックサム アルゴリズムとは異なり、元の (変更されていない) 形式と同じファイル ハッシュを持つファイルを変更することは非常に困難です。 つまり、チェックサムは破損につながる単純なメモリ 障害を検出することを目的としていますが、ファイル ハッシュを使用して、ウイルス、ハッカー、トロイの木馬プログラムによって導入されたファイルなど、ファイルに対する意図的かつ微妙な変更を検出できます。
Authenticode 署名では、ファイル ハッシュは、ファイルの署名者にのみ認識される秘密キーを使用してデジタル署名されます。 ソフトウェア コンシューマーは、ファイルのハッシュ値を計算し、Authenticode デジタル署名に含まれる署名付きハッシュの値と比較することで、ファイルの整合性を確認できます。 ファイル ハッシュが一致しない場合は、PE イメージ ハッシュの対象となるファイルの一部が変更されています。
Authenticode PE イメージ ハッシュでは何がカバーされますか?
PE イメージ ハッシュの計算にすべてのイメージ ファイル データを含めることはできません。 場合によっては、単に望ましくない特性を示す場合があります (たとえば、一般公開されているファイルからデバッグ情報を削除することはできません)。時にはそれは単に不可能です。 たとえば、Authenticode 署名にイメージ ファイル内のすべての情報を含めることはできず、その PE イメージ ハッシュを含む Authenticode 署名を PE イメージに挿入し、その後、すべてのイメージ ファイル データを計算に含めることで同じ PE イメージ ハッシュを生成できます。これは、ファイルに最初に存在しなかった Authenticode 署名が含まれるようになりました。
Authenticode PE イメージ ハッシュを生成するためのプロセス
このセクションでは、PE イメージ ハッシュの計算方法と、Authenticode 署名を無効にせずに PE イメージの部分を変更する方法について説明します。
Note
特定のファイルの PE イメージ ハッシュは、ハッシュされたファイル内に属性証明書を含めることなく、別のカタログ ファイルに含めることができます。 実際には Authenticode 署名を含まない PE イメージを変更することで、Authenticode 署名付きカタログ ファイル内の PE イメージ ハッシュを無効にすることが可能になるため、これは関連しています。
セクション テーブルで指定されている PE イメージのセクション内のすべてのデータは、次の除外範囲を除き、全体でハッシュされます。
省略可能なヘッダーの Windows 固有のフィールドのファイル CheckSum フィールド。 このチェックサムには、ファイル全体 (ファイル内の属性証明書を含む) が含まれます。 多くの場合、チェックサムは Authenticode シグネチャを挿入した後の元の値とは異なります。
属性証明書に関連する情報。 Authenticode 署名に関連する PE イメージの領域は、イメージの全体的な整合性に影響を与えることなく、Authenticode 署名をイメージに追加したり、イメージから削除したりできるため、PE イメージ ハッシュの計算には含まれません。 PE イメージの再署名またはタイム スタンプの追加に依存するユーザー シナリオがあるため、これは問題ではありません。 Authenticode では、ハッシュ計算から次の情報が除外されます。
オプションのヘッダー データ ディレクトリの [証明書テーブル] フィールド。
直前の [証明書テーブル] フィールドが指す証明書テーブルと対応する証明書。
PE イメージ ハッシュを計算するために、Authenticode は、セクション テーブルで指定されたセクションをアドレス範囲で並べ替え、結果のバイト シーケンスをハッシュして除外範囲を渡します。
最後のセクションの最後を過ぎた情報。 最後のセクションを超えた領域 (最も高いオフセットで定義) はハッシュされません。 この領域には、一般的にデバッグ情報が含まれています。 デバッグ情報は通常、デバッガーのアドバイザリと見なすことができます。実行可能プログラムの実際の整合性には影響しません。 製品が配信された後にイメージからデバッグ情報を削除することは、文字通り可能であり、プログラムの機能には影響しません。 実際、これはディスク節約の手段として行われる場合があります。 PE イメージの指定されたセクションに含まれるデバッグ情報は、Authenticode 署名を無効にしないと削除できないことに注意してください。
Windows プラットフォーム SDKで提供されている makecert ツールと signtool ツールを使用して、Authenticode 署名の作成と検証を試すことができます。 詳細については、以下の「リファレンス」を参照してください。
References
Windows 用のダウンロードとツール (Windows SDK を含む)