【问题标题】:Shared memory between kernel and user mode. How to share handle?内核和用户模式之间的共享内存。如何共享处理?
【发布时间】:2015-06-04 05:08:53
【问题描述】:

我正在尝试在用户进程和内核之间使用共享内存。

选项一 - 让内核创建部分并让用户模式应用程序通过名称“Global\my_mem”打开内存。它仅在只读模式下工作。当我尝试使用 FILE_MAP_WRITE 打开部分时,它会拒绝访问(5)。不确定如何授予访问权限或修改 DACL。

选项二 - 通过 IOCTL 传回句柄。这个是有问题的,因为在 KERNEL 中打开的部分的句柄是 0xFFFFFFFF80001234。我的理解是设置了任何高位的句柄不能在用户模式下使用。特别是如果应用程序是 32 位的 :) 最初我预计节句柄会有点类似于内核文件句柄,我将能够使用它。

在内核和用户模式之间建立共享内存通道的正确方法是什么?

【问题讨论】:

  • 微软发布了this文档,详细描述了选项#1。

标签: c++ windows kernel


【解决方案1】:

由于您提到 32 位应用程序,我假设它位于用户进程和设备驱动程序之间 - 我会使用 IOCTL - METHOD_IN_DIRECT(在缓冲区中接收数据)和 METHOD_OUT_DIRECT(将数据写入缓冲区) .

如果共享内存在多​​个用户进程和一个或多个设备驱动程序之间 - 建议使用共享内存对象方法。

【讨论】:

    【解决方案2】:

    对于选项 1,您可以通过 OBJECT_ATTRIBUTES structure 的成员 SecurityDescriptor 指定分配给新创建对象的安全描述符。

    对于选项 2,您需要创建一个额外的句柄作为用户句柄,您可以通过在 OBJECT_ATTRIBUTES 结构中不指定 OBJ_KERNEL_HANDLE 标志来实现。这仅在您在属于用户应用程序进程的线程上下文中运行时打开新句柄才有效,例如,在处理从用户应用程序接收到的 IOCTL 时。

    另一个选项是内核驱动程序使用ZwMapViewOfSection将该部分映射到用户模式应用程序的地址空间本身。

    使用节的一个问题是驱动程序本身只能从系统线程安全地访问它。如果这是一个问题,您可以直接共享内存,而不是通过一个部分。如果您在内核模式下分配内存,您可以使用MmMapLockedPagesSpecifyCache 将其映射到用户模式应用程序的地址空间。

    另一个选项是the driver to access a memory buffer allocated by the user-mode process

    这两种方法的缺点是缓冲区(或共享的部分)必须锁定在内存中,而使用节允许缓冲区可分页。

    【讨论】:

    • 感谢您的建议。只是在处理 IOCTL_MINIPORT_PROCESS_SERVICE_IRP 时尝试创建句柄(没有 OBJ_KERNEL_HANDLE),但稍后在系统线程的上下文中映射剖面视图。没用。不接受句柄。
    • 您能否指定(如果可能)如何分配内存并将其映射到系统进程,同时在用户进程的上下文中将其映射到那里?
    • 您不能同时为用户进程和系统线程使用一个句柄。我将进行编辑以澄清。至于在驱动程序中分配内存,然后将其映射到用户模式应用程序的地址空间,我没有手头的详细信息,但 MmMapLockedPagesSpecifyCache 的文档特别指出同时具有用户模式和系统模式映射同时也不是问题。但是,如果您仍然使用系统线程,则最好使用节,因为它更简单并且允许内存分页。
    • 谢谢。有用。在非管理员用户进程挂起 irp 的上下文中,创建部分,保存句柄 1。在系统线程按名称打开部分的上下文中,创建句柄2 和映射视图,完成irp 并将句柄1 发送回来。在用户进程中使用 handle1 并进行另一个映射。但同时我发现这不是推荐的方式,需要使用 DeviceIO IOCTL IOCTL_SCSI_PASS_THROUGH_DIRECT 作为 storport miniport 驱动。已回答!
    猜你喜欢
    • 2015-12-12
    • 2011-12-16
    • 2018-06-08
    • 2012-03-02
    • 1970-01-01
    • 1970-01-01
    • 2016-08-14
    • 2016-10-12
    • 2019-07-27
    相关资源
    最近更新 更多