私の経験では、hakanによって提供された提案は機能しません。これが私がすることです。
出力は、アタッチされたハンドラーが。で示されるオブジェクトのメンバーであることを示しています_target。ダンプすることで、メソッドテーブルを取得できます。
説明のために、同様の例を作成しました。
0:000> !do 02844de4
Name: System.EventHandler
MethodTable: 0067afa4
EEClass: 0052ef88
Size: 32(0x20) bytes
(C:\windows\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
Fields:
MT Field Offset Type VT Attr Value Name
002e6d58 40000ff 4 System.Object 0 instance 02842d20 _target
0058df70 4000100 8 ...ection.MethodBase 0 instance 00000000 _methodBase
0058743c 4000101 c System.IntPtr 1 instance 2cc060 _methodPtr
0058743c 4000102 10 System.IntPtr 1 instance 0 _methodPtrAux
002e6d58 400010c 14 System.Object 0 instance 00000000 _invocationList
0058743c 400010d 18 System.IntPtr 1 instance 0 _invocationCount
この場合、でオブジェクトを確認します02842d20。
0:000> !do 02842d20
Name: app.Foo
MethodTable: 002c30bc
EEClass: 002c13d4
Size: 12(0xc) bytes
(C:\workspaces\TestBench\app\bin\x86\Debug\app.exe)
Fields:
None
したがって、ターゲットタイプはapp.Fooです。このタイプのメソッドをダンプしてみましょう。
0:000> !dumpmt -md 002c30bc
EEClass: 002c13d4
Module: 002c2c5c
Name: app.Foo
mdToken: 02000002 (C:\workspaces\TestBench\app\bin\x86\Debug\app.exe)
BaseSize: 0xc
ComponentSize: 0x0
Number of IFaces in IFaceMap: 0
Slots in VTable: 6
--------------------------------------
MethodDesc Table
Entry MethodDesc JIT Name
002ec015 002e6cbc NONE System.Object.ToString()
002ec019 002e6cc4 NONE System.Object.Equals(System.Object)
002ec029 002e6cf4 NONE System.Object.GetHashCode()
005f4930 002e6d1c JIT System.Object.Finalize()
005f8238 002c30b4 JIT app.Foo..ctor()
005f8270 002c30a8 JIT app.Foo.Bar(System.Object, System.EventArgs)
MethodDescテーブルの値を元の値と比較します_methodPtr。明らかな一致はありません。
_methodPtrはjmp、問題の関数のアドレスに対してaを実行するか、修正ルーチンを呼び出すコードの一部を指しているため、次のステップは!u、の値に対してコマンドを使用することです_methodPtr。jmp指示が表示されれば、アドレスがわかり、それを使用!uしてメソッドを取得します。
一方、が表示された場合は、次のcallようにclr!PrecodeFixupThunkポイントされたメモリをダンプすることでMethodDescを取得できます。_methodPtr
0:000> dd 2cc060
002cc060 7e5d65e8 00005e6e 002c30a8 00000000
002cc070 00000000 00000000 00000000 00000000
002cc080 00000000 00000000 00000000 00000000
3番目のDWORDとして、メソッドテーブルエントリのように見えるものが表示されます。値を上記のメソッドテーブルと比較する002c30a8と、メソッドの名前がであることがわかりますapp.Foo.Bar。
これは構築された例であるため、私はメソッドを見つけたことを知っています。この場合、私は探していました。
実際には、イベントの実際の使用法に応じてフィールドの使用方法が異なるため、上記の例が示すよりも少し複雑になる可能性があります。ただし、私の経験では、上記のアプローチは一般的なパブリッシャー/サブスクライバーのシナリオで機能します。
実装の詳細の詳細についてcomdelegate.cppは、共有ソースCLIのファイルを確認してください。