简体   繁体   中英

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.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM