我有一个函数驻留在应用程序的类中,我的目标是将一个dll注入目标进程并通过其地址调用该成员函数。 这是功能:
void GameAudio::StopAllSounds(void) // this is at address 0x004A0656
我试过这样称呼它
typedef void(__stdcall * caller)(void);
caller call = (caller)0x004A0656;
我已经使用了所有内容:__stdcall
,__cdecl
,__thiscall
。
答案 0 :(得分:1)
类的非static
成员函数签名与普通函数不同。
例如,
class X {
public:
void foo ();
};
void foo ();
在上述情况下,X::foo()
和::foo()
彼此不同。请记住,引擎盖下的X::foo()
有点像:
void X::foo (X* const this);
^^^^^ implicitly added
因此,您尝试执行的操作会导致未定义的行为。
如果您坚持使用其地址调用成员函数,那么最好使其成为static
成员函数。
class X {
public:
static void foo ();
};
void foo ();
X::foo()
和::foo()
的签名相同。
修改:从您的评论中,您似乎无法控制源代码。我建议使用正确的函数签名调用约定而不是硬编码地址。伪代码
typedef void (GameAudio::*caller_type)();
caller_type caller = &GameAudio::StopAllSounds;
GameAudio object;
(object.*caller)();
答案 1 :(得分:1)
C ++中没有您正在做的语法。 请注意,该功能甚至可能是虚拟的,因此您将调用错误的函数。
最简单的方法是使用额外的GameAudio*
参数将其更改/添加到/添加非成员函数或静态成员函数。可以使用指向指针的函数轻松调用该函数。
如果您仍想直接调用成员函数,最好的选择可能是使用汇编程序。问题在于可移植性:您的解决方案将取决于编译器,SO,架构甚至ABI版本。