获取成员函数的内存地址

Get memory address of member function?

本文关键字:内存 地址 函数 成员 获取      更新时间:2023-10-16

如何在c++中获得成员函数的绝对地址?(我需要这个来思考。)

成员函数指针不起作用,因为我不能将它们转换为绝对地址(void *)——我需要知道内存中实际函数的地址,而不仅仅是相对于类型的地址。

在MSVC中存在一种语法来获取成员函数的地址(从MSVC 2005开始)。但这很棘手。此外,无法通过常规方法将获得的指针强制转换为其他指针类型。尽管存在一种方法可以做到这一点。

示例如下:

// 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并不强烈推荐这种强制转换。

然而你可以这样做。当然,这是完全依赖于实现的,您必须知道适当的调用约定来进行思考+具有适当的汇编技能。

试试这个。应该允许你将任意值转换为任意值:)

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);

默认情况下,c++成员函数使用__thiscall调用公约。为了绕行一个成员函数,既蹦床绕行必须有完全相同的呼叫约定目标函数。不幸的是,VC编译器不支持因此,创建合法的detour和trampoline函数的唯一方法是使它们成为"detour"类的类成员。

此外,c++不支持将指针转换为成员函数指向任意指针。获取原始指针,即地址的成员函数必须移动到临时成员函数中 幸运的是,编译器将优化代码以删除额外的内容指针操作。

来自Microsoft Detour库。他们处理代码注入,并讨论获取非虚成员函数的地址。当然,这是编译器实现特定的东西。

你可以在这里找到这个库http://research.microsoft.com/en-us/downloads/d36340fb-4d3c-4ddd-bf5b-1db25d03713d/default.aspx

对于仍然在寻找获得函数的内存地址(而不是跳转)的答案的人来说,这是我的解决方案:

UINT32 RelativityToTrampoline = *(UINT32*)((UINT64)&Func + 1);
UINT64 RealFuncAddr = (UINT64)&Func + RelativityToTrampoline + 5;