ステップゼロ;注入されたDLLにはエントリポイントが必要です。Init()
を呼び出すと、LPCWSTR
が単一のパラメータとして使用され、int
が返されます。つまり、LoadLibrary()
と同じシグネチャであり、スレッド開始機能アドレスとしても同様に有効です。
ステップ1;ロードライブラリとリモートスレッドを使用して注入します。注入されたDLLで何も巧妙にしないでくださいDLLMain()
。注入スレッドの終了コードとして返されたHMODULE
を格納します。これは注入されたDLLのHMODULE
で戻り値はLoadLibrary()
です。
のx64上のHMODULE
がGetThreadExitCode()
から返さDWORD
値よりも大きく、アドレス空間の変化が意味するよう/DYNAMICBASE
とASLR(アドレス空間配置のランダム化)が有効になっている場合、これはもはやx64の上で信頼性の高いアプローチであることに注意してくださいHMODULE
の値がDWORD
に入るのに十分小さい可能性はもはやなくなっています。共有メモリを使用して通信するための作業については、以下のコメントとリンクされた質問(こちら)を参照してください。HMODULE
ステップ2;注入を行っているプロセスにLoadLibraryを使用して注入されたDLLをロードします。その後、アドレス空間にInit()
のエントリポイントのオフセットを見つけて、そこからアドレス空間に注入されたDLLのHMODULE
を引きます。これで、Init()
関数の相対オフセットが得られました。ターゲットプロセス(すなわち、ステップ1で保存した値)に注入されたDLLのHMODULE
をとり、それにInit()
の相対アドレスを追加します。ターゲットプロセスにInit()
というアドレスが設定されました。
ステップ3; LoadLibrary()
を呼び出すのと同じ「リモートスレッド」アプローチを使用して、ターゲットプロセスにInit()
を呼び出します。文字列をInit()呼び出しに渡すことができます。これはあなたが気に入っているものであれば何でも構いません。
私がする傾向があるのは、名前付きパイプ名の一部として使用する一意の文字列キーを渡すことです。 Injected DLLと注入プロセスは、名前付きパイプの名前を知っているので、それらの間で通信することができます。 Init()
関数はDLLMain()
ではなく、DLLMain()
(LoadLibrary
などから呼び出されていない)に影響する制限を受けず、通常の処理を行うことができます。注入されたDLLと注入プロセスが名前付きパイプを介して接続されると、コマンドやデータの結果を好きなように前後に渡すことができます。 Init()
関数を文字列に渡すので、名前付きパイプがこの特定のインスタンスのインジェクションプロセスとこの特定のインジェクションされたDLLに対して一意であることを確認できます。つまり、インジェクションプロセスの複数のインスタンスを同時に実行でき、複数のターゲットプロセスに注入することができ、これらの通信チャネルはすべてユニークで制御可能です。
CreateRemoteThread(...、dllExportAddrInRemoteProcess、stringBuffer、...)に文字列を渡すと、(WriteProcessMemoryなしで)どのように動作するのかわかりません。しかし、両方のプロセスでは、注入されたスレッドのプロセスIDとスレッドIDを知っているので、IPCで使用されている名前の一部として使用できます。 – Anders
はい、WriteProcessMemory()はLoadLibrary()と同じ方法で使用します。私はあなたが他の手段でユニークなIDをファッジすることに同意しますが、制限のためにDLLMain()で行うことができない初期化を行うために、DLLMain()以外のものを呼び出す必要があります。 –
終了コードのタイプはDWORDです - 32ビットの符号なしint値、プロセスが64ビットであればHMODULEを取得する方法は? – amanjiang