Shoeisha Technology Media

CodeZine(コードジン)

記事種別から探す

EXEファイルの内部構造(セクション)

Windows実行ファイル「EXE」の謎に迫る 第3回

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2006/06/30 00:00

本連載では、EXEファイルの内部構造について解説していきます。特にEXEファイルに関する日本語の資料が少ないのが現状です。筆者自身の経験を踏まえ、実際にEXEファイルの解析ができるようになるための資料となるよう解説していきます。第3回となる今回は、PEヘッダの後に配置されているセクションについて解説します。

目次

はじめに

 前回で解説したPEヘッダに引き続き、今回もEXEファイル内のデータフォーマットの一部分「セクション」に関する話題で突き進みます。

 それにしても、EXEファイルは調べ手に休ませる余地を与えません。PEヘッダという大きな構造体をクリアしたと思ったら、お次は複数個も存在するセクションが登場するのです。PEヘッダは大きくても1つしかなかったのでまだ良いのですが、セクションだけは更に細分化されたデータ構造を指定するため、少々厄介です。更に、セクションにはデータサイズ・RVA(イメージベースからの相対オフセット)など、生データに関するより詳細な情報が保持されます。

 経験豊富な方はこのような文章を読んでお気づきかもしれませんが、薄い資料でセクションに関するリサーチを行うと、メモリダンプと睨めっこという状況に陥ります。筆者は数週間の間、セクション周りのメモリダンプと暮らしたことがあるので間違いありません!(こんなことを自慢しても、何の役にも立ちませんが…)

セクションとは

 PEヘッダの後にネイティブコード、リソース情報、デバッグ情報など、必要に応じてさまざまなデータが配置されています。それらのデータは、種類ごとにセクションという区切りで格納されています。

セクションの配置図
セクションの配置図

 各セクションのファイル内の保存位置、またはメモリにロードされたときの位置はアライメントに従わなければならない点も注意しておきましょう。例えば、IMAGE_OPTIONAL_HEADER32構造体のFileAlignmentメンバに0x1000が設定されているときは、各セクションのファイルの保存位置は0x1000で割り切れる数になります。

セクションヘッダ(IMAGE_SECTION_HEADER構造体)

 PEヘッダなどの後に続いて、ネイティブコード、リソース情報などの各セクションが配置される形になりますが、その前にセクションヘッダと呼ばれる、各セクションの「特徴」を示すための領域が存在します。

 ここで言う特徴とは、対象となるセクションがどのようなサイズで格納されているのか、読み込み専用であるのか、または書き込みもできるのか、実行可能な領域であるのかなどのことを指し、これらの情報はIMAGE_SECTION_HEADER構造体で指定できます。

 IMAGE_SECTION_HEADER構造体は、PEヘッダの直後にファイルアライメントを考慮しながら配置されます。また、IMAGE_SECTION_HEADER構造体はセクションの数だけ数珠つながりのように存在します。例えば、セクションが3つ存在する場合は、

  • 1つ目のIMAGE_SECTION_HEADER構造体
  • 2つ目のIMAGE_SECTION_HEADER構造体
  • 3つ目のIMAGE_SECTION_HEADER構造体
  • 1つ目のセクションデータ
  • 2つ目のセクションデータ
  • 3つ目のセクションデータ

 という順序でEXEファイル内に格納されます。

IMAGE_SECTION_HEADER構造体
typedef struct _IMAGE_SECTION_HEADER {
    BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];
    union {
            DWORD   PhysicalAddress;
            DWORD   VirtualSize;
    } Misc;
    DWORD   VirtualAddress;
    DWORD   SizeOfRawData;
    DWORD   PointerToRawData;
    DWORD   PointerToRelocations;
    DWORD   PointerToLinenumbers;
    WORD    NumberOfRelocations;
    WORD    NumberOfLinenumbers;
    DWORD   Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
  • Name
  • Nameにはセクションの名前を指定します。一般的には次に挙げる名前が多く使われています。実際には第2回で解説したデータディクショナリからの指定アドレスでセクションの役割が決定するので、この名前は単なる参考値になります。
    表1 一般的なセクション名
    名前役割
    .textネイティブコード
    .dataグローバル変数用の領域、初期値
    .idataインポート関数情報
    .edataエクスポート関数情報
    .rsrcリソース情報
    .debugデバッグ情報
    .reloc再配置情報
    .tlsスレッドごとの静的変数に関する情報
  • VirtualSize
  • VirtualSizeはメモリ上におけるセクションのサイズです。SizeOfRawDataメンバの値よりも大きいときは、差分領域が0で埋め尽くされます。
  • VirtualAddress, SizeOfRawData, PointerToRawData
  • 次のVirtualAddressはメモリ上におけるセクションの位置であり、SizeOfRawDataはファイル上におけるセクションのサイズです。続く、PointerToRawDataはファイル上におけるセクションの位置です。
  • PointerToRelocations
  • PointerToRelocationsは、再配置エントリ情報が格納されているファイル上の位置です。一般的なEXEファイルの場合は0です。
  • PointerToLinenumbers
  • PointerToLinenumbersは、行番号エントリ情報が格納されているファイル上の位置です。COFF行番号が存在しないときは0になります。
  • NumberOfRelocations, NumberOfLinenumbers
  • NumberOfRelocationsは再配置エントリの数です。一般的なEXEファイルの場合は0です。NumberOfLinenumbersは行番号エントリの数です。COFF行番号が存在しないときは0です。
  • Characteristics
  • Characteristicsにはセクションの特性を指定します。次のフラグを組み合わせることで表現できます。
    表2 セクションの特性フラグ
    名前説明
    IMAGE_SCN_CNT_CODE0x00000020セクションに実行コードが含まれています。
    IMAGE_SCN_CNT_INITIALIZED_DATA0x00000040セクションに初期化されたデータが含まれています。
    IMAGE_SCN_CNT_UNINITIALIZED_DATA0x00000080セクションに初期化されていないデータが含まれています。
    IMAGE_SCN_LNK_OVFL0x01000000セクションに拡張された再配置が含まれています。
    IMAGE_SCN_MEM_DISCARDABLE0x02000000セクションは必要があれば破棄できます。
    IMAGE_SCN_MEM_NOT_CACHED0x04000000セクションはキャッシュできません。
    IMAGE_SCN_MEM_NOT_PAGED0x08000000セクションはページングできません。
    IMAGE_SCN_MEM_SHARED0x10000000セクションをメモリ中で共有できます。
    IMAGE_SCN_MEM_EXECUTE0x20000000セクションをコードとして実行できます。
    IMAGE_SCN_MEM_READ0x40000000セクションを読むことができます。
    IMAGE_SCN_MEM_WRITE0x80000000セクションに書き込めます。

  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

バックナンバー

連載:Windows実行ファイル「EXE」の謎に迫る

もっと読む

All contents copyright © 2006-2017 Shoeisha Co., Ltd. All rights reserved. ver.1.5