Как скрыть процесс в диспетчере задач в C #? - PullRequest
33 голосов
/ 09 октября 2008

У меня есть требование скрыть процесс в диспетчере задач. Это для интранет-сценария. Итак, все законно. :)

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

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

Обновление2 : удаление ссылки на руткит. Каким-то образом этот пост выглядел негативно.

Ответы [ 16 ]

70 голосов
/ 09 октября 2008

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

45 голосов
/ 09 октября 2008

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

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

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

Здесь является примером руткита, который пытается сделать нечто подобное (и имеет несколько серьезных проблем).

18 голосов
/ 09 октября 2008

Если вы хотите запретить пользователям убивать процесс из диспетчера задач, вы можете просто использовать дескриптор безопасности для процесса, чтобы запретить доступ всем. Технически администраторы все еще могут убить процесс, взяв на себя ответственность за процесс и сбросив DACL, но нет интерфейса, который мог бы выполнить любую из этих вещей из диспетчера задач. Process Explorer может иметь интерфейс, хотя.

Когда ваш процесс запускается, используйте SetKernelObjectSecurity с DACL_SECURITY_INFORMATION, используя текущий дескриптор процесса. Установите DACL с нулевыми ACL. Это запретит любой доступ всем, включая тех, кто пытается завершить ваш процесс с помощью диспетчера задач.

Вот пример, который также меняет владельца процесса:

SECURITY_DESCRIPTOR sd;
ACL dacl;
SID_IDENTIFIER_AUTHORITY ntauth = SECURITY_NT_AUTHORITY;
PSID owner;

assert(InitializeAcl(&dacl, sizeof dacl, ACL_REVISION));

assert(AllocateAndInitializeSid(&ntauth, 1, SECURITY_LOCAL_SYSTEM_RID, 0,0,0,0,0,0,0, &owner));

assert(InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION));

assert(SetSecurityDescriptorDacl(&sd, TRUE, &dacl, FALSE));

assert(SetSecurityDescriptorOwner(&sd, owner, FALSE));

assert(SetKernelObjectSecurity(GetCurrentProcess(), DACL_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION, &sd));

assert(FreeSid(owner) == NULL);

К сожалению, это не кажется эффективным. Я все еще могу закрыть процесс (хотя и не как пользователь с ограниченными правами). Возможно, диспетчер задач становится владельцем или вызывает какую-то другую привилегию для прекращения процесса? Кажется, я помню эту работу в предыдущих версиях Windows (я тестировал 2003), но я мог ошибиться.

10 голосов
/ 09 октября 2008

Я надеюсь, что вы не сможете.

Обновление: учитывая сценарий, я думаю, что вам, вероятно, будет лучше запустить его под другой учетной записью администратора. Это может помочь предупредить людей о том, что они не должны убивать процесс.

6 голосов
/ 09 октября 2008

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

4 голосов
/ 28 февраля 2012

Написать драйвер - вы можете использовать ObRegisterCallbacks для регистрации уведомления о доступе к объекту процесса. Возвращать STATUS_ACCESS_DENIED, когда DesiredAccess содержит права доступа, которые вам не нравятся, например, завершение процесса или запись в память процесса.

http://msdn.microsoft.com/en-us/library/windows/hardware/ff558692(v=vs.85).aspx

4 голосов
/ 09 октября 2008

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

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

3 голосов
/ 11 января 2013

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

public static void ToggleTaskManager(bool toggle)
{
    Microsoft.Win32.RegistryKey HKCU = Microsoft.Win32.Registry.LocalMachine;
    Microsoft.Win32.RegistryKey key = HKCU.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Policies\System");
    key.SetValue("DisableTaskMgr", toggle ? 0 : 1, Microsoft.Win32.RegistryValueKind.DWord);
}
3 голосов
/ 27 декабря 2009

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

Я не совсем уверен в том, как настроить хук, но тогда вы не используете цикл while, который тратит впустую CPU.

3 голосов
/ 09 октября 2008

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

...