[英]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.