gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 22:32:53 26 4
gpt4 key购买 nike

我正在开发一个家长控制应用程序(用 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 中,如果应用程序是由登录用户启动的,即使是管理员也无法终止进程(访问被拒绝)。但是,如果您切换到另一个用户帐户(管理员或标准用户),然后选中“显示所有用户的进程”,那么您可以毫无问题地终止该进程。任何人都可以提示我为什么以及如何解决它吗?

编辑:
我知道有些人对这个问题感到不安,但这是我的困境。这是我编写的主要供自己使用的家长控制。主要特点是我想监控和限制我的 child 玩游戏(而不是简单地关闭所有游戏)。我可以为 children 分配一个标准用户帐户,他们无法终止进程。但是,某些游戏(例如 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
{
/// <summary>
/// Class responsible for exposing undocumented functionality making the host process unkillable.
/// </summary>
public static class ProcessProtection
{
[DllImport("ntdll.dll", SetLastError = true)]
private static extern void RtlSetProcessIsCritical(UInt32 v1, UInt32 v2, UInt32 v3);

/// <summary>
/// Flag for maintaining the state of protection.
/// </summary>
private static volatile bool s_isProtected = false;

/// <summary>
/// For synchronizing our current state.
/// </summary>
private static ReaderWriterLockSlim s_isProtectedLock = new ReaderWriterLockSlim();

/// <summary>
/// Gets whether or not the host process is currently protected.
/// </summary>
public static bool IsProtected
{
get
{
try
{
s_isProtectedLock.EnterReadLock();

return s_isProtected;
}
finally
{
s_isProtectedLock.ExitReadLock();
}
}
}

/// <summary>
/// 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.
/// </summary>
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();
}
}

/// <summary>
/// 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.
/// </summary>
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 应用程序,您需要 Hook SessionEnding 事件,这是您调用 Unprotect() 方法的地方,以防万一有人注销或关闭计算机。这绝对必须是 SessionEnding 事件,而不是 SystemEvents.SessionEnded 事件。通常在 SystemEvents.SessionEnded 事件被调用时,如果您花费太长时间解除保护,您的应用程序可能会被强制终止,从而导致每次重新启动或注销时出现 BSOD。如果使用 SessionEnding 事件,就可以避免这个问题。关于该事件的另一个有趣事实是,在某种程度上,您可以对注销或关机提出异议。此外,您显然希望在 Application.Exit 事件处理程序中调用 Unprotect()

在部署此机制之前确保您的应用程序是稳定的,因为如果进程受到保护,崩溃也会使您的计算机蓝屏。

请注意所有因采取这些措施而攻击您的人,请忽略他们。是否有人可能会使用此代码来做一些恶意的事情并不重要,这是一个为了完全合法的原因而停止完全合法的研究的糟糕借口。在我的例子中,我将其开发为我自己的应用程序的一部分,因为成人(管理员)不希望能够通过终止它来停止我的进程。他们明确需要此功能,因为它可以防止他们自己无法绕过软件的设计目的。

关于c# - 如何防止应用程序在任务管理器中被杀死?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16968581/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com