さて、関数スコープの静的instance
変数は、.map
によって生成されたファイルには表示されcl.exe /Fm
ません。また、WinDbgで使用すると表示されないx programname!*MyClass*
ため、マングルされた名前にはまったく含まれていないようですMyClass
。
オプション1:分解するMyClass::getInstance
このアプローチは簡単なようです。
0:000> uf programname!MyClass :: getInstance
programname!MyClass :: getInstance [programname.cpp @ 14]:
140040105055プッシュebp
14 00401051 8bec mov ebp、esp
15 00401053 a160b34200 mov eax、dword ptr [programname!$ S1(0042b360)]
15 00401058 83e001およびeax、1
15 0040105b 7526 jne funcstat!MyClass :: getInstance + 0x33(00401083)
programname!MyClass :: getInstance + 0xd [programname.cpp @ 15]:
15 0040105d 8b0d60b34200 mov ecx、dword ptr [programname!$ S1(0042b360)]
15 00401063 83c901またはecx、1
15 00401066 890d60b34200 mov dword ptr [programname!$ S1(0042b360)]、ecx
15 0040106c b9b0be4200 mov ecx、offset programname!instance(0042beb0)
15 00401071 e88fffffff call programname!ILT + 0(?? 0MyClassQAEXZ)(00401005)
15 00401076 68e03e4200プッシュオフセットプログラム名! `MyClass :: getInstance'::` 2':: `'インスタンス''の動的アテキシットデストラクタ(00423ee0)
15 0040107b e8f3010000 call programname!atexit(00401273)
15 00401080 83c404 add esp、4
programname!MyClass :: getInstance + 0x33 [programname.cpp @ 16]:
16 00401083 b8b0be4200 mov eax、offset programname!instance(0042beb0)
17 00401088 5d pop ebp
17 00401089 c3 ret
これから、コンパイラがオブジェクトを呼び出したことがわかります$S1
。もちろん、この名前は、プログラムにある関数スコープの静的変数の数によって異なります。
オプション2:オブジェクトのメモリを検索する
@gbjbaanbの提案を拡張するために、MyClass
仮想関数がある場合、その場所を難しい方法で見つけることができるかもしれません。
- プロセスのフルメモリダンプを作成します。
- フルメモリダンプをWinDbgにロードします。
- 次のコマンドを使用して
x
、MyClassのvtableのアドレスを検索します。
0:000> x programname!MyClass :: `vftable '
00425c64 programname!MyClass :: `vftable'=
- 次のコマンドを使用し
s
て、プロセスの仮想アドレス空間(この例では0〜2GB)でMyClassのvtableへのポインターを検索します。
0:000> s -d 0 L?7fffffff 00425c64
004010dc 00425c64 c35de58b cccccccc cccccccc d \ B...]........。
0040113c 00425c64 8bfc458b ccc35de5 cccccccc d \ B..E...].....。
0042b360 00425c64 00000000 00000000 00000000 d \B............。
- コマンドを使用し
dt
てクラスのvtableオフセットを検索し、検索から返されたアドレスからそれを減算します。これらは、オブジェクトの可能なアドレスです。
0:000> dtプログラム名!MyClass
+ 0x000 __VFN_table:Ptr32
+ 0x008 x:Int4B
+ 0x010 y:フロート
dt programname!MyClass 0042b360
オブジェクトのメンバー変数を調べ、オブジェクトが0042b360(または他のアドレス)にあるという仮説をテストするために使用します。上で行ったように、おそらくいくつかの誤検知が発生しますが、メンバー変数を調べることで、どれがシングルトンであるかを判断できる場合があります。
これはC++オブジェクトを見つけるための一般的な手法であり、分解するだけではやり過ぎですMyClass::getInstance
。