3

DLLを別のプロセスに挿入していて、そのアドレス(0x54315)に基づいてそのバイナリにある関数を呼び出したいと思います。

実際に関数を宣言して、それをこのアドレスに設定するにはどうすればよいですか?

#define FUNC 0x54315

void *myFuncPtr;

int main()
{
 myFuncPtr = FUNC;  // pretty sure this isn't how

 myFuncPtr(); // call it?
}
4

3 に答える 3

5

myFuncPtr関数ポインタとして定義する必要がありますvoid*。aは呼び出し可能ではありません。

そのためにtypedefを使用するのが最善です:

typedef void (*funptr)(void);
funprt myFuncPtr;

(関数が何も受け取らず、何も返さないと仮定します。)

次に、割り当てに関する警告が表示されます。型キャストを使用して「沈黙」させます。これは実際に行う必要があることだからです。

ただし、署名が一致しない場合、呼び出し規約が間違っている場合、またはアドレスが間違っている場合、コンパイラは何も検証できず、断片を取得することができます。

于 2012-05-20T13:39:10.077 に答える
5

既存の回答は機能しますが、関数ポインター用の変数も必要ありません。あなたはただすることができます:

#define myfunc ((void (*)(void))0x54315)

そしてmyfunc()、通常の関数と同じように呼び出します。関数の実際の引数と戻り値の型に一致するように、キャストの型を変更する必要があることに注意してください。

于 2012-05-20T15:50:13.673 に答える
3

構文が実際に関数ポインタになるように修正されると、コードは機能するはずです。この回答の最初のバージョンでは、正しく読むことができませんでした。ごめん。

Matが述べているように、関数ポインタの適切な構文は次のようになります。

void (*myFuncPtr)(void) = (void (*)(void)) FUNC;

typedefC関数ポインタの構文はやや複雑なので、これは多くの場合、aを使用することで簡略化されます。

また、挿入されたDLLが実行されるたびに、呼び出される関数が同じ正確なアドレスにあることを本当に確認する必要があります。どうすればそれを確信できるかわかりませんが...

また、呼び出し規約と関数が期待する可能性のある引数に注意を払う必要がありますFUNC。これを間違えると、スタックが破損する可能性があるためです。

于 2012-05-20T13:35:01.470 に答える