Перехватить момент конвертации потока в GUI поток

Тема в разделе "WASM.NT.KERNEL", создана пользователем Vicshann, 17 дек 2020.

  1. Vicshann

    Vicshann Member

    Публикаций:
    0
    Регистрация:
    22 сен 2020
    Сообщения:
    36
    Возможно ли такое?
    Нужно для борьбы с внедрением DLL через оконные хуки методом получения THREADINFO и выставления TIF_DISABLEHOOKS в TIF_flags (PsGetCurrentThread -> PsGetThreadWin32Thread).

    Проблема в том что если не удалось загрузить DLL с хуком или она вернула FALSE из DlllMain то система будет пытаться ее загрузить снова и снова.
     
  2. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    Это ведь юзермод, зачем ядро ?

    Обратный ядерный вызов пропатчить(KiUCB), тогда будет вся последовательность инит, clientsetup etc. И проблем в ядре не будет.
     
    RETN нравится это.
  3. Vicshann

    Vicshann Member

    Публикаций:
    0
    Регистрация:
    22 сен 2020
    Сообщения:
    36
    THREADINFO это структура ядра, TIF_flags из юзермода не доступно. Патчить ntdll::KiUserCallbackDispatcher на крайний случай, лучше уж сразу ClientLoadLibrary подменить в User32 при ее загрузке, так как уже установлен PsSetLoadImageNotifyRoutine
     
  4. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    Vicshann,

    Почему не доступно, может флажки можно через апи изменить, это не имеет значения. В ядре это всё сложно сделать, там сессии с клонами ядерного гуя - они не в общей ядерной памяти; от патча защита в самом ядре(KPP(PG)), если использовать какие то нотифи то совместимости в версиях не будет. Вам что бы работало лишь в 10-ке, а остальное не нужно, либо колхозить интернал разбирать, сигнатуры составлять для версий ?

    > Патчить ntdll::KiUserCallbackDispatcher на крайний случай

    Выше я это предложил, не обязательно патчить, можно ссылку на таблицу векторов поменять(apfn), конечно придётся отключить защиту(cfg).

    Но если это защита ядерная, то любое решение юзермод не годится, так как сразу будет обход в том же моде, а при нём есчо и атака на кривой ядерный код.

    Как это решить правильно красиво хз.
    --- Сообщение объединено, 17 дек 2020 ---
    А откуда инфа про эти интернал флаги, w2k ?

    Код (Text):
    1. * History:
    2. * 02-07-91     DavidPe     Created.
    3. * 1994 Nov 02  IanJa       Hooking desktop and console windows.
    4. \***************************************************************************/
    5.  
    6. LRESULT xxxCallHook2(
    7.     PHOOK phkCall,
    8.     int nCode,
    9.     WPARAM wParam,
    10.     LPARAM lParam,
    11.     LPBOOL lpbAnsiHook)
    12. {
    13.     UINT        iHook;
    14.     PHOOK       phkSave;
    15.     LONG_PTR     nRet;
    16.     PTHREADINFO ptiCurrent;
    17.     BOOL        fLoadSuccess;
    18.     TL          tlphkCall;
    19.     TL          tlphkSave;
    20.     BYTE        bHookFlags;
    21.     BOOL        fMustIntersend;
    22.  
    23.     CheckCritIn();
    24.  
    25.     if (phkCall == NULL) {
    26.         return 0;
    27.     }
    28.  
    29.     iHook = phkCall->iHook;
    30.  
    31.     ptiCurrent = PtiCurrent();
    32.     /*
    33.      * Only low level hooks are allowed in the RIT context
    34.      * (This check used to be done in PhkFirstValid).
    35.      */
    36.     if (ptiCurrent == gptiRit) {
    37.         switch (iHook) {
    38.         case WH_MOUSE_LL:
    39.         case WH_KEYBOARD_LL:
    40.  
    41. #ifdef REDIRECTION
    42.         case WH_HITTEST:
    43. #endif // REDIRECTION
    44.  
    45.             break;
    46.  
    47.         default:
    48.             return 0;
    49.         }
    50.     }
    51.  
    52.     /*
    53.      * If this queue is in cleanup, exit: it has no business calling back
    54.      * a hook proc. Also check if hooks are disabled for the thread.
    55.      */
    56.     if (    ptiCurrent->TIF_flags & (TIF_INCLEANUP | TIF_DISABLEHOOKS) ||
    57.             ((ptiCurrent->rpdesk == NULL) && (phkCall->iHook != WH_MOUSE_LL))) {
    58.         return ampiHookError[iHook + 1];
    Ниже есть это:

    Код (Text):
    1.            nRet = xxxHkCallHook(phkCall, nCode, wParam, lParam);
    2.  
    3.             Lock(&ptiCurrent->sphkCurrent, phkSave);
    4.             if (ptiCurrent->pClientInfo)
    5.                 ptiCurrent->pClientInfo->phkCurrent = phkSave;
    6.  
    7.             ThreadUnlock(&tlphkSave);
    8.  
    9.             /*
    10.              * This hook proc faulted, so unhook it and try the next one.
    11.              */
    12.             if (phkCall->flags & HF_HOOKFAULTED) {
    13.                 PHOOK   phkFault;
    14.  
    15.                 phkCall = PhkNextValid(phkCall);
    16.                 phkFault = ThreadUnlock(&tlphkCall);
    17.                 if (phkFault != NULL) {
    18.                     FreeHook(phkFault);
    19.                 }
    20.  
    21.                 continue;
    22.             }
    - обратный вызов в юзер. Видно что ловушка снимается, если юзер сфейлит.

    Больше паблик ссылок в 2к нет, разве что на запись при завершении оконного обьекта.
     
    RETN нравится это.
  5. Vicshann

    Vicshann Member

    Публикаций:
    0
    Регистрация:
    22 сен 2020
    Сообщения:
    36
    Я смотрел в WinXP, там действительно нет способа выставить этот флаг через API. Фактически это все для семерки нужно, если в десятке можно выставить процессу флаг защищенного (PS_PROTECTED_TYPE в EPROCESS) и это будет без последствий для его работы.
    Но как всегда, хочется найти красивое и универсальное решение:)
     
  6. RETN

    RETN Member

    Публикаций:
    4
    Регистрация:
    4 апр 2020
    Сообщения:
    74
    Не не, там идет все в сисколы, только эмуляция спасёт, Клерыч поправь, но я тоже все пробовал без патча ядра - нифига не выходит, шадов блин, а потом......
    --- Сообщение объединено, 18 дек 2020 ---
    >Нужно для борьбы с внедрением DLL через оконные хуки методом получения THREADINFO
    Почитай мою статью, это не обязательно в ядре хучить , а в APC твоей dll всего лишь юзермод, смотришь треды свои и чужие, отсеиваешь и убиваешь. Руткисов давно нет сайта, я там сорцы выкладывал с полиморфом встроенным, ну хз, щас не найду [Без лавэ :) ;) ]
     
    Последнее редактирование: 18 дек 2020
  7. Vicshann

    Vicshann Member

    Публикаций:
    0
    Регистрация:
    22 сен 2020
    Сообщения:
    36
    Есть только драйвер, который фильтр файловой системы и установил LoadImageNotifyRoutine.
    Вот из него и нужно боротся с внедрением DLL в защищаемый процесс. Он просто блокирует доступ к файлу, LoadLibraryExW в User32::ClientLoadLibrary возвращает NULL и из-за этого win32k постоянно пытается загрузить эту DLL снова.
     
  8. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    Vicshann,

    Начнём с начала что бы не лезть в интернал. Есть апи, которая устанавливает ловушку загрузкой модуля. Если модуля нет, то апи вернёт ошибку, не будет пытаться загрузить вновь и не впадёт в рекурсию; где то там в недрах гуя ты допустил ошибку приводящую к рекурсивной загрузке.
     
  9. Vicshann

    Vicshann Member

    Публикаций:
    0
    Регистрация:
    22 сен 2020
    Сообщения:
    36
    Если DLL, которая регистрируется через SetWindowsHookEx вернет FALSE из DLLMain, или просто LoadLibrary не сможет ее загрузить, то win32k не отметит ее как уже загруженную и будет пытаться загрузить снова, когда поток к нему обратится.
    Драйвер защиты от инжектов как раз и не дает открыть файл этот dll и LoadLibrary возвращает NULL и этот NULL возвращается ответом в win32k через NtCallbackReturn.

    Я не DLL с инжектами делаю, у меня для такого особый инжектор:)
    Моя задача сделать так, что бы драйвер защиты спокойно работал и не вызывал нагрузку на систему. А постоянные попытки загрузки DLL с хуками систему грузят. Потому что многие приложения суют свои DLL в чужие процессы таким способом. И когда драйвер их все блокирует, win32k постоянно пытается их загрузить при разных GUI событиях.
     
    Последнее редактирование: 18 дек 2020
  10. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    Vicshann,

    Тоесть если нет файла система впадёт в цикл его ожидания, это врядле. Давно ничего не отлаживал тк не нужно было, но это наверно нужно посмотреть. Как такое может быть, это повесит систему. Обратные теневые вызовы просты, перед передачей управления в юзер освобождаются ресурсы. Нельзя провести на это атаку, были попытки и фиксы.

    Как же тогда апи вернёт управление, для загрузки ловушки не создаётся второй поток. Что то тут не то, либо ты ошибся либо какой то баг что мало вероятно гуй на ошибки вылезан, это нужно проверять.
     
  11. Vicshann

    Vicshann Member

    Публикаций:
    0
    Регистрация:
    22 сен 2020
    Сообщения:
    36
    Нет, я сначала в отладчике проверил, менял просто одну букву пути к DLL в User32::ClientLoadLibrary и тогда ClientLoadLibrary вызывалась снова и снова для этой DLL. Потом сделал DLL, возвращающую FALSE из DLLMain и получил тот же эффект.
    Почему так происходит станет понятно если декомпилировать win32k::xxxLoadUserApiHook::xxxLoadHmodIndex
     
  12. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    Vicshann,

    Причём тут вообще обратные вызовы, зачем ты в дебри полез. Снимай сервисный лог с апи загрузки ловушки, там будет файловая проверка и возврат управления. Если у тебя ядерный фильтр, то он референс на файловом обькте легально увидит, останется лишь посмотреть откуда вызов. Вот нравится вам колхозить ;)
    --- Сообщение объединено, 19 дек 2020 ---
    Vicshann,

    > Нет, я сначала в отладчике проверил, менял просто одну букву пути к DLL

    Полностью неверный ошибочный подход к задаче. Поэтому ты и полез в интернал, в дебри гуя. Не составил тех задание(задачу не сформулировал), а выдал лишь своё ошибочное решение, которое нужно разбирать и в конце решения не может быть.

    Я могу посмотреть любой лог, для этого есть инструмент, но думаю не годится - потеряем будущего спеца, в тень гуя мало кто залазил..
     
  13. Vicshann

    Vicshann Member

    Публикаций:
    0
    Регистрация:
    22 сен 2020
    Сообщения:
    36
    Как мне лог поможет пометить DLL в битовой маске как загруженную? Потому что win32k сам ее не пометит, получив NULL от ClientLoadLibrary.
    *(_DWORD *)(*(_QWORD *)(vptiCurrent + 0x158) + 0x154i64) |= 1 << vHookIdx;
     
  14. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    Vicshann,

    Если вызвать SetHook() с не существующим файлом, поток повиснет ?

    Врядле, вначале файл будет наверно открыт, до каких то обратных вызовов как ты не поймёшь. Это ты завис на ClientLoadLibrary :lol:
     
    RETN нравится это.
  15. Vicshann

    Vicshann Member

    Публикаций:
    0
    Регистрация:
    22 сен 2020
    Сообщения:
    36
    Не существующую DLL вряд ли получится передать в SetWindowsHookEx, так как там уже ее HMODULE надо передать. Проверять лень потому что это к делу ни как не относится:)
     
  16. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    Vicshann,

    Ну так если лень, тогда ковыряй свой колбек зачем спросил.
     
  17. RETN

    RETN Member

    Публикаций:
    4
    Регистрация:
    4 апр 2020
    Сообщения:
    74
    SetWindowsHookEx - это из шадова - да, отловить можно, но попыток с 2010г я помню множество. На то он и шадов, там прямые знаешь ли сисколы и прочая лабудень. Возможно не в тему. но дрова я писал, для перехвата шадова в играх. А так все кастомно на уровне админа в юзерморде без проблем.
     
  18. Vicshann

    Vicshann Member

    Публикаций:
    0
    Регистрация:
    22 сен 2020
    Сообщения:
    36
    Сделал нормальный тест хуков для этого драйвера. За одним и для тех, кто не верит что такое на самом деле происходит:)
    Проблема в том, что драйвер блокирует загрузку этой DLL только в защищаемый процесс. Если бы он блокировал ее и в том, который ставит хук, то SetWindowsHookEx сразу бы вернула ошибку.
    https://dropmefiles.com/VQi1w
     
  19. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    Vicshann,

    Файлы удалены, но это не важно. Следует понимать суть того что ты тестом называешь. Если в системном механизме участвует не системный драйвер то его не тестят а проводят на него атаку. Вначале выясняется возможно ли это реверс. Если там крипта(те он криптован), то есть метод который всю инфу наглядно нужную дает - монитор выборки. Наверно можно и локально через вд сделать, не могу точно сказать. Обычно применяется вирта которая даёт нужный лог.