Filesystems 文件系统筛选器驱动程序-文件名损坏

Filesystems 文件系统筛选器驱动程序-文件名损坏,filesystems,driver,windows-kernel,filter-driver,Filesystems,Driver,Windows Kernel,Filter Driver,我目前正在开发一个文件系统过滤器驱动程序 筛选器驱动程序所做的是检查正在创建和删除哪些文件,并留下日志 在大多数情况下,这个过滤器驱动程序运行良好 然而,有时TargetFileObject->FileName会被奇怪地分解成Unicode字符串 我不知道为什么会这样 发生这种情况时,会出现BSOD (BSOD的原因是0x19错误池头。)在保存文件名和日志记录后调用ExFreePool函数时发生 我应该忽视这种情况吗?或者有没有办法验证这样的东西 上面的图片可能是“\Windows\…” 谁有

我目前正在开发一个文件系统过滤器驱动程序

筛选器驱动程序所做的是检查正在创建和删除哪些文件,并留下日志

在大多数情况下,这个过滤器驱动程序运行良好

然而,有时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中是有效的