Minifilter 在特定情况下丢失已删除的文件 Windows 10 1903 +

Minifilter missing deleted files in particular scenarios Windows 10 1903 +

我有一个 minifilter 驱动程序错过了某些文件的删除,问题在于不知道它们是如何删除的。 Windows 10 1903 及以上就是这种情况。测试了 1809 之前的版本并且工作正常。

例如 MS C++ 2008 x86 redistributable https://www.microsoft.com/en-gb/download/details.aspx?id=29,安装 setup.exe 解压文件到 C:{random GUID}(可以在日志中看到)然后安装。之后文件/目录被删除,我错过了带有以下代码的 IRP。

我目前使用 FileDispositionInformation 监视 IRP_MJ_SET_INFORMATION 文件删除,您可以通过转到资源管理器和 shift + delete 来测试它。

添加了 IRP_MJ_CREATE 以便在关闭时删除以及根据 RbMm 评论。

我还监视用于移动文件或重命名的 FileRenameInformation,如果您 move/rename 资源管理器中的文件,这同样有效。

我理想的解决方案是在创建时获取文件并将其复制到另一个位置,但我不确定从哪里开始。我查看了一些 minifilter 示例,但找不到示例中 PreOperationCallback 的位置来复制新创建的文件。

我的另一个选择是尝试通过上面的示例了解如何获取这些已删除的文件。是否有任何其他 FileInformationClass 案例可供我检查以识别此类删除。

我的 PreOperationCallback 代码如下:

FLT_PREOP_CALLBACK_STATUS PreOperationCallback(_Inout_ 
PFLT_CALLBACK_DATA Data,
_In_ PCFLT_RELATED_OBJECTS FltObjects, 
_Flt_CompletionContext_Outptr_ PVOID* CompletionContext)
{

  /* IRP-based I/O operation? */
  if (FLT_IS_IRP_OPERATION(Data)) {

   if (Data->Iopb->MajorFunction == IRP_MJ_CREATE) {

    if (Data->Iopb->Parameters.Create.Options & (FILE_DELETE_ON_CLOSE)) {
        DbgPrint("FILE_DELETE_ON_CLOSE");
        return process_irp(Data, FltObjects, CompletionContext, FALSE, FALSE);

   }else if (Data->Iopb->MajorFunction == IRP_MJ_SET_INFORMATION) {

   switch (Data->Iopb->Parameters.SetFileInformation.FileInformationClass) {

     case FileDispositionInformation:
        // deleting a file we need to action
        if (((FILE_DISPOSITION_INFORMATION*) Data->Iopb->Parameters.SetFileInformation.InfoBuffer)->DeleteFile) {
          return process_irp(Data, FltObjects, CompletionContext, FALSE, FALSE);
        }
        break;

     case FileRenameInformation:

       // Process the request according to our needs e.g copy the file
       return process_irp(Data, FltObjects, CompletionContext, FALSE, TRUE);
     }
   }
 }

  return FLT_PREOP_SUCCESS_NO_CALLBACK;
}

更新 - 我刚刚创建了一个非常简单的 C# 应用程序来创建文件并使用 File.Delete("C:\test.txt");驱动程序未在 1903 及更高版本的当前代码库中选择此选项。

您必须 'process_irp' FileRenameInformationEx 和 FileDispositionInformationEx,如下所示。

switch (Data->Iopb->Parameters.SetFileInformation.FileInformationClass) {

 case FileDispositionInformation:
 case 64/*FileDispositionInformationEx*/:
    // deleting a file we need to action
    if (((FILE_DISPOSITION_INFORMATION*) Data->Iopb->Parameters.SetFileInformation.InfoBuffer)->DeleteFile) {
      return process_irp(Data, FltObjects, CompletionContext, FALSE, FALSE);
    }
    break;

 case FileRenameInformation:
 case 65/*FileRenameInformationEx*/:
   // Process the request according to our needs e.g copy the file
   return process_irp(Data, FltObjects, CompletionContext, FALSE, TRUE);
 }

}