如何防止应用程序在任务管理器中被杀?

我正在研究一个家长控制应用程序(用WPF编写),并且想禁止任何人(包括管理员)杀死我的进程。 前一阵子,我在网上找到了以下代码,它几乎完美无缺,但有时它不起作用。

static void SetAcl() { var sd = new RawSecurityDescriptor(ControlFlags.None, new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null), null, null, new RawAcl(2, 0)); sd.SetFlags(ControlFlags.DiscretionaryAclPresent | ControlFlags.DiscretionaryAclDefaulted); var rawSd = new byte[sd.BinaryLength]; sd.GetBinaryForm(rawSd, 0); if (!Win32.SetKernelObjectSecurity(Process.GetCurrentProcess().Handle, SecurityInfos.DiscretionaryAcl, rawSd)) throw new Win32Exception(); } 

在Win7中,如果应用程序由登录用户启动,即使管理员也无法终止该进程(访问被拒绝)。 但是,如果您切换到另一个用户帐户(管理员或标准用户),然后选中“显示所有用户的进程”,则可以毫无问题地终止该进程。 任何人都可以给我一个暗示为什么以及如何解决它?

编辑:
我知道有些人对这个问题感到不安,但这是我的两难选择。 这是我主要为自己使用而写的父母控制。 主要特点是我想要监控和限制孩子们的游戏(不仅仅是关闭所有游戏)。 我可以为孩子分配一个标准的用户帐户,他们无法杀死这个过程。 但是,有些游戏(例如Mabinogi)要求管理员权限可以玩。 所以,我每次都要输入我的管理员密码,这很烦人。

顺便说一句,我不确定它是否符合Stackoverflow的政策,如果你想查看它,请点击我的应用程序: https : //sites.google.com/site/goppieinc/pc-screen-watcher 。

编辑:
这篇文章的主要观点是询问是否有人可以给我一个提示,为什么发布的代码并不总是有效 – 例如,如果你为所有用户显示进程。

有些评论是正确的,你正在玩一款注定无法结束的游戏。 但是,据我所知,将您的流程设置为关键内核流程似乎可以为您带来明显的胜利。 任何杀死该进程的企图都会使您的计算机失灵。 代码是:

 /* Copyright © 2017 Jesse Nicholson This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */ using System; using System.Runtime.InteropServices; using System.Threading; namespace MyRedactedNamespace { ///  /// Class responsible for exposing undocumented functionality making the host process unkillable. ///  public static class ProcessProtection { [DllImport("ntdll.dll", SetLastError = true)] private static extern void RtlSetProcessIsCritical(UInt32 v1, UInt32 v2, UInt32 v3); ///  /// Flag for maintaining the state of protection. ///  private static volatile bool s_isProtected = false; ///  /// For synchronizing our current state. ///  private static ReaderWriterLockSlim s_isProtectedLock = new ReaderWriterLockSlim(); ///  /// Gets whether or not the host process is currently protected. ///  public static bool IsProtected { get { try { s_isProtectedLock.EnterReadLock(); return s_isProtected; } finally { s_isProtectedLock.ExitReadLock(); } } } ///  /// If not alreay protected, will make the host process a system-critical process so it /// cannot be terminated without causing a shutdown of the entire system. ///  public static void Protect() { try { s_isProtectedLock.EnterWriteLock(); if(!s_isProtected) { System.Diagnostics.Process.EnterDebugMode(); RtlSetProcessIsCritical(1, 0, 0); s_isProtected = true; } } finally { s_isProtectedLock.ExitWriteLock(); } } ///  /// If already protected, will remove protection from the host process, so that it will no /// longer be a system-critical process and thus will be able to shut down safely. ///  public static void Unprotect() { try { s_isProtectedLock.EnterWriteLock(); if(s_isProtected) { RtlSetProcessIsCritical(0, 0, 0); s_isProtected = false; } } finally { s_isProtectedLock.ExitWriteLock(); } } } } 

这里的想法是你尽快调用Protect()方法,然后在你自愿关闭应用程序时调用Unprotect()

对于WPF应用程序,您将要挂钩SessionEnding事件,这是您将调用Unprotect()方法的地方,以防有人注销或关闭计算机。 这绝对必须是SessionEnding事件,而不是SystemEvents.SessionEnded事件。 通常在调用SystemEvents.SessionEnded事件时,如果您花费太长时间来释放保护,则可以强制终止您的应用程序,每次重新启动或注销时都会导致BSOD。 如果使用SessionEnding事件,则可以避免此问题。 关于该事件的另一个有趣的事实是,您在某种程度上可以对注销或关闭提出异议。 此外,您显然希望在Application.Exit事件处理程序中调用Unprotect()

在部署此机制之前,请确保您的应用程序稳定,因为如果进程受到保护,崩溃也会导致您的计算机失败。

作为所有攻击你采取这些措施的人的说明,请忽略它们。 如果有人可能使用这些代码来做恶意的事情并不重要,这是一个很糟糕的理由,可以完全合法地停止合法的研究。 在我的情况下,我已将此作为我自己的应用程序的一部分开发,因为成人(管理员) 不希望能够通过杀死它来阻止我的过程。 他们明确地希望这个function,因为它阻止自己绕过软件的设计目的。

使它成为WPF方只是一个客户端。 在这种情况下,“服务器”必须是Windows服务。 然后将服务设置为自动启动(最后一部分需要管理员权限)。 如果它作为网络管理员运行,则获得奖励。

如果服务的进程被终止,Windows会立即再次启动它。 然后,无论用户尝试什么,他们都无法真正阻止程序的逻辑,除非他们拥有管理权限并自行停止服务。 仅使用WPF GUI进行配置。

系统帐户比管理员更高(至少在操作系统的情况下)。 系统帐户和管理员帐户具有相同的文件权限,但它们具有不同的function。 系统帐户由操作系统和在Windows下运行的服务使用。 Windows中有许多服务和进程需要能够在内部登录(例如在Windows安装期间)。 系统帐户是为此目的而设计的; 它是一个内部帐户,不会显示在用户管理器中,无法添加到任何组,也无法为其分配用户权限。

因此,挑战在于如何在安装过程中将应用程序权限提升为系统帐户。 我不确定如何提升你的过程。 但值得阅读后面的参考文献1 , 参考2 。 此外,即使我们假设您设法将其设置为系统帐户,但在管理您自己的应用程序时,即使是指数级超级用户,您仍可能面临更多挑战。