3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PEファイルのバイナリ構造(3) IMAGE_NT_HEADERS

Posted at

IMAGE_NT_HEADERS

IMAGE_DOS_HEADERの後に配置されている構造体がこの「IMAGE_NT_HEADERS」となります。
上記のIMAGE_DOS_HEADERのe_lfanewメンバを使用してアクセスが可能です。
ちなみにImageNtHeader()という関数で参照することも可能ですが、今回はあえて低レベルな方法でアクセスしていきます。

IMAGE_NT_HEADERS& tNT = (*(IMAGE_NT_HEADERS*)&(pFile[tDOS.e_lfanew]));

こちらの構造体は具体的には以下の様な定義をされています。

typedef struct _IMAGE_NT_HEADERS {
  DWORD                 Signature;
  IMAGE_FILE_HEADER     FileHeader;
  IMAGE_OPTIONAL_HEADER OptionalHeader;
} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;
メンバ
Signature 固定の値「PE\0\0」が指定されている。IMAGE_NT_SIGNATUREとして定義。
FileHeader COFFファイル(.objファイル)のヘッダ形式。実行環境等が確認できる。
IMAGE_OPTIONAL_HEADER データ部分へのオフセットなどが登録されている構造体。

このIMAGE_NT_HEADERSですが、実は32bitと64bitでサイズが異なります。
通常はマクロで隠蔽されてしまっていますので意識しなくても良いのですが、今回は対象としているファイル側の環境に合わせる必要がありますので、チェックして対応してやる必要があります。
また今回はWindowsの実行ファイルの解析を目的としますので、この段階で対象のアーキテクチャなどを確認して絞り込みを行っておきます。

ちなみにIMAGE_FILE_HEADERまでは構造体のサイズは同じですので、最初はネイティブの構造体で読み込んでアーキテクチャを確認したところで32bitと64bitの処理を分岐させます。

以下は単純化したサンプルコードです。

IMAGE_NT_HEADERS& tNT = (*(IMAGE_NT_HEADERS*)&(pFile[tDOS.e_lfanew]));
if( tNT.FileHeader.Machine == IMAGE_FILE_MACHINE_I386 )
{
	IMAGE_NT_HEADERS32& tNT32 = (*(IMAGE_NT_HEADERS32*)&(pFile[tDOS.e_lfanew]));
	// 32bitバイナリ用の処理
}
else if( tNT.FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64 )
{
	IMAGE_NT_HEADERS64& tNT64 = (*(IMAGE_NT_HEADERS64*)&(pFile[tDOS.e_lfanew]));
	// 64bitバイナリ用の処理
}
else
{
	return false;
}

次はIMAGE_OPTIONAL_HEADERの解析を行います。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?