资料:寒江独钓
目的:过滤驱动学习
先把它的代码自己敲一次。先把几个概念再百度~~~
#include <ntddk.h>
#include <ntddkbd.h>
#define KEY_UP 1
#define KEY_DOWN 0
#define LCONTROL ((USHORT)0x1D)
#define CAPS_LOCK ((USHORT)0x3A)
unsigned char asciiTbl[]={
0x00, 0x1B, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x2D, 0x3D, 0x08, 0x09, //normal
0x71, 0x77, 0x65, 0x72, 0x74, 0x79, 0x75, 0x69, 0x6F, 0x70, 0x5B, 0x5D, 0x0D, 0x00, 0x61, 0x73,
0x64, 0x66, 0x67, 0x68, 0x6A, 0x6B, 0x6C, 0x3B, 0x27, 0x60, 0x00, 0x5C, 0x7A, 0x78, 0x63, 0x76,
0x62, 0x6E, 0x6D, 0x2C, 0x2E, 0x2F, 0x00, 0x2A, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x38, 0x39, 0x2D, 0x34, 0x35, 0x36, 0x2B, 0x31,
0x32, 0x33, 0x30, 0x2E,
0x00, 0x1B, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x2D, 0x3D, 0x08, 0x09, //caps
0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49, 0x4F, 0x50, 0x5B, 0x5D, 0x0D, 0x00, 0x41, 0x53,
0x44, 0x46, 0x47, 0x48, 0x4A, 0x4B, 0x4C, 0x3B, 0x27, 0x60, 0x00, 0x5C, 0x5A, 0x58, 0x43, 0x56,
0x42, 0x4E, 0x4D, 0x2C, 0x2E, 0x2F, 0x00, 0x2A, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x38, 0x39, 0x2D, 0x34, 0x35, 0x36, 0x2B, 0x31,
0x32, 0x33, 0x30, 0x2E,
0x00, 0x1B, 0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 0x26, 0x2A, 0x28, 0x29, 0x5F, 0x2B, 0x08, 0x09, //shift
0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49, 0x4F, 0x50, 0x7B, 0x7D, 0x0D, 0x00, 0x41, 0x53,
0x44, 0x46, 0x47, 0x48, 0x4A, 0x4B, 0x4C, 0x3A, 0x22, 0x7E, 0x00, 0x7C, 0x5A, 0x58, 0x43, 0x56,
0x42, 0x4E, 0x4D, 0x3C, 0x3E, 0x3F, 0x00, 0x2A, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x38, 0x39, 0x2D, 0x34, 0x35, 0x36, 0x2B, 0x31,
0x32, 0x33, 0x30, 0x2E,
0x00, 0x1B, 0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 0x26, 0x2A, 0x28, 0x29, 0x5F, 0x2B, 0x08, 0x09, //caps + shift
0x71, 0x77, 0x65, 0x72, 0x74, 0x79, 0x75, 0x69, 0x6F, 0x70, 0x7B, 0x7D, 0x0D, 0x00, 0x61, 0x73,
0x64, 0x66, 0x67, 0x68, 0x6A, 0x6B, 0x6C, 0x3A, 0x22, 0x7E, 0x00, 0x7C, 0x7A, 0x78, 0x63, 0x76,
0x62, 0x6E, 0x6D, 0x3C, 0x3E, 0x3F, 0x00, 0x2A, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x38, 0x39, 0x2D, 0x34, 0x35, 0x36, 0x2B, 0x31,
0x32, 0x33, 0x30, 0x2E
};
typedef struct _FILTER_DEVICE_EXTEN
{
PDEVICE_OBJECT pFilterDeviceObject;//过滤设备
PDEVICE_OBJECT pTagerDeviceObject;//绑定的设备对象
KSPIN_LOCK Lockspin;//调用时的保护锁
KEVENT ProcessEvent;//进程间同步
PDEVICE_OBJECT LowDeviceObject;//绑定前底层设备对象
}FILTER_DEVICE_EXTEN,*PFILTER_DEVICE_EXTEN;
NTSTATUS
ObReferenceObjectByName(
PUNICODE_STRING ObjectName,
ULONG Attributes,
PACCESS_STATE AccessState,
ACCESS_MASK DesiredAccess,
POBJECT_TYPE ObjectType,
KPROCESSOR_MODE AccessMode,
PVOID ParseContext,
PVOID *Object
);
extern POBJECT_TYPE IoDriverObjectType;
ULONG gC2pKeyCount = 0;
VOID FilterUnload(IN PDRIVER_OBJECT pDriverObject);
VOID c2pDetach(IN PDEVICE_OBJECT pDeviceObject);
NTSTATUS AllIrpOther(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp);
NTSTATUS FilterPower(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp);//IRP_MJ_POWER要调用一个PoCallDriver与PoStartNextPowerIrp
NTSTATUS FilterPnp(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp);//IRP_MJ_PNP还要一个PNP(即插即用)分发函数
NTSTATUS AttachDeviceObject(PDRIVER_OBJECT pDriverObject);
NTSTATUS FilterReadIrp(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp);//read irp
NTSTATUS FilterCompletionRoutine(IN PDEVICE_OBJECT pCRDeviceObject,IN PIRP pCRIrp,IN PVOID Context);
void __stdcall print_keystroke(UCHAR sch);
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING puServiceRegPath)
{
int i;
for (i=0;i<IRP_MJ_MAXIMUM_FUNCTION+1;i++)
{
pDriverObject->MajorFunction[i]=AllIrpOther;
}
pDriverObject->DriverUnload=FilterUnload;//卸载函数
pDriverObject->MajorFunction[IRP_MJ_POWER]=FilterPower;
pDriverObject->MajorFunction[IRP_MJ_PNP]=FilterPnp;
pDriverObject->MajorFunction[IRP_MJ_READ]=FilterReadIrp;
return AttachDeviceObject(pDriverObject);
}
/************************************************************************/
/* 其它直接用IoCallDriver把IRP传到下一层驱动中 */
/************************************************************************/
NTSTATUS AllIrpOther(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp)
{
PFILTER_DEVICE_EXTEN pFilterExten;
KdPrint(("Other IRP!\n"));
pFilterExten=(PFILTER_DEVICE_EXTEN)pDeviceObject->DeviceExtension;
IoSkipCurrentIrpStackLocation(pIrp);
return IoCallDriver(pFilterExten->LowDeviceObject,pIrp);
}
/************************************************************************/
/*生成过滤设备并绑定键盘设备及保存各种设备地址在扩展设备中 */
/************************************************************************/
NTSTATUS AttachDeviceObject(PDRIVER_OBJECT pDriverObject)
{
NTSTATUS status;
UNICODE_STRING uKbdKeyName;
PFILTER_DEVICE_EXTEN pFilterExten;
PDEVICE_OBJECT pTargetDevice=NULL;
PDEVICE_OBJECT pLowDevice=NULL;
PDEVICE_OBJECT pFilterDevice=NULL;
PDRIVER_OBJECT KbdDriverObject = NULL;
RtlInitUnicodeString(&uKbdKeyName, L"");
status = ObReferenceObjectByName (
&uKbdKeyName,
OBJ_CASE_INSENSITIVE,
NULL,
0,
IoDriverObjectType,
KernelMode,
NULL,
&KbdDriverObject
);
if(!NT_SUCCESS(status))
{
KdPrint(("找不到驱动对象。\n"));
return( status );
}
else
{
ObDereferenceObject(pDriverObject);
}
pTargetDevice=KbdDriverObject->DeviceObject;
while (pTargetDevice)
{
status=IoCreateDevice(pDriverObject,
sizeof(FILTER_DEVICE_EXTEN),
NULL,
pTargetDevice->Type,
pTargetDevice->Characteristics,
FALSE,
&pFilterDevice);
if (!NT_SUCCESS(status))
{
KdPrint(("Create Device Error!\n"));
return status;
}
pLowDevice=IoAttachDeviceToDeviceStack(pFilterDevice,pTargetDevice);
if (!pLowDevice)
{
KdPrint(("Attach Device No Success!\n"));
return status;
}
pFilterExten=(PFILTER_DEVICE_EXTEN)pFilterDevice->DeviceExtension;
RtlZeroMemory(pFilterExten,sizeof(FILTER_DEVICE_EXTEN));//zero memory
pFilterExten->pFilterDeviceObject=pFilterDevice;
pFilterExten->pTagerDeviceObject=pTargetDevice;
pFilterExten->LowDeviceObject=pLowDevice;
KeInitializeSpinLock(&(pFilterExten->Lockspin));
KeInitializeEvent(&(pFilterExten->ProcessEvent), NotificationEvent, FALSE);
pFilterDevice->DeviceType=pLowDevice->DeviceType;
pFilterDevice->Characteristics=pLowDevice->Characteristics;
pFilterDevice->StackSize=pLowDevice->StackSize+1;
pFilterDevice->Flags |= pLowDevice->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE) ;
//next device
pTargetDevice =pTargetDevice->NextDevice;
}
return status;
}
/************************************************************************/
/* IRP_MJ_POWER */
/************************************************************************/
NTSTATUS FilterPower(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp)
{
PFILTER_DEVICE_EXTEN pFilterExten;
pFilterExten =(PFILTER_DEVICE_EXTEN)pDeviceObject->DeviceExtension;
PoStartNextPowerIrp( pIrp );
IoSkipCurrentIrpStackLocation( pIrp );
return PoCallDriver(pFilterExten->LowDeviceObject, pIrp );
}
/************************************************************************/
/* IRP_MJ_PNP */
/************************************************************************/
NTSTATUS FilterPnp(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp)
{
PFILTER_DEVICE_EXTEN pFilterExten;
PIO_STACK_LOCATION irpStack;
NTSTATUS status = STATUS_SUCCESS;
// 获得真实设备。
pFilterExten = (PFILTER_DEVICE_EXTEN)(pDeviceObject->DeviceExtension);
irpStack = IoGetCurrentIrpStackLocation(pIrp);
switch (irpStack->MinorFunction)
{
case IRP_MN_REMOVE_DEVICE:
KdPrint(("IRP_MN_REMOVE_DEVICE\n"));
// 首先把请求发下去
IoSkipCurrentIrpStackLocation(pIrp);
IoCallDriver(pFilterExten->LowDeviceObject, pIrp);
// 然后解除绑定。
IoDetachDevice(pFilterExten->LowDeviceObject);
// 删除我们自己生成的虚拟设备。
IoDeleteDevice(pDeviceObject);
status = STATUS_SUCCESS;
break;
default:
// 对于其他类型的IRP,全部都直接下发即可。
IoSkipCurrentIrpStackLocation(pIrp);
status = IoCallDriver(pFilterExten->LowDeviceObject, pIrp);
}
return status;
}
/************************************************************************/
/* UnLoad */
/************************************************************************/
VOID FilterUnload(IN PDRIVER_OBJECT pDriverObject)
{
PDEVICE_OBJECT DeviceObject;
PDEVICE_OBJECT OldDeviceObject;
PFILTER_DEVICE_EXTEN pFilterExten;
LARGE_INTEGER lDelay;
PKTHREAD CurrentThread;
//delay some time
lDelay = RtlConvertLongToLargeInteger(-1000000);
CurrentThread = KeGetCurrentThread();
// 把当前线程设置为低实时模式,以便让它的运行尽量少影响其他程序。
KeSetPriorityThread(CurrentThread, LOW_REALTIME_PRIORITY);
UNREFERENCED_PARAMETER(pDriverObject);
KdPrint(("DriverEntry unLoading...\n"));
// 遍历所有设备并一律解除绑定
DeviceObject = pDriverObject->DeviceObject;
while (DeviceObject)
{
// 解除绑定并删除所有的设备
c2pDetach(DeviceObject);
DeviceObject = DeviceObject->NextDevice;
}
ASSERT(NULL ==pDriverObject->DeviceObject);
while (gC2pKeyCount)
{
KeDelayExecutionThread(KernelMode, FALSE, &lDelay);
}
KdPrint(("DriverEntry unLoad OK!\n"));
return;
}
VOID
c2pDetach(IN PDEVICE_OBJECT pDeviceObject)
{
PFILTER_DEVICE_EXTEN pFilterExten;
BOOLEAN NoRequestsOutstanding = FALSE;
pFilterExten = (PFILTER_DEVICE_EXTEN)pDeviceObject->DeviceExtension;
__try
{
__try
{
IoDetachDevice(pFilterExten->pTagerDeviceObject);
pFilterExten->pTagerDeviceObject = NULL;
IoDeleteDevice(pDeviceObject);
pFilterExten->pFilterDeviceObject = NULL;
DbgPrint(("Detach Finished\n"));
}
__except (EXCEPTION_EXECUTE_HANDLER){}
}
__finally{}
return;
}
/************************************************************************/
/* read irp */
/************************************************************************/
NTSTATUS FilterReadIrp(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp)
{
NTSTATUS status;
PFILTER_DEVICE_EXTEN pFilterExten;
//PIO_STACK_LOCATION currentIrpStack;
KEVENT waitEvent;
status= STATUS_SUCCESS;
KeInitializeEvent( &waitEvent, NotificationEvent, FALSE );
if (pIrp->CurrentLocation == 1)
{
KdPrint(("Dispatch encountered bogus current location\n"));
status = STATUS_INVALID_DEVICE_REQUEST;
pIrp->IoStatus.Status = status;
pIrp->IoStatus.Information = 0;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return(status);
}
// 全局变量键计数器加1
gC2pKeyCount++;
// 得到设备扩展。目的是之后为了获得下一个设备的指针。
pFilterExten=(PFILTER_DEVICE_EXTEN)pDeviceObject->DeviceExtension;
// 设置回调函数并把IRP传递下去。 之后读的处理也就结束了。
// 剩下的任务是要等待读请求完成。
//currentIrpStack = IoGetCurrentIrpStackLocation(pIrp);
IoCopyCurrentIrpStackLocationToNext(pIrp);
IoSetCompletionRoutine( pIrp, FilterCompletionRoutine,
pDeviceObject, TRUE, TRUE, TRUE );
return IoCallDriver( pFilterExten->LowDeviceObject, pIrp );
}
NTSTATUS FilterCompletionRoutine(IN PDEVICE_OBJECT pCRDeviceObject,IN PIRP pCRIrp,IN PVOID Context)
{
PIO_STACK_LOCATION IrpSp;
ULONG buf_len;
PUCHAR buf;
size_t i,numKeys;
PKEYBOARD_INPUT_DATA KeyData;
buf = NULL;
buf_len = 0;
IrpSp = IoGetCurrentIrpStackLocation( pCRIrp );
// 如果这个请求是成功的。很显然,如果请求失败了,这么获取
// 进一步的信息是没意义的。
if( NT_SUCCESS( pCRIrp->IoStatus.Status ) )
{
// 获得读请求完成后输出的缓冲区
buf = pCRIrp->AssociatedIrp.SystemBuffer;
KeyData = (PKEYBOARD_INPUT_DATA)buf;
// 获得这个缓冲区的长度。一般的说返回值有多长都保存在
// Information中。
buf_len = pCRIrp->IoStatus.Information;
numKeys = buf_len / sizeof(KEYBOARD_INPUT_DATA);
//… 这里可以做进一步的处理。我这里很简单的打印出所有的扫
// 描码。
//for(i=0;i<buf_len;++i)
for(i=0;i<numKeys;++i)
{
//DbgPrint("ctrl2cap: %2x\r\n", buf[i]);
DbgPrint("\n");
//DbgPrint("numKeys : %d",numKeys);
DbgPrint("ScanCode: %x ", KeyData[i].MakeCode);
//DbgPrint("%s\n", KeyData[i].Flags ?"Up" : "Down" );
print_keystroke((UCHAR)KeyData->MakeCode);
if( KeyData[i].MakeCode == CAPS_LOCK)
{
KeyData[i].MakeCode = LCONTROL;
}
}
}
gC2pKeyCount--;
if( pCRIrp->PendingReturned )
{
IoMarkIrpPending( pCRIrp );
}
return pCRIrp->IoStatus.Status;
}
// flags for keyboard status
#define S_SHIFT 1
#define S_CAPS 2
#define S_NUM 4
static int kb_status = S_NUM;
void __stdcall print_keystroke(UCHAR sch)
{
UCHAR ch = 0;
int off = 0;
if ((sch & 0x80) == 0) //make
{
if ((sch < 0x47) ||
((sch >= 0x47 && sch < 0x54) && (kb_status & S_NUM))) // Num Lock
{
ch = asciiTbl[off+sch];
}
switch (sch)
{
case 0x3A:
kb_status ^= S_CAPS;
break;
case 0x2A:
case 0x36:
kb_status |= S_SHIFT;
break;
case 0x45:
kb_status ^= S_NUM;
}
}
else //break
{
if (sch == 0xAA || sch == 0xB6)
kb_status &= ~S_SHIFT;
}
if (ch >= 0x20 && ch < 0x7F)
{
DbgPrint("%C \n",ch);
}
}