繁体   English   中英

如何使用函数指针从其内存地址调用成员函数?

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

我正在为旧应用程序开发补丁,该应用程序的所有者不再拥有src代码。

我在其main()之前将dll注入到目标应用程序的.exe中。 这个dll安装了我做的补丁。

该应用程序具有C ++自定义类型(类或结构),似乎是图形字体管理器,具有一些我需要通过其中一些补丁调用的功能。

我通常称这些“本机”成员函数的方式是创建一个包装函数,该函数通过asm内联调用本机成员函数。 我这样做是因为我无法找到如何通过C ++函数指针来完成此操作。

与创建许多肿的函数包装器相比,我再次尝试以更好的方式完成此任务。 这次,我尝试使用类/结构作为该本机类型的虚拟包装器,但是似乎缺少与我无法弄清的函数指针语法相关的内容。

这是我正在尝试做的一个示例:

/* 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)();
}

如果很清楚我想要什么,除了该函数包装器之外,还有更好的方法吗?

提前致谢。

您的问题之一至少是您的代码与您的问题不匹配。 您谈论的是函数指针,但您编写的是void(NC_FontDevice::*_UseTexturesTransparency)() 不是函数指针。 这是指向成员函数(PMF)的指针。 完全不同的野兽,您不能假设它们是简单的指针。 它们通常甚至都不相同。

我怀疑您在0x635FD0处找到了一个函数。 该函数可能看起来像void _UseTexturesTransparency(NC_FontDevice*) 当然,在编译时它可能是成员函数的一部分,但这并不重要。 这是黑客行为,我们在这里很实用。 如果我们可以将它视为普通的函数指针,为什么还要处理PMF的复杂性呢?

[edit]根据注释,MSVC ++将在成员函数中使用ECX作为this参数。 碰巧的是,它还支持常规函数的__fastcall调用约定,该约定将前32位参数放入ECX 这不是一个完美的替代品。 __fastcall还使用EDX作为第二个参数。 如果现有代码在堆栈上需要其他参数,则可能需要在其中使用虚拟参数。

您可以检查堆栈参数,因为在成员函数的__thiscall调用约定下,被调用方将清理堆栈。 幸运的是,这与__fastcall约定匹配。

您是否考虑过使用std :: bind和std :: function代替? C ++ 11和boost有它。

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

这将创建一个对您的对象起作用的回调函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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