SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

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

EXEファイルの内部構造(PEヘッダ)

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


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

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

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

はじめに

 皆さんは、アプリケーションを起動させるEXEファイルの中身について考えてみたことはありますか? 本稿では、EXEファイルの内部構造について解説していきます。特にEXEファイルに関する日本語の資料が少ないのが現状です。そのため、解析に手を出してみたいと思っても挫折してしまった方も少なくないのではないでしょうか。本稿は、筆者自身の経験を踏まえ、実際にEXEファイルの解析ができるようになるための資料となるよう解説していきます。

 前回、第1回では、EXEファイルの概要として、MZシグネチャ、マシンタイプ、ネイティブコード、リソース、デバッグ情報などについて説明しました。これらの一部はPEヘッダと呼ばれる場所に格納されています。また、そのPEヘッダより前にあるEXEファイルの先頭には、IMAGE_DOS_HEADER構造体、MS-DOS用スタブなどがあり、それらがWindowsの元となったMS-DOS用のものであることなどを説明しました。

 今回は、EXEファイルの特性が書き込まれているPEヘッダ部分について解説します。

PEヘッダのフォーマット

 PEヘッダ(Portable Executable)ヘッダは、IMAGE_NT_HEADERS32という構造体にその内容が定義されています。IMAGE_NT_HEADERS32構造体は「winnt.h」に定義されているので、Visual C++の開発環境のある方は参照してみてください。次にその定義を示します。

IMAGE_NT_HEADERS32構造体
typedef struct _IMAGE_NT_HEADERS {
    DWORD Signature;
    IMAGE_FILE_HEADER FileHeader;
    IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
PEヘッダ(IMAGE_NT_HEADERS32構造体)
PEヘッダ(IMAGE_NT_HEADERS32構造体)

Signatureメンバ

 どうやらEXEファイルは、シグネチャが好きなようです。EXEの先頭2バイトに「MZ」 というシグネチャが出てきたにもかかわらず、PEヘッダの先頭部分にも、やはりシグネチャが存在します。ここには、0x00004550「PE00」という値が保持されます。ちょっと注意が必要なのは、「MZ」と異なり、4バイトであるという点です。PEヘッダ以降のデータは、32ビットのWindows OS(以下、Win32)を意識して決定付けられているため、4バイトデータの出現率が高くなります。

 ちょっと余談になりますが、実はEXEファイルは大きな構造体だと言っても過言ではありません(既にお気づきの方もいるかもしれませんね)。普段皆さんが利用する構造体と大きく異なるのは、可変長のデータが多いといったところでしょうか。ネイティブコードのサイズがどれほどのものになるかは、各アプリケーションごとに異なるので、単純な構造体としてEXEファイルを定義することはできませんが、確定的なデータの並び、メンバの並びに準じたフォーマットであることは間違いないようです。

IMAGE_FILE_HEADER構造体

 IMAGE_NT_HEADERS32に定義されている、IMAGE_FILE_HEADER構造体について解説します。どんどん深い内容に入っていきますが、頑張っていきましょう。IMAGE_FILE_HEADER構造体の定義内容は次のとおりです。

IMAGE_FILE_HEADER構造体
typedef struct _IMAGE_FILE_HEADER {
    WORD    Machine;
    WORD    NumberOfSections;
    DWORD   TimeDateStamp;
    DWORD   PointerToSymbolTable;
    DWORD   NumberOfSymbols;
    WORD    SizeOfOptionalHeader;
    WORD    Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

IMAGE_FILE_HEADER構造体の各メンバについて

 MachineメンバではEXEファイルがどのようなマシン上での動作を想定しているのか、次のフラグから指定されます。

表1 マシンタイプを示すフラグ
名前説明
IMAGE_FILE_MACHINE_UNKNOWN0x0あらゆるマシンタイプに適用可能だと仮定される内容
IMAGE_FILE_MACHINE_I3860x14cIntel 386以降およびその互換プロセッサ
IMAGE_FILE_MACHINE_R30000x162
IMAGE_FILE_MACHINE_R40000x166MIPS(r)リトルエンディアン
IMAGE_FILE_MACHINE_R100000x168
IMAGE_FILE_MACHINE_ALPHA0x184Alpha AXP(tm)
IMAGE_FILE_MACHINE_M68K0x268Motorola 68000シリーズ
IMAGE_FILE_MACHINE_POWERPC0x1f0Power PC、リトルエンディアン
IMAGE_FILE_MACHINE_SH30x1a2日立SH3
IMAGE_FILE_MACHINE_SH40x1a6日立SH4
IMAGE_FILE_MACHINE_ARM0x1c0
  • NumberOfSections
  • NumberOfSectionsにはEXEファイルが保持するセクションの数が保持されます。セクションについての詳細は後述します。
  • TimeDateStamp
  • TimeDateStampにはEXEファイルが作成された日時が保持されます。
  • PointerToSymbolTable、NumberOfSymbols
  • PointerToSymbolTableNumberOfSymbolsにはそれぞれ、シンボルテーブルのファイル位置、シンボルの数が保持されます。シンボルテーブルを使用しない一般的なEXEファイルでは、0が保持されています。
  • SizeOfOptionalHeader
  • SizeOfOptionalHeaderには、この後に出てくるIMAGE_OPTIONAL_HEADER32構造体のサイズが保持されます。当たり前の話になってしまいますが、sizeof(IMAGE_OPTIONAL_HEADER32)です。
  • Characteristics
  • Characteristicsにはファイルの属性値を指定します。主に、次のようなフラグが使用されることが多いです(より詳しい情報は、MSDNを検索してみると良いでしょう)。
    表2 ファイルの属性値を示すフラグ
    名前説明
    IMAGE_FILE_EXECUTABLE_IMAGE0x0002イメージのみを示します。イメージファイルが有効であり、実行され得ることを示します。このフラグがセットされていない場合は、一般にリンカのエラーです。
    IMAGE_FILE_LINE_NUMS_STRIPPED0x0004COFF行番号が削除されています。
    IMAGE_FILE_LOCAL_SYMS_STRIPPED0x0008ローカルシンボルのためのCOFFシンボルが削除されています。
    IMAGE_FILE_32BIT_MACHINE0x010032ビットアーキテクチャのマシン。
    IMAGE_FILE_DLL0x2000イメージファイルは、ダイナミックリンクライブラリ(DLL)です。これらのファイルはほとんどあらゆる目的で実行ファイルと見なされますが、直接実行することはできません。

会員登録無料すると、続きをお読みいただけます

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

次のページ
IMAGE_OPTIONAL_HEADER32構造体

修正履歴

この記事は参考になりましたか?

  • このエントリーをはてなブックマークに追加
Windows実行ファイル「EXE」の謎に迫る連載記事一覧

もっと読む

この記事の著者

山本 大祐(ヤマモト ダイスケ)

普段はActiveBasicと周辺ツールの開発を行っています。最近は諸先輩方を見習いながら勉強中の身。AB開発日記

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/412 2006/09/20 13:36

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング