【问题标题】:OpenProcess: access denied error only on Windows 8.1OpenProcess:仅在 Windows 8.1 上出现拒绝访问错误
【发布时间】:2015-04-02 21:58:51
【问题描述】:

我有一个程序可以调整 SeDebugPrivilege,然后开始迭代系统进程并为它们调用 OpenProcess(并执行其他操作,但现在并不重要)。当然,该程序也以管理员模式运行。在 Windows XP 和 Windows 7 它可以正常工作,但在 Windows 8.1 上,OpenProcess 因以下系统进程而失败,并出现 ERROR_ACCESS_DENIED(5):smss.exe、csrss.exe、services.exe时间>。正如我所知道的 SeDebugPrivilege 我应该能够打开这些进程并为它们检索句柄。有没有人知道,什么样的魔法只在 Windows 8.1 上导致了这个错误?

(无论如何我在 CreateToolhelp32Snapshot 的相同进程中遇到相同的错误)

【问题讨论】:

  • 我猜你已经没有足够的权限了。

标签: windows winapi windows-8.1 openprocess


【解决方案1】:

Windows 8.1 引入了system protected process 的概念。这是在第三方反恶意软件的上下文中记录的,但假设它也用于保护特别关键的系统进程似乎是合理的。

系统保护进程是 Windows Vista 中作为 DRM 措施引入的 Protected Process mechanism(Microsoft Word 文档)的扩展。

即使具有调试权限,您也无法获得受保护进程的任何这些访问权限:

  • DELETE
  • READ_CONTROL
  • WRITE_DAC
  • WRITE_OWNER
  • PROCESS_CREATE_THREAD
  • PROCESS_DUP_HANDLE
  • PROCESS_QUERY_INFORMATION
  • PROCESS_SET_QUOTA
  • PROCESS_SET_INFORMATION
  • PROCESS_VM_OPERATION
  • PROCESS_VM_READ
  • PROCESS_VM_WRITE

您应该仍然可以通过请求PROCESS_QUERY_LIMITED_INFORMATION 访问来打开该进程。根据文档,SYNCHRONIZEPROCESS_TERMINATE 访问也是允许的。

【讨论】:

  • 感谢您的回答!我明天会更仔细地阅读您提供的内容,但现在我有点失望和困惑,为什么我什至无法从这些过程中读取信息......
  • 您应该可以通过PROCESS_QUERY_LIMITED_INFORMATION 访问权限读取一些信息。这取决于你到底想得到什么。
  • 我认为 PROCESS_QUERY_LIMITED_INFORMATION 对我来说还不够,所以我会寻找另一种方式(可能在内核或其他方式中)。我需要有关内存和加载模块的信息...
【解决方案2】:

它只能在内核中完成。获取所需信息的最佳方式是:

PsLookupProcessByProcessId()
KeStackAttachProcess()
ZwQueryInformationProcess() or whatever other functions you need to now call within the context of the attached process.
KeStackDetachProcess()

或者,如果您只是在试验,没有将任何东西放入生产代码中,您可以遍历各种半透明结构(EPROCESS、PEB、VAD 等)来获取您需要的信息。

【讨论】:

    【解决方案3】:

    我最近在运行 Win32 OpenProcess API 时遇到访问被拒绝错误(在我的情况下为错误代码 5),然后在运行 CreateProcessAsUser 时遇到。就我而言,我在 Windows 10 上运行,但我怀疑它是相似的,但自从我开始工作后,我想我会分享一些对我有帮助的东西。

    当我使用 C# 时,我的 Win32 方法签名如下:

    [DllImport("kernel32.dll")]
            private static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, uint dwProcessId);
    

    影响成功访问现有进程(在我的例子中是一个 winlogon.exe 进程)的一个关键因素是正确定义正确的“所需访问”值。就我而言,我使用了一个常量“MAXIMUM_ALLOWED”,定义为:

    private const uint MAXIMUM_ALLOWED = 0x2000000;
    

    对服务的调用如下所示:

    IntPtr hProcess = OpenProcess(MAXIMUM_ALLOWED, false, targetWinlogonProcessId);
    

    这建立了正确的访问方式。我还将我的进程(Web 服务)作为 LocalSystem 帐户运行,该帐户具有相当好的权限。它开始于:

    请注意,我可以使用 SYSTEM 帐户运行此命令,方法是下载 PsExec.exe 并运行 PsExec.exe -i -s cmd.exe 以启动命令提示符,以便我可以使用该帐户查询权限。你可以在这里找到一个很好的权限列表:

    https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/user-rights-assignment

    就我而言,我想添加我通过 secpol.msc 添加的 SeAssignPrimaryTokenPrivilege 和 SeIncreaseQuotaPrivilege:

    您所需的特定权限可能取决于您使用的帐户,但我希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 2014-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-07
      • 1970-01-01
      • 2015-08-22
      • 2015-12-21
      • 2011-03-24
      相关资源
      最近更新 更多