我将<windows驱动开发>里12章第3节的挂载设备的实例代码, 挂载到了键盘的驱动上。
先声明本人绝对不是准备做盗号木马用的,就是想把新掌握的知识玩个新鲜的熟悉下,毕竟键盘想按就按下,比写个vc程序来测试这个挂载驱动的KdPrint()的信息来的方便,如果想盗号我想直接读键盘缓冲区应该更适用吧。
然后我发现个问题,就是当我按键速度快点,或者是按了10次左右的单一键后,键盘就没有相应了。后来我用IRPtrace获取irp信息,发现最后一个irp是close-kbdclass.
下面是相关的代码,和截获得信息
=============================IRPtrace===================================================
Close
IRP 82B76E48
Previous Next
IRP
82B76E48h
Major function
IRP_MJ_CLOSE
Minor function
00h
Target Device
KeyboardClass0 (Kbdclass)
State
Completed
Status
STATUS_SUCCESS
Sent
2010-12-29 21:22:50:390
by
HelloDDKB.sys!+4360h (F78E0360)
process
System(4h)
thread
28h
at IRQL
PASSIVE_LEVEL
Completed
2010-12-29 21:22:50:390
by
KBDCLASS.SYS!+118Ch (F77E518C)
process
System(4h)
thread
28h
at IRQL
PASSIVE_LEVEL
========================================================================================================
==========================DriverEntry函数的部分代码=====================================================
RtlInitUnicodeString( &DeviceName, L"\\Device\\KeyboardClass0" );/*MyDDKDeviceA*/ PDEVICE_OBJECT DeviceObject = NULL;
PFILE_OBJECT FileObject = NULL;
//寻找DriverA创建的设备对象
ntStatus = IoGetDeviceObjectPointer(&DeviceName,FILE_ALL_ACCESS,&FileObject,&DeviceObject); if (!NT_SUCCESS(ntStatus))
{
KdPrint(("DriverB:IoGetDeviceObjectPointer() 0x%x\n", ntStatus ));
return ntStatus;
} //创建自己的驱动设备对象
ntStatus = CreateDevice(pDriverObject); if ( !NT_SUCCESS( ntStatus ) )
{
ObDereferenceObject( FileObject );
DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
return ntStatus;
} PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) pDriverObject->DeviceObject->DeviceExtension; PDEVICE_OBJECT FilterDeviceObject = pdx->pDevice; //将自己的设备对象挂载在DriverA的设备对象上
PDEVICE_OBJECT TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,DeviceObject );
//将底层设备对象记录下来
pdx->TargetDevice = TargetDevice; if ( !TargetDevice )
{
ObDereferenceObject( FileObject );
IoDeleteDevice( FilterDeviceObject );
DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
return STATUS_INSUFFICIENT_RESOURCES;
}
FilterDeviceObject->DeviceType = TargetDevice->DeviceType;
FilterDeviceObject->Characteristics = TargetDevice->Characteristics;
// FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
// FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |
// DO_BUFFERED_IO ) );
FilterDeviceObject->Flags=TargetDevice->Flags;
ObDereferenceObject( FileObject );
=======================================================================================================
===========================IRP_MJ_READ派遣函数的代码===================================================
NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj,
IN PIRP pIrp)
{
KdPrint(("DriverB:Enter B HelloDDKRead\n"));
NTSTATUS ntStatus = STATUS_SUCCESS;
//将自己完成IRP,改成由底层驱动负责 PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)pDevObj->DeviceExtension; //将当前IRP堆栈拷贝底层堆栈
IoCopyCurrentIrpStackLocationToNext(pIrp); //设置完成例程
IoSetCompletionRoutine(pIrp,MyIoCompletion,NULL,TRUE,TRUE,TRUE); //调用底层驱动
ntStatus = IoCallDriver(pdx->TargetDevice, pIrp); //当IoCallDriver后,并且完成例程返回的是STATUS_SUCCESS
//IRP就不在属于派遣函数了,就不能对IRP进行操作了
if (ntStatus == STATUS_PENDING)
{
KdPrint(("STATUS_PENDING\n"));
}
ntStatus = STATUS_PENDING; KdPrint(("DriverB:Leave B HelloDDKRead\n")); return ntStatus;
}
========================================================================================================
==================完成函数的代码========================================================================
#pragma PAGEDCODE
NTSTATUS
MyIoCompletion(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context)
{
//进入此函数标志底层驱动设备将IRP完成
KdPrint(("Enter MyIoCompletion\n"));
KdPrint(("==IoStatus=%x====\n",Irp->IoStatus.Status));
if(NT_SUCCESS(Irp->IoStatus.Status))
{
PUCHAR c;
c=(PUCHAR)Irp->AssociatedIrp.SystemBuffer;
KdPrint(("%x %x %x %x-%x %x %x %x\n%x %x %x %x\n",c[0],c[1],c[2],c[3],c[4],c[5],
c[6],c[7],c[8],c[9],c[10],c[11]));
}
if (Irp->PendingReturned)
{
//传播pending位
IoMarkIrpPending( Irp );
} return STATUS_SUCCESS;//Irp->IoStatus.Status;
//return STATUS_SUCCESS;//同STATUS_CONTINUE_COMPLETION
}
========================================================================================================
各位高手帮看下吧,我新手,怕自己说不清楚,就直接将代码都复制过了来。但愿这些代码看起来不是那么的让人烦
先声明本人绝对不是准备做盗号木马用的,就是想把新掌握的知识玩个新鲜的熟悉下,毕竟键盘想按就按下,比写个vc程序来测试这个挂载驱动的KdPrint()的信息来的方便,如果想盗号我想直接读键盘缓冲区应该更适用吧。
然后我发现个问题,就是当我按键速度快点,或者是按了10次左右的单一键后,键盘就没有相应了。后来我用IRPtrace获取irp信息,发现最后一个irp是close-kbdclass.
下面是相关的代码,和截获得信息
=============================IRPtrace===================================================
Close
IRP 82B76E48
Previous Next
IRP
82B76E48h
Major function
IRP_MJ_CLOSE
Minor function
00h
Target Device
KeyboardClass0 (Kbdclass)
State
Completed
Status
STATUS_SUCCESS
Sent
2010-12-29 21:22:50:390
by
HelloDDKB.sys!+4360h (F78E0360)
process
System(4h)
thread
28h
at IRQL
PASSIVE_LEVEL
Completed
2010-12-29 21:22:50:390
by
KBDCLASS.SYS!+118Ch (F77E518C)
process
System(4h)
thread
28h
at IRQL
PASSIVE_LEVEL
========================================================================================================
==========================DriverEntry函数的部分代码=====================================================
RtlInitUnicodeString( &DeviceName, L"\\Device\\KeyboardClass0" );/*MyDDKDeviceA*/ PDEVICE_OBJECT DeviceObject = NULL;
PFILE_OBJECT FileObject = NULL;
//寻找DriverA创建的设备对象
ntStatus = IoGetDeviceObjectPointer(&DeviceName,FILE_ALL_ACCESS,&FileObject,&DeviceObject); if (!NT_SUCCESS(ntStatus))
{
KdPrint(("DriverB:IoGetDeviceObjectPointer() 0x%x\n", ntStatus ));
return ntStatus;
} //创建自己的驱动设备对象
ntStatus = CreateDevice(pDriverObject); if ( !NT_SUCCESS( ntStatus ) )
{
ObDereferenceObject( FileObject );
DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
return ntStatus;
} PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) pDriverObject->DeviceObject->DeviceExtension; PDEVICE_OBJECT FilterDeviceObject = pdx->pDevice; //将自己的设备对象挂载在DriverA的设备对象上
PDEVICE_OBJECT TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,DeviceObject );
//将底层设备对象记录下来
pdx->TargetDevice = TargetDevice; if ( !TargetDevice )
{
ObDereferenceObject( FileObject );
IoDeleteDevice( FilterDeviceObject );
DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
return STATUS_INSUFFICIENT_RESOURCES;
}
FilterDeviceObject->DeviceType = TargetDevice->DeviceType;
FilterDeviceObject->Characteristics = TargetDevice->Characteristics;
// FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
// FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |
// DO_BUFFERED_IO ) );
FilterDeviceObject->Flags=TargetDevice->Flags;
ObDereferenceObject( FileObject );
=======================================================================================================
===========================IRP_MJ_READ派遣函数的代码===================================================
NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj,
IN PIRP pIrp)
{
KdPrint(("DriverB:Enter B HelloDDKRead\n"));
NTSTATUS ntStatus = STATUS_SUCCESS;
//将自己完成IRP,改成由底层驱动负责 PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)pDevObj->DeviceExtension; //将当前IRP堆栈拷贝底层堆栈
IoCopyCurrentIrpStackLocationToNext(pIrp); //设置完成例程
IoSetCompletionRoutine(pIrp,MyIoCompletion,NULL,TRUE,TRUE,TRUE); //调用底层驱动
ntStatus = IoCallDriver(pdx->TargetDevice, pIrp); //当IoCallDriver后,并且完成例程返回的是STATUS_SUCCESS
//IRP就不在属于派遣函数了,就不能对IRP进行操作了
if (ntStatus == STATUS_PENDING)
{
KdPrint(("STATUS_PENDING\n"));
}
ntStatus = STATUS_PENDING; KdPrint(("DriverB:Leave B HelloDDKRead\n")); return ntStatus;
}
========================================================================================================
==================完成函数的代码========================================================================
#pragma PAGEDCODE
NTSTATUS
MyIoCompletion(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context)
{
//进入此函数标志底层驱动设备将IRP完成
KdPrint(("Enter MyIoCompletion\n"));
KdPrint(("==IoStatus=%x====\n",Irp->IoStatus.Status));
if(NT_SUCCESS(Irp->IoStatus.Status))
{
PUCHAR c;
c=(PUCHAR)Irp->AssociatedIrp.SystemBuffer;
KdPrint(("%x %x %x %x-%x %x %x %x\n%x %x %x %x\n",c[0],c[1],c[2],c[3],c[4],c[5],
c[6],c[7],c[8],c[9],c[10],c[11]));
}
if (Irp->PendingReturned)
{
//传播pending位
IoMarkIrpPending( Irp );
} return STATUS_SUCCESS;//Irp->IoStatus.Status;
//return STATUS_SUCCESS;//同STATUS_CONTINUE_COMPLETION
}
========================================================================================================
各位高手帮看下吧,我新手,怕自己说不清楚,就直接将代码都复制过了来。但愿这些代码看起来不是那么的让人烦
解决方案 »
- VC6 ADO 怎样删除一个字段的记录而不影响别的字段?
- 如何获取BitTorrent的种子数,下载者数和种子健康度。
- 急:请问哪里有《COM技术内幕》的随书代码??
- 关于ASP组件的问题
- 一个很简单的问题:如何异步复制文件,显示进度,并且能够中途取消复制。最好能有代码
- 不知道如何用VB在程序中得到本机在internet上的IP地址?
- 高分寻求源代码!!!!点对点文件传输,一定要能完整传输word,excel文件!
- 请如何在TreeView中得到DOC类的句柄!调用它下面的函数!
- 请问哪里有将rtf格式转化成html格式的控件或源码下载,急
- 我调试程序时,出现 Unhandled exception in *.exe:0xC0000005:Accesss Violation,该怎么进行下一步处理?谢谢
- 如何开发ocx控件?求步骤与最简单的例子
- 用vs2008做调试好的代码我要怎么打包成一个程序呢
用windbg可以在本机调试你虚拟机上的代码。