0
votes

I am trying to figure out how to hook class member functions in C++. I have already got vtable and normal function hooking down, but I'm stumped. I am trying to use the same method I use for C function hooking, overwriting the first 6 bytes of the function with a jmp call. I am able to find what I think is the address of the class function with __asm mov eax, class::method. I am able to use the pointer obtained to call the function successfully. But when I edit the function with the aforementioned method, create an instance of the class, and call the method it still runs the hooked function. But when I call the function from the pointed obtained from eax it properly is diverted to the other function. I am at a loss, how can I accomplish this properly? Thank you.

My code/output:

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;
}

output:

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

PS: I know that I will have to pass the this pointer to the function in a real scenario, but that should be quite easy after I get the hook working.

1
I don't even understand how this is working since you are not calling VirtualProtect to make the memory writable. Are you sure this is all the code? - Mike Kwan
Are you sure the function has not been inlined? - JasonD
Your hooks have no effect because the test class methods are implicitly declared as inline. - Raymond Chen
I wonder why someone ever would want to do that. - Bartek Banachewicz
That is what I thought was happening. I suppose the real question is how do I get the memory location of a specific instance's method? void(test::* tt)() = &t.meth1; doesn't work. - Hacktank

1 Answers

0
votes

My problem was that my functions were being automatically set to inline. The code works perfectly when this is not the case. Thank you Raymond & Jason.