关于winapi:OpenProcess:仅在Windows 8.1上访问被拒绝错误

OpenProcess: access denied error only on Windows 8.1

我有一个程序,该程序可以调整SeDebugPrivilege,然后开始遍历系统进程并为它们调用OpenProcess(还有其他功能,但是现在不重要了)。 该程序当然也以管理员模式运行。 在Windows XP和Windows 7上,它可以正常工作,但在Windows 8.1上,对于具有ERROR_ACCESS_DENIED(5)的以下系统进程,OpenProcess失败:smss.exe,csrss.exe,services.exe。 据我所知,SeDebugPrivilege应该可以打开这些进程并检索它们的句柄。 有人知道吗,什么样的魔术仅在Windows 8.1上导致此错误?

(无论如何,对于CreateToolhelp32Snapshot,相同的过程都存在相同的错误)


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

系统保护的进程是Windows Vista中作为DRM措施引入的"保护的进程"机制(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


我最近在运行Win32 OpenProcess API时遇到了Access is Denied错误(在我的情况下为错误代码5),然后在运行CreateProcessAsUser时遇到了错误。就我而言,我在Windows 10上运行,但我怀疑它与Windows 10类似,但是自从我开始工作以来,我想我会分享一些对我有帮助的事情。

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

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

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

1
private const uint MAXIMUM_ALLOWED = 0x2000000;

该服务调用如下所示:

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

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

enter image description here

请注意,通过下载PsExec.exe并运行PsExec.exe -i -s cmd.exe来启动命令提示符,我能够使用SYSTEM帐户运行此命令,因此我可以使用该帐户查询特权。您可以在此处找到良好的权限列表:

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

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

enter image description here

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


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

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

或者,如果您只是试验而不在生产代码中放入任何内容,则可以遍历各种半透明结构(EPROCESS,PEB,VAD等)以获得所需的信息。