简体   繁体   中英

Prevent C# app from process kill

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

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. Raymond Chen posted on this some time ago:The arms race between programs and users

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:

  • 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)
  • 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

  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. 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.

  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).

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.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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