私は回り道を使用しません (私は実際にそれを嫌っています!) が、ホット パッチが適用できない関数を迂回することは、次のように一般的な方法で行うことができます。
ステップ 1:JMP <your code>
関数の先頭に a を挿入します。5 バイトかかります。最も近い命令に合わせるには、おそらくもう少しかかります。例として
フックする関数の開始:
SUB ESP,3C
PUSH EDI
PUSH ESI
//more code
次のようになります。
JMP MyFunction
//more code
これを行う0xE9
には、最初のバイトに書き込み、次に(function_addr - patch_addr + sizeof(INT_PTR))
続く DWORD に値を書き込みます。WriteProcessMemory
で読み取り/書き込み/実行権限を設定した後、書き込みを行う必要がありますVirtualProtectEx
ステップ 2: 次に、アセンブリ インターフェイスを作成します。
void __declspec(naked) MyFunc()
{
__asm
{
call Check ;call out filter func
test eax,eax ; test if we let the call through
je _EXIT
sub esp,3c ; its gone through, so we replicate what we overwrote
push edi
push esi
jmp NextExecutionAddress ; now we jump back to the location just after our jump
_EXIT:
retn ; note, this must have the correct stack cleanup
}
}
NextExecutionAddress は、実行時に を使用して入力する必要がありますModuleBase + RVA
。
正直なところ、EAT (Export Address Table) で dll のエクスポート テーブルをフックするか、IAT (Import Address Table) でフィルタしたい funcs を呼び出すもののインポート テーブルをフックする方が簡単で、優れています (!)。回り道には、これらのタイプのフック用の関数が必要です。そうでない場合は、それを行うための自由に利用できる他のライブラリがあります。
もう 1 つの方法は、迂回を使用して、dll を使用してアプリ内のすべての呼び出しをフックし、それらを独自のコードのプロキシ関数に再ルーティングすることです。これには、バイナリ全体のすべてではなく、特定の呼び出しのみをフィルター処理できるという利点があります(を使用して同じことを行うことは可能ですが、それは_ReturnAddress
より多くの作業です)、欠点はパッチを適用する場所をキャプチャすることです (私は ollydbg + カスタム パッチ エンジンを使用します)。 Watcom で作成#pragma aux
されたもの、または VC7+ によって生成された最適化された呼び出し)。
1 つの重要な注意事項: マルチスレッド アプリをフックする場合、アプリを中断してパッチを適用するか、またはアトミックに を使用する必要がありますInterlockedExchange
(InterlockExchange64
私InterlockedExchangePointer
はすべての IAT/EAT フックに後者を使用します。パーティープロセス」)
リンク先の投稿を見ると、私の意見では、主にアセンブリが原因で、そこにあるメソッドは恐ろしいものです:Pしかし、取得したこのポインターをどのように呼び出し、どのように取得しますか?