我正在使用C#和C++/CLI编写一个应用程序,我有一些代码可以暂停进程。但是,我想防止其他进程(如Process Explorer)将它们取消暂停。是否可能获得独占进程句柄或以其他方式阻止其他应用程序执行此操作?如果可以,该怎么实现呢?
这是不可能从用户模式下做到的。
任何拥有SE_DEBUG_PRIVILEGE
令牌权限的进程都可以打开进程/线程句柄并拥有所有访问权限(仅当它不是受保护进程时)。
你可以从内核模式中使用ObRegisterCallbacks
注册自己的回调函数,并过滤进程/线程句柄打开尝试。比如阻止句柄打开或从OB_PRE_CREATE_HANDLE_INFORMATION
中删除PROCESS_SUSPEND_RESUME
,THREAD_SUSPEND_RESUME
和THREAD_RESUME
的DesiredAccess
. 但是这并不能防止其他内核模式代码调用导出的APIPsResumeProcess
。
通常对象句柄部分支持独占访问。在OBJECT_ATTRIBUTES
中查找OBJ_EXCLUSIVE
标志(这始终作为任何打开/创建对象调用的第三个参数传递--ZwOpenProcess
也是如此), 但是这仅在创建对象时设置了OBJ_EXCLUSIVE
标志时才有效。否则,你将得到STATUS_INVALID_PARAMETER
或如果句柄已被其他进程打开,则会得到STATUS_ACCESS_DENIED
。但由于进程总是没有使用OBJ_EXCLUSIVE
标志创建的,因此你无法以排他方式打开它(我已经没有提到在与进程会话相关的csrss.exe
中,已存在一个打开的句柄指向你的进程)。
你可以将代码注入到另一个正在运行的进程中,并修补由NTDLL导出的NtResumeProcess和NtResumeThread例程。导出的例程将执行系统调用,但是在此转换发生之前,您可以拦截并重定向执行到自己的回调例程以应用过滤 - 返回STATUS_ACCESS_DENIED或其他适当的NTSTATUS错误代码以阻止操作。
这不会防止某人通过手动系统调用绕过您的补丁。您最好的选择是使用ObRegisterCallbacks,然后为除自己以外的任何调用者剥离PROCESS_SUSPEND_RESUME。
通过运行时字节打补丁的第一种方法很好,因为只要做得正确,用户模式挂钩就不是问题。还有一些开源库可以实现这一点,微软拥有自己的API挂钩库,名为MS Detours。使用ObRegisterCallbacks方法需要一个内核模式设备驱动程序,这就需要数字签名来支持内核模式软件签名(对于启用了安全启动的系统,您需要扩展验证签名,这仅发放给真正注册的公司,价格更高)。
祝你好运。
SeDebugPrivilege
,你的应用程序也可能需要)的其他进程仍然可能覆盖你的限制。 - ozeanixSeDebugPrivilege
是对的 - 我想到的是SeTcbPrivilege
和SeAssignPrimaryToken
。我已经很久没有需要记住这些了! - ozeanixSeDebugPrivilege
,我们可以从 LocalSystem 进程中打开令牌或线程并模拟。因此,如果我们拥有SeDebugPrivilege
,我们可以获得 Windows 下的所有特权。 - RbMm