Autologin en otra aplicación. c#

Iniciado por #Aitor, 9 Noviembre 2018, 21:14 PM

0 Miembros y 1 Visitante están viendo este tema.

#Aitor

Buenas, tengo una aplicación que tiene dos formularios (usuario y contraseña), y quisiera diseñar una aplicación que logease en esa otra aplicación automáticamente.

Lo he hecho con SendKeys y funciona bastante bien, el problema está en que si el usuario mueve la ventana, o hace click fuera de otro formulario, los datos evidentemente se pasan ahí.

He estado leyendo sobre que alternativas existen, la Api de windows y controlar la ventana del proceso de la aplicación.

¿Podría alguien orientarme poniendome algún ejemplo de como se usaría?
Mi algoritmo en PHP (estupideces y más).
Código (php) [Seleccionar]
while($Se_feliz){
  Piensa_un_OBJETIVO(); // Sin excusas!
  if($Tienes_un_objetivo){
    Suspira(); // Sé paciente.
    if($Consigues_el_objetivo){ echo "¡Felicidades #Aitor!";return;
      //RETURN; ¿O volvemos a empezar?
    }else{
      Inténtalo_de_nuevo();
    }
  }
}

ThunderCls

#1
1- Supongo que algo mas "trabajado" incluiría cualquier técnica de inter-comunicacion de procesos o IPC por sus siglas en ingles (Shared Memory, Named Pipes, File Mapping, Mailslot, Remote Procedure Calls, etc), a no ser que necesites específicamente una técnica de trabajo con ventanas y simulacion de clicks y/o pulsaciones de teclado

2- Tambien pudieras echarle un ojo a las funciones PostMessage/SendMessage y/o SendInput (Aunque no estoy seguro si funcionan sin tener en cuenta el foco)

Aqui tienes alguna lectura recomendada
https://stackoverflow.com/questions/2113950/how-to-send-keystrokes-to-a-window
https://stackoverflow.com/questions/1220820/how-do-i-send-key-strokes-to-a-window-without-having-to-activate-it-using-window
https://stackoverflow.com/questions/8782648/how-to-send-keys-to-a-minimized-window-in-c
https://cboard.cprogramming.com/windows-programming/118217-sending-keystrokes-other-*non-focus*-application.html


-[ "...I can only show you the door. You're the one that has to walk through it." – Morpheus (The Matrix) ]-
http://reversec0de.wordpress.com
https://github.com/ThunderCls/

z3nth10n

#2
Más que un sendkeys, que como tu comentas es una ***** si mueves la ventana. Lo que podrías hacer es intentar leer el proceso en tiempo de ejecucción:

https://stackoverflow.com/a/1433888/3286975

No se si funcionará, pero la idea es algo tal que así, si el proceso que se está ejecutando es una aplicación de .NET lo tienes fácil.

Simplemente, usa dynamics...

Ejemplo:


Código (csharp) [Seleccionar]
//get the current process
// System.Diagnostics.Process p = System.Diagnostics.Process.GetCurrentProcess();

// En vez de hacer esto, hacemos esto otro:
// https://docs.microsoft.com/es-es/dotnet/api/system.diagnostics.process.getprocesses?view=netframework-4.7.2#System_Diagnostics_Process_GetProcesses
// Busca como obtener el proceso en concreto que quieres editar

//get its main windows handle (only works, if the form is already created)
IntPtr hWnd = p.MainWindowHandle;

//locate the form by its native handle
dynamic f = System.Windows.Forms.Form.FromHandle(hWnd) as System.Windows.Forms.Form;

// establecemos en tiempo de ejecucción la propiedad Text del TextBox obtenido por proceso
f.txtLoquesea.Text = "hola";


No lo se si funcionará, pero la idea es esta.

Ahora si el proceso está ofuscado, olvidate, que ni con Spy++ lo vas a conseguir.




Edito:

Aquí he hecho un pequeño ejemplo de como se haría gracias a este documento de CodeProject (https://www.codeproject.com/Articles/790966/Hosting-And-Changing-Controls-In-Other-Application):

https://github.com/z3nth10n/ComunicadorDeProcesos

Pasos a seguir:

1. Ejecuta Login.exe (está en Login/bin/Debug/)
2. Abre el proyecto (ComunicadorDeProcesos)
3. Ejecuta el proyecto y verás lo que ocurre
4. Ya haz lo propio con lo que necesites.

Te recomiendo que uses Spy++ por si te perdieses o tuvieses problemas. :P

Edito2:

Estaba pensando que el formulario de login tendrá un boton el cual también querrás clicar, en ese caso, usa esto:

https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.button.performclick?view=netframework-4.7.2

Un saludo.

Interesados hablad por Discord.

Eleкtro

#3
Cita de: #Aitor en  9 Noviembre 2018, 21:14 PM¿Podría alguien orientarme poniendome algún ejemplo de como se usaría?

Para hacer uso de las técnicas de IPC más recomendables, solo serían una opción válida si tú has desarrollado dicha aplicación, es decir, si tienes acceso al código fuente de la misma, pues deberias implementar el algoritmo de comunicación tanto en el proceso emisor, como el receptor (o cliente y servidor, quien lo prefiera llamar así). En tal caso, mi recomendación, y dado que no parece haber necesidad de establecer una conexión online, sería crear un bloque de memoría compartido (la ya mencionada técnica de 'Shared Memory' en Inglés) mediante la clase System.IO.MemoryMappedFiles.MemoryMappedFile, de la cual tienes ejemplos oficiales disponibles en microsoft.docs, y otros muchos en la WWW en general.

De lo contrario, lo recomendable, y dado que el propósito sería evitar depender de que la ventana tenga activo el foco de entrada, sería utilizar la función nativa SendMessage (o PostMessage, según cómo lo quieras hacer) junto al mensaje de ventana WM_SETTEXT, logicamente antes de poder enviar el mensaje primero debes identificar la ventana (el control) al que le quieres enviar el mensaje (el texto a insertar). De nuevo no hace falta mencionar que tienes ejemplos (miles de ellos) en la WWW. Y si necesita enviar cualquier otra cosa que no sea texto, es decir, si lo que quieres es simular una tecla o una combinación de teclas, entonces debes usar el mensaje de ventana WM_KEYDOWN + WM_KEYUP (quizás también WM_SYSKEYDOWN + WM_SYSKEYDOWN, dependiendo de las teclas específicas que necesites simular). Repito, esta metodología no requiere tener activo el foco de entrada de la ventana objetivo.

Como alternativa, y esto ya si que tendríapor requisito depender del foco de entrada de la ventana, usarías la API nativa de RAW_INPUT, lo que viene a ser la función nativa SendInput, vaya, lo cual es bastante tedioso de implementar en su totalidad, pero efectivo, y ya existen ejemplos que puedes utilizar, de hecho, si te quieres ahorrar tiempo en declarar decenas de P/Invokes, estructuras nativas y demás, entonces tienes a tu disposición librerías como Windows Input Simulator:


La API de Microsoft UI Automation (en la librería de clases de WPF), cómo ya han mencionado también, sería otra opción, tiene sus ventajas (sobre todo el gran nivel de abstracción que le otorga un manejo facil e intuitivo) y también sus desventajas (es muy, muy lento en comparación, para iterar el árbol visual o visual tree de una aplicación), aparte, solo soporta aplicaciones que sean accesibles por el mismo, lo cual hoy por hoy por lo general la mayoría lo son, pero es importante mencionarlo ya que no es 100% compatible con todo tipo de ventanas, cómo si que lo es la API de Windows en su lugar.

En resumen, si no quieres depender del foco de entrada de la ventana objetivo, usa SendMessage/PostMessage junto a los mensajes de ventana ya mencionados, si no te importa depender del foco de entrada de la ventana, entonces usa SendInput (preferiblemente la implementación de SendInput de la librería ya mencionada).

Saludos.








Serapis

Yo lo que no entiendo aquí, es que si has creado una aplicación y necesitas loguearte en ella desde otra aplicación, porqué te empeñas en hacerlo a través de la interfaz de usuario, se me antoja como disparar a una diana a ciegas...

Si tu eres quien ha diseñado la 1ª aplicación y quieres hacer una 2ª, lo razonable es que modificarás la 1ª, para alojar un método que pueda ser invocado para hacer login... probablemente la 1ª deba hacer de servidor, para aceptar además otro tipo de peticiones y la 2ª aplicación haría las veces de 'cliente'...

Acceder a una aplicación mediante interfaz de usuario, sería más bien cuando tu no eres el dueño de la aplicación, o meor dicho, cuando tu no las has diseñado, no tienes el código fuente para modificarlo... caso típico de cuando se hizo por encargo, y con el tiempo el programador/empresa que te lo hicieron desapareció y no hay posibilidad de modificar el código...