【问题标题】:Minifilter driver: how to replace file content on open?Minifilter驱动程序:如何在打开时替换文件内容?
【发布时间】:2012-12-14 17:56:48
【问题描述】:

我有一个顶级微过滤驱动和一个用户模式服务,类似于Scanner MSDN example

我希望我的用户模式服务在 A.txt 文件内容在记事本中打开时替换它。

因此,在IRP_MJ_CREATE 操作后回调中,我正在向服务发送通知并等待它将新数据写入文件。
但是服务无法打开A.txt,因为它已经被记事本锁定了。

如何让我的服务在不使用内核FltWriteFile的情况下写入数据?
这样做的最佳方法是什么?

也许取消文件打开,让服务写入数据并使用相同的参数重新打开它而不离开操作后回调?
也许我应该在预操作中覆盖所需的访问权限?

---
任何信息将不胜感激。如果您认为这个问题缺乏细节,请告诉我。

【问题讨论】:

标签: c windows driver minifilter


【解决方案1】:

不要在 PostOperation 中通知您的服务,而是在 PreOperation 回调中执行此操作。当您在 PostOperation 中执行此操作时,Notepad.exe 文件已经打开,这就是在您的服务中打开失败的原因。

此外,如果您还没有这样做,则必须在 PreOperation 中等待您的服务将新数据写入文件。

【讨论】:

  • 正确。但是在预操作中我无法获取文件名信息,所以我没有 A.txt 比较。
  • @aleksk,我认为您应该能够使用 FltGetFileNameInformation 在预创建中获取文件名。
  • 我能够通过在预操作中修改共享访问来实现这一点。
    我也对FltGetFileNameInformation 文档感到困惑,该文档说必须从帖子中调用 FltGetTunneledName -op 如果在预操作中调用 FltGetFileNameInformation 以进行硬链接和重命名,则获取正确的文件名。谢谢。
【解决方案2】:

我不太同意 Rogan 的 回答,因为文件很可能在记事本之前被任何其他进程锁定。 这不是这里的问题,或者至少不是你应该如何看待这个问题。

如果你想让记事本对 A.txt 有一定的看法,只需使用记事本的 FILE_OBJECT 并从内核自己编写。请记住使用 ObReferenceObjectByPointer 并请求 WRITE 访问权限。由于访问模式将是内核模式,因此您将被允许。

或者,如果您真的希望由您的服务完成,请自己从驱动程序中打开文件并为您的服务提供句柄。从内核模式打开文件可能会抑制共享模式等,您需要阅读 FltCreateFileEx2 的文档以确保您拥有所有必要的参数。 在您刚刚打开的 FileObject 上使用 ObOpenObjectByPointer 并访问模式 UserMode。确保您将通过 KeStackAttachProcess 连接到用户模式的进程地址空间。

PostCreate 中的操作顺序:

  1. FltCreateFileEx2(the_file、ignore_share_access 等)
  2. KeStackAttachProcess(your_service_eprocess)
  3. ObOpenObjectByPointer(UserMode=access_mode) -> 现在你的 um 进程有了文件的句柄
  4. KeUnstackDetachProcess()
  5. HANDLE 指针发送到用户模式进程,因为它现在可以使用它了。
  6. 等待用户模式服务写入数据并关闭句柄 取消引用获得的 FileObject 并关闭 FltCreateFileEx2 的句柄。
  7. 让记事本进行创建
  8. 利润。

祝你好运。

【讨论】:

    【解决方案3】:

    //声明

    PFLT_CALLBACK_DATA Data //Note: you get this in preOperation as argument so dont need to defined explicitly
    
    PFLT_FILE_NAME_INFORMATION nameInfo=NULL;//must be declared
    NTSTATUS status;
    
    
    if(KeCurrentIrql()==PASSIVE_LEVEL)// file operation should be performed in IRQL PASSIVE_LEVEL
    {
    
    status=FltGetFileNameInformation(Data,FLT_FILE_NAME_OPENED |FLT_FILE_NAME_qUERY_ALWAYS_ALLOW_CACHE_LOOKUP,&nameInfo);
    
    if(NT_SUCCESS(status))
    {
     status = FltParseFileNameInformation(nameInfo);
    }
    }
    

    //现在你有了nameInfo结构中的文件信息。

    //你可以获得文件信息,阅读上述结构的文档将帮助你更多地了解它们。特别是 PFLT_FILE_NAME_INFORMATION 。

    【讨论】:

      猜你喜欢
      • 2017-10-17
      • 2020-06-17
      • 1970-01-01
      • 2019-12-21
      • 2012-09-25
      • 2021-11-20
      • 1970-01-01
      • 2017-04-13
      • 1970-01-01
      相关资源
      最近更新 更多