1

Why does the function not get hooked when called with instance member obj.myFunc() ?

class Myclass
{

public:
    virtual void myFunc() = 0;

};
class Derived : public Myclass
{
public:
    void myFunc()
    {
        std::cout << "Actual method is called" << std::endl;
    }
};

    void __fastcall hk_myFunc(void* thisPtr, int edx)
    {
        std::cout << "Hooked method is called" << std::endl;
    }

typedef void(__thiscall *fPtr)();

int main()
{
    Derived* ptr = new Derived();
    ptr->myFunc();// Output : Actual method is called.
    void** vTPtr = *(reinterpret_cast<void ***>(ptr));
    DWORD oldProtection;
    VirtualProtect(vTPtr, 4, PAGE_EXECUTE_READWRITE, &oldProtection);
    *vTPtr = reinterpret_cast<fPtr>(&hk_myFunc);
    VirtualProtect(vTPtr, 4, oldProtection, 0);
    ptr->myFunc(); //Output: Hooked method is called
    Derived obj = *ptr;
    obj.myFunc(); // Output : Actual method is called. Why ??
    return 0;
}
1
  • Have you tried disassembling the output and looking at the differences?
    – Milhous
    Jan 28, 2019 at 3:05

1 Answer 1

2

The problem is the way you reference this object with a new pointer.

Derived obj = *ptr;

This actually creates a new object utilizing the data of the old object. Yay! C++!

IDA Decompilation

In line 27 you can see that a new object is generated by calling a constructor. If you have a look at the disassembly, you'll see the vtable is not used for the function call. Hence you end up with the non-modified function.

disassembly

Btw, when you change the line referenced above to

(*ptr).myFunc();

The output works as expected

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.