Странность с хуками SSDT

Тема в разделе "WASM.NT.KERNEL", создана пользователем XshStasX, 1 ноя 2011.

  1. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    Код (Text):
    1. typedef struct _KSERVICE_TABLE_DESCRIPTOR {
    2.     PULONG_PTR Base;
    3.     PULONG Count;
    4.     ULONG Limit;
    5.     PUCHAR Number;
    6. } KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR;
    7.  
    8. PKSERVICE_TABLE_DESCRIPTOR  KeServiceDescriptorTable;
    9.  
    10. BOOLEAN InitSSDTHooks()
    11. {  
    12.     UNICODE_STRING uRoutine;
    13.  
    14.     RtlInitUnicodeString(&uRoutine,L"KeServiceDescriptorTable");
    15.     KeServiceDescriptorTable =(PKSERVICE_TABLE_DESCRIPTOR) MmGetSystemRoutineAddress(&uRoutine);
    16.     return (KeServiceDescriptorTable != NULL) ;
    17. };
    18.  
    19.  
    20. BOOLEAN   HookSSDTEntry(LONG Entry,PVOID NewHandler,PVOID *OldHandler)
    21. {
    22.     if ( Entry<KeServiceDescriptorTable->Limit)
    23.     {  
    24.        
    25.         *OldHandler = KeServiceDescriptorTable->Base[Entry];
    26.         KeServiceDescriptorTable->Base[Entry] = NewHandler;
    27.         return TRUE;
    28.     };
    29.     return FALSE;
    30. };
    31.  
    32. BOOLEAN GetIndexSystemService(PVOID RoutineAddress,ULONG*Index)
    33. {
    34.     CHAR *pByte = (CHAR*) RoutineAddress;
    35.     *Index = 0;
    36.     if ( *pByte != (CHAR)0xB8 /*mov eax, N*/ )
    37.         return FALSE;
    38.  
    39.     *Index = *(PULONG_PTR)(pByte + 1);
    40.     return TRUE;
    41. };
    42.  
    43.  
    44. /// Установка хука
    45.     p = GetProcAddress(pNtdll,"ZwQueueApcThread",FALSE); // возвращает указатель на функцию
    46.     if ( GetIndexSystemService(p,&Index) ) 
    47.     if ( HookSSDTEntry(Index,(PVOID)NewNtQueueApcThread,(PVOID)&OldNtQueueApcThread) == FALSE )
    48.         DbgPrint("HookSSDT(ZwQueueApcThread) fail\n");
    49.     else
    50.         DbgPrint("ZwQueueApcThread  __asm{ mov eax,%x } \n",Index);
    51.  
    52.  
    53.  
    54. //// Обработка хука
    55. NTSTATUS NTAPI NewNtQueueApcThread  (   HANDLE  ThreadHandle,
    56.                                         PKNORMAL_ROUTINE    ApcRoutine,
    57.                                         PVOID   NormalContext,
    58.                                         PVOID   SystemArgument1,
    59.                                         PVOID   SystemArgument2  
    60.     )
    61. {
    62.         if (KeGetCurrentIrql() == PASSIVE_LEVEL)
    63.         if ( (PsIsSystemThread(PsGetCurrentThread()) == FALSE)  )
    64.         {
    65.             PTHREAD_BASIC_INFORMATION BasicInfo;
    66.             ULONG retSize = sizeof(THREAD_BASIC_INFORMATION);
    67.             do{
    68.                
    69.                 if ( ! (BasicInfo = (PTHREAD_BASIC_INFORMATION)QueryInformationThread(ThreadHandle,ThreadBasicInformation,&retSize)) )
    70.                     break;     
    71.                 if ( BasicInfo->ClientId.UniqueProcess != PsGetCurrentProcessId())
    72.                     DbgPrint("WARNING:  Inject   process [ %x -> %x] \n",PsGetCurrentProcessId(),BasicInfo->ClientId.UniqueProcess);
    73.             }while(0);
    74.         };
    75.     return OldNtQueueApcThread(ThreadHandle,ApcRoutine,NormalContext,SystemArgument1,SystemArgument2);
    76. };
    Установка хука проходит успешно и RKu его отображает, через некоторое время этот хук снимается... как такое может быть?
    ОС хп, сп3. там розреша запись в ssdt.
    Чистая виртуалка на вмваре.
    Прикрепил тестовый драйвер он ставит нотификации на создание процессов, где просто выводит дебажные строки.
    в хуках аналогично только вывод дебажной строки.
     
  2. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Стоит ли какое-то антивирусное ПО в системе? Есть ли возможность отладить систему? Если есть, я бы поставил точку останова на запись в SSDT на адрес ф-ии и ждал, пока он сработает, чтобы выявить, кто это постарался.

    Еще одна непонятная вещь: SSDT доступна только для чтения. HookSSDTEntry свободно в нее пишет. Полагаю, что CR0.WP сброшен, но в коде этого не видно. В общем, этот момент не ясен.
     
  3. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    Разобрался тестируемый код востанавливал SSDT перед вызовом ZwQueueApcThread.
     
  4. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    Mika0x65
    Как поставить точку останова на запись?
    bm ?
     
  5. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    XshStasX
    ba[ID] Access Size [Options] [Address [Passes]] ["CommandString"]
     
  6. billi12

    billi12 New Member

    Публикаций:
    0
    Регистрация:
    31 июл 2011
    Сообщения:
    44
    У меня папра вопросов.
    1. Так в SSDT Zw или Nt????????????????? Если Zw, то тогда где Nt???????????

    2. XshStasX, у тебя не убивается система после снятия хуков и выгрузки драйвера?

    3. if (KeGetCurrentIrql() == PASSIVE_LEVEL)
    if ( (PsIsSystemThread(PsGetCurrentThread()) == FALSE)

    Объясните зачем это плз.
     
  7. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    В SDT адреса NT-сервисов, т.е. функций с префиксом Nt, а ZwXxx() это экспорты ядра, переходники к сервисам.

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

    Это лучше спросить у автора.
    Проверка на irql=0 не имеет смысла здесь.
    Ну а проверка на поток ядра это, вероятно, какая-то особенность логики.
     
  8. billi12

    billi12 New Member

    Публикаций:
    0
    Регистрация:
    31 июл 2011
    Сообщения:
    44
    Спасибо за скорый ответ. Я делаю подобный перехват, но перехватывая, собираю информацию типа имени файла, хэндл после createfile и пр. За основу брал драйвер stracer, так вот там с InterlockedIncrement/Decrement в начале и в конце изменяется переменная calls_in_progress. На выгрузке стоит проверка while(calls_in_progress){}. После снятия хука с течением времени вызовы завершаются и эта переменная уменьшается, но не координально. Как будто вызовы остаются выполняться. Почему так?

    А если выгружаю - всё падает после пары секунд) Можно как-нибудь организовать схему перехвата с сбором инфы до и после и при этом чтобы легко все выгружать?
     
  9. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Возможно, тупо ошибка где-то в коде драйвера.
    А некоторые вызовы, если они синхронные, действительно могут долго не завершаться.

    Самый надёжный метод это скопировать код перехватчиков куда-нибудь в память, а драйвер спокойно выгрузить. При следующем запуске драйвера проверить, что все вызовы завершились, и освободить память, выделенную в прошлый раз. Это необходимо, чтобы не было утечек.
     
  10. billi12

    billi12 New Member

    Публикаций:
    0
    Регистрация:
    31 июл 2011
    Сообщения:
    44
    Спасибо большое.
     
  11. billi12

    billi12 New Member

    Публикаций:
    0
    Регистрация:
    31 июл 2011
    Сообщения:
    44
    Блин, случилась неведомая фигня! Я попробовал запустить при работающем драйвере студию и получил бсод! Это у них такая защита? Или мой буфер на 30000 записей за секунду переполнился!??

    Если 1ое - как обойти?