代码之家  ›  专栏  ›  技术社区  ›  Clay

如何在服务和用户进程之间共享内存?

  •  6
  • Clay  · 技术社区  · 16 年前

    我有一组Win32应用程序,它们使用创建的共享内存段共享信息 CreateFileMapping() MapViewOfFile() . 其中一个应用程序是系统服务;其余的由登录用户启动。在Windows XP上,没有问题。我们把我们的部分命名为global \ something,一切都很好。

    Vista(和假定的Windows7)中的额外安全性似乎阻止了这种体系结构的工作。普通用户不允许在全局命名空间中创建(Win32错误5)对象。msdn表明,如果帐户具有__create global_特权,那么所有权限都应该是良好的,但实际情况似乎并非如此。 此外,Vista___integrity_功能可防止__low integrity_用户进程访问__high integrity_服务创建的共享内存对象。看来我可以通过一些魔法来解决这个问题 SetSecurityDescriptorSacl() 咒语,但我很难学会说SACL。

    所以问题是: 在服务和正常用户进程之间使用共享内存段的正确方法是什么?

    为了抢占__的简单答案,只需关闭UAC__,我们__处于一个相当封闭的环境中,这是不可能的。

    编辑:服务和用户进程都需要对段进行读/写访问。

    1 回复  |  直到 6 年前
        1
  •  9
  •   Top-Master OMG Ponies    6 年前

    最简单的方法是让您的服务创建共享内存,并在createfilemapping中指定一个dacl,该dacl授予常规用户对共享内存的读取访问权。

    普通用户没有创建全局权限,但服务可以拥有此权限。如果您必须让用户创建共享内存,然后让服务探测它,那么您可以有一个IPC方案,在这个方案中,您的用户代码向包含文件映射句柄的服务发送一条消息,然后服务将调用Duplicatehandle来获取对它的引用。这将需要您的服务以调试特权运行。

    创建DACL的最简单方法是使用ConvertStringSecurityDescriptorToSecurityDescriptor,它采用一个名为SDDL的指定ACL格式的字符串。

    Writing Secure Code 包含一个关于用sddl创建dacl的优秀章节。

    // Error handling removed for brevity
    SECURITY_ATTRIBUTES attributes;
    ZeroMemory(&attributes, sizeof(attributes));
    attributes.nLength = sizeof(attributes);
    ConvertStringSecurityDescriptorToSecurityDescriptor(
             L"D:P(A;OICI;GA;;;SY)(A;OICI;GA;;;BA)(A;OICI;GR;;;IU)",
             SDDL_REVISION_1,
             &attributes.lpSecurityDescriptor,
             NULL);
    
    CreateFileMapping(INVALID_HANDLE_VALUE, &attributes,
                  PAGE_READWRITE, sizeHigh, sizeLow, L"Global\\MyObject");
    
    LocalFree(attributes.lpSecurityDescriptor);
    

    “d:p(a;oici;ga;;;sy)(a;oici;ga;;;ba)(a;oici;gr;;;iu)”指定DACL。D:P表示这是一个dacl(而不是sacl)。..。你很少使用sacl),后面跟着几个ace字符串来控制谁可以访问。每一个都是一个(allow)并允许对象和包含继承(oici)。第一个将所有访问权(ga-grant all)授予系统(sy)和管理员(ba,内置管理员)。最后一个将read(gr)授予交互式用户(iu),后者实际上是登录到会话的用户。

    完成后,普通用户应该能够调用OpenFileMapping来获取共享映射的句柄,并能够将其映射到自己的进程中。由于普通用户对对象的权限有限,他们必须确保打开对象并将其映射为只读访问。

    如果用户需要写访问,您可以用gwgr替换gr。请注意,这是不安全的—这样,有限的用户就可以在服务读取和解析信息时修改共享内存,从而导致服务崩溃。

    推荐文章