|
阅读:3589回复: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 |
|