У меня тут получается так: вызов CreateService через каналы RPC улетает в services.exe, который и создаёт запись в реестре. Я попытался в обработчике ZwCreateProcess(Ex) получить токен у процесса, вызовом ZwFilterToken с флагом DELETE_MAX_PRIVILEGES убрать из него привилегию на запуск драйвера, после чего установить обратно вызовом ZwSetInformationProcess с классом ProcessAccessToken. В результате драйвер как устанавливался, так и устанавливается. Что я делаю неправильно? Цель- запретить конкретному приложению устанавливать драйвера в систему.
И еще не забудь перехватывать ZwLoadDriver и ZwCreateKey, а иначе приложение может само создать запись в реестре и загрузить драйвер (я обычно этим методом пользуюсь).
Привет. А где именно отлавливать LPC, если в services.exe всё улетает через RPC (то есть протокол уровня сети)? Нет ли где хороших примеров, чтобы не изобретать велосипед? А всякие там ZwCreateKey я уже перехватил, проблема именно в передаче данных в services.exe. Кстати, нашёл одну интересную вешь. Оказывается, через COM/DCOM можно запустить IE с передачей ему любой строки параметров.
Тогда на ум приходит только перехват соответствующих обработчиков в services.exe с поиском их по сигнатуре, но недостаток этого метода в том, что он сильно зависим от версии винды и даже от сервиспака. Есть еще один вариант - перехватывать SC Manager функции в юзермоде и реализовать управление установкой сервисов и драйверов самому, а процесс services.exe прибить, чтобы приложение не смогло к нему обратиться напрямую. Недостаток этого метода в сложности его корректной реализации, но мне кажется, что следует использовать именно его. Примеров применения этих методов к сожалению нигде не встречал.
2 Ms Rem Ты знаешь, ты был прав. В случае с CreateService RPC работает как LPC. В Win2k я всё отфильтровал, там всё просто. А вот в XP пересылка работает через ZwRequestWaitReplyPort, хендл у этого порта неименованный, а в данных, которые пересылаются, такая каша, что ничего не понял. Кто-нибудь знает, как бы отфильтровать CreateService в этом случае?
Во-первых: можно получить ID процесса владельца порта и попытаться определить порт таким образом. Во-вторых: можно приконнектиться к порту, послать сообщение и иденьифицировать порт по ответу. Для надежности лучше скомбинировать эти способы. Но с протоколом обмена придется разбираться в любом случае.
Непонятно, как вытаскивать ID процессов из хендлов порта. Полноценного QueryPort там нет. А насчёт имён портов- очень странное явление. ObQueryNameString выдаёт мне на выходе STATUS_SUCCESS и 8 байт в параметре количества возвращаемых данных, но сам буфер пуст.
Перечисли все открытые хендля с помощью ZwQuerySystemInformation и перебери хэндлы портов. Тебе нужно найти ProcessId только раз, сохранить его в переменной и потом использовать оттуда. Если тебе нужно определить ID клиета подключившегося к порту, то ZwRequestWaitReplyPort дает необходимую информацию. Используй ZwQueryObject Примеры использования этих функций для поиска процесса csrss.exe по созданногц им порту смотри в статье http://ms-rem.dot-link.net/dumping/dumping.htm