he observado que por este foro circulan peticiones de usuarios que desean introducirse en el mundo del hooking en Windows y he decidido codear una breve aplicación, comentada al detalle para su buen entendimiento y poder comprender las nociones básicas del Hooking.
La verdad que aprendí hace unos 2 días, me puse en C a codearlo pero .NET me tira más, ya después de leer la documentación de MSDN (abajo os dejo el link) y utilizar un poquito (la Web) Pinvoke para declarar las funciones del API ya pude completar el programa.
El programa simplemente establece un Hook de tipo LowLevelKeyBoard, captura las teclas interceptadas por el hook y finalmente las guarda una a una en un fichero de la carpeta actual.
Link Documentacion Hooks-> http://msdn.microsoft.com/en-us/library/windows/desktop/ms632589%28v=vs.85%29.aspx
Como no, comparto con vosotros el Source del programa. Está codeado bajo el Framework 4.0 y desarrollado en Visual Basic .NET (VS 2010)
Link de descarga -> http://www.mediafire.com/?4fbdmx5obwu5k10
Source:
Código
Imports System.Runtime.InteropServices Imports System.IO Imports System.Threading Imports System.Windows.Forms Public Class Form1 Enum Constantes As Integer WH_KEYBOARD_LL = 13 HC_ACTION = 0 WM_KEYDOWN = &H100 WM_KEYUP = &H101 WM_SYSKEYDOWN = &H104 WM_SYSKEYUP = &H105 End Enum '-> Constantes utilizadas en el Hook Global <StructLayout(LayoutKind.Sequential)> _ Public Class KBDLLHOOKSTRUCT Public vkCode As UInt32 Public scanCode As UInt32 Public flags As UInt32 Public time As UInt32 Public dwExtraInfo As UIntPtr End Class '-> Estructura que contiene los mensajes interceptados por el Hook #Region "Declaraciones_API" <DllImport("user32.dll")> _ Friend Shared Function SetWindowsHookEx(ByVal idHook As Integer, ByVal lpfn As HookProc, ByVal hInstance As IntPtr, ByVal threadId As Integer) As Integer End Function <DllImport("user32.dll")> _ Friend Shared Function CallNextHookEx(ByVal hhk As IntPtr, ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As KBDLLHOOKSTRUCT) As Integer End Function <DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _ Public Shared Function GetModuleHandle(ByVal lpModuleName As String) As IntPtr End Function <DllImport("user32.dll", SetLastError:=True)> _ Public Shared Function UnhookWindowsHookEx(ByVal hhk As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean End Function #End Region '-> Declaraciones de APIs para el uso de Hooks (SetWindowsHookEx...) Enum HookType As Integer WH_JOURNALRECORD = 0 WH_JOURNALPLAYBACK = 1 WH_KEYBOARD = 2 WH_GETMESSAGE = 3 WH_CALLWNDPROC = 4 WH_CBT = 5 WH_SYSMSGFILTER = 6 WH_MOUSE = 7 WH_HARDWARE = 8 WH_DEBUG = 9 WH_SHELL = 10 WH_FOREGROUNDIDLE = 11 WH_CALLWNDPROCRET = 12 WH_KEYBOARD_LL = 13 WH_MOUSE_LL = 14 End Enum '-> Tipos de Hooks para monitorizar mensajes 'Declaramos un delegado y le asignamos sus respectivos argumentos Delegate Function HookProc(ByVal code As Integer, ByVal wParam As IntPtr, ByVal lParam As KBDLLHOOKSTRUCT) As Integer Private CallbackDelegate As HookProc = Nothing 'Declaramos la variable Hook. Será la encargada de almacenar la direccion de memoria del Hook Dim hook As IntPtr = IntPtr.Zero 'Procedimiento asociado al puntero AddressOf(CallBackDelegate) Private Function HookprocHandler(ByVal code As Integer, ByVal wParam As IntPtr, ByVal lParam As KBDLLHOOKSTRUCT) As Integer Try 'Code es la variable encargada de decir si existe un mensaje. Si code !=0 no habra nada. If (code < 0) Then 'Damos paso al siguiente Hook y procedemos con el continuamiento del Sistema Return CallNextHookEx(IntPtr.Zero, code, wParam, lParam) Else Dim sr As New StreamWriter(CurDir() & "\log.txt", True) 'Segun el código devuelto a la pulsación de la tecla (257,258) Select Case wParam Case Constantes.WM_KEYDOWN, Constantes.WM_SYSKEYDOWN Dim key As Char = ChrW(lParam.vkCode) 'Imprimimos el caracter ASCII en pantalla sr.Write(key) End Select sr.Close() Return CallNextHookEx(IntPtr.Zero, code, wParam, lParam) End If Catch ex As Exception End Try Return 1 End Function Private Sub Iniciar_Hook() Try 'Asociamos a dicho procedimiento un puntero hacia el controlador del Hook (HookProcHandler) CallbackDelegate = New HookProc(AddressOf HookprocHandler) If hook <> 0 Then 'Desinstalamos el Hook UnhookWindowsHookEx(hook) hook = IntPtr.Zero btn_hook.Text = "Hookear Teclado" Else 'Instalamos un Hook Global (LowLevelKeyBoard) y llamamos a la funcion HookProcHandler 'Los ultimos dos parametros indican el HINSTANCE y PID, se utilizarian en caso de Hook local _ 'empleados en juegos y demás. hook = SetWindowsHookEx(HookType.WH_KEYBOARD_LL, CallbackDelegate, 0, 0) btn_hook.Text = "Desinstalar Hook" FileSystem.Kill(CurDir() & "\log.txt") End If Catch ex As Exception End Try End Sub Private Sub btn_hook_Click(sender As System.Object, e As System.EventArgs) Handles btn_hook.Click Iniciar_Hook() End Sub End Class
Espero que os haya gustado el aporte. Cualquier duda que pueda surgir con el tema posteadla aquí, no olvideis que esto es lo más básico, los hooks tienen muchísimo juego.
Un Saludo