阅读:3078回复:1
minifilter下过滤写操作无法使用FltDoCompletionProcessingWhenSafe 或FltQueueDeferredIoWorkItem
学习MINIFILTER中,一反编译文件得到如下,我尝试将写成C
但是FltDoCompletionProcessingWhenSafe与FltQueueDeferredIoWorkItem总是失败 FltQueueDeferredIoWorkItem返回STATUS_FLT_NOT_SAFE_TO_POST_OPERATION 请问是什么原因? 函数主要为对写到硬盘的数据进行处理 所以设置为FLTFL_OPERATION_REGISTRATION_SKIP_CACHED_IO IRP_MJ_WRITE, FLTFL_OPERATION_REGISTRATION_SKIP_CACHED_IO, FileProPreWrite, FileProPostWrite /*****************************************************************************************/ /****************************************************************************************************************************/ int __stdcall Write_post(int a1, int a2, int a3, int a4) { int ebp0; // ebp@0 int result; // eax@1 int v6; // eax@11 int v7; // edi@11 int v8; // esi@14 signed int v9; // [sp-8h] [bp-38h]@12 int v10; // [sp-4h] [bp-34h]@12 int v11; // [sp+10h] [bp-20h]@1 char v12; // [sp+17h] [bp-19h]@1 CPPEH_RECORD ms_exc; // [sp+18h] [bp-18h]@2 result = 0; v11 = 0; v12 = 1; if ( a3 ) { ms_exc.disabled = 0; if ( *(_DWORD *)(a1 + 12) < 0 || !*(_DWORD *)(a1 + 16) ) { v11 = 0; goto LABEL_18; } if ( !(**(_BYTE **)(a1 + 8) & 0x42) ) IoGetTopLevelIrp();//此函数有发挥作用? if ( !(a4 & 1) ) { if ( (unsigned __int8)FltDoCompletionProcessingWhenSafe(a1, a2, a3, a4, sub_13DB8, &v11) )//我写的代码中这些有很大概率无法进入 { v12 = 0; goto LABEL_18; } if ( !(*(_BYTE *)a1 & 1) ) goto LABEL_18; v6 = FltAllocateDeferredIoWorkItem(); v7 = v6; if ( v6 ) { v8 = FltQueueDeferredIoWorkItem(v6, a1, sub_13E70, 1, a3);//我写的代码中这些有很大概率无法进入,返回 if ( v8 >= 0 ) { v12 = 0; v11 = 1; goto LABEL_18; } FltFreeDeferredIoWorkItem(v7); v10 = v8; v9 = 1165; } else { v10 = 0; v9 = 1155; } } v11 = 0; LABEL_18: ms_exc.disabled = -2;//异常处理 可暂时不理会 sub_147C4(a3, ebp0);//清除内存等操作 result = v11; } return result; } /********************************************************************************************************/ FLT_POSTOP_CALLBACK_STATUS FileProPostWrite( __inout PFLT_CALLBACK_DATA Data, __in PCFLT_RELATED_OBJECTS FltObjects, __in_opt PVOID CompletionContext, __in FLT_POST_OPERATION_FLAGS Flags) { PPRE_2_POST_CONTEXT p2pCtx; FLT_POSTOP_CALLBACK_STATUS RetPostOperationStatus; NTSTATUS status; PVOID newBuf = NULL; LARGE_INTEGER WriOffset; ULONG WriLen; UNICODE_STRING BackFile; OBJECT_ATTRIBUTES ObjAttrib; IO_STATUS_BLOCK IoStatusBlock = {0}; int i; HANDLE BackHandle = NULL; LARGE_INTEGER Interval; PFILE_OBJECT FileObject; ULONG WriteBytes; PFLT_DEFERRED_IO_WORKITEM PFltDefIoWorkItem = NULL; p2pCtx = CompletionContext; newBuf = p2pCtx->SwappedBuffer; //获得内存地址 if(!newBuf) { DbgPrint("PostWri SwappedBuffer is NULL\n"); ExFreeToNPagedLookasideList(&Pre2PostContextList,p2pCtx); return FLT_POSTOP_FINISHED_PROCESSING; } //确认之前写操作成功 if((Data->IoStatus.Status < 0) || !(Data->IoStatus.Information)) { DbgPrint("PostWri IRP Not Success\n"); goto PostWriEnd; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //确认写入成功开始对备份文件写入 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// WriOffset = p2pCtx->WriteOffset; WriLen = p2pCtx->WriLen; DbgPrint("p2pCtx->WriteOffset %I64d\n",p2pCtx->WriteOffset); DbgPrint("p2pCtx->WriLen %d\n",p2pCtx->WriLen); DbgPrint("Buffer Address 0x%lx\n",newBuf); if (FltDoCompletionProcessingWhenSafe(Data,FltObjects,CompletionContext,Flags, WriteSafePostCallback,&RetPostOperationStatus)) // RetPostOperationsStatus { return RetPostOperationStatus; } else { DbgPrint("FltDoCompletionProcessingWhenSafe Failed\n"); PFltDefIoWorkItem = FltAllocateDeferredIoWorkItem(); if( NULL == PFltDefIoWorkItem ) { Data->IoStatus.Status = STATUS_UNSUCCESSFUL; Data->IoStatus.Information = 0; DbgPrint("FltAllocateDeferredIoWorkItem Failed\n"); goto PostWriEnd; } status = FltQueueDeferredIoWorkItem(PFltDefIoWorkItem,Data,WriteQueueDefWorkItem,DelayedWorkQueue,CompletionContext); if(!NT_SUCCESS(status)) { Data->IoStatus.Status = STATUS_UNSUCCESSFUL; Data->IoStatus.Information = 0; FltFreeDeferredIoWorkItem(PFltDefIoWorkItem); DbgPrint("FltQueueDeferredIoWorkItem Failed %lx\n",status); goto PostWriEnd; } ExFreePool(p2pCtx->SwappedBuffer); ExFreeToNPagedLookasideList(&Pre2PostContextList,p2pCtx); return FLT_POSTOP_MORE_PROCESSING_REQUIRED; } PostWriEnd: //此处应该将释放内存放入完成例程FltDoCompletionProcessingWhenSafe中 ExFreePool(p2pCtx->SwappedBuffer); ExFreeToNPagedLookasideList(&Pre2PostContextList,p2pCtx); return FLT_POSTOP_FINISHED_PROCESSING; } |
|
沙发#
发布于:2010-12-17 11:24
或者这个问题转化成这个角度吧
我想仅仅过滤指定文件向磁盘写入内容的操作,请问如下设置对不对 { IRP_MJ_CREATE, //FLTFL_OPERATION_REGISTRATION_SKIP_CACHED_IO, 0, FileProPreCreate, FileProPostCreate}, { IRP_MJ_CLEANUP, 0, FileProPreCleanup, NULL}, { IRP_MJ_WRITE, FLTFL_OPERATION_REGISTRATION_SKIP_CACHED_IO, FileProPreWrite, FileProPostWrite}, 。。。。。。。。。 因为只是过滤磁盘操作 所以忽略掉缓存IO请问是否合适 在CREATE中进行文件名过滤 如果是我需要的文件 则设置StreamContext流上下文 然后再write写操作中进行上下文判断 这种思路是否正确? 设置流上下文及这些IRP中设置FLTFL_OPERATION_REGISTRATION_SKIP_CACHED_IO 是否正确? 因为在写操作 IRP_MJ_WRITE中截获指定文件写入磁盘的操作后 ,我想另开FltDoCompletionProcessingWhenSafe进行一些操作 根据WDK帮助 FltDoCompletionProcessingWhenSafe是不能再PAGING IO 下成功的 那么我该怎么办? THX |
|