1

この掲示板での最初の質問で、すでにかなり長い質問です。申し訳ありません (そして、このプラットフォームから得た素晴らしいヒントに感謝します)。

Microsoft Detours を使用して複数の関数をフックしようとしています (多かれ少なかれプラグイン コードであるため、フックしたい関数は記述されていません/変更できませんが、同じプロセス/スレッドで直接アクセスできます)。

フックされるすべての関数は、C スタイルのコンパイラによって生成され、常に次のアセンブラ「スタートアップ」コードを持ちます。

045A1A85  push        ebp  
045A1A86  push        ebx  
045A1A87  push        esi  
045A1A88  push        edi  
045A1A89  call        045A1A8E  
045A1A8E  pop         eax  
045A1A8F  mov         ebx,eax  
//go on with a little bit more assembler code

いくつかのレジスタがスタックにプッシュされ、call 命令が次の行に呼び出されるのがわかります (既に述べたように、この生成されたコードにアクセスできないため、これを変更しないでください)。call 命令はスタックを変更します - このスタックの変更は eax レジスタに保存され、以降の処理に使用されます (!!!)

このメソッドは以下にフックされます。

045A1A85  jmp         hooking_function (528040h)  
045A1A8A  int         3  
045A1A8B  int         3  
045A1A8C  int         3  
045A1A8D  int         3  
045A1A8E  pop         eax  

フッキング関数は、トランポリン関数にジャンプするだけのネイキッド関数として定義されています。

__inline __declspec(naked) void hooking_function()
{
    //more code in future
    __asm {
        jmp org_func_trampoline
    }
}

次のトランポリン機能を使用:

031F0060  push        ebp  
031F0061  push        ebx  
031F0062  push        esi  
031F0063  push        edi  
031F0064  call        045A1A8E  
031F0069  jmp         045A1A8E  

主な問題は、トランポリン アセンブラ コードの call 命令が 1) スタックに間違った値を追加することです (この場合は 045A1A89 ではなく 031f0064 に) --> eax でさらに処理すると間違った結果が返されます 2) 多かれ少なかれ破棄されます次の「ret」が「031F0069」に戻るため、スタック フレーム ==> 同じ処理が 2 回行われます。ret は再び呼び出され、間違った機能につながります..

フックしたいすべての関数が上記のプリアンブルで始まることが保証されていないことを理解してください..したがって、フック関数を書き直すことはできず、トランポリンメソッドを無視することはできません...

したがって、このすべてのテキストの後の基本的な質問: Microsoft Detour を使用して関数をフックすることは可能ですか?関数の最初の 5 バイトで呼び出し命令が呼び出されますか? (そうでない場合、代替手段はありますか?)

読んでいただきありがとうございます(そして、うまくいけばあなたの助けに)

4

1 に答える 1

1

元のコードが実行されます

045A1A89  call        045A1A8E  
045A1A8E  pop         eax  

これは、eipレジスタの内容を取得する簡単な方法です。はpop eaxすぐにリターン アドレス ( 045A1A8E) をスタックから削除し、実行時に の値に設定eaxし ます。eip

Detours は明らかにこれを知る方法がなく、それをサブルーチンのように扱いcall 045A1A8Eます。eaxeip

に戻る理由が完全にはわかりません031F0069。投稿したコードを読んでも、そうすべきではありません。

そうです、これは非常に特殊なケースです。Detours は通常、最初のいくつかの命令の間に呼び出しがある関数を完全にフックできます。これは、Detoursが不利な方法でそれらを分割するために、これら2つの指示を完全に配置することに成功しました。

于 2011-08-16T01:41:22.703 に答える