subhook icon indicating copy to clipboard operation
subhook copied to clipboard

[Question] Replace Class Function?

Open SvarunSoda opened this issue 1 year ago • 0 comments

I'm attempting to replace a C++ class function using this library.


I'm able to replace a standalone function as in the following example:

#include <iostream>
#include "subhook/subhook.h"

std::string TestFx() {return "TEST";}
std::string ReplaceFx() {return "REPLACED";}

subhook_t testHook;
subhook_flags_t testHookFlags;

int main() 
{
    std::cout << "Normal: " << TestFx() << "\n";
    
    testHook = subhook_new(&TestFx, &ReplaceFx, testHookFlags);
    subhook_install(testHook);
    std::cout << "Replaced: " << TestFx() << "\n";

    subhook_remove(testHook);
    std::cout << "Reverted: " << TestFx() << "\n";

    return 0;
}

Where I simply replace TestFx with ReplaceFx, and works without issues:

Normal: TEST
Replaced: REPLACED
Reverted: TEST

However, attempting to replace a class function is proving more difficult. It appears that I cannot simply supply a class function to the subhook_install function in the same manner.

Attempting the following example:

#include <iostream>
#include "subhook/subhook.h"

class TestClass
{
public:
    std::string TestFx() {return "TEST";}
};

std::string ReplaceFx() {return "REPLACED";}

subhook_t testHook;
subhook_flags_t testHookFlags;

int main() 
{
    TestClass* tc = new TestClass();
    std::cout << "Normal: " << tc->TestFx() << "\n";
    
    testHook = subhook_new(&TestClass::TestFx, &ReplaceFx, testHookFlags);
    subhook_install(testHook);
    std::cout << "Replaced: " << tc->TestFx() << "\n";

    subhook_remove(testHook);
    std::cout << "Reverted: " << tc->TestFx() << "\n";
    delete tc;

    return 0;
}

Results in:

E0167   argument of type "std::string (TestClass::*)()" is incompatible with parameter of type "void *"

Attempting to use reinterpret_cast to typecast TestClass::TestFx to void* results in:

E0171   invalid type conversion

As far as I understand, the reason for these errors is because pointers to class functions are often larger than pointers to standalone functions, hence they often times don't fit in a void* type.

However, it doesn't appear that subhook_install accepts anything other than void*, so I'm a bit confused as to how one would replace a class function using this method.


What is the proper way to replace a class function using this library?

Thanks for reading my post, any guidance is appreciated.

SvarunSoda avatar Apr 07 '24 06:04 SvarunSoda