Как стать автором
Обновить

Учим французский или как получить универсальный адаптер из диагностического сканера концерна PSA

Время на прочтение3 мин
Количество просмотров8.7K
Чтобы предотвратить снижение IQ во время самоизоляции, возникло желание сделать что-то полезное для себя, а если повезет — не только. Нарезая n-ый круг по квартире, мой взгляд зацепился за автомобильный сканер, который я брал у знакомого для дальнейшего изучения, а именно Lexia 3, он же Actia XS Evolution. Вот такой:
image
Его огромным минусом было то, что работать с ним может только софт DiagBox, предназначенный для диагностики автомобилей марки Peugeout/Citroen. С последним мириться было нельзя (с), поэтому возникла мысль, а что если этот сканер заставить отправлять и получать произвольные сообщения в CAN-шину автомобиля, тем самым превратив его в универсальный адаптер.

Итак, план действий:

  1. Собрать обмен по шине USB между ПК и нашим пациентом.
  2. Разобраться как происходит общение между драйвером адаптера и программным обеспечением.
  3. Повторить обмен и почувствовать себя молодцом (спойлер: вышло все несколько сложнее).

1. Обмен


Программный комплекс DiagBox свободно гуляет по интернету, поэтому трудностей с пунктом 1 не возникло, тем более в комплекте с ним идет небольшая утилита для идентификации адаптера, что несколько упростило задачу из пункта 2. При получении обмена по шине USB помогла пробная версия программы USBLyzer.
Идем к успеху. На картинке отправленный пакет данных, вид устройства в диспетчере и та самая утилитка.

image

Глядя на IRP'ы при открытии устройства и обмене с ним можно сделать вывод, что работа производится через штатный механизм ввода-вывода Windows, а именно, для открытия виртуального файла устройства функция CreateFile и для обмена — DeviceIOControl.

image

2. Разбор полетов


Данные собраны, IOCTL ID и флаги получены, осталось дело за малым, открыть файл-устройство и отправить туда пачку байт. Вот только что открывать? Поиск через WinObj результатов не дал, при подключении адаптер не имеет точного имени, лишь неявную ссылку с постоянно меняющимся ID, то есть просто открыть устройство наподобие COM-порта не получится

CreateFile("\\\\.\\COM1", ...)

Изучение файлов программы внесло ясность, оказалось все довольно просто — адаптер имеет свой уникальный GUID, с помощью которого у операционной системы запрашивается список всех устройств с таким GUID и если они присутствуют, мы получим ссылку на устройство, вида
\\?\USB#VID_103A&PID_F000#6&268bff9b&0&7#{75a835f4-d77d-4402-8585-c42247f25b76}\vcommusb0 открытие которой будет успешным.

Функция, возвращающая путь взамен GUID:

CM_Get_Device_Interface_List(InterfaceClassGuid, pDeviceID, Buffer, BufferLen, ulFlags);

«файл» успешно открывается, не забываем про флаги, которые добыли через USBLyzer

Device = CreateFile(DeviceName, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);

3. Финал


Отправляем пакет байт, а в ответ — тишина…

bStatus = DeviceIoControl(Device, 0x220003, send_buf, send_len, out_buf, max_out_len, &returned_len, NULL);

Долго я сидел и смотрел в монитор, вот тот самый обмен, вот приходят ответы от устройства, вот они флаги, в точности такие, как я повторил, но ничего не выходит.

image

Окончательно потеряв всякую надежду на успех, у меня оставалось последнее — тяжелая артиллерия в виде диска от журнала «Хакер» с программой OllyDbg. Запускаем, аттачимся к процессу, ставим брякпоинт на функции DeviceIoControl и что же мы видим.

image

Царь-то не настоящий. Абсолютно другой IOCTL код, данные совсем не похожи на те, что видно через USBLyzer.

То, что было отправлено в устройство:

<b>00 FA</b> <i>AA</i> BA 7C 15 00 00 00 00 00 00

А это ушло по USB:

40 05 15 C0 <b>00 FA</b> 00 00 <i>AA</i> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 41

Подсказка крылась в названии устройства, видимом в диспетчере задач. На сайте Microsoft'а нашел статью о том, что такое UMDF USB драйвер. Наглядная блок-схема:

image

Выходит, то, что мы видим в USBLyzer'е это транспортный уровень передачи клиентских данных, который реализован в UMDF драйвере (направление 7 на картинке), в то время как мы передаем данные устройству (направление 2 на картинке), которые дойдут сначала в драйвер, а потом уйдут в шину USB. Надеюсь понятно объяснил.

Теперь все стало ясно, откуда другие IOCTL ID и данные. Чтож, так даже проще, не нужно ломать голову над тем, как реализовать транспорт, у нас простейший интерфейс запрос-ответ. Также в файлах программы случайно завалялось описание протокола обмена (частичное), жаль только на французском.

image

Согласно ему, в сообщении выше была запрошена версия прошивки (00 FA), на что был получен ответ со строкой APPLI_XS_Fuji_ P106138A V4.3.0 @ACTIA 02.01.12.

ВСЕ. Настраиваем CAN, отправляем адреса запрос-ответ для общения по протоколу ISO-TP и получаем полноценно работающий адаптер с автомобилем. Для удобства пользования была написана обертка, которая насколько это возможно соответствует стандарту PassThru J2534, для того, чтобы этот адаптер можно было использовать с различным автомобильным софтом, в том числе собственной разработки.

Видео работы (stdout выведен в консоль для удобства отладки):


Исходники можно посмотреть тут
Теги:
Хабы:
Всего голосов 15: ↑15 и ↓0+15
Комментарии5

Публикации

Истории

Ближайшие события

Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн
Антиконференция X5 Future Night
Дата30 мая
Время11:00 – 23:00
Место
Онлайн
Конференция «IT IS CONF 2024»
Дата20 июня
Время09:00 – 19:00
Место
Екатеринбург