2012-12-28 59 views
0

我想弄清楚如何在C++中挂钩类成员函数。我已经有了vtable和正常的函数挂钩,但我很难过。我正在尝试使用与C函数挂钩相同的方法,用jmp调用覆盖函数的前6个字节。我能够找到我认为是类功能的地址__asm mov eax,class :: method。我能够使用获得的指针成功调用函数。但是,当我用上述方法编辑函数时,创建一个类的实例,并调用它仍然运行挂钩函数的方法。但是当我从eax获得的指针调用函数时,它恰当地转向了另一个函数。我不知所措,我该如何做到这一点呢?谢谢。在C++中挂钩非虚拟成员函数

我的代码/输出:

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:我知道我必须通过这个函数指针在真实的情景,但应该是挂钩工作后很容易。

+0

我甚至都不知道这是如何工作的,因为你没有调用'VirtualProtect'来使内存可写。你确定这是所有的代码? –

+0

你确定这个功能没有被内联? – JasonD

+3

你的钩子没有效果,因为'test'类方法被隐式声明为'inline'。 –

回答

0

我的问题是我的功能被自动设置为内联。如果情况并非如此,代码完美无缺。谢谢Raymond & Jason。