获取独占进程句柄

Posted

技术标签:

【中文标题】获取独占进程句柄【英文标题】:Obtain Exclusive Process Handle 【发布时间】:2017-06-12 20:34:12 【问题描述】:

我正在用 C# 和 C++/CLI 编写一个应用程序,并且我有暂停进程的代码。但是,我想防止它们被另一个进程(例如 Process Explorer)取消挂起。是否可以获得独占进程句柄或以其他方式阻止其他应用程序执行此操作?如果有,怎么做?

【问题讨论】:

我能给您的最佳指导是查看Process Security and Access Rights 上的 MSDN 文档。您可能能够修改正在暂停的进程的 ACL,以防止任何其他进程取消暂停它。然后,当您想取消暂停它时,您将再次修改 ACL,取消暂停,然后再次限制 ACL。但是,具有足够高权限的其他进程(例如 SeDebugPrivilege,您的应用可能也需要)可能仍会覆盖您的限制。 不管怎样,仅仅为您自己的应用程序获取SeDebugPrivilege 可能是一个相当大的挑战!我记得您的应用需要以SYSTEM 用户身份运行,才能拥有足够的权限来修改自己的权限列表。 @ozeanix,如果你做得对的话。任何以管理员权限运行的进程都可以启用调试权限。 (好吧,无论如何,在默认配置中。) 进程句柄没有“共享模式”。您需要更改进程的 ACL 和所有权,并且可能需要更改其所有线程。当然,这不会影响管理用户。可能会以某种方式阻止内核模式下的访问,但这没什么意义。 @HarryJohnston 你对SeDebugPrivilege 的看法是对的——我想的是SeTcbPrivilegeSeAssignPrimaryToken。很久没有记住这些了! 【参考方案1】:

这在用户模式下是不可能的。

在令牌中启用SE_DEBUG_PRIVILEGE 的任何进程都可以打开具有所有访问权限的进程/线程句柄(仅当它不受保护的进程时)。

在内核模式下,您可以使用ObRegisterCallbacks 注册自己的回调并过滤进程/线程打开尝试。说拒绝句柄打开或从OB_PRE_CREATE_HANDLE_INFORMATION 中的DesiredAccess 中删除PROCESS_SUSPEND_RESUMETHREAD_SUSPEND_RESUMETHREAD_RESUME。但这并不能阻止另一个内核模式代码调用导出的 api PsResumeProcess

一般来说,对象句柄部分支持独占访问。在OBJECT_ATTRIBUTES 中寻找OBJ_EXCLUSIVE 标志(这始终作为第三个参数传递给任何打开/创建对象调用-ZwOpenProcess),但这仅在OBJ_EXCLUSIVE 标志为在创建对象时设置。 否则你得到STATUS_INVALID_PARAMETER 或者如果句柄已经被另一个进程打开,你得到STATUS_ACCESS_DENIED。但是因为总是在没有OBJ_EXCLUSIVE 标志的情况下创建进程 - 你不能以独占方式打开它(我已经没有说在与进程会话相关的csrss.exe 中已经存在你进程的打开句柄)

【讨论】:

【参考方案2】:

您可以将代码注入另一个正在运行的进程并修补由 NTDLL 导出的 NtResumeProcess 和 NtResumeThread 例程。导出的例程将执行系统调用,但是您可以在此转换发生之前拦截并将执行重定向到您自己的回调例程以应用过滤 - 返回 STATUS_ACCESS_DENIED 或另一个适当的 NTSTATUS 错误代码以阻止操作。

但这不会阻止有人通过手动系统调用绕过您的补丁。您最好的选择是 ObRegisterCallbacks,然后为您以外的任何调用者剥离 PROCESS_SUSPEND_RESUME。

通过运行时字节修补的第一种方法很好,因为只要正确完成用户模式挂钩就不是问题。还有一些开源库可以实现这一点,微软也拥有自己的名为 MS Detours 的 API 挂钩库。 ObRegisterCallbacks 方法将需要内核模式设备驱动程序,因此需要支持内核模式软件签名的数字签名(以及支持启用安全启动的系统,您需要扩展验证签名,该签名只发给真正注册的公司,而且价格要高得多)。

祝你好运。

【讨论】:

以上是关于获取独占进程句柄的主要内容,如果未能解决你的问题,请参考以下文章

delphi 知道路径和进程如何获取窗口句柄?

C# 根据进程ID获取进程主窗口句柄

C++ 获取进程句柄问题

C# 根据进程ID获取进程主窗口句柄

c# 设置窗体句柄

Delphi 我想获得进程句柄,怎么每次都变化