Envío de "KEYDOWN" a aplicación externa

Iniciado por TomaSs, 26 Febrero 2013, 21:04 PM

0 Miembros y 3 Visitantes están viendo este tema.

TomaSs

Pues recurro a vuestra sabiduría para ver si, como otras veces, podríais darme un poco de luz.
El tema es que quiero hacer un programilla que me camine solo en un juego mientras está minimizado, pero no hay manera... He probado con SendMessage, PostMessage y keybd_event, y nada, lo máximo que he conseguido ha sido que me escriba en el propio chat del juego la letra que mando, pero lo que es hacer alguna acción, no hace nada...

También he ido un poco más allá con el Spy++, para ver cuales eran las apis que llamaba el juego, y he obtenido los siguientes mensajes:

Pulsando la tecla shift directamente en el juego:
000A041A P WM_KEYDOWN nVirtKey:VK_SHIFT cRepeat:1 ScanCode:2A fExtended:0 fAltDown:0 fRepeat:0 fUp:0 [wParam:00000010 lParam:002A0001]
000A041A P WM_KEYDOWN nVirtKey:VK_SHIFT cRepeat:1 ScanCode:2A fExtended:0 fAltDown:0 fRepeat:1 fUp:0 [wParam:00000010 lParam:402A0001]
000A041A P WM_KEYDOWN nVirtKey:VK_SHIFT cRepeat:1 ScanCode:2A fExtended:0 fAltDown:0 fRepeat:1 fUp:0 [wParam:00000010 lParam:402A0001]


Enviando un SendMessage desde mi programita a la propia ventana del juego, a través de SendMessage(hwnd, (uint)WM_KEYDOWN, (UIntPtr)0x00000010, (IntPtr)(0x002A0001)) , he obtenido esto:
000A041A S WM_KEYDOWN nVirtKey:VK_SHIFT cRepeat:1 ScanCode:2A fExtended:0 fAltDown:0 fRepeat:0 fUp:0 [wParam:00000010 lParam:002A0001]
000A041A R WM_KEYDOWN lResult:00000000
000A041A S WM_KEYDOWN nVirtKey:VK_SHIFT cRepeat:1 ScanCode:2A fExtended:0 fAltDown:0 fRepeat:0 fUp:0 [wParam:00000010 lParam:002A0001]
000A041A R WM_KEYDOWN lResult:00000000
000A041A S WM_KEYDOWN nVirtKey:VK_SHIFT cRepeat:1 ScanCode:2A fExtended:0 fAltDown:0 fRepeat:0 fUp:0 [wParam:00000010 lParam:002A0001]
000A041A R WM_KEYDOWN lResult:00000000


El tema es que llama a las mismas apis con el mismo wParam y lParam, exactamente igual, el tema es que al llamar desde mi programa saca ese "lResult:00000000" que no se que será, no se si habría que meter un delay entre llamada y llamada y puede ser que sea por eso, o nose...

Alguien sabría decirme algo? A alguien que le haya pasado ya o lo que sea xd

Muchas gracias de antemano! ;)

kub0x

¿A que juego estás intentando enviar el mensaje WM_KEYDOWN? ¿Al emplear las APIs Post/SendMessage, al parámetro hWnd le asignas el identificador de la ventana del proceso?
¿Has intentado pasarle un PostMessage con el parámetro lParam "seteado" a 0? Cómo útlimo recurso, métele un delay entre las llamadas a las API, pero vamos, el delay se suele emplear para que la aplicación destino intérprete el mensaje adecuadamente y no se "coma" el mensaje que le envies.

Saludos!
Viejos siempre viejos,
Ellos tienen el poder,
Y la juventud,
¡En el ataúd! Criaturas Al poder.

Visita mi perfil en ResearchGate


TomaSs

Pues lo estoy intentando con el juego TheWarZ.
Voy a probar con el lparam a 0 como has dicho, a ver que pasa...

TomaSs

#3
Pues mi comprobación ha ido más allá, el tema es el siguiente:

Me he dado cuenta de que en el juego, cuando pulsas shift para comenzar a andar, y dejarlo pulsado, obtengo con spy++ lo siguiente:

Pulsando shift en el juego:
00020528 P WM_KEYDOWN nVirtKey:VK_SHIFT cRepeat:1 ScanCode:2A fExtended:0 fAltDown:0 fRepeat:0 fUp:0 [wParam:00000010 lParam:002A0001 time:5:27:04.800]
00020528 P WM_KEYDOWN nVirtKey:VK_SHIFT cRepeat:1 ScanCode:2A fExtended:0 fAltDown:0 fRepeat:1 fUp:0 [wParam:00000010 lParam:402A0001 time:5:27:05.502]
00020528 P WM_KEYDOWN nVirtKey:VK_SHIFT cRepeat:1 ScanCode:2A fExtended:0 fAltDown:0 fRepeat:1 fUp:0 [wParam:00000010 lParam:402A0001 time:5:27:05.549]
00020528 P WM_KEYDOWN nVirtKey:VK_SHIFT cRepeat:1 ScanCode:2A fExtended:0 fAltDown:0 fRepeat:1 fUp:0 [wParam:00000010 lParam:402A0001 time:5:27:05.596]
00020528 P WM_KEYDOWN nVirtKey:VK_SHIFT cRepeat:1 ScanCode:2A fExtended:0 fAltDown:0 fRepeat:1 fUp:0 [wParam:00000010 lParam:402A0001 time:5:27:05.643]
00020528 P WM_KEYDOWN nVirtKey:VK_SHIFT cRepeat:1 ScanCode:2A fExtended:0 fAltDown:0 fRepeat:1 fUp:0 [wParam:00000010 lParam:402A0001 time:5:27:05.690]
00020528 P WM_KEYDOWN nVirtKey:VK_SHIFT cRepeat:1 ScanCode:2A fExtended:0 fAltDown:0 fRepeat:1 fUp:0 [wParam:00000010 lParam:402A0001 time:5:27:05.736]


Y lo que he apreciado es que como se puede ver, nada más pulsar el shift, manda el fRepeat a 0, y los siguientes a 1 (y por consiguiente el lParam también cambia).
Por lo que he probado a mandar desde mi programa así, primero el lParam tal cual se ve la primera instrucción y los siguientes pues como todos los siguientes, y tampoco...

Así pues, me he fijado más y le he añadido para que me saque la hora en los mensajes, y he visto que la diferencia de tiempo entre la primera llamada (lParam:002A0001) y la segunda (lParam:402A0001) es de 0'702, y siempre que empiezo la pulsación esa es la diferencia de tiempo, y las diferencias de tiempo entre todas las demas, todas las de lParam:402A0001, es de 0'047.
Esto es lógico que siempre sea la misma diferencia por el buffer del teclado o lo que sea supongo, pero, no podrá ser que el juego chekee eso y que tal vez yo tenga que tratar de meter un delay de ese mismo tiempo???

EDITO: pues ya he simulado casi perfecto ese tiempo y nada, no hace nada, asik a saber...

kub0x

Al parecer el juego al que intentas enviar dichas pulsaciones utiliza un motor gráfico, ya sea DirectX 9 .. OpenGL etc Al enviar mensajes que contienen carácteres a la aplicación, ésta los recibe y los puede imprimir en la pantalla de Chat, pero ésta no será capaz de interpretar las pulsaciones por ejemplo, de movimiento, ya que de éso se ocupa el apartado del render gráfico, es decir, el evento provocado por el envío de 1 caracter a la ventana chat es manejado por la aplicación en sí, no tiene nada que ver con el apartado del render, ya que este último se ocupa y se dedica a reproducir las funcionalidades gráficas del juego.

Échale un vistazo a esto para más info:

http://foro.elhacker.net/empty-t383429.0.html
http://guidedhacking.com/showthread.php?2791-HELP-Strange-SendKey-Bug-Counter-Strike-Source (A este user le pasa lo mismo que a tí :D)

Saludos!
Viejos siempre viejos,
Ellos tienen el poder,
Y la juventud,
¡En el ataúd! Criaturas Al poder.

Visita mi perfil en ResearchGate


TomaSs

#5
pues vaya... mi idea no era hacer un cheat la verdad... pensé que sería algo mucho más fácil, pero tampoco termino de entenderlo, si realmente cuando se pulsa una tecla en el teclado se manda una instrucción al SO, no? como no va a poderse hacer sin hookear el juego? xd
entonces debería poderse hacer hookeando el keyboard o algo así, no? porque lo que es el "evento" en general, parte del teclado al pulsar la tecla :S

pues vaya...

kub0x

A mi entender, no me hagas mucho caso, quien se encarga de los movimientos del personaje en tu caso, es el controlador del motor gráfico (DirectX) por lo tanto para poder interactuar con éste, tienes que hacerlo directamente desde la librería del DirectX.
Estaría bien que alguien se pasara por este tema y nos diera un poco más de info, pero lo más seguro es que tengas que realizar un hook a dicha librería.

Si implementas un hook de teclado, lo que logras es interceptar los mensajes enviados a la cola de mensajes del sistema al haber pulsado cualquier tecla del teclado.

Saludos!
Viejos siempre viejos,
Ellos tienen el poder,
Y la juventud,
¡En el ataúd! Criaturas Al poder.

Visita mi perfil en ResearchGate


TomaSs

Pues muchas gracias fiera ;) y si, a ver si alguien nos da un poco de luz :D

Gracias!

TomaSs

Pues al final he conseguido hacer algo con un lenguaje de scripts, que no puedo mandar la pulsación a la ventana en concreto, y no puedo mandarle la pulsación cuando está minimizada, pero si que me simula las pulsaciones correctamente y el juego responde sin problemas.
A! El lenguaje en cuestión es AutoHotkey, que es bastante interesante para estas cosillas la verdad...

Perdonad que esto no tenga nada que ver con .NET, ya que en principio buscaba algo para .NET, pero al final conseguí esto, pero podéis moverlo a la categoría de Scripting sin problemas.