elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Trabajando con las ramas de git (tercera parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP) (Moderador: kub0x)
| | | |-+  [SOURCE] Algoritmo KeyLogger (RawInput)
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: [SOURCE] Algoritmo KeyLogger (RawInput)  (Leído 6,081 veces)
Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.878



Ver Perfil
[SOURCE] Algoritmo KeyLogger (RawInput)
« en: 4 Julio 2015, 18:31 pm »

INTRODUCCIÓN


Buenas!.

La forma tradicional de capturar las pulsaciones del teclado es mediante un hook del teclado, sin embargo, esta técnica está deprecada en .Net, ya que existe una forma alternativa o "moderna" que aporta bastantes mejoras (sobre todo mejoras de rendimiento), RawInput (el cual también sirve para sustituir a un LL-Hook del mouse):

About Raw Input

Citar
The raw input model is different from the original Windows input model for the keyboard and mouse.

In the original input model, an application receives device-independent input in the form of messages that are sent or posted to its windows, such as WM_CHAR, WM_MOUSEMOVE, and WM_APPCOMMAND. In contrast, for raw input an application must register the devices it wants to get data from.

Also, the application gets the raw input through the WM_INPUT message.

There are several advantages to the raw input model:

    An application does not have to detect or open the input device.
    An application gets the data directly from the device, and processes the data for its needs.
    An application can distinguish the source of the input even if it is from the same type of device. For example, two mouse devices.
    An application manages the data traffic by specifying data from a collection of devices or only specific device types.
    HID devices can be used as they become available in the marketplace, without waiting for new message types or an updated OS to have new commands in WM_APPCOMMAND.

Siempre tuve curiosidad por RawInput pero nunca me animé a implementar este modelo ya que sabía que iba a ser una auténtica pesadilla de P/Invoking, pero al final la curiosidad pudo conmigo, y tras analizar decenas de ejemplos y semi-ejemplos en C#, acabé acumulando suficiente información para desarrollar el core de un keylogger para uso genérico en VB.Net.





DESCRIPCIÓN


Esto NO es un programa, es un algoritmo o código que encapsula los datos y las definiciones de la API de Windows de los miembros de RawInput, junto a todo lo demás adicional y necesario, exponiendo sus funcionalidades a través de una Class, con propiedades, y eventos.

Se puede decir que es la base o el core para poder desarrollar la UI de un KeyLogger, ya que usando esta Class solamente sería necesario diseñar la UI y/o adaptar este código si fuese necesario según las necesidades del programador por ejemplo para monitorizar las ventana que tiene el foco activado, o la interpretación textual de las teclas del sistema, etc...

Hay varias cosas que perfeccionar y refactorizar en el código, no comparto este código cómo si fuese el mejor y más completo algoritmo del mundo, me he tomado la molestia de decorar bastante este post por que creo que el código cómo ejemplo está muy bien ...ha sido bastante laborioso y por ese motivo se merece una mención especial de esta forma (por mi parte), pero simplemente comparto el código para mostrarles una manera curiosa, distina y mejor, una alternativa "moderna" a la deprecada técnica de SetWindowsHookEx + CallNextHookEx + UnhookWindowsHookEx para llevar a cabo la misma tarea.





CARACTERÍSTICAS


  • Multi-Idioma
    El keylogger soporta distintos layouts del teclado.
    Gracias a esto, se puede cambiar el comportamiento de las pulsaciones en cualquier momento, por ejemplo del teclado Español (es-ES) al Inglés (en-US).

  • Multi-Dispositivo
    El Keylogger soporta varios dispositivos de teclado al mismo tiempo.
    NOTA: En teoría. Se intentan registrar todos los dispositivos conectados que sean de tipo "KEYBOARD", pero no lo puedo probar con certeza.

  • Soporte para caracteres especiales.
    Gracias a la función 'ToUnicodeEx' de la API de Windows, el Keylogger es capaz de interpretar caracteres especiales cómo la Ñ o la Ç.
    NOTA: En teoría. No lo he probado con el layout ruso por ejemplo.

  • Ignorar teclas, caracteres, o strings producidos por teclas muertas (dead keys).
    Se puede especificar una serie de teclas, caracteres, o strings que serán ignorados por el keylogger.

  • Controlar las operaciones de pegado (pasting) de texto (Ctrl+v).
    Se puede activar esta característica para que, mediante un evento, se nos notifique el texto que se ha pegado (si algún texto) al pulsar la combinación de teclas Ctrl+V.






DEMOSTRACIÓN


A la derecha está lo que escribo en un editor de texto, a la izquierda está lo que intercepta el keylogger y la interpretación de las teclas del sistema.



El código que he utilizado para desarrollar el ejemplo:
Código
  1. Public NotInheritable Class Form1 : Inherits Form
  2.  
  3.    Private WithEvents keyLogger As InputDevice
  4.  
  5.    Public Sub New()
  6.  
  7.        Me.InitializeComponent()
  8.  
  9.        ' Instance an InputDevice object, which enumerates and registers the keyboards found.
  10.        Me.keyLogger = New InputDevice(Me.Handle)
  11.  
  12.        ' Set keyboard layout to the default culture, in my case 'es-ES'.
  13.        Me.keyLogger.Language = InputLanguage.DefaultInputLanguage.Culture.Name
  14.  
  15.        ' Handle text pasting operations (Ctrl+V).
  16.        Me.keyLogger.HandlePastes = True
  17.  
  18.        ' Avoid raising KeyPressed event for non-relevant keys for this app example:
  19.        ' Left/Right Shift, Alt, AltGr, CapsLock, NumLock, and Left/Right Win key.
  20.        Me.keyLogger.IgnoredKeys = {Keys.ShiftKey, Keys.Menu, Keys.CapsLock, Keys.NumLock, Keys.LWin, Keys.RWin}
  21.  
  22.        ' Me.keyLogger.IgnoredChars = {"^"c}
  23.        ' Me.keyLogger.IgnoredCharsComparer = EqualityComparer(Of Char).Default
  24.  
  25.        ' Me.keyLogger.IgnoredStrings = {"^^"}
  26.        ' Me.keyLogger.IgnoredStringsComparer = StringComparer.OrdinalIgnoreCase
  27.  
  28.    End Sub
  29.  
  30.    Private Sub KeyLogger_KeyPressed(ByVal sender As Object, ByVal e As InputDevice.KeyPressedEventArgs) _
  31.    Handles keyLogger.KeyPressed
  32.  
  33.        Me.Label_Handle.Text = String.Format("Device Handle: {0}", e.DeviceInfo.DeviceHandle.ToString)
  34.        Me.Label_Type.Text = String.Format("Device Type: {0}", e.DeviceInfo.DeviceType)
  35.        Me.Label_Name.Text = String.Format("Device Name: {0}", e.DeviceInfo.DeviceName.Replace("&", "&&"))
  36.        Me.Label_Descr.Text = String.Format("Device Description: {0}", e.DeviceInfo.DeviceDescription)
  37.        Me.Label_Key.Text = String.Format("Device Key: System.Windows.Forms.Keys.{0}", e.DeviceInfo.Key.ToString)
  38.        Me.Label_DevCount.Text = String.Format("Devices Count: {0}", Me.keyLogger.DeviceCount.ToString)
  39.  
  40.        Select Case e.DeviceInfo.Key
  41.  
  42.            Case Keys.Enter
  43.                e.DeviceInfo.Chars = ControlChars.CrLf & "{ENTER}"
  44.  
  45.            Case Keys.Back
  46.                e.DeviceInfo.Chars = "{BACKSPACE}"
  47.  
  48.            Case Keys.ControlKey
  49.                e.DeviceInfo.Chars = "{CTRL}"
  50.  
  51.            Case Else
  52.                ' ...
  53.  
  54.        End Select
  55.  
  56.        Me.TextBox1.Text = e.DeviceInfo.Chars
  57.        Me.TextBox2.AppendText(e.DeviceInfo.Chars)
  58.  
  59.    End Sub
  60.  
  61.    Private Sub KeyLogger_HotkeyPastePressed(ByVal sender As Object, ByVal e As InputDevice.HotkeyPastePressedEventArgs) _
  62.    Handles keyLogger.HotkeyPastePressed
  63.  
  64.        Me.TextBox2.AppendText("{INIT_PASTE}" & e.ClipboardData & "{END_PASTE}")
  65.  
  66.    End Sub
  67.  
  68.    Private Sub Button_Clean_Click(sender As Object, e As EventArgs) _
  69.    Handles Button_Clean.Click
  70.  
  71.        Me.TextBox2.Clear()
  72.  
  73.    End Sub
  74.  
  75.    Private Sub Button_Dispose_Click(ByVal sender As Object, ByVal e As EventArgs) _
  76.    Handles Button_Dispose.Click
  77.  
  78.        If Me.keyLogger IsNot Nothing Then
  79.            Me.keyLogger.Dispose()
  80.        End If
  81.  
  82.    End Sub
  83.  
  84. End Class





DIAGRAMA DE CLASS


v





CÓDIGO FUENTE


http://pastebin.com/sMGREDTj
http://pastebin.com/u7uKf8ge

Espero que les haya gustado.

Si encuentran cualquier bug por favor coméntenlo aquí.

Saludos!


« Última modificación: 5 Julio 2015, 07:17 am por Eleкtro » En línea



DarK_FirefoX


Desconectado Desconectado

Mensajes: 1.263


Be the change you wanna see in te world


Ver Perfil
Re: [SOURCE] Algoritmo KeyLogger (RawInput)
« Respuesta #1 en: 4 Julio 2015, 19:22 pm »

Esto está genial, muy buen trabajo (como siempre), le estoy echando un vistazo, si tengo alguna duda pregunto.

Salu2s


En línea

someRandomCode

Desconectado Desconectado

Mensajes: 250



Ver Perfil
Re: [SOURCE] Algoritmo KeyLogger (RawInput)
« Respuesta #2 en: 31 Agosto 2015, 01:25 am »

Elektro, has visto el tema de los Detours?
La verdad que hasta ahora lo que venia haciendo despues de investigar y tratar de implementar muchas cosas es cargar una DLL desde un recurso previo haberla descifrado..
Me voy a poner a leer sobre RawInputs a ver que onda.. Lamentablemente lo unico que encuentro es para gamepads, lectores de codigo de barras, etc..
Mi lenguaje de eleccion es C/C++ con Qt como framework.. Tenes algun enlace que me puedas compartir?
En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.878



Ver Perfil
Re: [SOURCE] Algoritmo KeyLogger (RawInput)
« Respuesta #3 en: 31 Agosto 2015, 10:20 am »

Elektro, has visto el tema de los Detours?

¿Te refieres a Microsoft Detours?, tengo entendido que ese producto es para el API-Hooking, de todas formas nunca he usado Detours ni me lo he planteado (al requerir hacer wrappers de su librería) ya que en .Net se vuelve innecesaria su utilización al existir algunas alternativas cómo EasyHook o Nektra Deviare, siendo esta última, Deviare, la mejor opción.

Mi lenguaje de eleccion es C/C++ con Qt como framework.. Tenes algun enlace que me puedas compartir?

No, pero esto son ejemplos para el teclado en Visual C++ que imagino te podrán servir de mejor ayuda:

Minimal Key Logger Using RAWINPUT
Combining Raw Input and keyboard Hook to selectively block input from multiple keyboards

saludos
« Última modificación: 31 Agosto 2015, 10:24 am por Eleкtro » En línea



someRandomCode

Desconectado Desconectado

Mensajes: 250



Ver Perfil
Re: [SOURCE] Algoritmo KeyLogger (RawInput)
« Respuesta #4 en: 31 Agosto 2015, 13:43 pm »

Estuve leyendo sobre GetRawInputData, y hay que establecer el parseo de mensajes en WM_INPUT, si hay alguna ventana privilegiada en el sistema puede no funcionar verdad? Dado que el parseo de mensajes tanto como el de eventos sobre las coordenadas o durante la ejecucion de algo con privilegios en las ultimas versiones de Windows siempre me ha dado problemas consulto :P

Parece como que dispararia varias alarmas a nivel de sistema tambien.. Has hecho alguna prueba de concepto como para probar?
En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.878



Ver Perfil
Re: [SOURCE] Algoritmo KeyLogger (RawInput)
« Respuesta #5 en: 5 Septiembre 2015, 17:38 pm »

Estuve leyendo sobre GetRawInputData, y hay que establecer el parseo de mensajes en WM_INPUT, si hay alguna ventana privilegiada en el sistema puede no funcionar verdad? Dado que el parseo de mensajes tanto como el de eventos sobre las coordenadas o durante la ejecucion de algo con privilegios en las ultimas versiones de Windows siempre me ha dado problemas consulto :P

Parece como que dispararia varias alarmas a nivel de sistema tambien.. Has hecho alguna prueba de concepto como para probar?

La documentación oficial en MSDN explica poquito y me deja algunas cosas con interrogantes, pero de todas formas el mensaje de ventana WM_INPUT es posteado en la cola de mensajes de la o las aplicaciones que se hayan registrado con RegisterRawInputDevices, particularmente del thread desde el que se haya registrado (normalmente el thread de la UI, ya que se necesita un HWND para la estructura RAWINPUTDEVICE), por ende, en principio creo que no tendría por qué dar problema alguno ya que teorica o supuestamente el mensaje le llegará a todas las ventanas que cumplan ese requisito, sean privilegiadas o no, sin embargo, quizás tambien pueda depender de otros factores (limitaciones, errores humanos, u otras cosas secundarias a tener en cuenta), ya que por ejemplo, con el tipo de hooking convencional, es decir, el uso de LowLevelKeyboardProc y LowLevelMouseProc, hay que tener mucho cuidado con el parámetro nCode que se devuelva tras procesar los mensajes, ya que si no se hace correctamente, entonces podría provocar un conflicto en el sistema que acabaría "bloqueando" el mensaje para el resto de aplicaciones, las cuales no podría procesarlo (durante el tiempo de vida de la app o thread, no es algo permanente claro está), tal vez eso sea lo que hayas podido experimentar en el pasado con los hooks, ya que al menos yo pasé por eso mismo cuando empecé a trastear con los windows_messages para un ll-hook del mouse, o tal vez te refieras a otro tipo de conflicto ?.

Sobre las pruebas, hombre, no voy a compartir algo sin comprobar que funciona lo que hice xD, pero fueron pruebas de uso básico o digamos "ético", quiero decir, no con seguridad de terceros implementada en el S.O, ni tampoco UAC ni nada, ni con otras aplicaciones en segundo plano registradas con RAWINPUT, pero ya digo, que en pricnipio no debería dar problemas...

Si descubres algo, un conflicto o lo que sea que se pueda mejorar, házmelo saber.

saludos!
« Última modificación: 5 Septiembre 2015, 18:07 pm por Eleкtro » En línea



Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
* [ Source ] Encoder and Decode [Algoritmo Simple] « 1 2 »
Programación Visual Basic
BlackZeroX 15 10,568 Último mensaje 7 Diciembre 2009, 20:36 pm
por Dessa
Algun algoritmo para la ordenacion del source?
Programación C/C++
taul 5 3,296 Último mensaje 4 Mayo 2010, 18:43 pm
por bizco
[C/C++][Source] s7ogger++ [KeyLogger]
Programación C/C++
s7evin 0 2,873 Último mensaje 14 Junio 2012, 19:30 pm
por s7evin
[Source] Algoritmo Conjetura de Goldbach
Java
juancaa 0 8,797 Último mensaje 10 Noviembre 2012, 22:05 pm
por juancaa
[SOURCE] Algoritmo de cifrado (35 MB/s)
Criptografía
El Benjo 4 4,724 Último mensaje 2 Septiembre 2013, 09:01 am
por El Benjo
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines