последствия TerminateProcess

Тема в разделе "WASM.WIN32", создана пользователем cresta, 18 апр 2006.

  1. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Процесс на старте создаёт мютекс, чтобы блокировать вторичный запуск. Этот же процесс запускает драйвер. При завершении процесса (без крайних мер) приложение посылает драйверу сигнал о выгрузке (DriverUnload). Мютекс закрывается виндой.



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

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

    А как быть с мютексом?

    Может ли работающий драйвер цивилизованными способами отследить исчезновение парентского процесса и прикрыть мютекс? PsSetCreateProcessNotifyRoutine не помогает.
     
  2. gloomyraven

    gloomyraven Руслан

    Публикаций:
    0
    Регистрация:
    16 апр 2006
    Сообщения:
    288
    Адрес:
    Москва
    По-моему, такие объекты как мьютексы, семафоры и т.д. уничтожаются самой системой при уничтожении его хэндла. В MSDN про это хорошо написано.
     
  3. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Вроде ж ясно написал: мютекс не закрывается.
     
  4. Jupiter

    Jupiter Jupiter

    Публикаций:
    0
    Регистрация:
    12 авг 2004
    Сообщения:
    532
    Адрес:
    Russia
    можно передавать хэндл мьютекса в драйвер, где звать (аналог в драйвере?) WaitForSingleObject и проверять возвращённое значение на WAIT_ABANDONED



    Return code/value

    WAIT_ABANDONED

    0x00000080L



    Description

    The specified object is a mutex object that was not released by the thread that owned the mutex object before the owning thread terminated. Ownership of the mutex object is granted to the calling thread, and the mutex is set to nonsignaled.
     
  5. Kola

    Kola New Member

    Публикаций:
    0
    Регистрация:
    23 июн 2004
    Сообщения:
    69
    Можно так:

    1) После старта драйвера приложение посылает ему запрос через DeviceIOControl

    2) Драйвет устанавливает для этого IRP Cancel routine, используя IoSetCancelRoutine, делает IoMakrIrpPending и возвращает STATUS_PENDING

    3) Приложение как-то закрывается, система отменяет все IRP процесса, и таким образом вызывается заданная ранее Cancel routine



    ЗЫ вообще-то странно что мутекс не убивается
     
  6. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    cresta

    А этот мьютекс больше никто не держит открытым? Драйвер например?
     
  7. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Драйвер о мютексе не знает. С мютексом как-нибудь потом.

    Тут более важная проблема: как из драйвера выгрузить его самого? В DriverEntry запускаю поток, в котором контролирую наличие родительского процесса:
    Код (Text):
    1. PKSTART_ROUTINE UnloadProc(PVOID Context){
    2.     NTSTATUS                    Status;
    3.     LARGE_INTEGER               Wait;
    4.     UNICODE_STRING              uDeviceName;
    5.  
    6.     Wait.LowPart = -10000000;
    7.     Wait.HighPart = -1;
    8.     while (TRUE){
    9.         KeDelayExecutionThread (KernelMode, FALSE, &Wait);
    10.         if (!g_UnloadActive) break;               //приложение закрылось нормально
    11.         if (g_ParentID && !ParentPresent()){     //приложение закрыто принудительно
    12.             DbgPrint("Thread About Term");
    13.             g_UnloadActive = FALSE;
    14.             DriverUnload(g_DriverObject);
    15.             break;
    16.         }
    17.     }
    18.     PsTerminateSystemThread (STATUS_SUCCESS);
    19.     return 0;
    20. }


    из вызова DriverUnload поток не возвращается (возможно эту процедуру нельзя вызывать самому)

    Если вызвать ZwUnloadDriver то ошибка "файл не найден", хотя передаю как нарисовано в msdn имя ключа в реестре

    RtlInitUnicodeString(&uDeviceName, L"\\Registry\\Machine\\CurrentControlSet\\Services\\MyDriver");

    Status = ZwUnloadDriver(&uDeviceName);



    [edited]

    Ключ реестра неправильно указал, если указать правильно - BSOD :dntknw:
     
  8. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Ничего лучше перехвата ZwTerminateProcess и возврата ACCESS_DENIED не придумал :dntknw:

    И драйвер не надо выгружать, и мютекс закрывать.
     
  9. CARDINAL

    CARDINAL Member

    Публикаций:
    0
    Регистрация:
    23 янв 2004
    Сообщения:
    551
    Адрес:
    Moscow
    вопрос если честно децкий
     
  10. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    CARDINAL

    Решение было изначально в кармане (с перехватом). Можно было и не задавать вопрос.

    Было интересно, как из драйвера выгрузить драйвер. Я не нашёл способа.

    Если знаешь - колись.
     
  11. Ms Rem

    Ms Rem New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2005
    Сообщения:
    1.057
    Адрес:
    С планеты "Земля"


    1) Выделить память через ExAllocatePool

    2) Скопировать туда код выгружающий драйвер

    3) Запустить этот код в новом потоке (PsCreateSystemThread)

    4) В этом коде делать ZwUnloadDriver и завершение потока.
     
  12. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Есть какие-либо особенности запуска потока во внешней памяти?

    Пробовал традиционным способом:
    Код (Text):
    1.             __asm{
    2.                 lea        eax,TrustedPresent
    3.                 sub        eax,ExternThread
    4.                 mov        [cb],eax
    5.             }
    6.             DbgPrint("Code size = %d", cb);
    7.             //пауза, чтобы прочесть DbgPrint :)
    8.             KeDelayExecutionThread (KernelMode, FALSE, &Wait);
    9.            
    10.             pExt = ExAllocatePool(PagedPool,cb);
    11.             if (pExt){
    12.                 DbgPrint ("Copy memory");
    13.                 KeDelayExecutionThread (KernelMode, FALSE, &Wait);
    14.                 memcpy (pExt, &ExternThread, cb);
    15.                 DbgPrint ("Try to start extern thread");
    16.                 KeDelayExecutionThread (KernelMode, FALSE, &Wait);
    17.                 Status = PsCreateSystemThread (&hThread,
    18.                                                 THREAD_ALL_ACCESS,
    19.                                                 0, 0, 0,
    20.                                                 (PKSTART_ROUTINE)pExt, 0);
    21.                 DbgPrint ("Status = %08X", Status);
    22.                 KeDelayExecutionThread (KernelMode, FALSE, &Wait);
    23.                 if (Status == STATUS_SUCCESS) ZwClose (hThread);
    24.             }
    25.  


    Последняя выведенная в DbgView строка - "Try to start extern thread". Дальше перезагрузка без комментариев.



    Копируемая процедура такая (до её выполнения дело не доходит):
    Код (Text):
    1. PKSTART_ROUTINE ExternThread(PVOID Context){
    2.     UNICODE_STRING              uDeviceName;
    3.     NTSTATUS                    Status;
    4.     LARGE_INTEGER               Wait;
    5.  
    6.     Wait.LowPart = -30000000;
    7.     Wait.HighPart = -1;
    8.    
    9.     DbgPrint("Driver About Unload");
    10.     KeDelayExecutionThread (KernelMode, FALSE, &Wait);
    11.     RtlInitUnicodeString(&uDeviceName,
    12.                         L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\MyDriver")  ;
    13.     DbgPrint ("%S", uDeviceName.Buffer);
    14.     KeDelayExecutionThread (KernelMode, FALSE, &Wait);
    15.     Status = ZwUnloadDriver(&uDeviceName);
    16.     KeDelayExecutionThread (KernelMode, FALSE, &Wait);
    17.     PsTerminateSystemThread (STATUS_SUCCESS);
    18.     return 0;
    19. }
     
  13. Ms Rem

    Ms Rem New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2005
    Сообщения:
    1.057
    Адрес:
    С планеты "Земля"


    ЛОЛ! ну ты блин даешь... Разве можно так писать? Код должен быть базонезависимым, иначе у тебя все call указывают после переноса в космос и естественно все падает.

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



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

    З.З.Ы. ты айс юзать пробовал? а то такие вопросы бы сами отпали.
     
  14. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Хм, я почему-то думал, что тут в отличие от юзера, единое адресное пространство, и я могу свободно обращаться к памяти драйвера

    Т.е. делая из внешнего потока например KeDelayExecution, я выполняю call dword ptr[KeDelayExecution], и этот dword ptr указывает на валидную ячейку в секции драйвера с адресом ф-ции.



    Ну раз это не так - переделываем.
     
  15. Ms Rem

    Ms Rem New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2005
    Сообщения:
    1.057
    Адрес:
    С планеты "Земля"
    Во-первых call может быть не call dword ptr[KeDelayExecution], а call jmp_KeDelayExecution, тоесть кол на переходник который идет по относительному адресу.

    Во-вторых, если ты будешь производить выгрузку драйвера, то надо быть готовым что в один прекрасный момент весь его образ просто пропадет из памяти, а значит ничем там пользоваться нельзя. И юзай айс чтобы понять запустился у тебя поток или нет и че там твориться.
     
  16. CARDINAL

    CARDINAL Member

    Публикаций:
    0
    Регистрация:
    23 янв 2004
    Сообщения:
    551
    Адрес:
    Moscow
    cresta

    слушай, реально, а ты чем дрова ладишь ?
     
  17. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Да ничем :dntknw:

    Сайс не приживается на компе, по windbg нет никакого материала (примера).

    Вот и использую метод проб и ошибок.

    Реально только DbgPrint кое-какую помощь оказывает. Ты наверное заметил мои "брейкпоинты" на основе KeDelayExecutionThread

    Это всё :dntknw:
     
  18. CARDINAL

    CARDINAL Member

    Публикаций:
    0
    Регистрация:
    23 янв 2004
    Сообщения:
    551
    Адрес:
    Moscow
    мда, давно бы айс наладил. патчей придумали тьму, выбирай любой.
     
  19. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    У него справка хорошая.