2012-02-12 7 views
1

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

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

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

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

я использовал все: __stdcall, __cdecl, __thiscall вы называете его.

+0

Вы уверены, что это всегда тот же адрес? –

+0

Да, я уверен :) –

+0

Что происходит, когда вы пытаетесь называть его? Вы пытались выполнить вызов в отладчике? А также помните, что все функции-члены класса имеют неявный аргумент 'this'. –

ответ

1

Незначительная функция функции класса не равна static, чем обычная функция. Например,

class X { 
public: 
    void foo(); 
}; 
void foo(); 

В описанном выше случае X::foo() и ::foo() отличаются друг от друга. Помните, что, X::foo() под капотом somewaht как:

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)(); 
+0

так его басикально невозможно? –

+0

да, но вы должны помнить, что эта функция находится в приложении, в котором у меня нет исходного кода, поэтому я не могу изменить функцию на статический –

+0

@ user1205008, с нормальной функцией-членом -> «вы не должны» это делать. Для функции 'static' member или функции в области пространства имен вы можете это сделать. Но я все еще сомневаюсь в необходимости использования адреса. Почему вы хотите использовать адрес? Это сделает ваш код не переносным. – iammilind

1

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

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

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

+0

ok Я слышу вас, так что басикально, если у меня нет источника для этого определенного приложения и вызвать эту функцию, которая находится в классе/структуре, была бы невозможна? btw я могу сказать, является ли функция виртуальной или нет, и эта конкретная функция не является –

+0

@ user1205008. Непросто узнать, является ли она виртуальной. И даже если это так, ваш указатель может быть указателем на реальную функцию или указателем на vtable-entry или на vtable-thunk ... Это будет зависеть от того, где вы нашли это число. Лучший способ узнать - разобрать программу и посмотреть вокруг этого адреса. И это, конечно, не невозможно, если вы пишете вызов в ассемблере, как это делает компилятор. Это просто сложно. – rodrigo

+0

Я использовал dissasembler –