0

C++ でクラス メンバー関数をフックする方法を理解しようとしています。私はすでに vtable と通常の関数をフックしていますが、困惑しています。C 関数のフックに使用するのと同じ方法を使用して、関数の最初の 6 バイトを jmp 呼び出しで上書きしようとしています。__asm mov eax, class::methodを使用して、クラス関数のアドレスと思われるものを見つけることができます。取得したポインターを使用して関数を正常に呼び出すことができます。しかし、前述のメソッドで関数を編集し、クラスのインスタンスを作成し、メソッドを呼び出すと、フックされた関数が引き続き実行されます。しかし、eaxから取得したポイントから関数を呼び出すと、適切に他の関数に流用されます。どうすればこれを適切に達成できますか? ありがとうございました。

私のコード/出力:

struct HOOKHANDLE {
    DWORD addr;
    char origcode[6];
    BYTE jmp[6];
};

void hookFunc(void *detfunc,void *tarfunc,HOOKHANDLE *hh) {
    hh->addr = (DWORD)detfunc;

    hh->jmp[0] = 0xE9; //jmp
    hh->jmp[5] = 0xC3; //ret

    ReadProcessMemory((HANDLE)-1,(void*)hh->addr,hh->origcode,6,0);
    DWORD calc = (DWORD)tarfunc - hh->addr - 5;
    memcpy(&hh->jmp[1],&calc,4);
    WriteProcessMemory((HANDLE)-1,(void*)hh->addr,hh->jmp,6,0);
}

class test {
public:
    void meth1() {
        std::cout << "method 1\n";
    }
    void meth2() {
        std::cout << "method 2\n";
    }
};

int main() {
    test t;

    void *mfptr;
    void *tfptr;

    __asm {
        mov eax, test::meth1;
        mov mfptr, eax;

        mov eax, test::meth2;
        mov tfptr, eax;
    }

    std::cout << "t.meth1() : ";
    t.meth1();
    std::cout << "pointer   : ";
    ((void(*)())mfptr)();
    HOOKHANDLE mhh;
    hookFunc(mfptr,tfptr,&mhh);
    std::cout << "t.meth1() : ";
    t.meth1();
    std::cout << "pointer   : ";
    ((void(*)())mfptr)();

    system("pause");
    return 0;
}

出力:

t.meth1() : method 1
pointer   : method 1
t.meth1() : method 1
pointer   : method 2
Press any key to continue . . .

PS: 実際のシナリオでは this ポインターを関数に渡す必要があることはわかっていますが、フックを機能させた後は非常に簡単なはずです。

4

1 に答える 1

0

私の問題は、関数が自動的にインラインに設定されていたことです。そうでない場合、コードは完全に機能します。レイモンドとジェイソンに感謝します。

于 2012-12-28T12:51:25.510 に答える