underthevoid
underthevoid

Reputation: 513

How to use function pointers to call member functions from its memory address?

I'm developing a patch to an old application which the owners doesn't have the src code anymore.

I'm injecting a dll into the target application's .exe before its main(). This dll install the patches I did.

The application have a C++ custom type (class or struct) of what seems to be a drawing font manager which have functions that I need to call through some of these patches.

The way I usually call these "native" member functions is creating a wrapper function that calls the native member function through asm inline. I do this way because I can't find out how to accomplish this through C++ function pointers.

I'm trying again to accomplish this in a better way than creating a lot of bloated function wrappers. This time I'm trying to use a class/struct as a virtual wrapper of that native type, but it seems I'm missing something related to function pointer syntax that I can't figure out.

This is a sample of what I'm trying to do:

/* NC for Native Class */
class NC_FontDevice
{
public:
    typedef void(NC_FontDevice::*_UseTexturesTransparency)();

    _UseTexturesTransparency *UseTexturesTransparency = reinterpret_cast<_UseTexturesTransparency*>(0x635FD0);

private:
    NC_FontDevice(){}
};

NC_FontDevice* GetFontDevice()
{
    NC_FontDevice* lpFontDevice = nullptr;

    /* 
        This asm inline block is here to show more or less what I do in those wrappers I told.
        I know this can be converted to a simple function pointer.
    */
    __asm
    {
        mov eax, 0x0041FE10
        call eax
        mov lpFontDevice, eax
    }

    return lpFontDevice;
}

void foo()
{
    auto lpFontDevice = GetFontDevice();

    // Here I get and "identifier X is undefined"
    (lpFontDevice->**UseTexturesTransparency)();
}

In case it is clear what I want, is there a better way to accomplish it besides that function wrappers?

Thanks in advance.

Upvotes: 0

Views: 796

Answers (2)

MSalters
MSalters

Reputation: 179799

One of your problems is at least that your code doesn't match your question. You talk about function pointers, yet you write void(NC_FontDevice::*_UseTexturesTransparency)(). That is not a function pointer. That is a pointer to member function (PMF). Entirely different beasts, and you can't assume these are simple pointers. They're generally not even the same size.

I suspect that you've found a function at 0x635FD0. That function probably looks like void _UseTexturesTransparency(NC_FontDevice*). Sure, it might have been (part of) a member function when it was compiled, but that doesn't really matter. This is hacking, we're being pragmatic here. Why deal with the complexities of a PMF if we can treat this as an ordinary function pointer?

[edit] Per the comments, MSVC++ will have used ECX for the this argument in member functions; as it happens it also supports the __fastcall calling convention for regular functions which puts the first 32 bit argument in ECX. It's not a perfect replacement; __fastcall also uses EDX for its second argument. You might need a dummy argument there, if the existing code expects further arguments on the stack.

You can check for stack arguments because under the __thiscall calling convention for member functions, the callee cleans the stack. Luckily this matches the __fastcall convention.

Upvotes: 3

Pawel Brzezinski
Pawel Brzezinski

Reputation: 56

Have you thought of using std::bind and std::function instead ? C++11 and boost have it.

    std::function x = std::bind(&ClassName::function,this);

This will create a callback function which will work on your object.

Upvotes: 0

Related Questions