pop↑ push↓

☆ (ゝω・)v

64bitのdll injection メモ

はじめに

x64化にあたってDLLの技術を再調査しました。下記の記事の続きにあたると思ってください。

popush.hatenablog.com

DLLインジェクション

DLLインジェクションについての概要は参考1を参照のこと。EU4/CK2マルチバイト化ではexeディレクトリにカスタムしたd3d9.dllを置いて、インターセプトを実現している。 カスタムしたd3d9.dllを作るコードは下記にある。

EU4dll/d3d9 at master · matanki-saito/EU4dll · GitHub

このDLLはdefファイルを使ってDirect3DCreate9とDirect3DCreate9Exをエクスポートしている。

EU4dll/d3d9.def at master · matanki-saito/EU4dll · GitHub

その実態は__declspec(naked)された関数であり、インラインアセンブラのjmpによって本来のd3d9.dllの関数に転送される。

EU4dll/dllmain.cpp at cebec8e139b69d3fe0b4e4c461ffb541f36960e9 · matanki-saito/EU4dll · GitHub

この転送先となる関数だが、これはDLLを読み込んだ時(DllMain)に設定される。SHGetKnownFolderPathでd3d9.dllの場所を特定して、LoadLibraryで読み込み、その中からGetProcAddressで必要となる二つの関数(Direct3DCreate9とDirect3DCreate9Ex)を見つけている。

EU4dll/dllmain.cpp at cebec8e139b69d3fe0b4e4c461ffb541f36960e9 · matanki-saito/EU4dll · GitHub

これでインターセプトは完成するので、あとはDllMainで必要なdllを読んだりすればよい。

EU4dll/dllmain.cpp at cebec8e139b69d3fe0b4e4c461ffb541f36960e9 · matanki-saito/EU4dll · GitHub

x64における問題

x64ではdeclspec(naked)とasm(インラインアセンブラ)が使えない(参考2,3)。

解決法

__declspec(naked)とインラインアセンブラは消してしまうしかない。ただしアセンブラはasmファイルで記述可能である。asmにハイライトをつけるために、下記のプラグインを入れる。 marketplace.visualstudio.com

ビルドするプラットフォームをx64にしたら、参考2を見てmasmを使えるようにしておく。 f:id:saito-matanki:20190818042203p:plain

srcフォルダにhook.asmを作り、ビルドに含める。 f:id:saito-matanki:20190818042300p:plain

asmは後にして、dllmain.cppを先に修正する。asmから参照できるように参照する変数はextern "C" で囲む必要がある(参考4)。同様にasmに共有したい変数があれば入れておく。asmにあって呼び出す必要がある関数もこの中に入れておく。

f:id:saito-matanki:20190818043649p:plain

hook.asmも中身を作っていく。最初のSTRUCTはC++側にある定義と同じにする。構造体をasm側で読み込むために必要になる。

EXTERNを使って、C++側にある構造体と変数を読み込む。STRUCTを使えば構造体も読み込める。

.CODE以下はcodeセグメント。PUBLIC nameとname: を使うと関数を定義できるが、これは使わないでname proc ~ name endpを使うこと。なぜかPUBLICだとブレークポイントが有効にならない。

構造体は最初のSTRUCTにキャストして使う(参考5)

f:id:saito-matanki:20190818043914p:plain

こんな感じでやると、ブレークポイントを置いてdllをinjectionできるようになる(画像はHOI4にd3d9.dllをinjectionしたもの)。 f:id:saito-matanki:20190818044621p:plain

参考

  1. DLLインジェクション - Wikipedia
  2. VisualStudioでx64アセンブリを書き、実行する方法 - 備忘録

  3. naked (C++) | Microsoft Docs

  4. 名前修飾 - Wikipedia

  5. Struct Operations