第 5 回。
今回は NT ヘッダーの末尾にある IMAGE_DATA_DIRECTORY についての概要編です。
IMAGE_DATA_DIRECTORY
typedef struct _IMAGE_DATA_DIRECTORY { DWORD VirtualAddress; DWORD Size; } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
単純な構造だと侮るなかれ。
ここまではヘッダーの解説でしたが、このデータ ディレクトリはデータ本体編への入口になるのです。
VirtualAddress
メモリ上にロードされた時に、このデータが置かれる位置を示します。
ロードされたイメージの先頭からの相対アドレスです。
Size
このデータのサイズです。
各データディレクトリの意味
IMAGE_OPTIONAL_HEADER の構造を抜粋して再掲します。
typedef struct _IMAGE_OPTIONAL_HEADER { // ... DWORD NumberOfRvaAndSizes; IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; } IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;
DataDirectory は IMAGE_DATA_DIRECTORY 構造体の配列です。
その要素数は IMAGE_NUMBEROF_DIRECTORY_ENTRIES で定義されます。この値は 16 です。
また、NumberOfRvaAndSizes も同じ値になります。
この配列は、その何番目の要素であるかによって、指す先の意味が決まっています。
名前は winnt.h 中で添字につけられた定数名です。
添字 | 名前 | 意味 |
---|---|---|
0 | IMAGE_DIRECTORY_ENTRY_EXPORT | エクスポート情報 |
1 | IMAGE_DIRECTORY_ENTRY_IMPORT | インポート情報 |
2 | IMAGE_DIRECTORY_ENTRY_RESOURCE | リソース |
3 | IMAGE_DIRECTORY_ENTRY_EXCEPTION | 例外情報 |
4 | IMAGE_DIRECTORY_ENTRY_SECURITY | セキュリティ情報 |
5 | IMAGE_DIRECTORY_ENTRY_BASERELOC | ベース再配置情報 |
6 | IMAGE_DIRECTORY_ENTRY_DEBUG | デバッグ情報 |
7 | IMAGE_DIRECTORY_ENTRY_ARCHITECTURE | アーキテクチャ固有の情報 |
8 | IMAGE_DIRECTORY_ENTRY_GLOBALPTR | グローバル ポインター |
9 | IMAGE_DIRECTORY_ENTRY_TLS | TLS(Thread Local Storage) |
10 | IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG | ロード構成情報 |
11 | IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT | バインドされたインポート情報 |
12 | IMAGE_DIRECTORY_ENTRY_IAT | インポート アドレス テーブル |
13 | IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT | 遅延インポート情報 |
14 | IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR | .NET メタデータ |
15 | (なし) | 予約 |
ImageDirectoryEntryToDataEx
ImageDirectoryEntryToDataEx 関数を使うと、PE ファイル中のデータ ディレクトリが指すデータの場所を取得することができます。
PVOID WINAPI ImageDirectoryEntryToDataEx( _In_ PVOID Base, _In_ BOOLEAN MappedAsImage, _In_ USHORT DirectoryEntry, _Out_ PULONG Size, _Out_opt_ PIMAGE_SECTION_HEADER *FoundHeader );
Base
対象の PE ファイルのメモリ上のアドレスです。
MappedAsImage
この PE ファイルが LoadLibrary 関数等でロードされている場合は TRUE、単にメモリマップドファイルとしてマップしただけだったり、ReadFile 関数等で読み込んでいる場合は FALSE を指定します。
DirectoryEntry
ディレクトリエントリの添字です。
上記の表の IMAGE_DIRECTORY_ENTRY_XXX を指定します。
Size
指定した領域のサイズが返されます。
IMAGE_DATA_DIRECTORY::Size の値です。
FoundHeader
指定した領域が含まれるセクションを指す IMAGE_SECTION_HEADER の情報が返されます。
戻り値
指定した領域のアドレスが返されます。