一个基于简单USB过滤驱动。。

来源:互联网 发布:php 开源工作流引擎 编辑:程序博客网 时间:2024/05/21 14:45

 

 

对于 PS/2 的串口过滤基本上使用通用的绑定设备的方法就可以实现,那么,在 USB 的传输方式上,究竟会是什么样的呢?

对于这个问题,我在 开源的 ctr2cap 的基础上,做了一些简化的操作,让它来达到这个功能。。。

想想今天数据结构的第一次上机考试,通过 USB 来传输文件的云云。。。

如果,我是老师,你们就完了,装上我写的这个驱动,什么东西都别想出去。。。

哈哈。。。当然,我没有这样做,但是我可以基于以上做一些很猥琐的操作,那是不难的。。。

当然,这样的绑定太常规了,过段时间,我要通过 HOOK API 来实现它,或者 通过 IDT 的重定向的指针,更底层的实现以下这个过滤。。。

#include <wdm.h>

#define KBD_DRIVER_NAME L"//Driver//Kbdclass"

PDRIVER_OBJECT gDriverObject = NULL;

typedef struct _C2P_DEV_EXT

{

ULONG nodeSize;

PDEVICE_OBJECT pFltDevObj; //过滤设备

KSPIN_LOCK IoRequestsSpinLock; //保护锁

KEVENT IoInProcessEvent; //同步处理

PDEVICE_OBJECT TargeDevObj; //要绑定的设备

PDEVICE_OBJECT LowerDevObj; //绑定前的底层设备

}C2P_DEV_EXT, *PC2P_DEV_EXT;

 

//对设备扩展的初始化

NTSTATUS c2pDevExtInit(PC2P_DEV_EXT devExt,

PDEVICE_OBJECT pFltDevObj,

PDEVICE_OBJECT pTargeDevObj,

PDEVICE_OBJECT LowerDevObj

)

{

memset(devExt, 0, sizeof(C2P_DEV_EXT));

devExt->nodeSize = sizeof(C2P_DEV_EXT);

devExt->pFltDevObj = pFltDevObj;

KeInitializeSpinLock(&(devExt->IoRequestsSpinLock));

KeInitializeEvent(&(devExt->IoInProcessEvent), NotificationEvent, FALSE);

devExt->LowerDevObj = LowerDevObj;

devExt->TargeDevObj = pTargeDevObj;

return STATUS_SUCCESS;

}

 

//声明一个未公开的函数

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;

//打开驱动对象并绑定

NTSTATUS c2pAttachDevice(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)

{

NTSTATUS status = 0;

UNICODE_STRING unitNameStr;

PC2P_DEV_EXT devExt;

PDEVICE_OBJECT pFltDevObj = NULL;

PDEVICE_OBJECT pTargeDevObj = NULL;

PDEVICE_OBJECT pLowerDevObj = NULL;

PDRIVER_OBJECT kbdDriverObj = NULL;

RtlInitUnicodeString(&unitNameStr, KBD_DRIVER_NAME);

status = ObReferenceObjectByName(

&unitNameStr,

OBJ_CASE_INSENSITIVE,

NULL,

0,

IoDriverObjectType,

KernelMode,

NULL,

&kbdDriverObj);

if (!NT_SUCCESS(status))

{

KdPrint(("geting device is fail /n"));

return status;

}

else

{

ObDereferenceObject(driver);

}

pTargeDevObj = kbdDriverObj->DeviceObject; //得到设备链的第一个设备

while (pTargeDevObj)

{

status = IoCreateDevice(driver,

sizeof(C2P_DEV_EXT),

NULL,

pTargeDevObj->DeviceType,

pTargeDevObj->Characteristics,

FALSE,

&pFltDevObj);

if (!NT_SUCCESS(status))

{

KdPrint(("createing is fail/n"));

return status;

}

pLowerDevObj = IoAttachDeviceToDeviceStack(pFltDevObj, pTargeDevObj); //绑定后,返回真实的设备指针

if (NULL == pLowerDevObj)

{

KdPrint(("attach device is fail/n"));

IoDeleteDevice(pFltDevObj);

pFltDevObj = NULL;

return status;

}

devExt = (PC2P_DEV_EXT)(pFltDevObj->DeviceExtension);

c2pDevExtInit(devExt,pFltDevObj, pTargeDevObj, pLowerDevObj); //初始化设备扩展

pFltDevObj->DeviceType = pLowerDevObj->DeviceType; //拷贝原来设备的信息

pFltDevObj->Characteristics = pLowerDevObj->Characteristics;

pFltDevObj->StackSize = pLowerDevObj->StackSize + 1;

pFltDevObj->Flags |= pLowerDevObj->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE);

pTargeDevObj = pTargeDevObj->NextDevice;

}

return status;

}

 

VOID c2pDetach(PDEVICE_OBJECT pDeviceObj)

{

PC2P_DEV_EXT devExt;

BOOLEAN NoRequstOutStand = FALSE;

devExt = (PC2P_DEV_EXT)(pDeviceObj->DeviceExtension);

__try

{

__try

{

IoDetachDevice(devExt->TargeDevObj);

devExt->TargeDevObj = NULL;

IoDeleteDevice(pDeviceObj);

devExt->pFltDevObj = NULL;

KdPrint(("deAttach is over/n"));

}

__except(EXCEPTION_EXECUTE_HANDLER)

{

}

}

__finally

{

}

return;

}

 

#define DELAY_ONE_MICROSECOND (-10)

#define DELAY_ONE_MILLISECOND (DELAY_ONE_MICROSECOND*1000)

#define DELAY_ONE_SECOND (DELAY_ONE_MILLISECOND*1000)

//卸载函数

VOID DriverUnload(PDRIVER_OBJECT driver)

{

PDEVICE_OBJECT devObj = NULL;

PDEVICE_OBJECT devOldObj = NULL;

PC2P_DEV_EXT devExt;

LARGE_INTEGER lDelay;

PRKTHREAD CurrentThread;

lDelay = RtlConvertLongToLargeInteger(100 * DELAY_ONE_MILLISECOND);

CurrentThread = KeGetCurrentThread();

KdPrint(("driver is unload.../n"));

devObj = driver->DeviceObject;

while (devObj) //卸载设备对象

{

c2pDetach(devObj);

devObj = devObj->NextDevice;

}

ASSERT(NULL == driver->DeviceObject);

while(gC2pKeyCount)

{

KeDelayExecutionThread(KernelMode, FALSE, &lDelay);

}

KdPrint(("driverUnload is ok/n"));

return;

}

//普通的分发函数

NTSTATUS c2pDispatchGeneral(PDEVICE_OBJECT device,

PIRP pIrp)

{

KdPrint(("General dispatch/n"));

IoSkipCurrentIrpStackLocation(pIrp);

return IoCallDriver(((PC2P_DEV_EXT)device->DeviceExtension)->LowerDevObj, pIrp);

}

//对电源的处理

NTSTATUS c2pDispatchPower(PDEVICE_OBJECT device,

PIRP pIrp)

{

PC2P_DEV_EXT devExt;

devExt = (PC2P_DEV_EXT)(device->DeviceExtension);

PoStartNextPowerIrp(pIrp);

IoSkipCurrentIrpStackLocation(pIrp);

return PoCallDriver(devExt->LowerDevObj, pIrp);

}

//即插即用的处理

NTSTATUS c2pDispatchPnp(PDEVICE_OBJECT device, PIRP pIrp)

{

PC2P_DEV_EXT devExt;

PIO_STACK_LOCATION IrpStack;

NTSTATUS status = STATUS_SUCCESS;

KIRQL oldIrq;

KEVENT event;

devExt = (PC2P_DEV_EXT)(device->DeviceExtension);

IrpStack = IoGetCurrentIrpStackLocation(pIrp);

switch (IrpStack->MinorFunction)

{

case IRP_MN_REMOVE_DEVICE:

KdPrint(("irp_mn_remove_device/n"));

IoSkipCurrentIrpStackLocation(pIrp);

IoCallDriver(devExt->LowerDevObj, pIrp);

IoDetachDevice(devExt->LowerDevObj);

 

IoDeleteDevice(device);

return STATUS_SUCCESS;

break;

default:

IoSkipCurrentIrpStackLocation(pIrp);

status = IoCallDriver(devExt->LowerDevObj, pIrp);

}

return status;

}

//完成函数

NTSTATUS c2pCompleteRead(PDEVICE_OBJECT device,

PIRP irp,

PVOID Context)

{

PIO_STACK_LOCATION pIrp;

ULONG buf_len = 0;

PUCHAR buffer = NULL;

size_t i;

pIrp = IoGetCurrentIrpStackLocation(irp);

if (NT_SUCCESS(irp->IoStatus.Status))

{

buffer = irp->AssociatedIrp.SystemBuffer; //得到缓冲区的内容

buf_len = irp->IoStatus.Information; //得到写入的长度

for (i = 0; i < buf_len; i++)

{

KdPrint(("ctr2 is %x/n", buffer));

}

}

gC2pKeyCount--;

if (irp->PendingReturned)

{

IoMarkIrpPending(irp);

}

return irp->IoStatus.Status;

}

//读的分发函数

NTSTATUS c2pDispatchRead(PDEVICE_OBJECT devObj, PIRP irp)

{

NTSTATUS status = STATUS_SUCCESS;

PC2P_DEV_EXT devExt;

PIO_STACK_LOCATION currentIrp;

KEVENT waitEvent;

KeInitializeEvent(&waitEvent, NotificationEvent, FALSE);

if (1 == irp->CurrentLocation)

{

KdPrint(("dispatch is Error /n"));

irp->IoStatus.Status = status;

irp->IoStatus.Information = 0;

IoCompleteRequest(irp, IO_NO_INCREMENT);

return status;

}

gC2pKeyCount++;

devExt = (PC2P_DEV_EXT)(devObj->DeviceExtension);

currentIrp = IoGetCurrentIrpStackLocation(irp);

IoCopyCurrentIrpStackLocationToNext(irp);

IoSetCompletionRoutine(irp, c2pCompleteRead, devObj, TRUE, TRUE, TRUE);

return IoCallDriver(devExt->LowerDevObj, irp);

}

//主函数

NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)

{

ULONG i;

NTSTATUS status;

KdPrint(("driver is starting/n"));

for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)

{

driver->MajorFunction = c2pDispatchGeneral;

}

driver->MajorFunction[IRP_MJ_READ] = c2pDispatchRead;

driver->MajorFunction[IRP_MJ_POWER] = c2pDispatchPower;

driver->MajorFunction[IRP_MJ_PNP] = c2pDispatchPnp;

driver->DriverUnload = DriverUnload;

 

gDriverObject = driver;

status = c2pAttachDevice(driver, reg_path);

return STATUS_SUCCESS;

}