実行可能ファイルの構造・補足

前回、説明していなかった部分があるので、それについて説明しておきます。


まず、前回もチラッと書いたことですが、リソースセクションの名前が ".rsrc" であると決めつけてはいけません。他の名前が付けられる可能性もあります。(HSP の実行ファイルのリソースセクションの名前は ".rsrc" なので、 HSP の実行ファイル専用のリソース書き換えを行なう分には問題ないのですが。)

そこで、実際のリソースセクションを探すには、オプションヘッダのデータディクショナリに含まれている情報を参照します。データディクショナリのインデックス 2 のエントリ(すなわち3番目のエントリ/オプションヘッダ先頭から112バイト目の位置)に、リソースデータの位置とサイズを示す IMAGE_SECTION_HEADER 構造体がある、というのは前回も述べたとおりです。

ところが、厄介なことがあります。それは、これが指し示す領域が、ある1つのセクションの領域と一致するとは限らない、ということです。どういうことかというと、リソースデータが含まれているセクションには、もしかしたら、リソース以外の何らかのデータが含まれているかも知れないのです。このような場合、データディクショナリが指し示すリソースの位置は、セクションデータの途中を指している可能性がありますし、リソースデータのサイズもセクションのサイズより小さくなってしまっています。ただし、ほとんどのコンパイラ・リンカでは、リソースデータだけのために1つのセクションを作成するので、それらで作成されたイメージファイルは( HSP の実行ファイルも)問題ないと思いますが。


もう1つ補足しておきます。

HSP でプログラムする場合はあまり関係ありませんが、 C/C++ でプログラムする場合には覚えておくと便利なことを教えておきます。 C/C++ を使わないという方は、読み飛ばしてくださって結構です。

Windows SDK のヘッダファイル WinNT.h には、 PE フォーマットに含まれるさまざまな構造体や定数、マクロが定義されています。

その中の1つに IMAGE_NT_HEADERS 構造体があります。この構造体は以下のように定義されています。

typedef struct _IMAGE_NT_HEADERS {
    DWORD                  Signature;
    IMAGE_FILE_HEADER      FileHeader;
    IMAGE_OPTIONAL_HEADER  OptionalHeader;
} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;

見てのとおり、この構造体は、 PE ファイル中で連続して存在するシグネチャ・ COFF ファイルヘッダ・オプションヘッダをまとめて定義したものです。この構造体のポインタにシグネチャのアドレスを格納することで、アクセスがより楽になるかと思います。

また、セクションテーブルに含まれる最初のセクションヘッダの位置を求めるには IMAGE_FIRST_SECTION マクロを使ってみましょう。

PIMAGE_NT_HEADERS  IMAGE_FIRST_SECTION( ntheader );

ntheaderIMAGE_NT_HEADERS 構造体のアドレス(すなわち、シグネチャのアドレス)を指定することで、最初の IMAGE_SECTION_HEADER 構造体のアドレスを得ることができます。