PEフォーマットについて~DLLのExport/Importを列挙~


前回PEフォーマットについて概要を説明したので、今回はその情報にアクセスしてDLLのExport/Importしている情報を列挙してみようと思います。

まずは、IMAGE_DATA_DIRECTORY配列にアクセスしてIMAGE_EXPORT_DIRECTORYや IMAGE_IMPORT_DESCRIPTOR配列の位置を求める必要があります。

DLLがExportしている関数一覧

IMAGE_EXPORT_DIRECTORY配列は以下のような構造体です.

この構造体の情報から、関数名や関数のアドレス情報といったものにアクセスすることが出来ます。AddressOf*** というメンバがRVA単位で各データへのポインタを持っています。これらの関係性を図示すると以下のようになります。

pe-format-export-list

これらの情報からDLLがエクスポートしている関数の一覧を出すコードは以下のようになります。下記のコードではLoadLibrary関数が返すモジュールハンドルがDLLのベースアドレスとなる点を利用してデータ構造にアクセスしています。ファイルから処理する場合には、この部分をファイルから読み込んだデータのバッファ先頭とすればよいです。

実行結果はこんな感じになります。

IMAGE_EXPORT_DIRECTORY
 Name=KERNEL32.dll
 Base=00000001
 NumberOfFunctions = 1364
 NumberOfNames = 1364
 AddressOfFunctions = RVA:000BFA28 (7538FA28)
 AddressOfNames     = RVA:000C0F78 (75390F78)
 AddressOfNameOrdinals = RVA:000C24C8
ExportFunctions
  0 [00013358] AcquireSRWLockExclusive 
  1 [000C9E34] AcquireSRWLockShared 
  2 [000C98B5] ActivateActCtx 
  3 [000C98D6] AddAtomA 

   (省略)

  1359 [000218CA] lstrcpynA 
  1360 [0003D4F6] lstrcpynW 
  1361 [000159EB] lstrlen 
  1362 [000159EB] lstrlenA 
  1363 [000116D0] lstrlenW 

DLLがImportしているDLL一覧

今度は逆にDLLが依存している他のDLLへの情報についてリストアップしてみます。使用する構造体は IMAGE_IMPORT_DESCRIPTOR です。これもまたOptionalHeaderから辿ることが出来ますが、プログラム上ではimagehlpのユーティリティを使って取得してしまいます。この構造体は以下のような形をしています。この構造体が複数個繋がって、依存するDLLの情報を表現しています。

pe-format-import-list

個数が明示的に記録されているのではなく、Characteristicsメンバが0となるとき終端を意味する構造となっています。この構造体のNameメンバがRVA単位で依存するDLLの名前を示しています。
これにアクセスしてリストアップするコードを以下に示します。

実行結果はこのようになります。自作の適当なDLLを読み込ませてみました(しかもデバッグ版)。単純に加算関数しか実装していないので最低限度の依存になっています。

DLL Dependency
KERNEL32.dll
MSVCR110D.dll

さらに依存する関数そのものにアクセスする場合には、FirstThunkメンバを参照して関数のリストを取得します。DLLエクスポート転送が使用される場合には ForwarderChainメンバが有効な値になるようですが、実際にはどうなるか今のところ確認していません。今後の課題ということで今回は保留にしておきます。

スポンサーリンク

シェアする

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

フォローする