http://prostoserver.com/rus/
Страница Игоря Разина
Программы Примеры Книги
Перехват Ctrl+Alt+Del
Демонстрационный проект
Немного теории
Процесс Winlogon при загрузке создает окно "SAS window", которое регистрирует HOTKEY для Ctrl+Alt+Del (CAD) и Ctrl+Shift+Esc (CSE). Вот собственно и все.
Перехват

Для перехвата CAD (CSE) нам необходимо внедрить DLL в процесс Winlogon, сабклассить указанное окно, и обрабатывать сообщение WM_HOTKEY:

// Новая оконная функция
LRESULT WINAPI NewSASProc( HWND hSAS, UINT msg, WPARAM wParam, LPARAM lParam )
{
    if( WM_HOTKEY == msg ){
         // Поймали HOTKEY CAD (CSE) - выводим сообщение на десктоп "Default" и затем выходим
         if( MAKELONG( MOD_CONTROL | MOD_ALT, VK_DELETE ) == lParam ){
              MessageBoxEx( GetActiveWindow(), TEXT("Ctrl + Alt + Del"), 
                                               TEXT("SAS Hook"), MB_DEFAULT_DESKTOP_ONLY, 0 );
              return 0;
             }

         if( MAKELONG( MOD_CONTROL | MOD_SHIFT, VK_ESCAPE ) == lParam ){
              MessageBoxEx( GetActiveWindow(), TEXT("Ctrl + Shift + Esc"), 
                                               TEXT("SAS Hook"), MB_DEFAULT_DESKTOP_ONLY, 0 );
              return 0;
             }
        }

    // Вызываем стандартный обработчик
    return CallWindowProc( g_OldSASProc, hSAS, msg, wParam, lParam );
}

Функция DllMain:

BOOL WINAPI DllMain( HINSTANCE hinstDll, DWORD fdwReason, PVOID fImpLoad )
{
    if( DLL_PROCESS_ATTACH == fdwReason ){
         // Находим окно
         g_hSASwnd = FindWindow( TEXT("SAS Window class"), TEXT("SAS window") );

         // Заменяем обработчик
         if( g_hSASwnd != NULL )
              g_OldSASProc = (WNDPROC) SetWindowLong( g_hSASwnd, GWL_WNDPROC, (LONG) NewSASProc );
        }

    if( DLL_PROCESS_DETACH == fdwReason ){
         // Возвращаем обработчик
         if( g_hSASwnd != NULL )
              SetWindowLong( g_hSASwnd, GWL_WNDPROC, (LONG) g_OldSASProc );
        }

    return TRUE;
}

Осталось дело за малым . внедрить DLL. Для этого нам нужны права администратора и, если кто не знает как это делается, программа Injector.

Эмуляция

Эмулировать нажатие CAD можно из службы примерно следующим образом:

HWINSTA hStaPrev  = GetProcessWindowStation();
HDESK   hDeskPrev = GetThreadDesktop( GetCurrentThreadId() );
HWINSTA hSta      = OpenWindowStation( TEXT("Winsta0"), 0, MAXIMUM_ALLOWED );
SetProcessWindowStation( hSta );
HDESK   hDesktop  = OpenDesktop( TEXT("Winlogon"), 0, 0, MAXIMUM_ALLOWED );
SetThreadDesktop( hDesktop );

// Рассылаем сообщение WM_HOTKEY
PostMessage( HWND_BROADCAST, WM_HOTKEY, 0, MAKELONG( MOD_CONTROL | MOD_ALT, VK_DELETE ) );

SetThreadDesktop( hDeskPrev );
SetProcessWindowStation( hStaPrev ); 
CloseDesktop( hDesktop );
CloseWindowStation( hSta );

Или из внедренной в Winlogon DLL:

PostMessage( HWND_BROADCAST, WM_HOTKEY, 0, MAKELONG( MOD_CONTROL | MOD_ALT, VK_DELETE ) );

© 2003—2017 Игорь Разин