我试图绕过应用程序中的某个功能。我有它的来源。
class Foot : public Something, public SomethingElse {
public:
Foot( double SomethingAgain, double Somethings,
Blahblah *AnotherThing = NULL );
virtual ~Foot();
virtual void detourmepls( const char *ARGUMENT );
};
这是在头文件中定义的方式。
这是我用来定义它的所以我会用正确的地址从我的dll调用它。
void (__cdecl* detourmepls)(const char *stuff);
这个虚拟空函数的真正调用约定是什么?
感谢任何帮助。
新编辑和信息:
我正在使用MS Detours 1.5
detourmepls = (void(__thiscall*)(void *Pthis,void *Unknown,const char *))DetourFunction((PBYTE)ADDRESS, (PBYTE)hookedFunction);
这就是我尝试绕行的原因(它非常混乱。)
答案 0 :(得分:0)
<强>背景强>
使用虚函数的回调需要'this'对象来解析虚函数。虚函数指针实际上更像是一个vtable“offset”(在存在多个虚拟双重秘密继承的情况下非常多毛;)。
__ cdecl不支持其中任何一项。
您注册回调的API是什么样的?听起来像是一个C-api。这些有时会带来空白*。如果没有,那么你需要将对象存储在其他地方。
回调仅限功能,无数据
如果它只是一个回调函数,而且没有用户数据,则需要将对象指针单独存储在您的一侧,并在静态函数中解析虚函数调用,这是您注册的函数。
void registerCallback(void (__cdecl* callbackfn)(const char* stuff));
class Foo {
static Foo* s_callback_object;
~Foo() {
// never hurts
if (this == s_callback_object)
s_callback_object = 0;
}
static void Foo::callbackResolver(const char* stuff) {
assert(s_callback_object);
s_callback_object->detourmepls(stuff);
}
}
Fop* foo::s_callback_object = 0;
Foo myFoo;
Foo::s_callback_object = &myFoo;
registerCallback(&Foo::callBackResolver);
使用用户数据的回调函数arg:
(这是应该如何做的,伙计们)
对于案例2,用户数据,您可以将其转换为您的对象:
void registerCallback(void (__cdecl* callbackfn)(const char* stuff),
void *userdata);
class Foo {
static void Foo::callbackResolver(const char* stuff, void *userdata) {
Foo* foo = reinterpret_cast<Foo*>(userdata);
foo->detourmepls(stuff);
}
}
Foo myFoo;
registerCallBack(&Foo::callbackResolver, &myFoo);
后一种方案即使在普通的C编程中也非常有用,所以如果你自己做API,就这样做吧。 :)