【问题标题】:DuplicateHandle: need to OpenProcess, but the access is deniedDuplicateHandle:需要OpenProcess,但是访问被拒绝
【发布时间】:2011-03-24 23:04:10
【问题描述】:

我使用 Windows 挂钩向我的应用程序发送消息,系统上的每个应用程序都会通知该应用程序有关 Windows 事件。

为了执行消息参数的编组,我使用共享内存。外部进程调用DuplicateHandle,但是为了与我的应用程序实例共享句柄,它应该调用OpenProcess 并具有PROCESS_DUP_HANDLE 权限要求。

实际上每个应用程序都可以使用这种架构发送消息,即使我需要为外部进程启用 SeDebugPrivilege。它实际上可以工作,除了没有 SeDebugPrivilege 令牌的 'explorer' 进程...

AdjustTokenPrivileges 的文档指出:

AdjustTokenPrivileges 函数无法向访问令牌添加新权限。它只能启用或禁用令牌的现有权限。要确定令牌的权限,请调用 GetTokenInformation 函数。

所以,问题是...如何将 SeDebugPrivilege 令牌添加到“explorer”进程,或者如何允许“explorer”进程调用OpenProcess(PROCESS_DUP_HANDLE, FALSE, pId)

【问题讨论】:

    标签: c++ security winapi elevated-privileges


    【解决方案1】:

    我不明白你为什么不使用 named 共享内存。如果您的共享内存对象有名称,则无需使用DuplicateHandle 即可打开此对象。

    如果您必须使用DuplicateHandle 并且需要能够在任何进程中使用OpenProcess(PROCESS_DUP_HANDLE, FALSE, pId),我发现您不应该使用SeDebugPrivilege。取而代之的是,您应该授予PROCESS_DUP_HANDLE 的权限 以使用pId 向每个人处理该过程。如果您创建一个进程,您可以指定安全描述符。如果进程已经创建,您可以使用OpenProcessGetSecurityInfo(参见http://msdn.microsoft.com/en-us/library/aa446654.aspx)和SetSecurityInfo来修改进程的安全描述符。

    要测试此方法,您只需使用管理权限启动 Process Explorer(请参阅 http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx),打开所选进程的安全选项卡(使用 pId 的进程)并修改其安全描述符。之后,所有进程都可以使用OpenProcess(PROCESS_DUP_HANDLE, FALSE, pId),而无需启用SeDebugPrivilege

    【讨论】:

    • 这似乎正是我所需要的! PROCESS_DUP_HANDLE 对应的 SID 是什么? (我无法使用 ProcEx 修改进程 SID... :()
    • PROCESS_DUP_HANDLE 是一个访问掩码,它指定由 ACE 控制的访问权限(请参阅msdn.microsoft.com/en-us/library/aa374868.aspx)。您选择的 SID 可以是所有人组的众所周知的 SID(请参阅msdn.microsoft.com/en-us/library/aa379649.aspx)。如果您不熟悉安全描述符,我建议您在可能的情况下使用 ConvertStringSidToSid 或 ConvertStringSecurityDescriptorToSecurityDescriptor 并使用安全描述符定义语言 (SDDL)(请参阅msdn.microsoft.com/en-us/library/aa379567.aspx)。
    • 我发现了这个:stackoverflow.com/questions/1909084/…(消息目的地是一个托管进程)。它可以工作,但无法为“explorer”所属的 WellKnownSidType.LogonIdsSid 设置访问掩码(无法创建 LogonIdsSid 类型的 SecurityIdentifier)。叹息。
    • 您可以使用 WellKnownSidType.InteractiveSid (NT AUTHORITY\INTERACTIVE) 或 WellKnownSidType.WorldSid (Everyone) 代替 LogonIdsSid。它也会起作用。
    • 是的,它可以工作,但是......如果我以“管理员”身份运行应用程序,即使我授予所有权限,外部应用程序也无法调用 OpenProcess。我是合理的,因为具有管理员权限的进程不能被低权限的进程打开。
    【解决方案2】:

    这是你想要完成的吗?

    1. 在“外部”进程中创建一块共享内存。
    2. 使用 DuplicateHandle 在应用程序中创建该内存的句柄
    3. 使用窗口消息将句柄值发送到您的应用程序
    4. 访问应用程序中的共享内存

    如果我理解正确,那么您根本不需要打开应用程序进程的句柄。相反,只需给共享内存块一个确定的名称,例如 SharedMem_XXX ,其中 XXX 是外部进程的 PID。然后,使用窗口消息将 PID 发送到您的应用程序。然后它可以重新创建名称并使用它来打开共享内存块。

    【讨论】:

    • 不错的解决方案,但这仅在我使用 SendMessage 而不是使用 PostMessage 时才有效,因为应用程序可以在应用程序处理消息之前发送多个消息。我尝试将 PostMessage 替换为 SendMessage,并查看系统性能是否受到影响。感谢您的启发!
    • 不客气。我不太明白您所说的 PostMessage 与 SendMessage 是什么意思,但这可能与您的架构有关。如果你能提供更多关于你想要完成的事情的细节,我可能会更有帮助。
    • 根据您的具体操作,还有其他 IPC 机制可能更适合您的需求,例如窗口消息、命名管道或远程过程调用。
    猜你喜欢
    • 2021-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-04
    • 1970-01-01
    相关资源
    最近更新 更多