简体   繁体   English

防止 C# 应用程序终止进程

[英]Prevent C# app from process kill

How can I protect my C# app from someone killing its process via taskman or programmatically?如何保护我的 C# 应用程序免遭他人通过 taskman 或以编程方式杀死其进程的影响?

Here is my scenario:这是我的场景:

App A is an MFC app developed by another team. App A 是另一个团队开发的 MFC 应用程序。 It has an unpublished text-based remote interface that is enabled via a backdoor.它有一个未发布的基于文本的远程界面,通过后门启用。

I'm developing app B, a C# WinForms app which interacts with A. B enables A's backdoor when it needs remote access closes it when finished (or on failure).我正在开发应用程序 B,这是一个与 A 交互的 C# WinForms 应用程序。B 在需要远程访问时启用 A 的后门,并在完成(或失败时)关闭它。

I'm exploring ways users could abuse B in order to gain access to A's hidden functionality, such as killing B's process after it has enabled A's remote interface.我正在探索用户可以滥用 B 以访问 A 隐藏功能的方式,例如在启用 A 的远程接口后杀死 B 的进程。 I'd like have one last chance for B to close A's backdoor when that happens.当这种情况发生时,我希望有最后一次机会让 B 关闭 A 的后门。

B uses localhost to interact with A, so I'm not worried about the power-down scenario. B 使用 localhost 与 A 交互,所以我不担心掉电的情况。

I'm looking for a solution that doesn't involve changing A.我正在寻找不涉及更改 A 的解决方案。

I'm not expecting to be able to stop Dark Tangent (though that would be a bonus), but right now a script kiddie could have his way with this design :)我不希望能够阻止 Dark Tangent(尽管这将是一个奖励),但现在脚本小子可以用这种设计来做他的方式:)

These apps run on Windows XP, but will also soon support Vista & 7.这些应用程序在 Windows XP 上运行,但很快也将支持 Vista 和 7。

Thanks in advance, Jim提前致谢,吉姆

I'm willing shut the app down when they try but need to do some things first.当他们尝试但需要先做一些事情时,我愿意关闭应用程序。

Having necessary steps at program shutdown leads to fragile programs that break easily.在程序关闭时采取必要的步骤会导致脆弱的程序很容易被破坏。 Even if you could prevent someone from killing your program via the task manager, you cannot stop them from turning off the computer, or even pulling the cable out of the wall.即使您可以通过任务管理器阻止某人杀死您的程序,您也无法阻止他们关闭计算机,甚至将电缆从墙上拉出。 Whatever task that was so vitally important to complete will be lost.任何需要完成的至关重要的任务都将丢失。 And what if there is a power cut?如果停电怎么办? Again your task won't complete and your vital clean up code will not be run.同样,您的任务不会完成,您的重要清理代码也不会运行。

Instead you should make your program robust to failures at any point.相反,您应该使您的程序在任何时候都对失败保持健壮。 Use transactions, and always save state to files atomically - make sure that you always have at least one valid copy of your data.使用事务,并始终以原子方式将状态保存到文件中 - 确保您始终至少拥有一份有效的数据副本。 Don't overwrite important files in a way that they become temporarily invalid.不要以暂时无效的方式覆盖重要文件。

Finally, you can add a dialog box to your program that when they try to close it, warns them that the program needs to shut down properly.最后,您可以向您的程序添加一个对话框,当他们尝试关闭它时,警告他们该程序需要正确关闭。 If you make your shutdown fast users won't want to kill it and will let it terminate properly.如果你让你的关机速度很快,用户就不会想杀死它,而是让它正常终止。 If your shutdown takes ages then people will try to kill it.如果您的关机需要很长时间,那么人们会试图杀死它。 If you are nice to your users, they will be nice to you too.如果你对你的用户好,他们也会对你好。

If shutting down fast means that the user will lose some unfinished work then warn them about this and give them the opportunity to wait for the task to finish, but if they really want to quit your program then let them quit.如果快速关闭意味着用户将丢失一些未完成的工作,则警告他们这一点并让他们有机会等待任务完成,但如果他们真的想退出您的程序,那就让他们退出。

You really, really, really don't want to do this.你真的,真的,真的不想这样做。 It makes users very angry!!让用户非常生气!! However, if it is supposed to be a service, run it as a service account and don't give admin rights to users.但是,如果它应该是一项服务,请将其作为服务帐户运行,并且不要向用户授予管理员权限。

You can't - as long as the user has the right to call TerminateProcess on your program, you can't prevent End Process from killing you immediately in task manager.你不能 - 只要用户有权在你的程序上调用 TerminateProcess,你就不能阻止 End Process 在任务管理器中立即杀死你。 Raymond Chen posted on this some time ago:The arms race between programs and users Raymond Chen 前段时间在此发帖:程序和用户之间的军备竞赛

Short answer: you can't and you shouldn't.简短的回答:你不能也不应该。

Long answer: You can try to start a second 'helper' process, that checks every x seconds if your app is still running.长答案:您可以尝试启动第二个“帮助程序”进程,该进程每 x 秒检查一次您的应用程序是否仍在运行。 If it isn't, it restarts it.如果不是,它会重新启动它。

If you want a process to run for a long time just don't trust users to keep it running, consider windows services.如果你想让一个进程运行很长时间只是不相信用户让它运行,考虑 Windows 服务。 They are designed for this.它们是为此而设计的。

I think everybody has missed the point.我想每个人都没有抓住重点。 If I read it correctly (after your edit) you wish to know when you are being "killed" so you can shut down gracefully?如果我正确阅读(在您编辑之后),您希望知道自己何时被“杀死”,以便可以优雅地关闭?

The point of "killing" is that you "can't" stop it. “杀”的意义在于你“不能”阻止它。 There are of course workarounds like using a second app to revive a killed app, but that has nothing to do with simply being able to shut down gracefully.当然有一些变通方法,比如使用第二个应用程序来恢复被杀死的应用程序,但这与简单地能够正常关闭无关。

The best approach is to either run as a service (so you can't be killed, just asked to shut down), or to restructure the way your app works so that it doesn't need to "tidy up" before it quits.最好的方法是要么作为服务运行(这样你就不会被杀死,只是被要求关闭),或者重构你的应用程序的工作方式,这样它就不需要在退出之前“整理”。 When an app is quit, most resources it holds are automatically cleaned up, so it's only really your own data that you have to close cleanly.当一个应用程序退出时,它所拥有的大部分资源都会被自动清理,所以你真正需要关闭的只是你自己的数据。 Approaches you could try are:您可以尝试的方法有:

  • Frequently commit your state to disk so that you don't lose much (or anything) if you are unexpectedly quit.经常将您的状态提交到磁盘,这样如果您意外退出,您就不会丢失太多(或任何东西)。 (Remember to flush all I/O streams to be sure they are committed to disk) (记住刷新所有 I/O 流以确保它们已提交到磁盘)
  • Save information to disk that allows you to detect an unexpected shutdown the next time your program runs, so it is able to detect and rectify whatever problems might have been caused by being killed.将信息保存到磁盘,以便您在下次程序运行时检测到意外关闭,因此它能够检测和纠正因被杀死而可能导致的任何问题。
  • Tell your users not to be idiots, and quit your application nicely.告诉你的用户不要当白痴,然后很好地退出你的应用程序。 Poke them in the eye if they ignore you.如果他们不理你,就戳他们的眼睛。 Usually after no more than two times they listen :-)通常他们听不超过两次:-)

In order to prevent your application from being terminated, you run your application as another user ( ie as a service , or as another user account), and limit users to be Standard User .为了防止您的应用程序被终止,您以另一个用户身份(作为服务或另一个用户帐户)运行您的应用程序,并将用户限制为标准用户

This way no malicious users can kill your process, since only administrators can kill it, and that is a privilege that you, apparently, don't trust anyone with.这样,恶意用户就无法杀死您的进程,因为只有管理员才能杀死它,而这显然是您不信任任何人的特权。

It has the advantage of following the intended design of the operating system.它的优点是遵循操作系统的预期设计。

@Jim @吉姆

If App A can receive modification requests如果 App A 可以接收修改请求

  1. Preferably, I would an architecture where all App B's are registered upon opening the backdoor and are required to ping App A with the registration at an interval so that App A can close it's own backdoor upon App B not informing it that it still needs access.最好,我会采用一种架构,其中所有 App B 在打开后门时都已注册,并且需要每隔一段时间 ping App A 进行注册,以便 App A 可以在 App B 没有通知它仍然需要访问时关闭它自己的后门。 This is still not perfectly secure but App A should not be structured with such an interface without some sort of self regulation for "secure" means of communication.这仍然不是完全安全的,但应用程序 A 不应该使用这样的界面来构建,而没有对“安全”通信方式进行某种自我调节。

  2. Or, you could suggest App A be modified to check for valid processes and if none are found while it's backdoor is open then it gets closed (this is spoofable since it goes by processed name).或者,您可以建议修改 App A 以检查有效进程,如果在其后门打开时未找到任何进程,则将其关闭(这是可欺骗的,因为它使用已处理的名称)。

Otherwise, it sounds like App B should shut the backdoor as often as possible when it does not need immediate access.否则,听起来 App B 应该在不需要立即访问时尽可能多地关闭后门。

Requiring an App B to provide security of access to App A is a poor model indeed.要求应用程序 B 提供对应用程序 A 访问的安全性确实是一个糟糕的模型。

As far as i know you can't, and even if you could you really shouldn't.据我所知你不能,即使你可以,你也不应该。 imagine how annoying it would be if you couldn't force kill an application.想象一下,如果您不能强制终止应用程序,那该有多烦人。

If its important that your application keep running you could always create a windows service that "pings" the application to ensure it is running (you could use named pipes, sockets, pid files... whatever).如果您的应用程序保持运行很重要,您可以始终创建一个 Windows 服务来“ping”应用程序以确保它正在运行(您可以使用命名管道、套接字、pid 文件……等等)。 if the service detects that the process has died then it can just restart it.如果服务检测到进程已经死亡,那么它可以重新启动它。 this is probably your best bet.这可能是你最好的选择。

When the application initiates for the first time could you not execute a 3rd ap/process that is running in the background and attempts to callback to App B every so ofter, so when that App B is closed.. App C can see that and executes a procedure to close App A's backdoor.当应用程序第一次启动时,您是否可以不执行在后台运行的第三个 ap/进程并尝试每隔一段时间回调到应用程序 B,因此当应用程序 B 关闭时.. 应用程序 C 可以看到并执行关闭App A后门的程序。

So that when App B closes successfully via the intended Close button it will disable App C from checking App B is still working fine...因此,当 App B 通过预期的关闭按钮成功关闭时,它将禁止 App C 检查 App B 是否仍然正常工作......

Im not really the best with C# at the moment but looking at your problem thats probably one of the ways i would try to do it..我目前并不是最擅长 C#,但看着你的问题,这可能是我尝试做的方法之一。

Also if App B checks App C aswell then if App C has gone down App B will close the backdoor if it can.此外,如果 App B 也检查 App C,那么如果 App C 已经关闭,App B 会尽可能关闭后门。

As the others say this may not be a good idea tho.正如其他人所说,这可能不是一个好主意。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM