Запретить доступ к программному процессу киоска

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

Любая помощь будет присвоена.

Тем не менее, я уверен, что есть функция в Windows, чтобы предотвратить закрытие процесса программы, как при попытке убить процесс rundll.exe . Я хочу знать эту функцию, если я могу назвать ее с помощью DllImport

Может ли кто-нибудь помочь с трюком?
Рубить?
Функция?
Любое другое решение?

РЕДАКТИРОВАТЬ:

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

EDIT 2: я пока не могу найти решение

Один из подходов, если вы можете получить доступ к идентификатору процесса в административном контексте, заключается в том, чтобы запретить разрешение PROCESS_TERMINATE для процесса конечным пользователям. Завершение процесса (через диспетчер задач или другие контексты) по умолчанию предоставляется владельцу, но может быть явно отклонено. Когда это отклонено, для завершения процесса потребуется, чтобы владелец вручную изменил ACL, а затем завершил процесс. Если пользователь не является ни администратором, ни владельцем процесса, он не сможет принудительно завершить процесс (например, через диспетчер задач), хотя процесс будет разрешен для выхода из системы.

Следующий код помещает явный отказ ACE в процессе с помощью PID processid для членов группы Everyone.

 #include "Aclapi.h" #include "Sddl.h" DWORD RestrictTerminateOnProcessId(DWORD processid) { PACL dacl = NULL, newdacl = NULL; HANDLE ph = NULL; PSECURITY_DESCRIPTOR* desc = NULL; PSID everyonesid = NULL; ph = OpenProcess(WRITE_DAC | READ_CONTROL, false, processid); if (!ph) goto cleanup; if (ERROR_SUCCESS != GetSecurityInfo(ph, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &dacl, NULL, desc)) goto cleanup; SID_IDENTIFIER_AUTHORITY WorldAuth = SECURITY_WORLD_SID_AUTHORITY; if (!AllocateAndInitializeSid( &WorldAuth,1,SECURITY_WORLD_RID, 0,0,0,0,0,0,0,&everyonesid)) goto cleanup; // begin copy dacl _ACL_SIZE_INFORMATION si; GetAclInformation(dacl, &si, sizeof(si), AclSizeInformation); DWORD dwNewAclSize = si.AclBytesInUse + (2*sizeof(ACCESS_DENIED_ACE)) + (2*GetLengthSid(everyonesid)) - (2*sizeof(DWORD)); newdacl = (PACL)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwNewAclSize); if (newdacl == NULL) goto cleanup; if (!InitializeAcl(newdacl, dwNewAclSize, ACL_REVISION_DS)) goto cleanup; if (!AddAccessDeniedAce(newdacl, ACL_REVISION_DS, PROCESS_TERMINATE, everyonesid)) goto cleanup; for (int i = 0; i < si.AceCount; i++) { LPVOID pace = NULL; if (!GetAce(dacl, i, &pace)) goto cleanup; if (!AddAce(newdacl, ACL_REVISION_DS, MAXDWORD, pace, ((PACE_HEADER)pace)->AceSize)) goto cleanup; } // end copy dacl if (!SetSecurityInfo(ph, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, newdacl, NULL)) goto cleanup; SetLastError(0); cleanup: DWORD ret = GetLastError(); if (desc) LocalFree(desc); if (newdacl) HeapFree(GetProcessHeap(), 0, (LPVOID)newdacl); if (ph) CloseHandle(ph); if (everyonesid) FreeSid(everyonesid); return !ret; } 

Вы можете создать службу, которая запускается при загрузке. Затем он отслеживает, когда пользователь входит в систему и запускает вашу программу. Оттуда у вас есть два варианта:

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

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

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

Если вы по-прежнему используете Windows XP, вместо системной службы вы можете зарегистрировать пакет уведомлений Winlogon . Они в основном неудобны, поскольку они запускаются в контексте winlogon.exe, поэтому они были удалены из Vista и выше.

Правильный способ сделать это:

Создайте пользователя для приложения Kiosk. Скажем, KioskUser Создайте других пользователей, которые делают вещи на компьютере. Допустим, что User1 NONE из них должен быть администратором. Им не нужно быть админами? Конечно, у них могут быть привилегии.

Вы будете использовать учетную запись User1 как обычно. Затем вы запускаете приложение Kiosk как KioskUser. (используйте команду runas) – добавьте приложение в сеанс и сделайте его видимым (см. аргументы для получения дополнительной информации об этом)

Пока пользователь1 входит в систему и приложение Kiosk запускается из KioskUser, User1 не может убить процесс.

Я бы не рекомендовал «взломать» систему и не изменить что-то в реестре. Кроме того, вы можете сделать приложение Kiosk услугами и запустить его под пользователем Kiosk.

Похоже, вы не можете предотвратить процесс от убийства – см. Этот вопрос и, в частности, ссылку, помещенную в объяснение .

Однако вы можете запретить пользователю открывать диспетчер задач из панели задач (щелкните правой кнопкой мыши -> открыть диспетчер задач), нажав Ctrl-Shift-Esc или набрав taskman в командной строке, используя следующий раздел реестра:

 HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System\DisableTaskMgr 

Установка этого параметра в 1 отключает диспетчер задач, 0 – снова.

Из командной строки отключите его так:

 reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System /v DisableTaskMgr /t REG_DWORD /d 1 /f 

И вы можете поменять эту команду:

 reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System /v DisableTaskMgr /t REG_DWORD /d 0 /f 

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

редактировать

Как указано в комментариях, вы можете перехватить системный вызов низкого уровня, чтобы изменить список сообщаемых процессов. Этот ответ ускользает от него, вам в основном придется писать руткит в режиме ядра, возможно, реализованный в качестве драйвера устройства. Вероятно, это будет работать только в Windows XP и ниже из-за изменений ядра, внесенных в Vista и далее. Однако это может быть сделано, мой друг создал прототип этого для его итоговой диссертации бакалавриата.

Вам также нужно будет рассмотреть другие методы запросов для процессов. IIRC NtQuerySystemInformation – это не единственный способ, с помощью которого процессы могут быть перечислены.

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

Здесь http://blogs.msdn.com/b/oldnewthing/archive/2004/02/16/73780.aspx вы можете видеть с одной стороны, почему это задача не совсем возможная, а с другой стороны – несколько возможностей, которые вы могли бы должны защищаться от …, которые будут:

deny PROCESS_TERMINATE
deny PROCESS_CREATE_THREAD
deny PROCESS_VM_WRITE
запретить PROCESS_SUSPEND_RESUME
Плюс любая защита, которую вы можете получить от отладчиков – еще один очень хитрый бизнес.

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

Декларация:

 PSECURITY_DESCRIPTOR desc = NULL; 

Инициализация:

 desc = (PSECURITY_DESCRIPTOR)GlobalAlloc(GMEM_FIXED, sizeof(PSECURITY_DESCRIPTOR)); 

Очистка:

 if (desc) GlobalFree(desc); 

Вызов:

 GetSecurityInfo(ph, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &dacl, NULL, &desc) 

Я также нашел эту статью по этой проблеме: http://i1.blogs.msdn.com/b/oldnewthing/archive/2012/12/12/10376639.aspx

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