VOID EvtIoDeviceControl(IN WDFQUEUE Queue, IN WDFREQUEST Request, IN size_t OutputBufferLength, IN size_t InputBufferLength, IN ULONG IoControlCode) { WDFDEVICE Device = WdfIoQueueGetDevice(Queue); UNREFERENCED_PARAMETER(OutputBufferLength); UNREFERENCED_PARAMETER(InputBufferLength); switch (IoControlCode) { case IOCTL_PCIDTF_GET_INFO: PciDtfDeviceGetInfo(Device, Request); break; case IOCTL_PCIDTF_READ_CFG: PciDtfDeviceReadWriteCfg(Device, Request, TRUE); break; case IOCTL_PCIDTF_WRITE_CFG: PciDtfDeviceReadWriteCfg(Device, Request, FALSE); break; case IOCTL_PCIDTF_GET_REG: PciDtfDeviceGetReg(Device, Request); break; case IOCTL_PCIDTF_READ_REG: PciDtfDeviceReadWriteReg(Device, Request, TRUE); break; case IOCTL_PCIDTF_WRITE_REG: PciDtfDeviceReadWriteReg(Device, Request, FALSE); break; case IOCTL_PCIDTF_ALLOC_DMA: PciDtfDeviceAllocDma(Device, Request); break; case IOCTL_PCIDTF_FREE_DMA: PciDtfDeviceFreeDma(Device, Request); break; case IOCTL_PCIDTF_READ_DMA: PciDtfDeviceReadWriteDma(Device, Request, TRUE); break; case IOCTL_PCIDTF_WRITE_DMA: PciDtfDeviceReadWriteDma(Device, Request, FALSE); break; case IOCTL_PCIDTF_GET_DMA_INFO: PciDtfDeviceGetDma(Device, Request); break; default: TRACE_MSG(TRACE_LEVEL_ERROR, TRACE_FLAG_QUEUE, "Unsupported I/O control code=0x%X (0x%X)\n", IoControlCode, IoGetFunctionCodeFromCtlCode(IoControlCode)); WdfRequestComplete(Request, STATUS_INVALID_DEVICE_REQUEST); break; } }
/******************************************************************************* * * 函 数 名 : DispatchDeviceControl * 功能描述 : * 参数列表 : pDriverObj -- * pIrp * 说 明 : * 返回结果 : 成功返回 STATUS_SUCCESS * *******************************************************************************/ NTSTATUS DispatchDeviceControl(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp) { NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST; // STATUS_UNSUCCESSFUL PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp); ULONG uIoControlCode = 0; PVOID pIoBuffer = NULL; ULONG uInSize = 0; ULONG uOutSize = 0; PHIDE_INFO pHi = NULL ; PPROTECT_PID_INFO pPi = NULL ; PPROTECT_NAME_INFO pNi = NULL ; PDEVICE_EXTENSION pde = (PDEVICE_EXTENSION)pDevObj->DeviceExtension ; // Get the IoCtrl Code uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode; // Get the buffer info pIoBuffer = pIrp->AssociatedIrp.SystemBuffer; uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength; uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength; KdBreakPoint() ; KeWaitForSingleObject(&pde->DeviceIoControlMutex, Executive, KernelMode, FALSE, NULL) ; switch(uIoControlCode) { // 添加要保护的进程名 case IOCTRL_ADD_PROTECT_NAME: { pNi = (PPROTECT_NAME_INFO)pIoBuffer ; if (sizeof(PROTECT_NAME_INFO) != uInSize || NULL == pNi) { break ; } // 这里可以判断一下返回值 if(AddProtectProcessName(pNi->ProcessName)) { status = STATUS_SUCCESS ; } } break ; case IOCTRL_ADD_PROTECT_PID: { pPi = (PPROTECT_PID_INFO)pIoBuffer ; if (sizeof(PROTECT_PID_INFO) != uInSize || NULL == pPi) { break ; } // 这里可以判断一下返回值 if( AddProtectProcessPID(pPi->uPID)) { status = STATUS_SUCCESS ; } } break ; // 处理隐藏进程 case IOCTRL_HIDE: { // Receive data form Application //dprintf("IOCTRL_HIDE\r\n"); // Do we have any data? // 判断传进来的参数是否正确 pHi = (PHIDE_INFO)pIoBuffer ; if (sizeof(HIDE_INFO) != uInSize || NULL == pHi) { break ; } // 这里可以判断一下返回值 if( HideProcess(pDevObj, pHi->uPID) ) { status = STATUS_SUCCESS ; } } break ; case IOCTRL_START_FILTER: { if (! pde->bIsFiltrateProcess) { pde->bIsFiltrateProcess = true ; status = STATUS_SUCCESS ; } } break ; case IOCTRL_STOP_FILTER: { if (pde->bIsFiltrateProcess) { pde->bIsFiltrateProcess = false ; status = STATUS_SUCCESS ; } } break ; // // TODO: Add execute code here. // default: { // Invalid code sent dprintf("Unknown IOCTL: 0x%X (%04X,%04X)\r\n", uIoControlCode, DEVICE_TYPE_FROM_CTL_CODE(uIoControlCode), IoGetFunctionCodeFromCtlCode(uIoControlCode)); status = STATUS_INVALID_PARAMETER; } break; } if(status == STATUS_SUCCESS) { pIrp->IoStatus.Information = uOutSize; } else { pIrp->IoStatus.Information = 0; } // Complete the I/O Request pIrp->IoStatus.Status = status; KeReleaseMutex(&pde->DeviceIoControlMutex, FALSE) ; IoCompleteRequest(pIrp, IO_NO_INCREMENT); return status; }
NTSTATUS DispatchDeviceControl(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp) { NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST; // STATUS_UNSUCCESSFUL PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp); ULONG uIoControlCode = 0; PVOID pIoBuffer = NULL; ULONG uInSize = 0; ULONG uOutSize = 0; // Get the IoCtrl Code uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode; pIoBuffer = pIrp->AssociatedIrp.SystemBuffer; uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength; uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength; switch(uIoControlCode) { case IOCTL_HELLO_WORLD: { dprintf("MY_CTL_CODE(0)=%d\r\n,MY_CTL_CODE"); // Return success status = STATUS_SUCCESS; } break; case IOCTRL_REC_FROM_APP: { // Receive data form Application //dprintf("IOCTRL_REC_FROM_APP\r\n"); // Do we have any data? if( uInSize > 0 ) { dprintf("Get Data from App: %ws\r\n", pIoBuffer); } // Return success status = STATUS_SUCCESS; } break; case IOCTRL_SEND_TO_APP: { // Send data to Application //dprintf("IOCTRL_SEND_TO_APP\r\n"); // If we have enough room copy the data upto the App - note copy the terminating character as well... if( uOutSize >= strlen( DATA_TO_APP ) + 1 ) { RtlCopyMemory( pIoBuffer, DATA_TO_APP, strlen( DATA_TO_APP ) + 1 ); // Update the length for the App pIrp->IoStatus.Information = strlen( DATA_TO_APP ) + 1; dprintf("Send Data to App: %s\r\n", pIoBuffer); // Return success status = STATUS_SUCCESS; } } break; // // TODO: Add execute code here. // default: { // Invalid code sent dprintf("Unknown IOCTL: 0x%X (%04X,%04X)\r\n", uIoControlCode, DEVICE_TYPE_FROM_CTL_CODE(uIoControlCode), IoGetFunctionCodeFromCtlCode(uIoControlCode)); status = STATUS_INVALID_PARAMETER; } break; } if(status == STATUS_SUCCESS) { pIrp->IoStatus.Information = uOutSize; } else { pIrp->IoStatus.Information = 0; } // Complete the I/O Request pIrp->IoStatus.Status = status; IoCompleteRequest(pIrp, IO_NO_INCREMENT); return status; }
NTSTATUS DiskDevDispatch(IN PDEVICE_OBJECT HookDevice,IN PIRP Irp) { PIO_STACK_LOCATION currentIrpStack=IoGetCurrentIrpStackLocation(Irp); ULONG ioControlCode; VERDICT Verdict; NTSTATUS ntStatus = STATUS_SUCCESS; PDISK_DEV_LIST DevEntry; ULONG Function; ANSI_STRING fullPathName; BOOLEAN FPNAllocated=FALSE; ULONG actualLen; PCHAR Action; ULONG ParamVal = 0; LARGE_INTEGER ByteOffset; POBJECT_NAME_INFORMATION DevName=NULL; KIRQL CurrIrql; BOOLEAN bInvisible; ULONG SectorSize = 0; ULONG DataLength = 0; ULONG ReqDataSize; PVOID RequestData; PSINGLE_PARAM pSingleParam; PFILTER_EVENT_PARAM pParam; ByteOffset.LowPart = 0; ByteOffset.HighPart = 0; fullPathName.Buffer=NULL; CurrIrql = KeGetCurrentIrql(); if (CurrIrql < DISPATCH_LEVEL) { ReqDataSize = sizeof(FILTER_EVENT_PARAM) + sizeof(SINGLE_PARAM) + MAXPATHLEN + 1 + sizeof(SINGLE_PARAM) + sizeof(ULONG) + sizeof(SINGLE_PARAM) + sizeof(LARGE_INTEGER); ReqDataSize += sizeof (SINGLE_PARAM) + __SID_LENGTH; RequestData = ExAllocatePoolWithTag(NonPagedPool, ReqDataSize, 'RboS'); pParam = (PFILTER_EVENT_PARAM)RequestData; if (pParam == NULL) { DbPrint(DC_DISK,DL_ERROR, ("Allocate buffer in DiskDevDispatch for RequestData failed\n")); } else { FILTER_PARAM_COMMONINIT(pParam, FLTTYPE_DISK, 0, 0, PreProcessing, 3); pSingleParam = (PSINGLE_PARAM) pParam->Params; // pParam->ProcName[0] = 0; // GetProcName(pParam->ProcName,NULL);//Irp???? if(CurrIrql<DISPATCH_LEVEL) { if(HookDevice->Flags & DO_DEVICE_HAS_NAME) { if(DevName = ExAllocatePoolWithTag(NonPagedPool,MAXPATHLEN*sizeof(WCHAR),'DSeB')) { if(NT_SUCCESS(ObQueryNameString(HookDevice,DevName,MAXPATHLEN*sizeof(WCHAR),&actualLen))) { if(fullPathName.Buffer = ExAllocatePoolWithTag(NonPagedPool,MAXPATHLEN,'DSeB')) { FPNAllocated=TRUE; fullPathName.Length=0; fullPathName.MaximumLength=MAXPATHLEN; RtlUnicodeStringToAnsiString(&fullPathName,&DevName->Name,FALSE); } } } } else { if(fullPathName.Buffer=ExAllocatePoolWithTag(NonPagedPool,MAXPATHLEN,'DSeB')) { FPNAllocated=TRUE; fullPathName.Length=10; fullPathName.MaximumLength=MAXPATHLEN; sprintf(fullPathName.Buffer,">%08x<",HookDevice); } } } pParam->FunctionMj = currentIrpStack->MajorFunction; if(currentIrpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL || currentIrpStack->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL) { ioControlCode = IoGetFunctionCodeFromCtlCode(currentIrpStack->Parameters.DeviceIoControl.IoControlCode);//(currentIrpStack->Parameters.DeviceIoControl.IoControlCode & 0x1ffc)>>2; if(ioControlCode > sizeof(NTDiskDeviceIOCTLName)/sizeof(PVOID)) { DbPrint(DC_DISK,DL_SPAM, ("!!! Disk_IOCTL 0x%x(0x%x) %s\n", currentIrpStack->Parameters.DeviceIoControl.IoControlCode, ioControlCode, fullPathName.Buffer == NULL ? UnknownStr : fullPathName.Buffer)); ioControlCode=0; } pParam->FunctionMi = ioControlCode; } else if(currentIrpStack->MajorFunction==IRP_MJ_READ || currentIrpStack->MajorFunction==IRP_MJ_WRITE) { SectorSize = currentIrpStack->DeviceObject->SectorSize == 0 ? 512 : currentIrpStack->DeviceObject->SectorSize; ParamVal=(ULONG)(*(__int64*)(¤tIrpStack->Parameters.Read.ByteOffset)/SectorSize); ByteOffset = currentIrpStack->Parameters.Read.ByteOffset; DataLength = currentIrpStack->Parameters.Read.Length; DbPrint(DC_DISK,DL_SPAM, ("%s %s Sec=%u Len=%u\n", NTMajorFunctionName[currentIrpStack->MajorFunction], fullPathName.Buffer == NULL ? UnknownStr : fullPathName.Buffer, ParamVal, DataLength)); pParam->FunctionMi = currentIrpStack->MinorFunction; } else pParam->FunctionMi = currentIrpStack->MinorFunction; #ifdef __DBG__ Action=ExAllocatePoolWithTag(NonPagedPool,MY_PAGE_SIZE,'DSeB'); if(Action) { DbPrint(DC_DISK,DL_INFO, ("%s %s (IRQL=%d)\n", NTGetFunctionStr(Action, pParam->HookID, pParam->FunctionMj, pParam->FunctionMi), fullPathName.Buffer == NULL ? UnknownStr : fullPathName.Buffer, CurrIrql)); ExFreePool(Action); } #endif //__DBG__ #ifdef __DBG__ // if(IoIsOperationSynchronous(Irp)==FALSE) // DbPrint(DC_DISK,DL_NOTIFY,("^^^^^^^^^ Async operation !!!!!!!!!\n")); #endif //__DBG__ if (IsNeedFilterEventAsyncChk(pParam->HookID, pParam->FunctionMj, pParam->FunctionMi,Irp, &bInvisible) == TRUE) { SINGLE_PARAM_INIT_NONE(pSingleParam, _PARAM_OBJECT_URL); sprintf(pSingleParam->ParamValue, "%s", fullPathName.Buffer); //сюда имя девайса pSingleParam->ParamSize = strlen(pSingleParam->ParamValue) + 1; SINGLE_PARAM_SHIFT(pSingleParam); SINGLE_PARAM_INIT_LARGEINTEGER(pSingleParam, _PARAM_OBJECT_BYTEOFFSET, ByteOffset); //+ ---------------------------------------------------------------------------------------- SINGLE_PARAM_SHIFT(pSingleParam); SINGLE_PARAM_INIT_ULONG(pSingleParam, _PARAM_OBJECT_DATALEN, DataLength); // ----------------------------------------------------------------------------------------- // reserve place for sid SINGLE_PARAM_SHIFT(pSingleParam); SINGLE_PARAM_INIT_SID(pSingleParam); pParam->ParamsCount++; // end reserve place for sid // ----------------------------------------------------------------------------------------- Verdict = FilterEvent(pParam, NULL); if(!_PASS_VERDICT(Verdict)) { if(Verdict == Verdict_Kill) { DbPrint(DC_DISK,DL_NOTIFY, ("Kill %s\n", pParam->ProcName)); KillCurrentProcess(); } else if(Verdict == Verdict_Discard) { DbPrint(DC_DISK,DL_NOTIFY, ("Discard disk operation\n"/*, pSingleParam->ParamValue*/)); } ntStatus = STATUS_ACCESS_DENIED; } } ExFreePool(RequestData); } } if (ntStatus != STATUS_ACCESS_DENIED) { DevEntry=DiskDevList; while(DevEntry) { if(DevEntry->Drv==HookDevice->DriverObject) break; DevEntry=DevEntry->Next; } if(DevEntry) ntStatus=(DevEntry->DiskDevDispArray[currentIrpStack->MajorFunction])(HookDevice,Irp); else { DbPrint(DC_DISK,DL_WARNING, ("!!! DiskDevDispatch. Device 0x%x (Drv=0x%x) not found in hooked list\n",HookDevice,HookDevice->DriverObject)); ntStatus=Irp->IoStatus.Status=STATUS_NO_SUCH_DEVICE; Irp->IoStatus.Information=0; IoCompleteRequest(Irp,IO_NO_INCREMENT); } } if (DevName != NULL) ExFreePool(DevName); if (fullPathName.Buffer != NULL) ExFreePool(fullPathName.Buffer); return ntStatus; }
NTSTATUS FWDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { NTSTATUS Status = STATUS_SUCCESS; PIO_STACK_LOCATION irpStack; PDEVICE_EXTENSION deviceExtension; PVOID ioBuf; ULONG inBufLength, outBufLength; ULONG ioControlCode; ULONG_PTR num=0; irpStack = IoGetCurrentIrpStackLocation(Irp); deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; Irp->IoStatus.Information = 0; // // Get the pointer to the input/output buffer and it's length // ioBuf = Irp->AssociatedIrp.SystemBuffer; inBufLength = irpStack->Parameters.DeviceIoControl.InputBufferLength; outBufLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength; ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode; // Irp->UserBuffer; // If METHOD_NEITHER, This is Output Buffer switch (ioControlCode) { case IOCTL_SETUPFW: { // if (g_AlreadyHookTCPIP) { InterlockedExchange(&g_InterceptTCPIPRcv, 1); } else { Status= FWHookTcpipRecvHandler(); if (NT_SUCCESS(Status)) { InterlockedExchange(&g_InterceptTCPIPRcv, 1); g_AlreadyHookTCPIP = 1; } } break; } case IOCTL_UNSETFW: { // InterlockedExchange(&g_InterceptTCPIPRcv, 0); //UNHOOK的行为就放到驱动卸载时候了 break; } case IOCTL_PENDDINGCHECKPORT: { //pendding进去 IoMarkIrpPending(Irp); ExInterlockedInsertHeadList(&g_AskUserConnectListHeader, &Irp->Tail.Overlay.ListEntry, &g_AskUserConnectListLock); Status= STATUS_PENDING; Irp->IoStatus.Status = Status; return Status; break; } case IOCTL_SETONEPORTSTATUS: { Status = SetupPortStatus(ioBuf, 1); break; } case IOCTL_RESPONSEPORTASK: { Status = ResponsePortAsk((PFIREWALL_ASKUSER)ioBuf); break; } case IOCTL_ReleasePENDDINGCHECKPORT: { Status = ReleasePenddingCheckPortIrp(); break; } case IOCTL_GETPORTSTATUS: { Status = GetPortRules(ioBuf, &outBufLength); if (Status==STATUS_INFO_LENGTH_MISMATCH) { Status = STATUS_SUCCESS; } Irp->IoStatus.Information = outBufLength; break; } default: { //Status = STATUS_INVALID_PARAMETER; kprintf("[SuperCI] Unknown IOCTL: 0x%X (%04X,%04X)\n", ioControlCode, DEVICE_TYPE_FROM_CTL_CODE(ioControlCode), IoGetFunctionCodeFromCtlCode(ioControlCode)); break; } } Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; }