En mi experiencia, la sugerencia ofrecida por hakan no funciona. Esto es lo que hago.
La salida muestra que el controlador adjunto es un miembro del objeto apuntado por _target
. Al eliminar eso obtendrás su tabla de métodos.
he construido un ejemplo similar, para ilustrar:
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
En este caso, voy a ver el objeto en 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
lo tanto, el tipo de destino es app.Foo
. Vamos a volcar los métodos para este tipo.
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)
comparar los valores de la tabla MethodDesc
con el valor original de _methodPtr
. Sin aparente coincidencia.
_methodPtr apunta a una pieza de código que, o bien hace un jmp
a la dirección de la función en cuestión o llama a una rutina de corrección de, por lo que el siguiente paso es utilizar el comando !u
en el valor de _methodPtr
. Si vemos una instrucción jmp
, tenemos la dirección y usando !u
en eso, obtenemos el método.
Si, por el contrario, vemos una call
-clr!PrecodeFixupThunk
podemos obtener el MethodDesc por vertimiento de la memoria apuntada por _methodPtr
como esto
0:000> dd 2cc060
002cc060 7e5d65e8 00005e6e 002c30a8 00000000
002cc070 00000000 00000000 00000000 00000000
002cc080 00000000 00000000 00000000 00000000
vemos algo que se parece a una entrada de tabla de métodos de como el tercer DWORD. Al comparar el valor 002c30a8
con la tabla de métodos anterior, vemos que el nombre del método es app.Foo.Bar
.
Dado que este es un ejemplo construido, sé que encontré el método que estaba buscando en este caso.
En realidad, puede ser un poco más complicado que el ejemplo anterior, ya que los campos se utilizan de manera diferente según el uso real del evento. Sin embargo, en mi experiencia, el enfoque anterior funcionará en el escenario general del editor/suscriptor.
Para obtener más información sobre los detalles de implementación, consulte el archivo comdelegate.cpp
de la CLI de origen compartido.
En lugar de comparar manualmente con la tabla de métodos, también puede usar el comando! DumpMD con el descriptor de método. – kicsit
Se ve mal en x64, solo un salto a un registro –