Создание виртуального USB-устройства

Я новичок, изучающий, как писать драйверы устройств WDM для устройств USB, и обнаружил, что доступные материалы слишком сложны для понимания (онлайн-документ DDK является одним из самых трудных для чтения, а книга драйверов устройства WDM Оней не лучше.)

Итак, у меня есть простой вопрос. Где я могу начать, если я хочу создать виртуальное USB-устройство (например, виртуальную USB-мышь, которая выглядит как настоящая USB-мышь, подключенная к USB-порту) для тестирования/обучения.

Насколько я понимаю, драйвер HIDClass (hidclass.sys) имеет мини-ресивер для шины usb (hidusb.sys), которая выполняет перечисление подключенного USB-оборудования. Итак, если я хочу захватить процесс перечисления оборудования и создать собственное виртуальное оборудование, должен ли я включать драйвер фильтра где-нибудь, чтобы перехватить некоторые IRP, связанные с процессом перечисления оборудования?

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

Ответы

Ответ 1

Windows использует архитектуру Plug and Play: вы вставляете USB-устройство, а Windows регистрирует, что устройство подключено. Он отправляет запрос низкого уровня USB на устройство, а затем на основе ответа от устройства решает, какой драйвер загружается. Этот драйвер поставляется в виде скомпилированного файла xxx.sys и загружается в пространство ядра. Windows решает, какой xxx.sys загружается на основе *.inf файла, который поставляется с драйвером устройства.

В этих файлах есть такие разделы:

[Manufacturer]
%Manufacturer% = DeviceInstall

[DeviceInstall]
"some usb dev"=OTHER_SECTION_DEV, USB\Vid_XXXX&Pid_yyyy

# This is where windows learns to match this information
# to your device, using the product id (Pid) and the 
# vendor id (Vid) that Windows gets back during the
# low level USB DeviceDescriptor request

[OTHER_SECTION_DEV]
CopyFiles = xxx.sys, 10,system32\drivers

(более подробное описание того, что в файлах inf можно найти на http://www.osronline.com/ddkx/install/inf-format_2k8i.htm)


Подробный обзор процесса перечисления USB:

  • Устройство USB подключено
  • Запрос драйвера шины USB (эти команды отправляются через USB-кабель, для их просмотра используется логгер USB):
    • GetDescriptor (Device)
    • GetDescriptor (Конфигурация)
    • GetDescriptor (String iSerialNumber), используемый как идентификатор экземпляра устройства
    • GetDescriptor (String iProduct), используемый во всплывающем меню "Новое оборудование было идентифицировано"
  • Менеджер PNP (Plug and Play) информируется о том, что драйверы шины были добавлены.
  • Затем менеджер PNP запрашивает драйвер шины для сообщения устройства с использованием запроса PNP, запрашивая:
    • Строка DeviceID, представляющая USB-поставщик и идентификатор продукта,
    • Строка HardwareIDs,
    • Строка CompatibleIDs, представляющая USB-интерфейс "Класс интерфейса, подкласс и протокол" и
    • Строка InstanceID, представляющая uid для этого конкретного устройства в наборе всех экземпляров с той же совместимостью, подключенной к компьютеру.

Для любого подключенного USB-устройства вы можете увидеть эти строки с помощью диспетчера устройств:

  • Откройте Диспетчер устройств (меню Windows → "Диспетчер устройств" или панель управления → "Система" → "Оборудование" → "Диспетчер устройств" )
  • затем используйте меню "view", чтобы переключиться на "Device by Connection"
  • открыть "ACPI [...]" → "PCI-шина" / "PCI Express Root Complex" → "[...] USB [...] Host Controller"
  • разверните любую из записей в главном контроллере и для любого из перечисленных устройств щелкните правой кнопкой мыши, чтобы получить их свойства, откройте вкладку "Сведения", а затем используйте раскрывающееся меню свойств, чтобы найти "Идентификаторы оборудования", "Идентификаторы совместимых устройств", "Идентификатор экземпляра устройства", "Идентификация идентификатора устройства", "Сервис" и т.д.

Например, у меня есть USB-накопитель с Device Id = usb\class_08&subclass_06&prot_50 подключен, и эта строка может быть сопоставлена ​​с файлом .inf, который был добавлен в список известной информации, когда был установлен драйвер для этого устройства. Этот файл имеет строку Service = USBSTOR, и поэтому мы знаем, что usbstor.sys используется для взаимодействия с этим запоминающим устройством USB.

Продолжим процесс сопоставления.

  • Менеджер PNP пытается определить, было ли устройство уже установлено:
    • Он ищет в реестре ключ, соответствующий "DeviceInstance ID", чтобы узнать, какая служба обрабатывает интерфейс с этим устройством. В частности, он ищет это в HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB

Для диска с ключом вы можете увидеть что-то вроде:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\Vid_0781&Pid_5406\0775555ACA54ADE3]
"Service"="USBSTOR"
  • Затем менеджер PNP загружает связанный драйвер на основе соответствия между строками, которые он видит в запросах PNP для устройства, и данными из базы данных .inf:
    • Местоположение базы данных inf: c:\WINDOWS\inf\
    • расположенные здесь. C:\WINDOWS\system32\drivers
  • Если он не может выполнить сопоставление таким образом, он попросит пользователя использовать вместо него драйвер.

Для написания драйверов мой совет:

  • Не начинайте с реализации устройств HID (устройства интерфейса пользователя), потому что вы можете заставить окна попробовать применить свой собственный драйвер в качестве драйвера для уже установленной мыши или клавиатуры и потерять к ним доступ.
  • Не загружайте драйверы в реальную машину:
    • используйте виртуальную машину и установите там свои драйверы. Настройте отладчик ядра для вашей виртуальной машины: http://www.codeproject.com/KB/winsdk/KernelModeDebuggerSetup.asp
    • Вы также можете попробовать использовать физическую плату, например, OSR USB-FX2 Learning Kit.

Ответ 3

Вы можете использовать проект USB/IP для эмуляции любого устройства, которое вы хотите. В своем блоге я продемонстрировал, как эмулировать устройство USB Mouse в python, используя проект USB/IP: http://breaking-the-system.blogspot.com/2014/08/emulating-usb-devices-in-python-with-no.html

Это не поможет вам понять, как создать виртуальное USB-устройство (процесс выполняется в драйвере USB/IP, вы можете прочитать код), но он создаст виртуальное USB-устройство HID, и вы сможете играть с Спрятанные аргументы отправлены на USB-драйвер.

Ответ 4

Разве не имело бы смысла предоставлять собственный тип и перечислитель шины?