2

对于非类函数 - 我可以简单地声明要绕行的函数的偏移量,例如:

typedef int (_cdecl* SomeFunc)(char* pBuffer, int size);

SomeFunc Real_SomeFunc = (SomeFunc)(0xCAFEBABE);

...

DetourAttach(&(PVOID&)Real_SomeFunc, (PVOID)Hook_SomeFunc); 

现在,绕行类的成员函数变得很困难 - detours 有一个示例:

https://github.com/microsoft/Detours/blob/master/samples/member/member.cpp

该示例已经定义了目标成员函数 - 但我不只知道将我的 DLL 注入的二进制文件中的偏移量 - 那么我该如何转换它

void (CDetour::* CDetour::Real_Target)(void) = 
    (void (CDetour::*)(void))&CMember::Target;

像这样:

void (CDetour::* CDetour::Real_Target)(void) = 
    (void (CDetour::*)(void))0xCAFEBABE;

我在这里遇到编译错误

有什么提示吗?

4

1 回答 1

1
void (CDetour::* CDetour::Real_Target)(void) = (void (CDetour::*)(void))0xCAFEBABE;

我在这里遇到编译错误

具体来说,就是error C2440: 'type cast' : cannot convert from 'unsigned int' to 'void (__thiscall CDetour::* )(void). There are no conversions from integral values to pointer-to-member values。转换为成员指针是一件不平凡的事情——它们可能是也可能不是简单的内存地址,具体取决于成员函数的类型和类层次结构的复杂性。多重虚拟继承给这个伪数据结构增加了额外的字段;除了代码地址之外,还有重新定位信息。此数据的格式是特定于编译器的。

出于我的目的,我使用这个特定于 MSVC 的宏:

/// Void pointer to Func pointer.
/// Assumes first four bytes should hold the address and rest be zero.
template<typename T> T VTOF(void* ptr)
{// fills in 4 bytes and zeroes the rest
    T result = 0;
    *(void**)&result = ptr;
    return result;
}

用法:ptr = VTOF<void (CDetour::*)(void)>((void*)0xCAFEBABE); 现在,这显然不适用于真正的复杂代码,但我认为它足以在挂钩中调用原始代码。自从我不得不在成员函数指针上使用它已经有一段时间了。

于 2018-06-01T16:44:26.557 回答