Предотвратить приложение C # от уничтожения процесса - PullRequest
8 голосов
/ 26 июня 2010

Как я могу защитить свое приложение на C # от того, что кто-то убил его процесс через Taskman или программно?

Вот мой сценарий:

Приложение A - это приложение MFC, разработанное другой командой. Он имеет неопубликованный текстовый удаленный интерфейс, который включен через черный ход.

Я занимаюсь разработкой приложения B, приложения C # WinForms, которое взаимодействует с A. B включает черный ход A, когда ему требуется удаленный доступ, закрывает его по окончании (или в случае сбоя).

Я изучаю способы, которыми пользователи могут злоупотреблять B, чтобы получить доступ к скрытой функциональности A, например, убить процесс B после того, как он включил удаленный интерфейс A. Я хотел бы иметь последний шанс для Б закрыть заднюю дверь А., когда это произойдет.

B использует localhost для взаимодействия с A, поэтому меня не беспокоит сценарий отключения питания.

Я ищу решение, не требующее замены A.

Я не ожидаю, что смогу остановить Темный тангент (хотя это было бы бонусом), но прямо сейчас сценарий-детишка может по-своему разобраться с этим дизайном:)

Эти приложения работают на Windows XP, но также скоро будут поддерживать Vista и 7.

Заранее спасибо, Jim

Ответы [ 9 ]

6 голосов
/ 26 июня 2010

Я готов закрыть приложение, когда они попытаются, но сначала нужно что-то сделать.

Наличие необходимых шагов при завершении работы программы приводит к хрупким программам, которые легко ломаются.Даже если вы можете запретить кому-либо убивать вашу программу с помощью диспетчера задач, вы не сможете остановить его от выключения компьютера или даже отсоединения кабеля от стены.Любая задача, столь жизненно важная для выполнения, будет потеряна.А что если происходит отключение питания?Опять же, ваша задача не будет выполнена, и ваш жизненно важный код очистки не будет запущен.

Вместо этого вы должны в любой момент сделать свою программу устойчивой к сбоям.Используйте транзакции и всегда сохраняйте состояние в файлах атомарно - убедитесь, что у вас всегда есть хотя бы одна действительная копия ваших данных.Не перезаписывайте важные файлы так, чтобы они временно стали недействительными.

Наконец, вы можете добавить в свою программу диалоговое окно, которое при попытке закрыть его предупреждает их о том, что программа должна быть закрыта должным образом.,Если вы быстро отключитесь, пользователи не захотят его убивать и позволят завершить работу должным образом.Если ваше отключение занимает много времени, люди будут пытаться убить его.Если вы любезны с вашими пользователями, они будут любезны и с вами.

Если быстрое выключение означает, что пользователь потеряет некоторую незаконченную работу, предупредите его об этом и дайте ему возможность дождаться выполнения заданиячтобы закончить, но если они действительно хотят выйти из вашей программы, то пусть они выходят.

4 голосов
/ 26 июня 2010

Вы не можете - до тех пор, пока пользователь имеет право вызывать TerminateProcess для вашей программы, вы не можете запретить конечному процессу немедленно убить вас в диспетчере задач. Раймонд Чен написал об этом некоторое время назад: http://blogs.msdn.com/b/oldnewthing/archive/2004/02/16/73780.aspx

4 голосов
/ 26 июня 2010

Вы действительно, действительно, действительно не хотите этого делать.Это очень злит пользователей!Однако если предполагается, что это служба, запустите ее как учетную запись службы и не предоставляйте права администратора пользователям.

2 голосов
/ 26 июня 2010

Я думаю, что все упустили момент.Если я правильно прочитал (после вашего редактирования), вы хотите знать, когда вас «убивают», чтобы вы могли изящно отключиться?

Смысл «убийства» в том, что вы «не можете» остановить его,Конечно, есть обходные пути, такие как использование второго приложения для восстановления убитого приложения, но это не имеет ничего общего с простой возможностью корректно завершить работу.

Наилучший подход состоит в том, чтобы запускаться как служба (так что вынельзя убить, просто попросить закрыть) или реструктурировать работу вашего приложения, чтобы оно не нуждалось в «очистке» перед выходом.Когда приложение закрывается, большинство ресурсов, которые оно содержит, автоматически очищаются, поэтому вам нужно аккуратно закрыть только ваши собственные данные.Подходы, которые вы можете попробовать:

  • Часто фиксируйте свое состояние на диске, чтобы не потерять много (или что-либо еще), если вы неожиданно завершите работу.(Не забудьте сбросить все потоки ввода / вывода, чтобы убедиться, что они зафиксированы на диске)
  • Сохранение информации на диск, которая позволяет обнаруживать неожиданное завершение работы при следующем запуске вашей программы, чтобы она могла обнаруживать иисправьте все проблемы, которые могли быть вызваны тем, что вас убили.
  • Скажите вашим пользователям, что они не идиоты, и хорошо выйдите из приложения.Ткните их в глаза, если они вас игнорируют.Обычно после не более двух раз они слушают: -)
2 голосов
/ 26 июня 2010

Краткий ответ: вы не можете и не должны.

Длинный ответ: вы можете попробовать запустить второй вспомогательный процесс, который каждые х секунд проверяет, все ли еще работает ваше приложение. Если это не так, он перезапускает его.

Если вы хотите, чтобы процесс выполнялся в течение длительного времени, просто не доверяйте пользователям поддерживать его, рассмотрите службы Windows. Они предназначены для этого.

1 голос
/ 28 июня 2010

@ Jim

Если приложение А может получать запросы на изменение

  1. Предпочтительно, я бы предпочел архитектуру, в которой все приложения B регистрируются при открытии бэкдора и должны пропинговать приложение A с регистрацией с интервалом, чтобы приложение A могло закрыть свой собственный бэкдор при приложении B, не сообщая об этом. что это все еще нуждается в доступе. Это все еще не совсем безопасно, но приложение А не должно быть структурировано с таким интерфейсом без какого-либо саморегулирования для «безопасных» средств связи.

  2. Или вы можете предложить изменить приложение A, чтобы проверять наличие допустимых процессов, и если ни один из них не найден, когда его задняя дверь открыта, то он закрывается (это может быть подделано, поскольку идет по обработанному имени).

В противном случае, похоже, что приложение B должно закрывать черный ход как можно чаще, когда ему не требуется немедленный доступ.

Требование к приложению B обеспечить безопасность доступа к приложению A действительно является плохой моделью.

1 голос
/ 28 июня 2010

Чтобы предотвратить прекращение работы вашего приложения, вы запускаете его как другой пользователь ( т.е. как служба или как другая учетная запись пользователя) и ограничить пользователей Стандартный пользователь .

Таким образом, злоумышленники не могут уничтожить ваш процесс, поскольку только администраторы могут уничтожить его, и это привилегия, которой вы, очевидно, никому не доверяете.

Преимущество заключается в том, что он следует предполагаемому дизайну операционной системы.

0 голосов
/ 28 июня 2010

Когда приложение запускается в первый раз, вы не можете выполнить 3-й ap / процесс, который работает в фоновом режиме и пытается вызвать обратный вызов к приложению B, так что когда это приложение B закрыто ... Приложение C может видеть это и выполняет процедуру, чтобы закрыть черный ход приложения А.

Так что, когда приложение B будет успешно закрыто с помощью соответствующей кнопки «Закрыть», оно отключит приложение C от проверки, что приложение B по-прежнему работает нормально ...

На данный момент я не лучший в C #, но, глядя на вашу проблему, это, вероятно, один из способов, которым я бы попытался это сделать ..

Кроме того, если приложение B также проверяет приложение C, то если приложение C закрылось, приложение B закроет черный ход, если сможет.

Как говорят другие, это может быть не очень хорошая идея.

0 голосов
/ 26 июня 2010

Насколько я знаю, вы не можете, и даже если бы вы могли, вы действительно не должны.представьте, как это будет раздражать, если вы не сможете принудительно убить приложение.

Если важно, чтобы ваше приложение продолжало работать, вы всегда можете создать службу Windows, которая "пингует" приложение, чтобы убедиться, что оно работает (вы можете использовать именованные каналы, сокеты, файлы pid ... что угодно).если служба обнаружит, что процесс умер, он может просто перезапустить его.это, вероятно, ваш лучший выбор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...