阅读:1403回复:2
请KMK大侠进来指点一下,这个问题已经折磨我一个礼拜了
在利用IP Filter Hook写一个简单的防火墙,但中间出现异常一直不明白是怎么回事,请高手帮忙分析一下:
应用程序调用AddFilter时通过DeviceIoControl传递一个IPFilter结构到驱动中,但在驱动中读取Irp->AssociatedIrp.SystemBuffer;出现页面访问异常,softice提示:Break due to Page Fault(0Eh) fault=0000 驱动主要源代码如下: NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { PDEVICE_OBJECT deviceObject = NULL; NTSTATUS ntStatus; UNICODE_STRING deviceNameUnicodeString; PDEVICE_EXTENSION deviceExtension; UNICODE_STRING deviceLinkUnicodeString; dprintf(\"tempDrv.SYS: entering DriverEntry\\n\"); RtlInitUnicodeString(&deviceNameUnicodeString, NT_DEVICE_NAME); ntStatus = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), &deviceNameUnicodeString, FILE_DEVICE_UNKNOWN, 0, TRUE, &deviceObject); if ( NT_SUCCESS(ntStatus) ) { deviceExtension = (PDEVICE_EXTENSION)deviceObject->DeviceExtension; deviceObject->Flags |= DO_BUFFERED_IO; RtlInitUnicodeString(&deviceLinkUnicodeString, DOS_DEVICE_NAME); ntStatus = IoCreateSymbolicLink(&deviceLinkUnicodeString, &deviceNameUnicodeString); if ( !NT_SUCCESS(ntStatus) ) { dprintf(\"tempDrv.SYS: IoCreateSymbolicLink failed\\n\"); } DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverObject->MajorFunction[IRP_MJ_CLOSE] = DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DrvDispatch; DriverObject->DriverUnload = DrvUnload; } if ( !NT_SUCCESS(ntStatus) ) { if (deviceObject) IoDeleteDevice(deviceObject); } return ntStatus; } NTSTATUS DrvDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PIO_STACK_LOCATION irpStack; PDEVICE_EXTENSION deviceExtension; PVOID ioBuffer; ULONG inputBufferLength; ULONG outputBufferLength; ULONG ioControlCode; NTSTATUS ntStatus; Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; irpStack = IoGetCurrentIrpStackLocation(Irp); deviceExtension = DeviceObject->DeviceExtension; ioBuffer = Irp->AssociatedIrp.SystemBuffer; inputBufferLength = irpStack->Parameters.DeviceIoControl.InputBufferLength; outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength; switch (irpStack->MajorFunction) { case IRP_MJ_CREATE: dprintf(\"tempDrv.SYS: IRP_MJ_CREATE\\n\"); break; case IRP_MJ_CLOSE: dprintf(\"tempDrv.SYS: IRP_MJ_CLOSE\\n\"); break; case IRP_MJ_DEVICE_CONTROL: dprintf(\"tempDrv.SYS: IRP_MJ_DEVICE_CONTROL\\n\"); ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode; switch (ioControlCode) { case IO_TEMPDRV_TEST: { dprintf(\"tempDrv.SYS: IO_TEMPDRV_TEST\\n\"); //*(UCHAR*)ioBuffer = \'a\'; Irp->IoStatus.Information = 1; break; } case IO_TEMPDRV_START: { dprintf(\"tempDrv.SYS: IO_TEMPDRV_START\\n\"); SetFilterFunction(FilterIpPacket); break; } case IO_TEMPDRV_STOP: { dprintf(\"tempDrv.SYS: IO_TEMPDRV_STOP\\n\"); SetFilterFunction(NULL); break; } case IO_ADD_RULE: { dprintf(\"tempDrv.SYS: IO_ADD_RULE inputBufLen:%d %d\\n\", inputBufferLength, sizeof(stFilterRule)); if (inputBufferLength == sizeof(stFilterRule)) { AddFilterRule((stFilterRule *) ioBuffer); } break; } .... default: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; dprintf(\"tempDrv.SYS: unknown IRP_MJ_DEVICE_CONTROL\\n\"); break; } break; } ntStatus = Irp->IoStatus.Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); // // We never have pending operation so always return the status code. // return ntStatus; } ULONG AddFilterRule(stFilterRule *pFr) { //strcat(SystemAddrMemory, \"In AddFilterRule \\r\\n\"); if (g_RuleNum >= MAX_FILTER_RULE ) { return 1; } memcpy(g_filterRule[g_RuleNum], pFr, sizeof(stFilterRule)); g_RuleNum++; return STATUS_SUCCESS; } 应用程序主要代码如下: BOOL CTestDrvDlg::AddFilter(IPFilter pf) { //we send the rule to the driver DWORD result = ipFltDrv.WriteIo(IO_ADD_RULE, &pf, sizeof(pf)); if (result != DRV_SUCCESS) { AfxMessageBox(\"DeviceIoControl IO_ADD_RULE\"); return FALSE; } else return TRUE; } void CTestDrvDlg::OnStart() { DWORD result; char szInBuf[200]; char szOutBuf[200]; //first i send one rule, for example, not permit icmp traffic IPFilter pf; /* pf.protocol = 1; //ICMP protocol pf.destinationIp = 0; //all destinations pf.sourceIp = 0; //all sources pf.destinationMask = 0; pf.sourceMask = 0; pf.destinationPort = 0; //all ports. As protocol isnt tcp neither udp, we can pass other values pf.sourcePort = 0; //all ports. As protocol isnt tcp neither udp, we can pass other values pf.drop = TRUE; //drop all this traffic result = AddFilter(pf); //send the rule */ //second, other rule. Web traffic is not allowed in this server pf.protocol = 6; //TCP protocol pf.destinationIp = inet_addr(\"127.0.0.1\"); //127.0.0.1, this host pf.sourceIp = 0; //all sources pf.destinationPort = htons(80); //all ports. As protocol isnt tcp neither udp, we can pass other values pf.sourcePort = 0; //all ports. As protocol isnt tcp neither udp, we can pass other values pf.drop = 0; //drop all this traffic result = AddFilter(pf); //send the rule // then i start to filter if(ipFltDrv.WriteIo(IO_TEMPDRV_START, NULL, 0) != DRV_ERROR_IO) { m_bStart.EnableWindow(FALSE); m_bStop.EnableWindow(TRUE); } } //Funtion to send data to the driver DWORD TDriver::WriteIo(DWORD code, PVOID buffer, DWORD count) { if(driverHandle == NULL) return DRV_ERROR_INVALID_HANDLE; DWORD bytesReturned; BOOL returnCode = DeviceIoControl(driverHandle, code, buffer, count, NULL, 0, &bytesReturned, NULL); if(!returnCode) return DRV_ERROR_IO; return DRV_SUCCESS; } [编辑 - 5/22/05 by portal_zhb] |
|
最新喜欢:![]() |
沙发#
发布于:2005-05-22 21:27
多谢,是ioctl_code定义错了,该成METHOD_BUFFERED后就OK了!
[编辑 - 5/22/05 by portal_zhb] |
|
板凳#
发布于:2005-05-22 20:40
既然你用Irp->AssociatedIrp.SystemBuffer,ioctl_code定义的时候就不要用METHORD_NEITHER,你检查一下,SystemBuffer是不是空
指针,如果不是,就是拷贝的长度大于SystemBuffer的大小了 |
|