【问题标题】:How to call member functions from their address如何从其地址调用成员函数
【发布时间】:2012-02-12 11:43:16
【问题描述】:

我有一个驻留在应用程序类中的函数,我的目标是将 dll 注入目标进程并通过其地址调用该成员函数。 这是函数:

void GameAudio::StopAllSounds(void) // this is at address 0x004A0656

我试过这样称呼它

typedef void(__stdcall * caller)(void);
caller call = (caller)0x004A0656;

我已经使用了所有东西:__stdcall__cdecl__thiscall 你说的。

【问题讨论】:

  • 你确定它总是同一个地址吗??
  • 当你尝试调用它时会发生什么?您是否尝试过在调试器中单步执行调用?还要记住,所有类成员函数都有一个隐含的this 参数。
  • 当我尝试调用它时它只是崩溃
  • @user1205008 - 如果您使用 C++ 语言中提供的各种技术以及良好的设计,则无需通过地址调用成员函数。改为使用覆盖和虚拟成员。
  • 您必须了解应用程序使用的 C++ ABI。不幸的是,这是一个非常不可移植的主题,它可能与所使用的编译器 version 一样多。你必须以某种方式传递一个实例指针,但唯一准确的规范是如何做到这一点的是 ABI。

标签: c++ member-function-pointers member-functions


【解决方案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)();

【讨论】:

  • 是的,但您必须记住,此函数位于我没有源代码的应用程序中,因此我无法将函数更改为静态
  • @user1205008,使用普通成员函数 --> “你不应该”这样做。对于static 成员函数或namespace 范围内的函数,您可以这样做。但是,我仍然怀疑是否需要使用地址。为什么要使用地址?它会使您的代码不可移植。
  • 我只针对我没有来源的特定应用程序,所以我必须使用地址
  • @user1205008,为什么不能将函数分配给正确的指针,而不是使用硬编码地址?我正在编辑我的答案来解决这个问题。
  • 我无法做到这一点,因为没有地址就无法将正确的函数分配给指针
【解决方案2】:

C++ 中没有针对您正在执行的操作的语法。 请注意,该函数甚至可能是虚函数,因此您会调用错误的函数。

最简单的方法是将其更改/变为/添加非成员函数或静态成员函数,并带有额外的GameAudio* 参数。使用指针函数可以轻松调用该函数。

如果您仍想直接调用成员函数,您最好的选择可能是使用汇编程序。那么问题就在于可移植性:您的解决方案将取决于编译器、SO、架构,甚至可能是 ABI 版本。

【讨论】:

  • 好的,我听到了,所以如果我没有这个特定应用程序的源代码并且调用驻留在类/结构中的这个函数是不可能的?顺便说一句,我可以判断该功能是否是虚拟的,而这个特定的功能不是
  • @user1205008 - 很难知道它是否是虚拟的。即使是这样,您的指针也可以是指向实际函数的指针,也可以是指向 vtable-entry 或 vtable-thunk 的指针……这取决于您在哪里找到该数字。最好的了解方法是反汇编程序并查看该地址。如果您像编译器那样在汇编程序中编写调用,这当然不是不可能的。这很棘手。
猜你喜欢
  • 1970-01-01
  • 2019-10-18
  • 2011-11-29
  • 2020-12-04
  • 1970-01-01
  • 1970-01-01
  • 2013-11-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多