防止 C# 应用程序终止进程
如何保护我的 C# 应用程序不被其他人通过任务管理器或以编程方式杀死其进程?
这是我的场景:
应用程序 A 是另一个团队开发的 MFC 应用程序。它有一个未发布的基于文本的远程界面,可通过后门启用。
我正在开发应用程序 B,这是一个与 A 交互的 C# WinForms 应用程序。B 在需要远程访问时启用 A 的后门,并在完成(或失败时)将其关闭。
我正在探索用户可以滥用 B 的方式来访问 A 的隐藏功能,例如在启用 A 的远程接口后杀死 B 的进程。当这种情况发生时,我希望 B 有最后一次机会关闭 A 的后门。
B 使用 localhost 与 A 交互,因此我不担心断电情况。
我正在寻找一个不涉及更改 A 的解决方案。
我并不期望能够阻止 Dark Tangent(尽管这将是一个额外的好处),但现在脚本小子可以按照自己的方式进行此设计: )
这些应用程序在 Windows XP 上运行,但很快也将支持 Vista 和 Windows XP。 7.
预先感谢, 吉姆
How can I protect my C# app from someone killing its process via taskman or programmatically?
Here is my scenario:
App A is an MFC app developed by another team. 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).
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. I'd like have one last chance for B to close A's backdoor when that happens.
B uses localhost to interact with A, so I'm not worried about the power-down scenario.
I'm looking for a solution that doesn't involve changing 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 :)
These apps run on Windows XP, but will also soon support Vista & 7.
Thanks in advance,
Jim
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
在程序关闭时采取必要的步骤会导致脆弱的程序很容易崩溃。即使您可以通过任务管理器阻止某人杀死您的程序,您也无法阻止他们关闭计算机,甚至无法阻止他们将电缆从墙上拉出。任何需要完成的至关重要的任务都将丢失。如果停电怎么办?同样,您的任务将无法完成,并且重要的清理代码将不会运行。
相反,您应该使您的程序在任何时候都能够应对失败。使用事务,并始终以原子方式将状态保存到文件中 - 确保您始终拥有至少一份有效的数据副本。不要以暂时无效的方式覆盖重要文件。
最后,您可以向程序添加一个对话框,当他们尝试关闭它时,警告他们程序需要正确关闭。如果你让你的关闭速度更快,用户将不想杀死它并让它正常终止。如果你的关闭需要很长时间,那么人们就会试图杀死它。如果您对用户友善,他们也会对您友善。
如果快速关闭意味着用户将丢失一些未完成的工作,那么请警告他们这一点,并给他们机会等待任务完成,但如果他们真的想退出你的程序,那就让他们退出。
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.
你不能 - 只要用户有权在你的程序上调用 TerminateProcess,你就无法阻止 End Process 在任务管理器中立即杀死你。 Raymond Chen 不久前发布过此内容:程序和用户之间的军备竞赛< /a>
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. Raymond Chen posted on this some time ago: The arms race between programs and users
你真的、真的、真的不想这样做。让用户非常愤怒!!但是,如果它应该是一项服务,请将其作为服务帐户运行,并且不要向用户授予管理员权限。
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.
简短的回答:你不能也不应该。
长答案:您可以尝试启动第二个“帮助程序”进程,该进程每 x 秒检查一次您的应用程序是否仍在运行。如果不是,它将重新启动。
如果您希望某个进程长时间运行,只是不信任用户让它保持运行,请考虑 Windows 服务。它们就是为此而设计的。
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. 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. 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:
为了防止您的应用程序被终止,您以另一个用户的身份运行您的应用程序(即作为服务,或作为另一个用户帐户) ,并将用户限制为标准用户。
这样,恶意用户就无法杀死您的进程,因为只有管理员才能杀死它,显然,您不信任任何人拥有这种特权。
它的优点是遵循操作系统的预期设计。
In order to prevent your application from being terminated, you run your application as another user (i.e. 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
如果应用程序A可以接收修改请求
最好,我会选择一个架构,其中所有应用程序B都在打开后门时注册,并且需要每隔一段时间对应用程序A进行注册,以便应用程序A可以关闭自己的后门应用程序 B 没有通知它它仍然需要访问权限。这仍然不是完全安全的,但应用程序 A 不应该在没有某种“安全”通信方式的自我调节的情况下构建这样的接口。
或者,您可以建议修改应用程序 A 以检查有效进程,如果在后门打开时未找到任何进程,则将其关闭(这是可欺骗的,因为它采用已处理的名称)。
否则,听起来 App B 在不需要立即访问时应该尽可能频繁地关闭后门。
要求应用程序 B 提供对应用程序 A 的访问安全性确实是一个糟糕的模型。
@Jim
If App A can receive modification requests
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. 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.
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).
Otherwise, it sounds like App B should shut the backdoor as often as possible when it does not need immediate access.
Requiring an App B to provide security of access to App A is a poor model indeed.
据我所知你不能,即使你可以,你也不应该这样做。想象一下,如果您无法强制终止应用程序,那将是多么烦人。
如果你的应用程序保持运行很重要,你总是可以创建一个 Windows 服务来“ping”应用程序以确保它正在运行(你可以使用命名管道、套接字、pid 文件......等等)。如果服务检测到该进程已经死亡,那么它可以重新启动它。这可能是您最好的选择。
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). if the service detects that the process has died then it can just restart it. this is probably your best bet.
当应用程序第一次启动时,您是否不能执行在后台运行的第三个 ap/进程,并尝试每隔一段时间回调到应用程序 B,因此当应用程序 B 关闭时。应用程序 C 可以看到并执行关闭App A后门的程序。
这样,当应用程序 B 通过预期的关闭按钮成功关闭时,它将禁用应用程序 C 检查应用程序 B 是否仍然正常工作...
我目前并不是 C# 的最佳人选,但看看你的问题,这可能是我的方法之一会尝试这样做。
此外,如果应用程序 B 也检查应用程序 C,那么如果应用程序 C 已关闭,应用程序 B 将关闭后门(如果可以的话)。
正如其他人所说,这可能不是一个好主意。
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.
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...
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..
Also if App B checks App C aswell then if App C has gone down App B will close the backdoor if it can.
As the others say this may not be a good idea tho.