如何在windows minifilter驱动程序中安全地获取文件名并进行比较
您好,我是filterdriver写作新手,所以我为我的基本问题道歉,我尝试从预读函数获取文件名,检查它是否等于我的文件名,并根据此信息执行一些逻辑 这是我的职责:如何在windows minifilter驱动程序中安全地获取文件名并进行比较,windows,driver,minifilter,filter-driver,Windows,Driver,Minifilter,Filter Driver,您好,我是filterdriver写作新手,所以我为我的基本问题道歉,我尝试从预读函数获取文件名,检查它是否等于我的文件名,并根据此信息执行一些逻辑 这是我的职责: FLT_PREOP_CALLBACK_STATUS SwapPreReadBuffers( _Inout_ PFLT_CALLBACK_DATA Data, _In_ PCFLT_RELATED_OBJECTS FltObjects, _Flt_CompletionContext_Outptr_ PVOID *C
FLT_PREOP_CALLBACK_STATUS SwapPreReadBuffers( _Inout_ PFLT_CALLBACK_DATA Data, _In_ PCFLT_RELATED_OBJECTS FltObjects, _Flt_CompletionContext_Outptr_ PVOID *CompletionContext )
{
PFLT_IO_PARAMETER_BLOCK iopb = Data->Iopb;
FLT_PREOP_CALLBACK_STATUS retValue = FLT_PREOP_SUCCESS_NO_CALLBACK;
PVOID newBuf = NULL;
PMDL newMdl = NULL;
PVOLUME_CONTEXT volCtx = NULL;
PPRE_2_POST_CONTEXT p2pCtx;
NTSTATUS status;
ULONG readLen = iopb->Parameters.Read.Length;
PFLT_FILE_NAME_INFORMATION NameInfo = NULL;
UNICODE_STRING FILE_NAME;
//
// Skip IRP_PAGING_IO, IRP_SYNCHRONOUS_PAGING_IO and
// TopLevelIrp.
//
if ((Data->Iopb->IrpFlags & IRP_PAGING_IO) || (Data->Iopb->IrpFlags & IRP_SYNCHRONOUS_PAGING_IO) || IoGetTopLevelIrp())
{
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
RtlInitUnicodeString( & FILE_NAME, L"my_file.txt" );
status = FltGetFileNameInformation( Data, FLT_FILE_NAME_NORMALIZED |
FLT_FILE_NAME_QUERY_DEFAULT, &NameInfo );
if (!NT_SUCCESS( status ))
{
DbgPrint("[-] SwapPreReadBuffers we couldn't extract %wZ info\n", Data->Iopb->TargetFileObject->FileName);
}
status = FltParseFileNameInformation( NameInfo );
if (!NT_SUCCESS( status ))
{
DbgPrint("[-] SwapPreReadBuffers we couldn't pars %wZ info\n", Data->Iopb->TargetFileObject->FileName);
}
DbgPrint("[+] pars gets me Name: %wZ extention: %wZ perentDir: %wZ volume: %wZ \n", NameInfo->Name, NameInfo->Extension, NameInfo->ParentDir, NameInfo->Volume);
if (RtlPrefixUnicodeString( &FILE_NAME, &NameInfo->Name, TRUE )) /* here i'm getting the blue screen*/
{
DbgPrint("[***] SwapPreReadBuffers we are at calles thats related to our file %wZ \n", Data->Iopb->TargetFileObject->FileName);
}
/* continue of the code*/
}
我的问题是,当我试图检查文件名是否等于我想要的文件名时,会出现蓝屏。
为什么司机会在这里看到蓝屏
多谢各位
坑
编辑:
我将代码更新为:
FLT_PREOP_CALLBACK_STATUS SwapPreReadBuffers( _Inout_ PFLT_CALLBACK_DATA Data, _In_ PCFLT_RELATED_OBJECTS FltObjects, _Flt_CompletionContext_Outptr_ PVOID *CompletionContext )
{
PFLT_IO_PARAMETER_BLOCK iopb = Data->Iopb;
FLT_PREOP_CALLBACK_STATUS retValue = FLT_PREOP_SUCCESS_NO_CALLBACK;
PVOID newBuf = NULL;
PMDL newMdl = NULL;
PVOLUME_CONTEXT volCtx = NULL;
NTSTATUS CbStatus = FLT_PREOP_SUCCESS_NO_CALLBACK;
PPRE_2_POST_CONTEXT p2pCtx;
NTSTATUS status;
ULONG readLen = iopb->Parameters.Read.Length;
PFLT_FILE_NAME_INFORMATION NameInfo = NULL;
UNICODE_STRING FILE_NAME;
//
// Skip IRP_PAGING_IO, IRP_SYNCHRONOUS_PAGING_IO and
// TopLevelIrp.
//
if ((Data->Iopb->IrpFlags & IRP_PAGING_IO) ||
(Data->Iopb->IrpFlags & IRP_SYNCHRONOUS_PAGING_IO) ||
IoGetTopLevelIrp()) {
DbgPrint("[-] SwapPreReadBuffers we out , this call not for us\n");
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
status = FltGetFileNameInformation( Data,
FLT_FILE_NAME_NORMALIZED
| FLT_FILE_NAME_QUERY_DEFAULT,
&NameInfo );
if (!NT_SUCCESS( status ))
{
DbgPrint("[-] SwapPreReadBuffers we couldn't extract info\n");
goto PreReadCleanup;
}
status = FltParseFileNameInformation( NameInfo );
if (!NT_SUCCESS( status ))
{
DbgPrint("[-] SwapPreReadBuffers we couldn't pars info\n");
goto PreReadCleanup;
}
if (NULL == NameInfo)
{
DbgPrint("[---] name info is actally 0\n");
}
else
{
DbgPrint("[*] address of name is %x:%x and address of extansion is %x:%x -> buffers are: name %x , extension: %x \nsize of info %d size of extension %d\n",NameInfo->Extension , &NameInfo->Extension, EXTENTION, &EXTENTION, NameInfo->Extension.Buffer , EXTENTION.Buffer ,NameInfo->Extension.Length , EXTENTION.Length);
}
if ((0 == RtlCompareUnicodeString( &EXTENTION, &NameInfo->Extension, TRUE ))) {
DbgPrint("[***] SwapPreReadBuffers we are at calles thats related to our file %wZ \n", &Data->Iopb->TargetFileObject->FileName);
DbgPrint("[+] pass parse\n");
DbgPrint("[+] pars gets me Name: %wZ\n extention: %wZ\n perentDir: %wZ\n volume: %wZ\n", &NameInfo->Name, &NameInfo->Extension, &NameInfo->ParentDir, &NameInfo->Volume);
}
else{
DbgPrint("[*] we pass compration check\n");
goto PreReadCleanup;
}
//
// Clean up
//
PreReadCleanup:
if (NameInfo) {
FltReleaseFileNameInformation( NameInfo );
}
return retValue;
}
我又看到了一个蓝屏,这是经过分析的堆芯转储:
kd> !analyze -v
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************
PAGE_FAULT_IN_NONPAGED_AREA (50)
Invalid system memory was referenced. This cannot be protected by try-except,
it must be protected by a Probe. Typically the address is just plain bad or it
is pointing at freed memory.
Arguments:
Arg1: 994af2a4, memory referenced.
Arg2: 00000000, value 0 = read operation, 1 = write operation.
Arg3: 82a72a17, If non-zero, the instruction address which referenced the bad memory
address.
Arg4: 00000000, (reserved)
Debugging Details:
------------------
READ_ADDRESS: GetPointerFromAddress: unable to read from 829a5718
Unable to read MiSystemVaType memory at 829851a0
994af2a4
FAULTING_IP:
nt!RtlCompareUnicodeStrings+3c
82a72a17 0fb706 movzx eax,word ptr [esi]
MM_INTERNAL_CODE: 0
CUSTOMER_CRASH_COUNT: 1
DEFAULT_BUCKET_ID: WIN7_DRIVER_FAULT
BUGCHECK_STR: 0x50
PROCESS_NAME: cmd.exe
CURRENT_IRQL: 0
TRAP_FRAME: a72b7974 -- (.trap 0xffffffffa72b7974)
ErrCode = 00000000
eax=00000003 ebx=994af2aa ecx=8da2064c edx=000000bf esi=994af2a4 edi=137f5b5e
eip=82a72a17 esp=a72b79e8 ebp=a72b79f4 iopl=0 nv up ei pl nz ac po nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010212
nt!RtlCompareUnicodeStrings+0x3c:
82a72a17 0fb706 movzx eax,word ptr [esi] ds:0023:994af2a4=????
Resetting default scope
LAST_CONTROL_TRANSFER: from 8287c3d8 to 828c941b
STACK_TEXT:
a72b795c 8287c3d8 00000000 994af2a4 00000000 nt!MmAccessFault+0x106
a72b795c 82a72a17 00000000 994af2a4 00000000 nt!KiTrap0E+0xdc
a72b79f4 82a72b0f 994af2aa 00000003 acca4e02 nt!RtlCompareUnicodeStrings+0x3c
a72b7a10 994a9105 994ad090 acca4d6c 00000001 nt!RtlCompareUnicodeString+0x25
WARNING: Stack unwind information not available. Following frames may be wrong.
a72b7a6c 8b756aeb 87587068 a72b7a8c a72b7ab8 MyDriver2+0x1105
a72b7ad8 8b7599f0 a72b7b2c 87435e48 00000000 fltmgr!FltpPerformPreCallbacks+0x34d
a72b7af0 8b759f01 a72b7b2c 00000000 862ff240 fltmgr!FltpPassThroughInternal+0x40
a72b7b14 8b75a3ba 032b7b00 862ff240 00000000 fltmgr!FltpPassThrough+0x203
a72b7b44 82872593 862ff240 87435e48 87435e48 fltmgr!FltpDispatch+0xb4
a72b7b5c 82a6699f 87435e48 87435fd8 87590d98 nt!IofCallDriver+0x63
a72b7b7c 82a9f2da 862ff240 87590d98 00000001 nt!IopSynchronousServiceTail+0x1f8
a72b7c08 828791ea 862ff240 87435e48 00000000 nt!NtReadFile+0x644
a72b7c08 773e70b4 862ff240 87435e48 00000000 nt!KiFastCallEntry+0x12a
0013f014 00000000 00000000 00000000 00000000 0x773e70b4
STACK_COMMAND: kb
FOLLOWUP_IP:
MyDriver2+1105
994a9105 ?? ???
SYMBOL_STACK_INDEX: 4
SYMBOL_NAME: MyDriver2+1105
FOLLOWUP_NAME: MachineOwner
MODULE_NAME: MyDriver2
IMAGE_NAME: MyDriver2.sys
DEBUG_FLR_IMAGE_TIMESTAMP: 597b0358
FAILURE_BUCKET_ID: 0x50_MyDriver2+1105
BUCKET_ID: 0x50_MyDriver2+1105
Followup: MachineOwner
---------
因此,crush在RtlCompareUnicodeString函数中是独立的(或者在以前的前缀版本中),但我不知道为什么会在那里出现crush,看起来我做的每件事都很好。你的bug不在调用中
rtlprefexonicodestring(&FILE\u NAME,&NameInfo->NAME,TRUE))
-这里一切正常。上一行中的错误:
DbgPrint("[+] pars gets me Name: %wZ extention: %wZ perentDir: %wZ volume: %wZ \n",
NameInfo->Name,
NameInfo->Extension,
NameInfo->ParentDir,
NameInfo->Volume);
%wZ
格式需要指向UNICODE\u字符串的指针
,因此必须
DbgPrint("[+] pars gets me Name: %wZ extention: %wZ perentDir: %wZ volume: %wZ \n",
&NameInfo->Name,
&NameInfo->Extension,
&NameInfo->ParentDir,
&NameInfo->Volume);
此外,如果FltGetFileNameInformation
失败,则在此之后不得使用NameInfo
(它将为0或未定义)。但你不能在代码中这样做
通常交换缓冲区需要在且仅在
数据->Iopb->IrpFlags&IRP_NOCACHE
时进行-因此,当数据读写到存储器时,这里有很多错误
另外,请说明您的变量扩展名是如何初始化的。谢谢您,因为muchi更改了我的代码,但当RTLPRefexInocDestring出现时,我仍然会出现蓝屏(我在注释时没有看到蓝屏,所以我相信这是问题的根源)@pit-您需要分析崩溃转储以查看问题的确切来源<当您传递
UNICODE\u字符串而不是UNICODE\u字符串*
时,code>DbgPrint
当然是错误的。在RtlPrefixUnicodeString(&FILE\u NAME,&NameInfo->NAME,TRUE)
如果NameInfo!=0
。但在这种情况下,您将在(我怎么说你需要正确处理FltGetFileNameInformation
@pit失败-以及你所有DbgPrint
中的%wZ
都是错误的。你每次通过UNICODE\u STRING
而不是UNICODE\u STRING*
-数据->Iopb->TargetFileObject->FileName
,例如,我将DbgPrint修复为&nameinform->Name
所以现在它们都是指针,我在每个!NT_SUCCESS(status)
案例中都添加了return,当我只注释掉rtlprefixunocodestring(&FILE\u Name,&NameInfo->Name,TRUE)
我很好,但是当有这个主持人时,我会看到一个蓝屏,所以我认为这与新代码版本中的no?有关:RtlCompareUnicodeString(&EXTENTION,&NameInfo->Extension,TRUE)
-其中Extension
被初始化,以及如何初始化?错误检查显示缓冲区
(0x994af2a4
)无效。这可能是在扩展名
(我猜)或&NameInfo>扩展名
中。并且您的dbgprint(新版本)无论如何都是错误的扩展名
是一个全局变量,它在驱动程序条目中初始化(初始化进行得很顺利,初始化后我在驱动程序条目中打印了Extension的值,以使舒尔知道它进行得很顺利。(我还尝试原样使用microsoft提供的cancelSafe迷你过滤器,但没有任何更改,而且它在同一个功能中也向我发送了命令,但出现了相同的错误(某些地址未验证))(cencel安全代码可以在这里找到)您的错误检查分析清楚地表明NameInfo->Extension
或Extension
中的Buffer
无效。或者。或者。如果您更深入地查找崩溃转储-这很容易准确查看。NameInfo->Extension
由fltmgr初始化,我怀疑它是否无效(如果您按原样显示所有代码,并且未在未显示的代码中损坏代码).扩展在驱动程序条目中初始化
-不是使用本地字符串?不是很晚才覆盖它?并在和dbgprint处修复-几乎所有错误。当您将UNICODE_字符串作为参数传递时,我从驱动程序条目中初始化它,如下所示`RtlInitUnicodeString(&EXTENTION,L“txt”)`