1

こんにちはIDAで私は機能を持っています

void __userpurge Test(int a1<eax>, int a2, int a3, int a4, char a5)

そして、私は自分の C++ インジェクトされた dll からそれをフック/呼び出したいと思います。

DWORD CALL_ORIGINAL = 0x00EAF6D0;
__declspec(naked) void  myHookedFunc(int a1,int a2,int a3,int a4,char a5) {
    __asm
 {

    push a5
    push a4
    push a3
    push a2
    push eax
    call  CALL_ORGIGINAL //maybe use JMP?
    retn

   }
}

そして、これはexeがこの関数を呼び出す方法です

mov     eax, [ebp+arg_4]
add     esp, 8
push    eax
push    ecx
mov     ecx, [edi+2138h]
mov     edx, [ecx+4]
mov     ecx, [edx+30h]
mov     edx, [ecx]
mov     eax, esp
mov     [eax], edx
mov     eax, [edi+20h]
mov     [esp+40h+var_24], esp
push    eax
push    eax
mov     eax, edi
call    Test
pop     edi
pop     esi  
retn

機能に数回あるようです

add     esp, 24h
retn    10h

より多くの引数があること、または IDA が間違った引数の型を取得したことを意味するのはどちらでしょうか?

4

1 に答える 1

2

__userpurge__usercall関数は、呼び出し元がスタックのクリーンアップを担当することを除いて、 と同様の呼び出し規約を使用します。ただし、IDA に投稿した追加のコードを見ると、不適切な数のパラメーター不適切な呼び出し規則が提供されている可能性があります。call CALL_ORGIGINALの場所にブレークポイントを配置してこれを確認し、呼び出しの前後で ESP の値を監視することをお勧めします。返されたときに ESP が異なる場合はCALL_ORIGINAL、スタックをクリーンアップしているため、これ以上何もする必要はありません。スタックをクリーンアップする場合CALL_ORIGINALは、差を 4 で割ることによって、渡されたパラメーターの数を決定できる可能性があります (各パラメーターが 32 ビットであると仮定します)。

eaxもう 1 つの問題は、(編集に含まれる呼び出しコードによると) スタックにプッシュしないことです。この関数を呼び出す既存のコードは、最初のパラメーターをeax配置しますが、スタックにはプッシュしません。

質問のコードに基づいて、パラメーターの数が正しいと仮定すると、フック関数は次の例のようになります。

__declspec(naked) void  myHookedFunc(int a1,int a2,int a3,int a4,char a5) {
    __asm
 {

    push a5
    push a4
    push a3
    push a2
    // eax is not pushed onto the stack
    call CALL_ORGIGINAL
    retn
   }
}

呼び出し規約とパラメータの数が正しい場合、ESP はすべての前後で同じ値になるはずCALL_ORIGINALです。そうでない場合は、正しい呼び出し規約とパラメーターを決定するために、もう少し調査する必要があります。

要するに、自分で確認しない限り、IDAを決して信用しないでください。

于 2013-05-29T14:06:47.660 に答える