获取独占式进程句柄

3

我正在使用C#和C++/CLI编写一个应用程序,我有一些代码可以暂停进程。但是,我想防止其他进程(如Process Explorer)将它们取消暂停。是否可能获得独占进程句柄或以其他方式阻止其他应用程序执行此操作?如果可以,该怎么实现呢?


我能给你的最好建议是查看MSDN关于进程安全和访问权限的文档。你可能能够修改你正在挂起的进程的ACL,以防止任何其他进程解除挂起。然后,当你想要取消挂起时,你会再次修改ACL,取消挂起,然后再次限制ACL。但是,具有足够高特权(例如SeDebugPrivilege,你的应用程序也可能需要)的其他进程仍然可能覆盖你的限制。 - ozeanix
1
@ozeanix,如果你做得对的话就不会有问题。任何以管理员权限运行的进程都可以启用调试特权。(至少在默认配置下是这样的。) - Harry Johnston
2
进程句柄没有“共享模式”。 您需要更改进程的ACL和所有线程的所有权。 当然,这不会影响管理员用户。 可能可以在内核模式下以某种方式阻止访问,但这毫无意义。 - Harry Johnston
@HarryJohnston,你说的SeDebugPrivilege是对的 - 我想到的是SeTcbPrivilegeSeAssignPrimaryToken。我已经很久没有需要记住这些了! - ozeanix
@ozeanix - 如果我们拥有 SeDebugPrivilege,我们可以从 LocalSystem 进程中打开令牌或线程并模拟。因此,如果我们拥有 SeDebugPrivilege,我们可以获得 Windows 下的所有特权。 - RbMm
显示剩余3条评论
2个回答

4

这是不可能从用户模式下做到的。

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

你可以从内核模式中使用ObRegisterCallbacks注册自己的回调函数,并过滤进程/线程句柄打开尝试。比如阻止句柄打开或从OB_PRE_CREATE_HANDLE_INFORMATION中删除PROCESS_SUSPEND_RESUMETHREAD_SUSPEND_RESUMETHREAD_RESUMEDesiredAccess. 但是这并不能防止其他内核模式代码调用导出的APIPsResumeProcess

通常对象句柄部分支持独占访问。在OBJECT_ATTRIBUTES中查找OBJ_EXCLUSIVE标志(这始终作为任何打开/创建对象调用的第三个参数传递--ZwOpenProcess也是如此), 但是这仅在创建对象时设置了OBJ_EXCLUSIVE标志时才有效。否则,你将得到STATUS_INVALID_PARAMETER或如果句柄已被其他进程打开,则会得到STATUS_ACCESS_DENIED。但由于进程总是没有使用OBJ_EXCLUSIVE标志创建的,因此你无法以排他方式打开它(我已经没有提到在与进程会话相关的csrss.exe中,已存在一个打开的句柄指向你的进程)。


0

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

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

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

祝你好运。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接