对于非类函数 - 我可以简单地声明函数的偏移量,如:
typedef int (_cdecl* SomeFunc)(char* pBuffer, int size);
SomeFunc Real_SomeFunc = (SomeFunc)(0xCAFEBABE);
...
DetourAttach(&(PVOID&)Real_SomeFunc, (PVOID)Hook_SomeFunc);
现在,这对于类的绕行成员函数变得困难 - 绕道有一个样本:
镜像:https://trac.netvor.sk/umage/browser/dllinject/detours/samples/member.cpp?rev=23
该示例已经定义了目标成员函数 - 但是我不知道二进制文件中我的DLL注入的偏移量 - 所以我该如何转换它
void (CDetour::* CDetour::Real_Target)(void) =
(void (CDetour::*)(void))&CMember::Target;
这样的事情:
void (CDetour::* CDetour::Real_Target)(void) =
(void (CDetour::*)(void))0xCAFEBABE;
我在这里收到编译错误
任何提示?
答案 0 :(得分:0)
哦,嘿,一个带有我的东西链接的老问题! (遗憾的是,它现在只是svn.netvor.sk。)
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);
现在,这显然不会在真正复杂的代码中工作,但我认为它足以在钩子中调用原始代码。已经有一段时间了,因为我必须在成员函数指针上使用它。