Filesystems 文件系统筛选器驱动程序-文件名损坏
我目前正在开发一个文件系统过滤器驱动程序 筛选器驱动程序所做的是检查正在创建和删除哪些文件,并留下日志 在大多数情况下,这个过滤器驱动程序运行良好 然而,有时TargetFileObject->FileName会被奇怪地分解成Unicode字符串 我不知道为什么会这样 发生这种情况时,会出现BSOD (BSOD的原因是0x19错误池头。)在保存文件名和日志记录后调用ExFreePool函数时发生 我应该忽视这种情况吗?或者有没有办法验证这样的东西 上面的图片可能是“\Windows\…” 谁有同样的问题并解决了它 -------------------------修改------------------------ 下面是我源代码的一部分Filesystems 文件系统筛选器驱动程序-文件名损坏,filesystems,driver,windows-kernel,filter-driver,Filesystems,Driver,Windows Kernel,Filter Driver,我目前正在开发一个文件系统过滤器驱动程序 筛选器驱动程序所做的是检查正在创建和删除哪些文件,并留下日志 在大多数情况下,这个过滤器驱动程序运行良好 然而,有时TargetFileObject->FileName会被奇怪地分解成Unicode字符串 我不知道为什么会这样 发生这种情况时,会出现BSOD (BSOD的原因是0x19错误池头。)在保存文件名和日志记录后调用ExFreePool函数时发生 我应该忽视这种情况吗?或者有没有办法验证这样的东西 上面的图片可能是“\Windows\…” 谁有
FLT_PREOP_CALLBACK_STATUS FLTAPI MinifilterPreCallBack
(
__inout PFLT_CALLBACK_DATA pData,
__in PCFLT_RELATED_OBJECTS pFltObjects,
__deref_out_opt PVOID* ppCompletionContext
)
{
...
if(KeGetCurrentIrql() != PASSIVE_LEVEL)
{
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
if(PsGetCurrentProcessId()==4)
{
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
...
Status = IoVolumeDeviceToDosName(Data->Iopb->TargetFileObject->DeviceObject, &DriveName);
...
UNICODE_STRING FileName = Data->Iopb->TargetFileObject->FileName;
WCHAR* FullFilePath = ExAllocatePool(NonPagedPool, (DriveName.Length + FileName.Length) * 2 + 10);
swprintf(FullFilePath, L"FILE_CREATED %wZ%wZ", &DriveName, &Data->Iopb->TargetFileObject->FileName);
... // Save Log or DbgPrint ...
ExFreePool(FullFilePath);
}
它的操作大致如上所述
找到驱动器名为IoVolumeDeviceToDosName(\Device\HarddiskVolume1->C:)
查找文件名(文件对象->文件名)
通过使用ExAllocatePool分配缓冲区大小
使用swprintf获取完整路径
我不知道为什么这是一个错误
当BSOD发生时,总是出现如上所述的断开字符串。
FileName
在任何文件对象结构中,无论是Data->Iopb->TargetFileObject
还是pFltObjects
,都不需要总是存在。操作系统可以在需要时释放内存
FileName
仅在Pre-Create
回调函数中有效。
通常,您需要将文件名作为流/文件/句柄上下文存储在您自己附加到文件对象的结构中。在任何文件对象结构中,无论是
Data->Iopb->TargetFileObject
还是pFltObjects
都不需要总是存在。操作系统可以在需要时释放内存
FileName
仅在Pre-Create
回调函数中有效。
通常,您需要将文件名作为流/文件/句柄上下文存储在您自己附加到文件对象的结构中。并在其他回调中使用它。缓冲区溢出
L“FILE_CREATED”的长度大于10。因此,缓冲区不足。缓冲区溢出
L“FILE_CREATED”的长度大于10。所以缓冲区不够。显然,
文件名.buffer
已经通过调用ExFreePool
释放了(这会导致前2个Unicode符号(x86上的4字节-sizeof(pvoid))——内存返回到池中。值得注意的是FileName.Length==0
。所以这里有双重自由。也许这是你和做这件事,没有查看代码硬说。为什么要尝试使用免费文件名?只有当您返回状态\重新分析时,这才有意义。还有——为什么你要通过ExFreePool
而不是RtlFreeUnicodeString
来释放name?替换为begin的rtlfreeUnionDestring
-您仍然有这个bsod吗?我从未两次释放相同的内存。据我所知,连续释放同一个内存本身就是一个蓝屏。我不确定是否需要重新分析状态。我找不好。我认为重要的是,swprintf()会由于断开的字符串而导致溢出。我尝试使用snwprintf来避免溢出,但同样的问题也发生了。我希望能够筛选出断开的字符串并忽略它们。在屏幕中显示FileObject.FileName
当在代码中显示绝对另一个(FullFilePath
)(以及用于什么NonPagedPool
此处?)。我如何说这种情况下的开始字符串更改(在屏幕上)由于FileObject.FileName.Buffer
已经免费了对不起,我没有足够的英语。我看不懂你的英语。您能简单地解释一下吗?显然,FileName.Buffer
已经通过调用ExFreePool
释放了(这会导致前2个Unicode符号(x86上的4字节-sizeof(pvoid))被破坏),内存返回到池中。值得注意的是FileName.Length==0
。所以这里有双重自由。也许这是你和做这件事,没有查看代码硬说。为什么要尝试使用免费文件名?只有当您返回状态\重新分析时,这才有意义。还有——为什么你要通过ExFreePool
而不是RtlFreeUnicodeString
来释放name?替换为begin的rtlfreeUnionDestring
-您仍然有这个bsod吗?我从未两次释放相同的内存。据我所知,连续释放同一个内存本身就是一个蓝屏。我不确定是否需要重新分析状态。我找不好。我认为重要的是,swprintf()会由于断开的字符串而导致溢出。我尝试使用snwprintf来避免溢出,但同样的问题也发生了。我希望能够筛选出断开的字符串并忽略它们。在屏幕中显示FileObject.FileName
当在代码中显示绝对另一个(FullFilePath
)(以及用于什么NonPagedPool
此处?)。我如何说这种情况下的开始字符串更改(在屏幕上)由于FileObject.FileName.Buffer
已经免费了对不起,我没有足够的英语。我看不懂你的英语。你能简单地解释一下吗?那么你的意思是,在预回调中,我需要将文件名存储在全局变量或我的驱动程序分配的内存空间中,并在后回调中使用它?文件名在回拨后是否无效?我认为它们在回拨后是有效的,但是。。。我会尝试和评论。他们保证它在PreCreate回调中是有效的。在其他IRP中,它可能是,也可能不是。那么您的意思是,在预回调中,我需要将文件名存储在全局变量或我的驱动程序分配的内存空间中,并在后回调中使用它?文件名在回拨后是否无效?我认为它们在回拨后是有效的,但是。。。我会尝试和评论。他们保证它在PreCreate callba中是有效的