我正在编写一个包含 Windows 服务和 GUI 程序的程序,因为 Windows 服务不能直接与 Windows 通信。
它是一个交互的程序,一个服务器守护进程阻止学生在多个工作站使用一个帐户登录。(防止密码共享)
GUI 进程使用 Windows 自动启动启动并以用户权限运行。因此,用户可以轻松地杀死 GUI 进程。这不好,因为 GUI 进程导致注销(和用户消息)。
如何阻止用户终止进程?
由于您无法选择使用操作系统安全性来防止这种情况,因此技术上的答案是无法做到这一点。那只剩下变通方法或替代方法。
一种不受官方支持的解决方法,依赖于未记录的功能,而您没有收到我的消息是:
public static class Unkillable
{
[DllImport("ntdll.dll", SetLastError = true)]
private static extern void RtlSetProcessIsCritical(UInt32 v1, UInt32 v2, UInt32 v3);
public static void MakeProcessUnkillable()
{
Process.EnterDebugMode();
RtlSetProcessIsCritical(1, 0, 0);
}
public static void MakeProcessKillable()
{
RtlSetProcessIsCritical(0, 0, 0);
}
}
调用后Unkillable.MakeProcessUnkillable
,终止进程将导致立即蓝屏。这是一个非常丑陋的解决方案,但很难反驳“可以在 2 分钟内实现”。
另一种解决方法是创建一组进程,这些进程通过在一个死亡时相互重新启动来进行合作。
GUI 进程使用 Windows 自动启动启动并以用户权限运行。因此,用户可以轻松地杀死 GUI 进程。
怎么样:您运行 GUI 进程向他们显示消息,但您使用该服务实际注销。然后他们可以随心所欲地终止 GUI 进程,而不会影响软件的主要功能。
也许您应该更好地配置您的网络。如果您的域设置正确,您可以设置一个登录脚本来检查域控制器以查看用户是否已经登录,如果他们在其他地方登录则将其注销。
我假设每台 PC 都设置了适当的帐户设置(即不是管理员)。
登录脚本还可以执行其他操作,例如设置网络共享。
您可以查看从任务管理器中隐藏进程的 rootkit 样式方法。这不是一个特别优雅的解决方案。
您可以使用此代码使进程难以杀死(纯 C,抱歉,但移植到 C# 应该不会太难)。
从技术上讲,这并不能阻止用户终止进程,因为他们可以更改权限,但他们需要编写代码或使用专门设计的工具来这样做。除非用户具有管理员权限,否则任务管理器和 pskill 都不起作用。
通过让服务使用备份/恢复权限来获取进程的所有权,可能会阻止非管理员用户更改权限。
我知道这是旧的,但它可能会帮助另一个正在阅读本文的人。
您可以通过 5 种方式做到这一点:
拥有一个签名的内核驱动程序并通过它保护运行您的进程。(最推荐)
使用 ntdll.dll 中的 RtlSetProcessIsCritical() 将您的进程标记为关键系统进程。
做2个过程。如果一个终止另一个启动它。
使用系统漏洞获取内核权限或加载未签名的内核驱动程序。
用户模式 rootkit 正在使用这种技术。它挂接任务管理器中的函数(一些 rootkit 甚至挂接它们不能单独挂接任务管理器的所有进程)并且它挂接的函数是 TerminateProcess,如果它试图终止您的进程,则返回 ERROR_ACCESS_DENIED。如果这不是您的进程,那么它将继续正常终止。我不推荐这种技术,因为很多 AV 会将其标记为 rootkit。
您不应该禁止用户杀死您的应用程序。如果在 GUI 大喊之后服务失败,那么您应该修复服务而不是 GUI。
但是,如果您真的想停止应用程序,请查看此处