DLLを改造して関数を追加する時の注意点
DLLを改造して関数を追加する場合の注意事項です。
一見Dependency Walkerで正常なDLLに見えても動作しないことがあるので、調査してみました。
エクスポートテーブルは以下のようなフォーマットになっています。
エクスポートヘッダ |
関数エントリーアドレス |
関数名テーブル アドレス |
序数テーブル |
ランタイム名と関数テーブル |
オフセット | サイズ | 内容 |
+0000 | DWORD | 0 |
+0004 | DWORD | タイムスタンプ |
+0008 | DWORD | 0(バージョン情報?) |
+000C | DWORD | DLL名が格納されたアドレスを格納 |
+0010 | DWORD | 序数の開始値 |
+0014 | DWORD | 関数の数 |
+0018 | DWORD | 関数名の数 |
+001C | DWORD | 関数のエントリーアドレステーブルの アドレスを格納 |
+0020 | DWORD | 関数名へのポインタテーブルを格納 |
+0024 | DWORD | 関数の序数配列(WORD型)の テーブルアドレス |
関数を追加した後の注意事項として以下のものがあります。
この序数名テーブルがアルファベット順に並んでいる必要があり、
そうでない関数は GerProcAddress で失敗するという落とし穴が実は存在します。
PEヘッダのオフセット +007c にはこのエクスポートテーブルのサイズが含まれ、サイズを変更した時にはここも書き換える必要があります。
PEヘッダの後ろにある再配置テーブルのサイズが実際と異なっていると、ブルースクリーンで落っこちることがあります。
コードを空領域に追加した場合、コードセクションのサイズを増加させるのを忘れないように。
Comments