оcтановить shutdown, запущенный ExitWindows

Тема в разделе "WASM.WIN32", создана пользователем Nouzui, 16 янв 2007.

  1. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    что можно сделать после вызова ExitWindows?
     
  2. ksu_ant

    ksu_ant New Member

    Публикаций:
    0
    Регистрация:
    28 сен 2005
    Сообщения:
    273
    Видимо, ничего.
    Скорее всего, можно функцию перехватить и не допускать ее выполнения, когда этого не хочется...
     
  3. rav

    rav New Member

    Публикаций:
    0
    Регистрация:
    19 июл 2004
    Сообщения:
    159
    Адрес:
    Москва
    Ловить LPC-пакет и гасить.
     
  4. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    какой пакет? %(
     
  5. DelExe

    DelExe New Member

    Публикаций:
    0
    Регистрация:
    22 авг 2005
    Сообщения:
    165
    Nouzui
    "Внутреннее устройство W2000" Руссиновича утверждает следующее:

    1. Csrss получает информацию о вызове ExitWindowsEx.
    2. Тогда Csrss "в интересах инициатора" пересылает скрытому окну WinLogon-a Windows-сообщение.
    3. Теперь уже WinLogon вызывает ExitWindowsEx.
    4. Csrss опять получает сообщение, но видит что завершить работу хочет уже Winlogon.
    5. Csrss начинает перебор процесов а дальше и сервисов, уведомляя их о завершении работы пользователя или системы.
    6. Потом ExitWindowsEx вызываеться ещё, но это уже связано с сервисами.
    Вообще эти пляски с бубном(если правильно я понимаю) нужны лишь для того чтоб Csrss получила сеанс интерактивного пользователя(их может быть много) от Winlogon-а.

    Теперь выводы:
    1. Ставить хуки на ExitWindowsEx.
    2. Перехватывать это загадочное сообщение для Winlogon-a.
    3. Делать вид что в танке на неприличные предложения системы: WM_QUERYENDSESSION, WM_ENDSESSION (или CTRL_LOGOFF_EVENT- для консоли).
    4. etc

    Вообще извращаться можно долго. Например тупой патч с драйвера бинарного кода csrss.
     
  6. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    да вопрос то больше теоретический

    WM_QUERYENDSESSION, помнится, начиная с 2k уже спасала..

    csrss.. брр

    а вот 2k изнутри:
    ntos\w32\ntser\server\exitwin.c
    Код (Text):
    1. NTSTATUS _ExitWindowsEx(
    2.     PCSR_THREAD pcsrt,
    3.     UINT dwFlags,
    4.     DWORD dwReserved)
    5. {
    6.     LUID luidCaller;
    7.     NTSTATUS Status = STATUS_SUCCESS;
    8.  
    9.     UNREFERENCED_PARAMETER(dwReserved);
    10.  
    11.     if ((dwFlags & EWX_REBOOT) || (dwFlags & EWX_POWEROFF)) {
    12.         dwFlags |= EWX_SHUTDOWN;
    13.     }
    14.  
    15.     //
    16.     // Only winlogon gets to set the high flags:
    17.     //
    18.  
    19.     if ( ( dwFlags & ( ~ ( EWX_VALID ) ) ) != 0 )
    20.     {
    21.         if ( HandleToUlong(pcsrt->ClientId.UniqueProcess) != gIdLogon )
    22.         {
    23.             KdPrint(( "Process %x tried to call ExitWindowsEx with flags %x\n",
    24.                         pcsrt->ClientId.UniqueProcess, dwFlags ));
    25.  
    26.             return STATUS_ACCESS_DENIED ;
    27.         }
    28.     }
    29.  
    30.     /*
    31.      * Find out the callers sid. Only want to shutdown processes in the
    32.      * callers sid.
    33.      */
    34.     if (!CsrImpersonateClient(NULL)) {
    35.         return STATUS_BAD_IMPERSONATION_LEVEL;
    36.     }
    37.  
    38.     Status = CsrGetProcessLuid(NULL, &luidCaller);
    39.     if (!NT_SUCCESS(Status)) {
    40.         CsrRevertToSelf();
    41.         return Status;
    42.     }
    43.  
    44.     /*
    45.      * Loop until we can do the shutdown; if we cannot do it,
    46.      *  we'll go to fastexit and bail.
    47.      */
    48.     while (TRUE) {
    49.  
    50.         LARGE_INTEGER li;
    51.  
    52.         Status = NtUserSetInformationThread(pcsrt->ThreadHandle,
    53.                                             UserThreadInitiateShutdown,
    54.                                             &dwFlags, sizeof(dwFlags));
    55.  
    56.         switch (Status) {
    57.         case STATUS_PENDING:
    58.             /*
    59.              * The logoff/shutdown is in progress and nothing
    60.              * more needs to be done.
    61.              */
    62.             goto fastexit;
    63.  
    64.         case STATUS_RETRY:
    65.             /*
    66.              * Another logoff/shutdown is in progress and we need
    67.              * to cancel it so we can do an override.
    68.              *
    69.              * if someone else is trying to cancel shutdown, exit
    70.              */
    71.             EnterCrit();
    72.             li.QuadPart  = 0;
    73.             if (NtWaitForSingleObject(gheventCancel, FALSE, &li) == WAIT_OBJECT_0) {
    74.                 Status = STATUS_PENDING;
    75.                 LeaveCrit();
    76.                 goto fastexit;
    77.             }
    78.             /*
    79.              * If no one will set gheventCancelled, don't wait.
    80.              */
    81.             if (gdwThreadEndSession == 0) {
    82.                 LeaveCrit();
    83.                 continue;
    84.             }
    85.  
    86.             NtClearEvent(gheventCancelled);
    87.             NtSetEvent(gheventCancel, NULL);
    88.             LeaveCrit();
    89.             /*
    90.              * Wait for the other guy to be cancelled
    91.              */
    92.             NtWaitForSingleObject(gheventCancelled, FALSE, NULL);
    93.  
    94.             EnterCrit();
    95.             /*
    96.              * This signals that we are no longer trying to cancel a
    97.              * shutdown
    98.              */
    99.             NtClearEvent(gheventCancel);
    100.             /*
    101.              * If someone managed to start a shutdown again, exit
    102.              *  Can this happen? Let's assert to check it out.
    103.              */
    104.             if (gdwThreadEndSession != 0) {
    105.                 UserAssert(gdwThreadEndSession == 0);
    106.                 Status = STATUS_PENDING;
    107.                 LeaveCrit();
    108.                 goto fastexit;
    109.             }
    110.             LeaveCrit();
    111.             continue;
    112.  
    113.         case STATUS_CANT_WAIT:
    114.  
    115.             /*
    116.              * There is no notify window and the calling thread has
    117.              * windows that prevent this request from succeeding.
    118.              * The client handles this by starting another thread
    119.              * to recall ExitWindowsEx.
    120.              */
    121.             goto fastexit;
    122.  
    123.         default:
    124.             if (!NT_SUCCESS(Status)) {
    125.                 SetLastError(RtlNtStatusToDosError(Status));
    126.                 goto fastexit;
    127.             }
    128.         }
    129.         break;
    130.     }
    131.  
    132.     /*
    133.      * This thread is doing the shutdown
    134.      */
    135.     EnterCrit();
    136.     UserAssert(gdwThreadEndSession == 0);
    137.     gdwThreadEndSession = HandleToUlong(pcsrt->ClientId.UniqueThread);
    138.     LeaveCrit();
    139.  
    140.     /*
    141.      * Call csr to loop through the processes shutting them down.
    142.      */
    143.     Status = CsrShutdownProcesses(&luidCaller, dwFlags);
    144.     /*
    145.      * Tell win32k.sys we're done.
    146.      */
    147.     NtUserSetInformationThread(pcsrt->ThreadHandle, UserThreadEndShutdown, &Status, sizeof(Status));
    148.  
    149.     EnterCrit();
    150.     gdwThreadEndSession = 0;
    151.     NtSetEvent(gheventCancelled, NULL);
    152.     LeaveCrit();
    153.  
    154. fastexit:
    155.     CsrRevertToSelf();
    156.  
    157.     return Status;
    158. }
    поиметь бы этот gheventCancel
    надо будет в pdbшниках поискать...
     
  7. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
     
  8. Freecod

    Freecod New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2006
    Сообщения:
    136
    В ответ на WM_QUERYENDSESSION возвращяй 0 в wParam, выключение прервётся.
    Но это только если не используется флаг EWX_FORCE
     
  9. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    похоже, единственный вариант

    кстати, почему я думал, что он не работает под Xp/2k:
    Код (Text):
    1. LRESULT CALLBACK WndProc(HWND, UINT uMsg, WPARAM, LPARAM)
    2. {
    3.     if(uMsg==WM_QUERYENDSESSION || Msg==WM_ENDSESSION)
    4.         return 0;
    5.  
    6.     return 1;
    7. }
    под 9x это помогало замечательно, а под 2k нет...
    так что надо:
    Код (Text):
    1. LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    2. {
    3.     if(uMsg==WM_QUERYENDSESSION || Msg==WM_ENDSESSION)
    4.         return 0;
    5.  
    6.     return DefWindowProc(hWnd, uMsg, wParam, lParam);
    7. }
    почему - непонятно
     
  10. 0xADD

    0xADD New Member

    Публикаций:
    0
    Регистрация:
    16 янв 2007
    Сообщения:
    5
    Можно AbortSystemShutdownW, если успеешь ))
     
  11. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    пробовал..
     
  12. Freecod

    Freecod New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2006
    Сообщения:
    136
    У меня с этим shutdown проблемы похлеще... Нужно дать прользователю время разобраться с моей прогой перед выключением, но если не возвращяться из WM_QUERYENDSESSION, вылазит окошко с пожеланием прибить неотвечающюю прогу, так что приходится сохранять флаг действия из lParam (выкл, перезагрузка, итд), возвращять 1, после действий самому инициализировать выключение с полученым флагом... Но охрененный баг в том, что какая-то комбинация флагов даёт в lParam одинаковое число! Вот и думай что там было...
     
  13. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    ладно.. понятно, что ничего не понятно
    а какие есть способы отследить shutdown и узнать его тип?
    ну вот для оконных - мессаги
    для консольных - хэндлеры.. кстати, а кто их вызывает, и каким потоком
    и раз уж кто-то это делает, нельзя ли заставить его же проделоть это в gui-приложниях?
    и как, например, отследить это событие в сервисах: SERVICE_CONTROL_SHUTDOWN они получат, но как узнать тип shutdown'а или отследить, что юзел логоффится
    и какие еще есть способы? какие-нибудь события, объекты ядра итд
     
  14. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    csrss
    наврядли.