Перехват функций из win32k.sys

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

  1. silver

    silver New Member

    Публикаций:
    0
    Регистрация:
    15 ноя 2006
    Сообщения:
    6
    Здравствуйте, пытаюсь сделать перехват функций из win32k.sys методом правки Service Descriptor Table Shadow. Саму ssdt нашёл, сравнил адрес найденной ssdt с тем адресом, что находит strace – они одинаковые.
    Проблема в том, что после замены адреса нужной функции моя функция не вызывается. В моей функции делается минимум действий: вызов DbgPrint и вызов реальной функции.
    Просмотрел исходник strace – никаких принципиальных отличий от своего кода не заметил, также ищется ssdt, также делается замена.
    В чём может быть проблема?
     
  2. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Зачем Shodow? ИМХО просто SDT править надо(KeServiceDescriptorTable которая).
    А может ещё сорс выложишь, а то по твоему объяснению всё должно работать как часы.
     
  3. silver

    silver New Member

    Публикаций:
    0
    Регистрация:
    15 ноя 2006
    Сообщения:
    6
    Добраться до ф-ий win32k.sys можно только через Shadow таблицу.
    На мой взгляд тоже работать должно как часы, но не работает и не могу понять почему.

    Вот ключевые моменты
    Код (Text):
    1. PSERVICE_DESCRIPTOR_TABLE find_shadow_table () //тут проблем нет, ищет правильно
    2. {
    3.     unsigned char *check = (unsigned char *)KeAddSystemServiceTable;
    4.     int i;
    5.     PSERVICE_DESCRIPTOR_TABLE rc = NULL;
    6.  
    7.     for (i=0; i<100; i++) {
    8.         __try {
    9.             rc = *(PVOID *)check;
    10.             if (!MmIsAddressValid (rc)
    11.                 || (rc == KeServiceDescriptorTable)
    12.                 || (memcmp (rc, KeServiceDescriptorTable, 4) != 0)) {
    13.                 check++;
    14.                 rc = NULL;
    15.             }
    16.         } __except (EXCEPTION_EXECUTE_HANDLER) {
    17.             rc = NULL;
    18.         }
    19.         if (rc)
    20.             break;
    21.     }
    22.     return rc;
    23. }
    24. ...
    25. //замена
    26. KeServiceDescriptorTableShadow = find_shadow_table();
    27. True_EngTextOut = (EngTextOut_t)KeServiceDescriptorTableShadow->win32k.ServiceTable[sdt_number];
    28. (EngTextOut_t)KeServiceDescriptorTableShadow->win32k.ServiceTable[sdt_number] = New_EngTextOut;
    29. ...
    30.  
    31. //ну, и код New_EngTextOut, если это имеет значение
    32. BOOL APIENTRY New_EngTextOut(
    33.         IN SURFOBJ  *pso,
    34.         IN STROBJ  *pstro,
    35.         IN FONTOBJ  *pfo,
    36.         IN CLIPOBJ  *pco,
    37.         IN RECTL  *prclExtra,
    38.         IN RECTL  *prclOpaque,
    39.         IN BRUSHOBJ  *pboFore,
    40.         IN BRUSHOBJ  *pboOpaque,
    41.         IN POINTL  pptlOrg,
    42.         IN MIX  mix
    43.     )
    44. {
    45. DbgPrint("Inside EngTextOut");
    46. return True_EngTextOut(pso,pstro,pfo,pco,prclExtra,prclOpaque,pboFore,pboOpaque,pptlOrg,mix);
    47. }
    Как уже говорил, мой код почти ничем не отличается от кода strace, strace работает, мой - нет.

    зы
    тестировалось на WinXP SP1, на других системах не проверял.
     
  4. silver

    silver New Member

    Публикаций:
    0
    Регистрация:
    15 ноя 2006
    Сообщения:
    6
    И ещё что интересно: если поставить перехват из моего драйвера, а потом запустить strace, то он пакажет адрес в ssdt для этой ф-ии = addr New_EngTextOut. Потом установит свой перехват и успешно отработает.
     
  5. Guest

    Guest Guest

    Публикаций:
    0
    В обычной SDT доступа к win32k вообще нет.
    Вот собственно была такая проблема на cracklab.ru:
    Код (Text):
    1. Ms-Rem
    2.  
    3. Ранг: 56.7 (постоянный)
    4. Статус: Участник
    5.  
    6.     Создано: Сен 15, 2005 08:00:55
    7. Цитата Личное сообщение Цитата Личное сообщение
    8.  
    9. MaxSS
    10. Помню геморроился я сам как-то с этим делом.
    11. Трабл номер раз: при перемещении SDT антивирусом КарлаСпермского меняется содержимое первой SST и смещение Shadow SDT, а следовательно вышеприведенный код не работает. Проблема решается сканированием KiAddSystemServiceTable на инструкцию lea ecx, KeServiceDescriptorTableShadow[eax].
    12. Вот работающий код находящий Shadow SDT на виндах от NT4 до лонгхорна и не боящийся приколов Дяди Карла:
    13.  
    14. void GetKeServiceDescriptorTableShadow()
    15. {
    16.     PUCHAR cPtr, pOpcode;
    17.     ULONG Length;
    18.    
    19.     for (cPtr = (PUCHAR)KeAddSystemServiceTable;
    20.          cPtr < (PUCHAR)KeAddSystemServiceTable + PAGE_SIZE;
    21.          cPtr += Length)
    22.     {
    23.         if (!MmIsAddressValid(cPtr)) break;
    24.  
    25.         Length = SizeOfCode(cPtr, &pOpcode);
    26.  
    27.         if (!Length || (Length == 1 && *pOpcode == 0xC3)) break;
    28.        
    29.         if (*(PUSHORT)pOpcode == 0x888D)
    30.         {
    31.             KeServiceDescriptorTableShadow = *(PVOID *)(pOpcode + 2);
    32.             break;
    33.         }
    34.     }
    35. }
    36.  
    37.  
    38. Функция SizeOfCode - получает размер инструкции по указателю. Я использовал свой дизассемблер длин LDasm.
    39.  
    40. Трабл номер два: содержимое SST win32k как и сам драйвер win32k.sys отображаються на ЮЗЕРМОДНЫЕ АДРЕСА, как и все драйвера имеющие отношение к графической подсистеме. Это не баг, так как на их страницах стоит атрибут супервизора. Соответствующая память отмаплена ТОЛЬКО в GUI процессы.
    41. Тоесть нужно подключаться к GUI процессу и там читать/модифицировать SST win32k. Я рекомендую подключаться к csrss.exe. Код ищущий этот процесс (не по имени):
    42.  
    43. HANDLE GetCsrPid()
    44. {
    45.     HANDLE                        Process, hObject;
    46.     HANDLE                        CsrId = (HANDLE)0;
    47.     OBJECT_ATTRIBUTES             obj;
    48.     CLIENT_ID                     cid;
    49.     UCHAR                         Buff[0x100];
    50.     POBJECT_NAME_INFORMATION      ObjName = (PVOID)&Buff;
    51.     PSYSTEM_HANDLE_INFORMATION_EX Handles;
    52.     ULONG                         r;
    53.  
    54.     Handles = GetInfoTable(SystemHandleInformation);
    55.  
    56.     if (!Handles) return CsrId;
    57.  
    58.     for (r = 0; r < Handles->NumberOfHandles; r++)
    59.     {
    60.         if (Handles->Information[r].ObjectTypeNumber == 21) //Port object
    61.         {
    62.             InitializeObjectAttributes(&obj, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
    63.            
    64.             cid.UniqueProcess = (HANDLE)Handles->Information[r].ProcessId;
    65.             cid.UniqueThread  = 0;
    66.  
    67.             if (NT_SUCCESS(NtOpenProcess(&Process, PROCESS_DUP_HANDLE, &obj, &cid)))
    68.             {
    69.                 if (NT_SUCCESS(ZwDuplicateObject(Process,
    70.                                                  (HANDLE)Handles->Information[r].Handle,
    71.                                                  NtCurrentProcess(),
    72.                                                  &hObject,
    73.                                                  0, 0, DUPLICATE_SAME_ACCESS)))
    74.                 {
    75.                     if (NT_SUCCESS(ZwQueryObject(hObject,
    76.                                                  ObjectNameInformation,
    77.                                                  ObjName,
    78.                                                  0x100, NULL)))
    79.                     {
    80.                         if (ObjName->Name.Buffer &&
    81.                             !wcsncmp(L"\\Windows\\ApiPort", ObjName->Name.Buffer, 20))
    82.                         {
    83.                             CsrId = (HANDLE)Handles->Information[r].ProcessId;
    84.                         }
    85.                     }
    86.  
    87.                     ZwClose(hObject);
    88.                 }
    89.  
    90.                 ZwClose(Process);
    91.             }
    92.         }
    93.     }
    94.  
    95.     ExFreePool(Handles);
    96.  
    97.     return CsrId;
    98. }
    99.  
    100.  
    101.  
    102. Трабл номер три: для выхова этих функций нужно использовать GUI поток. Отличается он от обычного тем, что в его NT_TIB в ServiceTable лежит указатель не на KeServiceDescriptorTable, а на KeServiceDescriptorTableShadow. Для создания GUI потока можно воспользоваться неэкспортируемой функцией PsConvertToGuiThread, но несуществует надежного способа ее поиска, поэтому я рекомендую менять указатель в NT_TIB вручную.
    103.  
    104. Трабл номер четыре: необходимо чтобы на процесс в котором создан поток отображались видео драйвера. Можно создать MDL, захватить память в другом процессе и отобразить себе с помощью MmMapLockedPagesSpecifyCache, но это геморно, поэтому создавай поток в том же csrss.exe.
    105.  
    106. Надеюсь мой ответ тебе чем нибудь поможет.
    107.  
    108. P.S. в следующий раз подобные вопросы задавай на васме, я обычно сижу там, и такой вопрос без внимания не оставлю.
    Может чем поможет.
     
  6. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    silver
    Может после замены еще какие-то действия надо выполнить?
     
  7. silver

    silver New Member

    Публикаций:
    0
    Регистрация:
    15 ноя 2006
    Сообщения:
    6
    im1111

    Код MS-Remа видел, вообщем то от него и отталкивался. Атачится к ГУИ поцессу не обязательно, если ставить перехват из dispatch routine драйвера, которая и так вызывается в контексте вызывающего процесса. Про проделки антивируса тоже знаю, но сейчас надо заставить работать хотябы то что есть.
     
  8. Guest

    Guest Guest

    Публикаций:
    0
    silver

    Скинь сорсы тестового драйвера, я протестю на своей системе - XP SP2, поищу причину траблы.
     
  9. silver

    silver New Member

    Публикаций:
    0
    Регистрация:
    15 ноя 2006
    Сообщения:
    6
    im1111
    Скинуть только в субботу смогу.
    Да и нет там ничего особенного, почти всё основное уже привёл. За кадром осталась только ф-ия поиска номера системного вызова по имени, но она точно работает нормально.
     
  10. FromRing0

    FromRing0 New Member

    Публикаций:
    0
    Регистрация:
    10 окт 2006
    Сообщения:
    73
    Пуск->Программы->Стандартные->бубен
     
  11. censored

    censored New Member

    Публикаций:
    0
    Регистрация:
    5 июл 2005
    Сообщения:
    1.615
    Адрес:
    деревня "Анонимные Прокси"
    FromRing0
    что это за ересь?
     
  12. silver

    silver New Member

    Публикаций:
    0
    Регистрация:
    15 ноя 2006
    Сообщения:
    6
    FromRing0
    Недержание словесное?
     
  13. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    censored
    Всё, теперь тебя из thx2 уберут =)
     
  14. Guest

    Guest Guest

    Публикаций:
    0
    Скидывай.