如何在C ++中获取成员函数的绝对地址? (我需要这个来进行捶击。)
成员函数指针不起作用,因为我无法将它们转换为绝对地址(void *
) - 我需要知道内存中实际函数的地址,而不仅仅是相对于类型的地址
答案 0 :(得分:25)
存在一种语法来获取MSVC中的成员函数的地址(从MSVC 2005 IMHO开始)。但这很棘手。而且,所获得的指针不可能通过传统方式转换为其他指针类型。尽管如此,仍然有办法做到这一点。
以下是示例:
// class declaration
class MyClass
{
public:
void Func();
void Func(int a, int b);
};
// get the pointer to the member function
void (__thiscall MyClass::* pFunc)(int, int) = &MyClass::Func;
// naive pointer cast
void* pPtr = (void*) pFunc; // oops! this doesn't compile!
// another try
void* pPtr = reinterpret_cast<void*>(pFunc); // Damn! Still doesn't compile (why?!)
// tricky cast
void* pPtr = (void*&) pFunc; // this works
即使使用reinterpret_cast
,传统演员也不起作用的事实可能意味着MS不会非常强烈推荐这种演员。
尽管如此,你可以这样做。当然这是所有依赖于实现的,你必须知道适当的调用约定来进行thunking +具有适当的汇编技能。
答案 1 :(得分:4)
试试这个。应该让你投入任何东西:)
template<typename OUT, typename IN>
OUT ForceCast( IN in )
{
union
{
IN in;
OUT out;
}
u = { in };
return u.out;
};
然后
void* member_address = ForceCast<void*>(&SomeClass::SomeMethod);
答案 2 :(得分:2)
来自Microsoft Detour库的默认情况下,C ++成员函数使用__thiscall调用 惯例。为了绕道一个成员的功能,两个蹦床 并且绕行必须具有完全相同的调用约定 目标函数。不幸的是,VC编译器不支持 __这个呼叫,所以创建合法的绕道和蹦床功能的唯一方法是让他们成为“绕道”班的班级成员。
此外,C ++不支持将指针转换为成员 函数到任意指针。 获取原始指针,地址 必须将成员函数移动到临时成员函数中 指针,然后通过获取它的地址,然后取消引用它。 幸运的是,编译器将优化代码以删除额外的代码 指针操作。
。他们处理代码注入并讨论获取非虚拟成员函数的地址。当然它是特定于编译器实现的东西。
您可以在http://research.microsoft.com/en-us/downloads/d36340fb-4d3c-4ddd-bf5b-1db25d03713d/default.aspx
找到图书馆答案 3 :(得分:0)
对于仍在寻找获取函数的内存地址(而不是跳转)的答案的人,这是我的解决方案:
UINT32 RelativityToTrampoline = *(UINT32*)((UINT64)&Func + 1);
UINT64 RealFuncAddr = (UINT64)&Func + RelativityToTrampoline + 5;