DLLとローダ 〜暗黙的リンクと明示的リンク

DLLを触っている。

DLLからDLLを読み込もうとする場合、通常の方法でいける。ただし、DLLのロード場所によってはDLLの探索ディレクトリに含まれないため、DLLのロードができない場合が出てくる。

このDLLのロードの仕方には2つある。暗黙的リンクと明示的リンクという呼び名が存在する。

通常、暗黙的リンクを用いる。この場合、インポートライブラリ(LIB)をリンクする必要があるが、DLLのAPIを直接呼び出すことができる。暗黙的リンクの場合、実行時にDLLのパスを検索する。ロードできなければDLLが見つからないというメッセージと共に呼び出し元は終了する。

明示的リンクは、コード中、LoadLibraryを用いてDLLを呼び出す。LoadLibraryで得られたハンドルを使いGetProcAddressにて例えば”RegCreateKeyEx”を呼び出す。DLL内の限られたAPIだけを使用するのなら楽だが、多数のAPIを使用する場合はかなり面倒だ。

この明示的リンクの場合、実行時にDLLのパスを解決している必要はなく、プログラムの実行時にLoadLibraryに正しいパスを渡すことができれば、DLLの呼び出しを行うことができる。この性質のため、プラグイン作成のときに利用される。プラグインの場合は、指定ディレクトリ内にDLLが存在するかどうかを確認し、DLLが存在する場合に指定の関数を用いてアクセスする。

で、暗黙的リンクを使いたいのだが、DLL検索パスに含まれない場所からDLLを読みたい。が、それは無理なので以下の検索パスにDLLを配置することになる。

  1. 実行中のプロセスの実行形式モジュールがあるフォルダ
  2. 現在のフォルダ
  3. Windows システム フォルダ
  4. Windows ディレクトリ

よってプログラムのフォルダ(現在のフォルダ)にDLLを置かない場合、Windowsシステム フォルダにDLLをコピーする。これがインストーラがDLLをシステム フォルダにコピーする理由である。

このシステム フォルダへのコピーを行わせない場合、DLLを検索できない。またhookしたプログラムが別の場所にある場合、暗黙的リンクされたDLLをhookさせるDLLから読むことはできない。

これを解決するために、ある種のローダ、もしくは暗黙的DLLの検索パスの操作が必要になるが、本命はローダの設計である。

んで、いいのかなぁ。

カテゴリー: チラシの裏 パーマリンク

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください