#cpp #c #winapi #драйвер
Есть задача разработать софт, который полностью блокирует рабочую станцию, показывая уведомление. Не должны работать никакие Alt+Tab, Ctrl+Alt+Del и т. д., и фокус должен быть на окне. Пользователь читает уведомление, и после окно закрывается. User32 подтупляет, и не совсем удобно. Есть какие-то способы, как, например, работают антивирусы? Как работает UAC? В какую сторону копать? Стоит требование, чтобы приложение работало на любой Windows. Без библиотек Windows путь к написанию драйвера?
Ответы
Ответ 1
... софт который полностью блокирует рабочую станцию показывая уведомление. Переключите пользователя на свой рабочий стол. Дело в том, что в рамках оконной станции (грубо говоря, одного рабочего места) можно иметь несколько рабочих столов. Они изолированы друг от друга (у каждого есть свой, независимый, список окон). Более того, текущий стол ведёт себя так, будто других столов не существует. Он захватывает весь пользовательский ввод и занимает всю площадь экрана. Кстати, окна UAC (запрос повышения привилегий на затемнённом фоне) как раз и создают для своих нужд отдельный рабочий стол, чтобы ни одна программа не могла перехватить вводимый пароль. Итак, что надо делать: Сохранить дескриптор текущего рабочего стола, чтобы к нему можно было бы вернуться (сам пользователь сможет это сделать только путём выхода из системы): const HDESK hOld = GetThreadDesktop(GetCurrentThreadId()); Создать рабочий стол (в нашем случае с именем reminder): const HDESK hNew = CreateDesktop( TEXT("reminder"), NULL, NULL, 0, DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS | DESKTOP_CREATEWINDOW, NULL ); Переключиться на него, заодно указав, что и все дальнейшие окна мы будем создавать на нём же: SetThreadDesktop(hNew); SwitchDesktop(hNew); ВАЖНО: нам нельзя создавать какие-либо окна на основном рабочем столе, иначе SetThreadDesktop() работать не будет: The SetThreadDesktop function will fail if the calling thread has any windows or hooks on its current desktop (unless the hDesktop parameter is a handle to the current desktop). Создать диалог с напоминанием. Пусть это будет блокирующий MessageBox(): MessageBox(NULL, TEXT("Текст напоминания"), TEXT("Напоминание"), MB_ICONWARNING); Вернуться на исходный рабочий стол: SwitchDesktop(hOld); По окончании работы рабочий стол надо закрыть во избежание утечки ресурсов: CloseDesktop(hNew); Не должны работать никакие Alt+Tab, Ctrl+Alt+Del и т. д. По определённым причинам окно диспетчера задач привязывается не к текущему, а к основному рабочему столу. Поэтому Ctrl+Shift+Esc и даже безопасный Ctrl+Alt+Delete хоть и открывают диспетчер задач, но он станет доступным только после возврата на основной рабочий стол, то есть тогда, когда вы и только вы этого захотите. ...и фокус должен быть на окне. Так как наш диалог является единственным на текущем рабочем столе, он автоматически получит фокус. Вот полный и готовый демонстрационный пример: #includeint CALLBACK WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { const HDESK hOld = GetThreadDesktop(GetCurrentThreadId()); const HDESK hNew = CreateDesktop( TEXT("reminder"), NULL, NULL, 0, DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS | DESKTOP_CREATEWINDOW, NULL ); SetThreadDesktop(hNew); SwitchDesktop(hNew); MessageBox(NULL, TEXT("Reminder text"), TEXT("Reminder"), MB_ICONWARNING); SwitchDesktop(hOld); CloseDesktop(hNew); return 0; } Ответ 2
Сделать универсальной такую программу "легально" - невозможно. Как минимум, столкнетесь с ограничениями прав (в любой нормальной организации все пользователи сидят в домене с очень ограниченными правами.) Соответственно, не сможете программой, запущенной от имени пользователя: Вешать хуки Управлять процессами Управлять сетевой активностью А вот нелегально - пожалуйста. Все просто: Ищете в любом драйвере уязвимость Пишете эксплоит Распространяете Получаете новый WannaCry :)
Комментариев нет:
Отправить комментарий