Как вызвать функции-члены с их адреса - PullRequest
1 голос
/ 12 февраля 2012

У меня есть функция, которая находится в классе в приложении, моя цель - внедрить dll в целевой процесс и вызвать эту функцию-член по ее адресу. Вот функция:

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

Я пытался назвать это так

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

Я использовал все: __stdcall, __cdecl, __thiscall Вы называете это.

Ответы [ 2 ]

1 голос
/ 12 февраля 2012

В C ++ нет синтаксиса для того, что вы делаете.Обратите внимание, что функция может быть даже виртуальной, и поэтому вы будете вызывать неправильную функцию.

Самый простой способ - это изменить / включить / добавить функцию, не являющуюся членом или статическую функцию-члендополнительный параметр GameAudio*.Эту функцию можно легко вызвать с помощью функции указателя.

Если вы все еще хотите вызывать функцию-член напрямую, вам лучше всего использовать ассемблер.Тогда проблема в переносимости: ваше решение будет зависеть от компилятора, SO, архитектуры и, возможно, даже от версии ABI.

1 голос
/ 12 февраля 2012

Сигнатура функции-члена класса, отличного от 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)();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...