プログラマのつれづれなるままにプログラマのつれづれなるままに音宮志久が思ったことなどをネタにします。プログラムネタ・数学ネタがメインです。Windowsの実行ファイル形式(6)Windowsの実行ファイル形式(6)コメントを残すちょっとネタに詰まってきました。ゲーム系で私がわかるネタならかけるんですが・・・。ネタ募集中?にしておきます。今回はIMAGE_DIRECTORY_ENTRY_IMPORT(DLLのインポート情報)に関するネタです。この部分はEXEファイルやDLLファイルでも改造(というより乗っ取り)によく利用される部分なので知っておくと便利かもしれません。型名とメンバ名で記述しますが、使用するはじめの情報はIMAGE_NT_HEADERS.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]の部分です。このデータで示されたメモリ(あるいはファイルデータ)には外部のDLLを実行ファイルがどのように使用しているかを示すデータがあります。この部分で関連している構造体はこんなものです。定義は一部省略していたりする(unionを削ったりしている)ので完全に同じものではありません。IMAGE_THUNK_DATA;#endifIMAGE_IMPORT_DESCRIPTORの中で使用するメンバは次の3つくらいです。Nameこのインポート情報で読み込まれる外部DLLのDLL名へのアドレスがImageBase相対位置で示されます。このDLL名は必ずCHAR型(UNICODEではなくASCIIコード)で示されているのでLoadLibraryに渡すときは必要に応じて変換する必要があります。OriginalFirstThunkこのインポート情報で読み込まれる対象の外部DLLに存在すると思われるモジュール名へのアドレス(の先頭アドレス)がImageBase相対位置で示されるか序数そのものが示されます。この情報は下に記述するFirstThunkの情報と一対となっています。このデータが0であるとき、インポート情報はこのデータで終端であることを示します。このアドレスの先のデータはIMAGE_THUNK_DATAの配列の状態と同じです。FirstThunkOriginalFirstThunkが示しているモジュールの呼び出し先アドレスを保存するためのメモリ領域へのアドレス(の先頭アドレス)がImageBase相対位置で示されます。実行ファイルが外部DLLのモジュールを呼び出すときの踏み台となるアドレスの内部仮想メモリの保存場所になります。*)の配列の状態と同じです。そのほかの構造体の説明はちょっと省きます。なくわかりづらい説明ですが、実コードをみた方が早いでしょう。kernel32のLoadLibrary関数などでDLLを呼び出すときのアドレスの解決手順の内部動作(例)です。FALSE;}}}即席で作ったのでコードミスがあるかもしれませんが・・・。(1)の部分は読み込むべきDLL名がどこにあるのかを示しているので、ファイル上のこの位置の情報を書き換えるとDLLの読み取りを自分が指定したDLLで乗っ取れるようになります。(2)の部分はlpNameで示されたモジュールに対して呼び出すアドレスをこの動作で確定させている訳なので、この部分で別のアドレスを代入してやれば自分の思ったモジュールを呼び出すことができる(つまりモジュールを乗っ取れる)訳です。この辺の構造体の説明はあまりない(VisualStudioについてくるヘルプにはありませんでした)ので注意を。この記事を書いているときにちょっとwinnt.hをのぞきながら書いたわけですが、なんか便利な定義がうろうろしていますね・・・。書いている途中に定義を更新したくらいです・・・。気がつかなかった自分が悪いですが。次回は続きになるのか新しい記事のために充電するのかはよくわかりませんが。ここまでということで。コメントをキャンセルメールアドレスが公開されることはありません。気になるプログラムネタや数学ネタがあったら書き込みたいのだが残業が長すぎて眠気が全くとれず体調があまりよくない。過労などでぶっ倒れるかもしれない。あと、さすがに独り身が寂しいのでなんとかしたいと考えてはいるのだが...。アクセスカウンタアクセス数:スポンサーリンクモバイルバージョンに。