【问题标题】:Two-way communication between kernel-mode driver and user-mode application?内核模式驱动程序和用户模式应用程序之间的双向通信?
【发布时间】:2012-12-13 20:09:49
【问题描述】:

我需要内核模式 WFP 驱动程序和用户模式应用程序之间的双向通信。驱动程序通过将 URL 传递给应用程序来启动通信,然后应用程序对该 URL 进行分类(娱乐、新闻、成人等)并将该类别传递回驱动程序。驱动程序需要知道过滤功能中的类别,因为它可能会根据该信息阻止某些网页。我在应用程序中有一个线程正在发出 I/O 请求,驱动程序将使用 URL 和 GUID 完成,然后应用程序会将类别写入该 GUID 下的注册表中,驱动程序将在其中提取它。不幸的是,正如驱动程序验证者所指出的那样,这是不稳定的,因为 Zw 注册表函数必须在 PASSIVE_LEVEL 运行。我正在考虑用映射的内存缓冲区尝试同样的事情,但我不确定中断要求是什么。另外,我想在注册表函数调用之前降低中断级别,但我不知道这样做的副作用是什么。

【问题讨论】:

  • 您已经在使用从驱动程序到应用程序的常规 I/O 来传递 URL;为什么不使用传统的 I/O 来返回结果呢?
  • 由于请求是从驱动程序发起的,我不知道如何使它工作。应用程序发出 I/O 请求,驱动程序使用输出缓冲区中的 URL 完成它,那么应用程序如何在 I/O 请求完成后将信息返回给驱动程序?此外,该操作具有时间敏感性,因为我正在决定是否阻止网页。

标签: windows driver interrupt wfp windows-kernel


【解决方案1】:

由于标注位于 DISPATCH,因此您的处理必须在工作线程或 DPC 中完成,这将允许您使用 ZwXXX。您应该出于通信目的使用反向回调,OSR 上有一个很好的文档。

我刚刚开始研究 WFP,但看起来即使在他们提供的示例中,Microsoft 也会重新注入数据包。我没有仔细研究它,但似乎他们丢弃数据包并在处理时重新注入。这足以让您的使用模式引擎做出决定。您还应该将数据包捕获限制到特定端口(在您的情况下为 80),这样您就不会进行不需要的额外处理。

【讨论】:

    【解决方案2】:

    您只需要有两种不同类型的 I/O 请求。

    如果您使用DeviceIoControl 来检索 URL(我认为这是最合适的方法),这就像添加第二个 I/O 控制代码一样简单。

    如果您使用ReadFile 或等效项,通常情况会有些混乱,但在这种特定情况下,您只有两种操作,其中一种是读取(驱动程序->应用程序)另一个是写入(应用程序->驱动程序)。因此,您可以使用WriteFile 发送回复,当然包括 GUID,以便驱动程序可以将您的回复与正确的查询相匹配。

    另一种方法(更类似于您原来的方法)是使用共享内存缓冲区。有关详细信息,请参阅this answer。这个想法的问题是你要么需要使用自旋锁(以系统性能和功耗为代价,当然不能在单核系统上工作)要么轮询(这既低效又不太适合时间敏感的操作)。

    【讨论】:

      【解决方案3】:

      PASSIVE_LEVEL 没有什么不稳定的地方。对注册表的访问必须处于 PASSIVE_LEVEL,因此如果驱动程序以更高的 IRQL 运行,则无法直接访问。不过,您可以通过卸载到工作项来做到这一点。通常不建议降低 IRQL,因为它与操作系统的意图相矛盾。

      您的协议确实听起来有些麻烦,直接进行应用程序驱动程序通信可能更可取。你可以在这里找到有用的信息:http://msdn.microsoft.com/en-us/library/windows/hardware/ff554436(v=vs.85).aspx

      【讨论】:

      • 对不起,我可以说得更好。它是“不稳定的”,因为它不会每次都崩溃,但 WFP 过滤器函数在 DISPATCH_LEVEL 运行,因此注册表函数不合适。
      猜你喜欢
      • 2013-03-30
      • 2015-04-14
      • 1970-01-01
      • 2011-06-23
      • 1970-01-01
      • 2014-08-03
      • 2019-04-04
      • 2015-11-19
      • 2016-06-10
      相关资源
      最近更新 更多