Получить DEVICE_OBJECT по имени устройства в обход ZwOpenFile
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 28.01.13 09:10
Оценка:
Есть у меня клавиатурный фильтр, изначально писанный под NT4. Соответственно, Legacy, для присоединения к клавиатурным устройствам использовавший IoAttachDevice по именам (DD_KEYBOARD_DEVICE_NAME плюс номер). Все прекрасно работало, драйвер в любой момент можно было выгрузить. Затем появилась 2k с поддержкой USB-клавиатур, и выяснилось, что к ним IoAttachDevice цепляться не хочет. Тогда я не стал вдаваться в проблему, а переделал, как рекомендовали Руссинович с Соломоном, на стандартный PnP-фильтр, цепляемый через UpperFilters, и получающий DEVICE_OBJECT'ы через AddDevice. Все опять-таки прекрасно работает, за исключением невозможности поставить/удалить/перезапустить драйвер без перезагрузки.

Сейчас у меня дошли руки его немного доработать, и перезагрузка целевой машины после каждой модификации (а если упал — то и двойная) уже достала. Решил переделать обратно в динамическое присоединение, тем более, что обработка Remove и Surprise Removal там уже есть, дело только за получением DEVICE_OBJECT целевого устройства. При попытке присоединения к устройству USB-клавиатуры IoAttachDevice возвращает STATUS_SHARING_VIOLATION, а ей это возвращает IoGetDeviceObjectPointer. Последняя работает через ZwOpenFile.

Собственно, вполне понятно, что системный процесс, сидящий на USB-клавиатуре, открыл устройство с запретом шаринга. По факту, мне и не нужен клиентский доступ, с получением FILE_OBJECT — достаточно простого увеличения RefCount. Если нахожу адрес объекта вручную, и затем передаю его IoAttachDeviceToDeviceStack — все прекрасно цепляется, работает, при выдергивании клавиатуры — отцепляется, при неотцепленной клавиатуре система корректно уходит в шатдаун, драйвер в любой момент выгружается, Verifier ни на него, ни на kbdclass не обижается. То есть, проблема исключительно в получении адреса объекта устройства.

В принципе, я могу тупо находить объект драйвера по постоянно присутствующему устройству \Device\KeyboardClass0, сканировать все его объекты устройств, и цепляться к каждому, но это уже попахивает грязным хаком.

Может, есть сравнительно честный способ получения адреса устройства по имени иначе, чем через его полноценное клиентское открывание?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.