· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.WIN32 —› Перехвать функций (глобальный)

<< . 1 . 2 . 3 .

Посл.отвђт Сообщенiе


Дата: Дек 2, 2003 19:05:55

Драйвер при вызовах функций ядра определяет PID процесса, который вызывает их (это ведь можно наверное сделать?)

Вот это и меня интересует.


Дата: Дек 2, 2003 19:56:18

Ну таки ядро имеет доступ к контексту процесса, чтоб определить его привелегии на выполнение операций. Следовательно и PID там есть. Иначе было бы нелогично весьма -)


Дата: Дек 2, 2003 20:17:19

rst

Разумеется. В линухе это элементарно. В винде планировщик тоже должен знать. Подождем Four-F. :)


Дата: Дек 3, 2003 11:04:03 · Поправил: Four-F

[ rst: А такая, слегка бредовая идея... ]

Гы. Этот способ уже приходил мне как-то в голову. Идея, кстати, только кажется бредовой с первого взгляда, но именно применительно к win32k и если её немного развить получается очень даже красиво.


[ rst: Делаем миррор ServiceTable (для себя).. ]

Это не так просто, т.к. функция KiSystemService, которая занимается диспетчеризацией системных сервисов, берет адрес таблицы из KTHREAD.ServiceTable. Это указатель либо на KeServiceDescriptorTable для не-GUI потоков, либо KeServiceDescriptorTableShadow для GUI потоков. Так вот, сделав копию ServiceTable нужно поместить указатель на неё в KTHREAD.ServiceTable. А это поле тоже, к сожалению, перезжает с места на место, в зависимости от версии системы. Есть KeAddSystemServiceTable, которая добавляет новую таблицу. Набрав в гугле KeAddSystemServiceTable можно даже пару-тройку статей об этом найти. Только не понятно как потом эту таблицу удалить. Но в данном случае можно и без копии обойтись, а работать прямо с KeServiceDescriptorTableShadow.

Схема примерно такая:

Узнаем индексы NtUserSetWindowsHookEx в NT4, 2000, XP, 2003 сервис пак не принципиально. Берем разницу maxIndex-minIndex. Прибавляем её к maxIndex и вычитаем из minIndex. Получаем некий диапазон индексов (с запасом) в пределах которого имеет смысл искать. Допустим это будет ~100-150 индексов. Вряд ли больше. Всего в таблицке для win32k ~600 функций.

Запускаем драйвер. Создаем в юзере поток и усыпляем его на событии. ID потока передаем драйверу. Этот поток будет не-GUI, т.е. он пока не трогает win32k. Сканим W32pArgumentTable (она содержит кол-во параметров сервисов) в пределах нашего диапазона индексов, и ищем все сервисы с 6 параметрами - именно столько принимает NtUserSetWindowsHookEx. Т.к. таких функций мало, число кандидатов уменьшается в ~10-20 раз. Т.о. имеем всего ~5-10 таргетов, которые и хучим и начинаем следить в хуковой функции за ID потоков, которые вызывают похученные сервисы - это просто - PsGetCurrentThreadId. Устанавливаем событие, на котором спит юзерный поток (на osr.com есть статья как разделять событие между ядром и юзером).

Проснувшийся юзерный поток вызывает SetWindowsHookEx с заведомо ошибочным набором параметров (зачем нам лишний хук), но так чтобы вызов до ядра дошёл. Это будет первый его GUI-вызов - система конвертнет его в GUI-поток в PsConvertToGuiThread и его KTHREAD.ServiceTable = KeServiceDescriptorTableShadow. Хуковая функция в драйвере увидит этот вызов и ID потока будет ровен искомому. Можно еще для пущей осторожности переданные параметры проверить - драйвер должен заранее знать с какими параметрами юзер вызвал SetWindowsHookEx. Всё. Вертаем все назад. Искомый индекс и соответственно адрес у нас в кармане.

Вот примерно такая схема. Практически руки не доходят проверить, но я на 99,99% уверен, что должно работать.


[ rst: в WinXP там не in2e а jmp на sysenter то-ли в ntdll толи в kernel32. ]

Под XP и 2003 sysenter вызывает KiSystemService, точно также как в NT4 и 2000 это делает int2e. В любом случае индекс вызываемого сервиса через регистр передается. Так что для нас это ничего не меняет.


Дата: Дек 3, 2003 14:49:22

Так вот, сделав копию ServiceTable нужно поместить указатель на неё в KTHREAD.ServiceTable. А это поле тоже, к сожалению, перезжает с места на место, в зависимости от версии системы. А нельзя ли "по-живому" ServiceTable резать?. Т.е. как я понял - она представляет из себя приблизительно тоже самое что и таблица векторов прерываний в старом добром ДОСе. Следовательно там храняться указатели на функции. Так вот драйвер делает у себя стабины указателей. Что-то типа:
API_1: jmp orig_API_1
И адреса этих стабов прописывает в ServiceTable. А оригинальные адреса прописывает в стабы. И тогда не нужно искать указатель на ServiceTable...


Дата: Дек 3, 2003 15:39:17

[ rst: А нельзя ли "по-живому" ServiceTable резать?. ]

Я именно это и предлагаю - патчить существующую KeServiceDescriptorTableShadow.


[ rst: И адреса этих стабов прописывает в ServiceTable. ... И тогда не нужно искать указатель на ServiceTable... ]

Как же пропишешь адреса стабов в ServiceTable не найдя указатель на неё? :-) Найти указатель на KeServiceDescriptorTableShadow не проблема, а указатель на KeServiceDescriptorTable вообще открыто экспортируется.

<< . 1 . 2 . 3 .


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.056