Red de conocimiento informático - Conocimiento sistemático - Investigación sobre enlaces de mensajes entre procesos en VB. neto

Investigación sobre enlaces de mensajes entre procesos en VB. neto

Todos sabemos que en VB, las funciones API se pueden usar para crear subclases para manejar sus propios procedimientos de formulario. Si se trata de procesos, eso es problemático. Debido a que nuestra función está en nuestro proceso (tonterías) y la función de procesamiento de mensajes de la ventana del proceso objetivo está en el proceso objetivo (tonterías), solo podemos intentar poner nuestro código en otro proceso para su ejecución y escribir un ensamblado que le diga a nuestro Me temo que procesar los mensajes que recibió da un poco de miedo. Entonces todos escriben una DLL. El principio es colocar la función de devolución de llamada en una DLL e inyectarla en otra DLL de proceso para modificar el controlador predeterminado de la ventana de destino: enviarnos el mensaje.

Por supuesto, hay un tipo diferente de /thuedownloads/indexes. Hay un paquete DLL con dssubcls dll. Siempre que llamemos a una API en nuestro programa, podemos completar fácilmente nuestro trabajo usando la función de devolución de llamada. Jaja, te ahorra la molestia de escribir una DLL tú mismo. ¿Son estos beneficios suficientes para atraer a la audiencia?

Bien, el código VB se puede encontrar en el paquete comprimido descargado. El autor proporciona un ejemplo basado en un bloc de notas (en el directorio \dssubcls), que es muy detallado. No es necesario describirlo en detalle. La clave es cómo usarlo en VB NET: cómo declarar API y cómo devolver la llamada. Primero veamos la declaración de VB para la API subclasificada.

Declarar subclase de función &lib ds subcls(ByVal HwndSubclass &_optionalByVal dirección&optionalByVal OldStyle&=_optionalByVal NewStyle&=_optionalByVal Ext & amp subclase ByVal opcional & amp=) traducida a VB NET La declaración se ve así (habitual, déjame expandir & ; en enteros)

Subclase la función Lib dssubcls(ByVal HwndSubclass As Integer Opcional ByVal Address As Integer = Opcional ByVal estilo antiguo As Integer = Opcional ByVal nuevo estilo As Integer = Opcional ByVal Ext As Integer = Opcional ByVal Subclase As Integer =) Declarado como Integer

Esto, ¿no es genial? El problema es que dicha declaración puede usar la función Addressof para pasar el segundo parámetro en VB (consulte el código fuente que descargó), pero en VB NET no es posible direccionar directamente: necesitamos delegar una devolución de llamada.

Devolución de llamada de enlace de función de delegado privado (ByVal wMsg As Integer ByVal wParam As Integer ByVal lParam As Integer)As Integer

Este delegado corresponde a las siguientes funciones

Privado función m callback(byval wmsg as integer byval wparam as integer byval lparam as integer)as integer maneja el mensaje obtenido aquí.

Función final

Al usarla, primero debes prestar atención a crear una instancia de este delegado.

arreglo privado _ COCD = Nueva devolución de llamada de gancho (dirección de mcall back)

En este momento, fix_COCD es nuestra referencia de función mCallback. Desde una perspectiva más intuitiva, fix_COCD es un puntero a mCallback, que es equivalente a la función Addressof en VB. El resultado pareció resolver el problema, por lo que escribimos el siguiente código para permitir que el proceso de la otra parte genere un mensaje.

La subclase (Handle fix_COCD) modifica el controlador.

¡El problema realmente surge! ¡El IDE indica que los tipos de variables no coinciden! ! En efecto. Pasemos un tipo HookCallBack como un número entero para que no pase la verificación y pueda transmitirse, ¿verdad? Por supuesto, puedes intentarlo. Lo que hice en este momento fue modificar la declaración API.

Subclase de función de declaración privada Lib dssubcls(ByVal HwndSubclass As Integer opcional ByVal Address Como devolución de llamada de enlace = Nada opcional ByVal OldStyle As Integer = opcional ByVal NewStyle As Integer = opcional ByVal Ext As Integer = opcional Seleccione ByVal Subclass As Integer =)¿Como Integet

¿Hacer que cumpla con nuestro llamado? ¿Un poco anormal? No, cuando se acostumbre a modificar las declaraciones API, encontrará que algunas cosas son muy simples y otras deben volver a entenderse. Lo mismo ocurre con la API WIN.

En este punto, ha completado la tarea

El código relativamente completo es el siguiente

CodePrivate declara la subclase de función Lib dssubcls(ByVal HwndSubclass As Integer opcional Dirección ByVal como devolución de llamada de gancho = Nada opcionalByVal Estilo antiguo como entero = opcional ByVal NewStyle como entero = opcional ByVal Ext como entero = opcional ByVal Subclase como entero =) Como entero función de declaración privada UseSendMessage Lib dssubcls (ByVal usa como entero) delegar arreglo privado _ cocd = nueva devolución de llamada de gancho (la dirección de la devolución de llamada m) se crea una instancia como Integer. Delegar devolución de llamada de gancho de función de delegado privado (byval wmsg Como entero byval wparam Como entero byval lparam Como entero) Como entero subhook público (byval handle Como entero) proc = subclase (handle fix _ cocd) modificar la función de procesamiento UseSendMessage () End Sub.

Función privada MC allback(ByVal wMsg As Integer ByVal wParam As Integer ByVal lParam As Integer)As Integer

Función final

Al usar este código, puede Encontrará algunas situaciones inesperadas, como wm_datacopy. En este momento, necesitamos obtener más la estructura apuntada por LPARTM y analizarla (lo que queremos leer es que la dirección específica de la memoria del proceso donde se encuentra la otra ventana está determinada por lParam; de hecho, lParam tiene Siempre ha sido un puntero: int PRT, pero es diferente de Integer. Exactamente lo mismo (si se usa, es posible que VB necesite usar Intprt toint o intprt=new intprt(integer)).

La clase CodePublic GetMsgPublic declara la función ReadProcessMemory Lib core (ByVal h proceso As Integer ByVal lpbase dirección As Integer ByVal LP buffer() As ByVal nSize As Integer ByRef lpnumberofbytes escribe As Integer) public declara la función ReadProcessMemory Lib core (ByVal h proceso Como Integer ByVal lpbase dirección Como Integer ByRef int Como Integer ByVal nS ize Como Integer ByRef lpnumberofbytes escribe Como Integer) Función de declaración pública OpenProcess Lib kernel (ByVal dwdesired acceso Como Integer ByVal binherithanHFFFF falso PID) Fin del cortocircuito

Función readmsg (la dirección ByVal es un número entero) Como Byte()Dim buf()Como ByteReadProcessMemory(hProc dirección buf) devuelve la función bufEnd

Anulaciones protegidas Subfinalize()close handle(hproc)mybase finalize( )end subend Clase Esta clase proporciona un método Readmsg para leer algún contenido, pero no está completo. Sabemos que la estructura señalada por LPARAM es así.

_Estructura pública COPYDATASTRUCTPublic dw data Como entero Public cbData Como IntegerPublic Public lpData Como estructura IntPtrEnd

No nos importa mucho dwData, pero puede haber información útil en él (I No quiero decir más aquí, algunos artículos en Internet son completamente engañosos)

cbData es la longitud de lpData.

Parece más intuitivo declarar lpData como un puntero aquí: es una dirección.

Con la dirección y longitud, ¿cómo leer el código? Escríbalo usted mismo.

Consulte mi ReadProcessMemory sobrecargada, que puede resultarle útil.

Por supuesto, las mencionadas anteriormente son solo situaciones típicas. Hay muchas ocasiones en las que el proceso utiliza mensajes personalizados (> &H A). Tomando como ejemplo la transmisión de datos, el proyecto que desarrollé imprimió los parámetros de mCallBack. y obtuve Se obtuvieron los siguientes resultados (solo se extrajo información útil en hexadecimal)

D

Donde lParam es un puntero, leí parte de él.

La función readmsg(la dirección ByVal es un número entero) Como Byte()Dim buf()Como ByteReadProcessMemory(hProc dirección buf) devuelve la función bufEnd

Ahora entiendo por qué el código anterior es así)

Luego lo procesé y obtuve la información que quería.

Información de la pieza de ajedrez en movimiento obtenida después de decodificar el mensaje: el jugador de ajedrez comienza en X, termina en Y, termina en X y termina en Y.

Movimiento de eventos (ByVal jugador As ByVal sx As ByVal sy As ByVal dx As ByVal dy As ByVal dy As ByVal nombre As ByVal[paso]As byte) función privada mcall back (ByVal wMsg As Integer ByVal wParam As Entero ByVal lParam As Integer)As Integer if wParam = & amp;h ThenDim s As Byte()= msg readmsg(lParam)RaiseEvent Move(s()s()s()s()s()s()s( ))Función End IfEnd

Por supuesto, la ReadProcessMemory sobrecargada no se ha utilizado en mi proyecto.

Sólo algo que añadir.

Para procesar mensajes de su propio formulario en VB NET, sólo necesita sobrecargar el proceso de procesamiento de mensajes del formulario.

Añadido.

Lishi Xinzhi/Article/program/net/201311/12647