2

この質問は、仮想メンバー関数の印刷アドレスに似てい ます

メンバー関数ポインターを使用して、(実行時に) 関数のメモリ位置を取得したいと思います。目標は、それらをログに記録し、事後分析を行い、WinDbg で「ln」を使用して、PDB シンボルを使用してどの関数であったかを取得することです。

ログに記録したい関数にまだ慣れていないため、スタック ウォーキングを使用できません。(そして、何十億もの関数を変更してアドレスを返すことはしたくありません...)。

短いサンプル:

class AClass
{
public :
   virtual AFunction(){;}

};

typedef void (AClass::*FxPtr)( void );


[...]
    AClass oAClass;

    AClass*  pSelf = &oAClass;
    FxPtr    pf    = &AClass::AFunction;

    DWORD nFctAddress = ???

アドレスを取得する方法を知っている人はいますか?

&(pSelf->*pf)

「エラー C2298: '&' : メンバー関数式へのポインターに対する不正な操作」を与える

メンバー関数ポインターが「奇妙な」構造であることは知っていますが、「これ」を知っているので、潜在的に仮想関数を vtable から検索する方法はありますか?

よろしく、

参照:

4

2 に答える 2

1
#include <stdio.h>

struct Class {
  virtual void AFunction( void ) { printf("1"); }
};

struct AClass : public Class {
  virtual void AFunction( void ) { printf("2"); }
};

typedef void (AClass::*FxPtr)(void);


int main( void ) {

  union {
    FxPtr pf;
    int rf[2];
  };

  pf = &AClass::AFunction;

  printf( "sizeof(pf)=%i\n", sizeof(pf) );

  printf( "%08X\n", pf );

  printf( "%08X %08X\n", rf[0], rf[1] );

/*
error: ISO C++ forbids taking the address of a bound member function
to form a pointer to member function.  Say '&AClass::AFunction'

  AClass a;
  FxPtr qf = &a.AFunction;
  printf( "sizeof(qf)=%i\n", sizeof(qf) );
*/

};

vtable へのアクセスは簡単ですが、アドレスで関数を識別するのは簡単ではありません。
いくつかのオプション:
1) .map ファイルを解析し、ロードして、typeid (または map の VMT インスタンス) でクラス名を検索し、その名前で関数アドレスを検索します。
2) 特定のオブジェクトに対して特定の仮想メソッドを呼び出す静的関数を作成し、それが asm でどのように見えるかを確認し、そのコードから vtable で関数のオフセットを取得し、アドレスを読み取ります。

?adr_CFunction@Class@@SIXPAU1@@Z PROC           ; Class::adr_CFunction, COMDAT
; _This$ = ecx
; 8    :   static void adr_CFunction( Class* This ) { This->CFunction(); }
    mov eax, DWORD PTR [ecx]
    mov edx, DWORD PTR [eax+8]
    jmp edx
?adr_CFunction@Class@@SIXPAU1@@Z ENDP           ; Class::adr_CFunction

3) "/Gh enable _penter function call" のような気の利いたオプションがあり、呼び出しの後、関数が実際に何かを実行する前に、すべての関数のアドレスを取得できます。次に、.map を使用して、トレースによって関数を識別できます。

于 2011-02-15T00:04:09.860 に答える
0

それはすべてマップファイルにあります。マップファイルの生成をオンにしてお楽しみください。

于 2011-02-14T23:07:59.880 に答える