1

アプリケーションのクラスに常駐する関数があります。私の目的は、dll をターゲット プロセスに挿入し、そのアドレスでそのメンバー関数を呼び出すことです。関数は次のとおりです。

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

私はそれをこのように呼んでみました

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

私はすべてを使いました: __stdcall, __cdecl,__thiscallあなたはそれに名前を付けます.

4

2 に答える 2

1

あなたがしていることのための C++ の構文はありません。関数は仮想でさえある可能性があるため、間違った関数を呼び出すことに注意してください。

GameAudio*最も簡単な方法は、追加のパラメーターを使用して、非メンバー関数または静的メンバー関数に変更/追加することです。その関数は、ポインターへの関数を使用して簡単に呼び出すことができます。

それでもメンバー関数を直接呼び出したい場合は、おそらくアセンブラーを使用するのが最善の策です。問題は移植性です。ソリューションは、コンパイラ、SO、アーキテクチャ、さらには ABI のバージョンに依存します。

于 2012-02-12T11:54:12.390 に答える
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)();
于 2012-02-12T11:47:38.347 に答える