USB-дескрипторы, VID/PID и что значит клонирование дескриптора
Что хранится в USB HID-дескрипторе и какие поля идентифицируют устройство, откуда взялись списки совместимых мышей и почему типовой дескриптор слабее клонированного.
Коротко
USB HID-дескриптор — это то, как устройство описывает себя при подключении: vendor ID, product ID, строки и формат отчётов. Клонирование дескриптора означает, что устройство ввода представляется идентичностью подключённой к нему настоящей мыши, а не собственной типовой.
На странице10
- Что такое USB-дескриптор?
- Какие поля дескриптора идентифицируют устройство
- Почему поменять только VID и PID недостаточно
- Откуда взялись списки совместимых мышей
- Как работает клонирование дескриптора
- Стоковая, типовая и клонированная идентичность
- Как проверить своё устройство
- Что клонированный дескриптор не может скрыть
- Частые вопросы о дескрипторах
- Источники
Что такое USB-дескриптор?
Когда подключается любое USB-устройство, хост просит его описать себя, и пока оно не ответит, больше ничего не происходит. Устройство отвечает набором дескрипторов. Дескриптор устройства говорит, кто его сделал и что это за модель, а дескриптор конфигурации — сколько у него интерфейсов. Дескрипторы интерфейсов и конечных точек (endpoint) говорят, что делает каждый интерфейс и как часто его нужно опрашивать. Всё, что является клавиатурой, мышью или геймпадом, дополнительно отправляет HID report descriptor, который описывает точную побайтовую структуру сообщений, которые устройство будет слать. Этот обмен называется энумерацией и занимает миллисекунды, ещё до загрузки какого-либо драйвера. Всё, что операционная система потом думает об устройстве, берётся из этих миллисекунд. Ваше устройство ввода отвечает на те же вопросы, и отвечать оно может хорошо или плохо.
Какие поля дескриптора идентифицируют устройство
Это не вся спецификация USB, но каждое поле из этого списка софт на хосте может прочитать без особых привилегий.
| Поле | Что в нём | Что оно выдаёт |
|---|---|---|
| idVendor (VID) | 16-битное число, которое компании присваивает организация по стандартам USB (USB-IF) | Кто сделал устройство. VID известного производителя мышей на машине с такой мышью ничем не примечателен. VID производителя отладочных плат — это уже вопрос |
| idProduct (PID) | 16-битное число, которое производитель присваивает конкретной модели | Какая это модель. VID и PID вместе — публичная идентичность устройства, и именно по этой паре работают сопоставление драйверов, телеметрия и инструменты инвентаризации |
| iManufacturer и iProduct | Индексы строковых дескрипторов, которые считываются как текст | Человекочитаемое имя, которое показывает диспетчер устройств. Поле, о котором забывают чаще всего, и самая простая улика, когда там написано то, чего не написала бы ни одна мышь |
| iSerialNumber | Необязательный индекс строки с серийным номером | Идентификатор конкретного экземпляра. У некоторых мышей он есть, у многих нет. Windows использует его, когда решает, то же ли это устройство, если его переподключили в другой порт |
| bcdDevice | Номер ревизии устройства, который задаёт производитель | Ревизия прошивки. У реальных продуктов это значение меняется от релиза к релизу. Значение, которое одинаково на всех экземплярах в мире и никогда не меняется, само по себе паттерн |
| bcdUSB | Версия спецификации USB, которую устройство якобы реализует | Под какую версию спецификации устройство себя выдаёт и сходится ли его поведение Full Speed или High Speed с остальным, что оно о себе заявляет |
| bDeviceClass и bInterfaceClass | Коды классов. Класс 3 — HID | Что это устройство класса HID (human interface device), а не накопитель, аудиоустройство или serial-адаптер |
| Число интерфейсов | Сколько функций отдаёт одно физическое устройство | Мышь ли это или составной гаджет: мышь плюс serial-порт плюс что-то ещё. Обычная мышь, как правило, не бывает тремя устройствами сразу |
| bInterval у конечной точки | Интервал опроса, который устройство запрашивает у хоста | Частота отчётов, которую оно якобы хочет. Устройство, чей дескриптор просит скромный интервал, а отчёты шлёт намного чаще, само себе противоречит |
| HID report descriptor | Usage page и usages, размеры полей осей, количество кнопок, колесо, любые вендорские коллекции | Форма устройства. Сколько кнопок, 8- или 16-битные оси движения, есть ли горизонтальное колесо и не отсутствует ли вендорский блок, который у этой модели должен быть |
Ни одно из этих полей не секретно, и ни для одного не нужен драйвер. Любой процесс на хосте может перечислить подключённые к нему устройства и прочитать каждое из этих полей.
Внимание
Почему поменять только VID и PID недостаточно
Vendor ID и product ID принимают за всю идентичность, и их действительно проверяют первыми, но это всего два числа из многих. Представьте устройство с VID и PID известного производителя мышей, у которого строка продукта по-прежнему называет микроконтроллерную плату. Его report descriptor объявляет не то число кнопок, что у этой модели, а конечная точка запрашивает интервал, который эта модель никогда не использует. Это выглядит хуже, чем если бы устройство вообще не трогали: наполовину скопированная идентичность не сходится, а несоответствие — именно то, что ищет проверка. Если меняете ID, меняйте и всё, что с ними связано.
Откуда взялись списки совместимых мышей
Старые passthrough-прошивки не разбирали дескриптор подключённой мыши. Вместо этого в них были жёстко прописанные профили: написанная вручную таблица раскладок отчётов для конкретных моделей. Подключили мышь из списка — прошивка знала, как декодировать её отчёты и как скопировать её идентичность. Подключили что-то другое — получали либо ничего, либо кашу вместо движения. Отсюда и вопрос про совместимые мыши, и на прошивках того поколения это реальное ограничение, которое нужно проверить до покупки мыши. Новые прошивки считывают раскладку с устройства во время энумерации и подстраиваются под неё, и самый наглядный пример — автоматический разбор HID report descriptor в MAKCM. Поэтому на актуальных устройствах списки перестали иметь значение, хотя к какому поколению относится ваша прошивка, всё равно лучше проверить, а не гадать.
Как работает клонирование дескриптора
Клонирование дескриптора работает в два шага. Устройство ввода проводит энумерацию настоящей мыши на своей host-стороне и считывает, что эта мышь сообщила о себе, а затем отдаёт те же ответы игровому ПК на своей device-стороне. Поэтому идентичность, которую видит игровой ПК, принадлежит мыши, которая действительно существует и действительно подключена, просто на одно звено дальше. Полное клонирование охватывает ID, строки, ревизию, раскладку интерфейсов и report descriptor, так что ответы согласуются между собой, потому что взяты с одного реального устройства. Частичное клонирование копирует ID, но оставляет строки или report descriptor от самого passthrough-устройства, и проблема несоответствия возвращается. Поэтому полезный вопрос о любой прошивке — не «умеет ли она подменять VID», а «какую часть дескриптора она копирует».
Совет
Стоковая, типовая и клонированная идентичность
Стоковая идентичность — это passthrough-плата, которая представляется тем, чем является. У нетронутой Teensy это vendor ID и строки продукта отладочной платы на машине, где ей больше неоткуда взяться. Типовая (generic) идентичность — выдуманная мышь, которая выглядит достаточно правдоподобно: стандартная HID-мышь (class-compliant) с нейтральными строками. Сама по себе она ничем не примечательна, но не соответствует ни одному продукту в продаже и одинакова у всех, кто пользуется этой прошивкой. Клонированная идентичность — это дескриптор той самой мыши, которая у вас в руке. Она непротиворечива, соответствует существующему продукту и различается у разных пользователей, потому что мыши у них разные. Это три разные позиции, и их можно выстроить от худшей к лучшей. Но ни одна из них ни от чего не защищает: этот порядок говорит о том, насколько заметна ваша аномалия, а не о безопасности.
Как проверить своё устройство
Делайте это на игровом ПК с помощью просмотрщика USB-устройств, чтобы увидеть своё устройство ввода так, как его видит игровой ПК. Это занимает пять минут и скажет вам больше, чем любая ветка на форуме.
- Строки продукта и производителя выглядят как у мыши, а не как у микроконтроллера или отладочной платы
- Vendor ID и product ID сочетаются друг с другом и соответствуют реально существующему продукту
- Число кнопок и колесо в report descriptor соответствуют заявленной модели
- Устройство отдаёт один интерфейс HID-мыши, а не мышь плюс serial-порт плюс клавиатуру, которой вы никогда не пользуетесь
- Запрашиваемый интервал опроса правдоподобен для заявленной модели
- Строка серийного номера есть или отсутствует — ровно так же, как у заявленной модели
- В диспетчере устройств нет имён, которых вы не ожидали бы увидеть на обычном игровом ПК
Внимание
Что клонированный дескриптор не может скрыть
Идеально клонированный дескриптор делает устройство непримечательным при энумерации, но никак не влияет на тайминг и форму движения, которое устройство подмешивает потом. Анализ происходит именно на этом, более позднем уровне, и беспокоятся на самом деле именно о нём. Движение, которое резко «прилипает» к цели, видно, что бы ни говорил дескриптор, как и слишком плавное движение. То же касается движения с одинаковой кривой ускорения на каждом флике или движения, которое корректирует позицию цели быстрее, чем способна рука. Работа с дескриптором убирает один класс простых сигналов. Она нужна, но сама по себе её недостаточно, и именно так люди с отличным сетапом и попадаются: считают её достаточной, а их движение выглядит как работа программы.
Частые вопросы о дескрипторах
Может ли игра прочитать дескриптор моей мыши?
Процесс на машине может перечислить подключённые USB-устройства и прочитать их дескрипторы без особых привилегий, а античит с доступом к ядру — тем более. Делает ли это конкретная игра и что она делает с результатом, никто за пределами этой компании честно вам не скажет.
Если я клонирую дескриптор своей настоящей мыши, не будет ли двух одинаковых устройств?
Нет: настоящая мышь подключена к host-стороне устройства ввода, а не к игровому ПК, поэтому игровой ПК видит только одно устройство с этой идентичностью. Если вы параллельно воткнёте настоящую мышь напрямую в игровой ПК, то создадите ровно тот дубликат, которого пытались избежать.
Клонировать дескриптор незаконно?
Использовать vendor ID другой компании — значит неправомерно использовать идентификатор, присвоенный этой компании, а заодно это вопрос условий использования (ToS) игры. Мы не юристы, и это не юридическая консультация. Технически, однако, это возможно.
Влияет ли смена дескриптора на производительность?
Report descriptor — влияет. Если объявить 16-битные относительные оси вместо 8-битных, большие смещения помещаются в один отчёт, а не обрезаются и не делятся на части. На больших фликах в этом и разница между плавным и ступенчатым движением, а поля идентичности на производительность не влияют вообще.
В моём чите есть переключатель spoof descriptor. Достаточно его включить?
Это лучше, чем оставить его выключенным, но само по себе полным решением не является. Выясните, что он на самом деле меняет: только ID или ещё строки и report descriptor. Затем проверьте результат с игрового ПК просмотрщиком устройств, а не верьте подписи у галочки.
Стоит ли брать в доноры дешёвую мышь?
Используйте мышь, которой реально играете. Смысл клонирования в том, чтобы идентичность соответствовала устройству, которое у вас правдоподобно есть и которым вы пользуетесь, а ваша настоящая мышь — самый правдоподобный вариант из всех.
Источники
Ранжирование стоковой, типовой и клонированной идентичности — наша собственная интерпретация, как и чеклист проверки, который основан на тестах на стенде.
- 01Microsoft Learn, USB device descriptors
поля idVendor, idProduct, строк и класса из таблицы и то, как Windows сопоставляет устройства по этим полям
learn.microsoft.com
- 02Microsoft, Windows debugging tools (WDK)
откуда берётся USB Device Viewer, который используется в чеклисте проверки
learn.microsoft.com
- 03MAKCM firmware, GPL-3.0
что актуальная прошивка MAKCM разбирает HID report descriptor подключённой мыши, а не использует список моделей
github.com
Читать дальше
Не получилось? Откройте тикет в Discord
Все гайды