The Jerusalem PostCouncil of Torah Sages meeting over Shas party chair Arye Deri's future in party postponedSky TG24Midterm, cosa cambia con la maggioranza dem al CongressoPunch2027: ADC inaugurates 63-member campaign team in Cross RiverZDF heuteEntdecken Sie das ZDF-NachrichtenstudioVanguardState Police: 30 states approve bill, six yet to respondNOSMeer dan 1,7 miljoen neppe Pokémon-kaarten onderschept in Rotterdamse havenAntara NewsIndonesia reports 401,586 respiratory cases linked to forest firesRai NewsMasters di Parigi: Musetti sfida Zverev, stasera Berrettini-HumbertSportstarIndia vs Korea LIVE Score, Asian Champions Trophy semifinal: IND 0-0 KOR; Match is underway, Harmanpreet leads sideESPNCFP top 25: What flaw keeps each team from the title20 MinutenMit Ariel kann nun ganz Deutschland Schweizerdeutsch lernen7sur7Le Monténégro aux portes de l’UE: une adhésion possible dès 2028
The Daily Newsstand · Free, Always
Wednesday, November 4, 2026

Разлочиваем модем Quectel EG25-G в робособаке Unitree Go2

Translate

Я Лев Ларин, инженер Unibot. Мы подключаем роботов к UNIBOT Fleet и дорабатываем их управление, интеграции и связь.

В первом разборе мы сняли региональное ограничение с Quectel EG25-GC в роботе-официанте. Во втором разобрались с RG255C-GL в Agibot X2 Ultra. А в статье про Unitree Go2 получили root, исправили Wi-Fi и добавили русские голосовые команды.

Теперь очередь дошла до сотовой связи этой собачки. В нашем Go2 установлен Quectel EG25-G с eSIM. Профиль читается, российская сеть видна, регистрации нет. Идём по знакомому пути: AT-диагностика, копия радиопрошивки, проверка MCC в коде Qualcomm Hexagon, точечное изменение и загрузка обратно.

После перезапуска модем зарегистрировался в Билайне.

Что стоит в Go2

У Go2 есть встроенная сотовая связь с eSIM. На нашем экземпляре активен профиль Orange: MCC/MNC домашней сети — 20801, APN — orange.m2m.spec. В России такой профиль должен регистрироваться в роуминге.

Сам модем подключён по USB к основному Linux-контроллеру робота. В него мы уже могли зайти по SSH.

Модуль Quectel EG25-G

Модуль Quectel EG25-G

Изображение модуля EG25-G с сайта Quectel.

Параметр

Наш экземпляр

Робот

Unitree Go2

Модем

Quectel EG25-G

Прошивка

EG25GGBR07A08M2G_A0.204.A0.204

USB VID:PID

2c7c:0125

Linux внутри модема

ARMv7, ядро 3.18.44

Радиокод

Qualcomm Hexagon, сжатие Q6zip

По USB ID устройство может определяться как EC25. Модель и полную версию мы уточнили командами модема. Прошивка здесь GB, а в первом роботе была GC: знакомое семейство ещё не означает совпадения образов и адресов.

eSIM читается, сеть не регистрируется

Основной AT-порт и GPS-порт уже использовал штатный vui_service, с модемом также работал ModemManager. Для диагностики выбрали свободный вспомогательный AT-интерфейс.

Начальное состояние:

CPIN: READY
CFUN: 1
CREG: 0,2
CGREG: 0,2
CGATT: 0
QNWINFO: "WCDMA","25020","WCDMA 2100",10563
QENG: "servingcell","LIMSRV",...

Профиль SIM доступен, радио включено, модем видит российскую сеть, но остаётся в ограниченном обслуживании. В ответах CREG и CGREG значение 2 означает поиск регистрации.

Обычная операторская персонализация была выключена: AT+CLCK="PN",2 возвращал 0. Роуминг и выбор технологии стояли в автоматическом режиме. В прочитанной области SIM-файла EF FPLMN, где хранятся запрещённые сети, были только FF.

APN оставили штатным. Следующим шагом проверили радиопрошивку.

Доступ к Linux самого модема

Временно включили USB-интерфейс ADB через механизм QADBKEY. ADB-клиент запустили на контроллере робота — USB-хосте модема.

Здесь ADB нужен для доступа к отдельному Linux внутри EG25-G. На стороне робота тоже Linux; Android в этой цепочке не требуется.

Из /firmware/image скопировали 49 файлов, около 48 МБ. Оригиналы сохранили на компьютере и контроллере робота. Для анализа взяли заводской пакет той же версии и побайтно сверили с ним все modem.*, прочитанные с устройства.

В release notes этого выпуска описаны ограничения регистрации в России и Иране. В modem.b22 нашлись строки:

reg_sim.c:quectel_check_current_plmn_is_need_forbidden MCC =%d%d%d
reg_sim.c:Current PLMN is Russian PLMN ,Forbidden

Оставалось найти функцию, которая ими пользуется.

Где оказался MCC 250

Нужный код был сжат Q6zip и лежал в modem.b19. У этого сегмента нет обычного ELF-флага исполняемого кода. Поиск только по исполняемым сегментам его пропускает.

Распаковали сегмент инструментом qualcomm-q6zip. Параметры нашей сборки:

Параметр

Значение

Версия Q6zip

0x0600

Число страниц

4450

Размер распакованной страницы

4096 байт

Страниц с двумя словами метаданных

3922

Размер распакованного кода

18 227 200 байт

Виртуальная база

0xd0000000

Граница метаданных важна: у последних страниц этих двух слов уже нет. Если продолжать их пропускать, распаковка даст неправильный результат. Виртуальную базу подтвердили таблицей отображения в modem.b13, затем разобрали инструкции Hexagon в Rizin.

По адресу 0xd023afc0 нашлась короткая функция. Она извлекала из аргумента три полубайта с цифрами MCC. Упрощённо:

a = packed_mcc & 0xf;
b = (packed_mcc >> 4) & 0xf;
c = (packed_mcc >> 8) & 0xf;

if (a == 2 && b == 5 && c == 0)
    return 1;

if (a == 4 && b == 3 && c == 2)
    return 1;

return 0;

MCC 250 — Россия, 432 — Иран. Десятичного числа 250 в этом условии нет: компилятор сравнивает отдельные цифры.

Проверили и вызывающий код. Он вызывал эту функцию по адресу 0xd023b030, а при результате 1 переходил в ветвь с сообщением Current PLMN is Russian PLMN ,Forbidden. Так связали сравнения цифр с запретом регистрации.

Один бит в радиокоде

Повторили вариант из первого кейса: заменили среднюю цифру российского MCC с 5 на 7. Условие стало распознавать 270 вместо 250. Проверка 432 осталась прежней.

В распакованном коде изменилось сравнение по адресу 0xd023afd8:

Было: P0 = cmp.eq(R1,#0x5)
Стало: P0 = cmp.eq(R1,#0x7)

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

Заново распаковали изменённую страницу и сравнили с оригиналом: отличается только нужное сравнение. Все остальные сжатые страницы, словари, указатели, метаданные и длина modem.b19 совпали. В радиокоде снова хватило одного бита.

Хеши и подпись

После изменения b19 пересчитали его SHA-256 в таблице modem.b01 и обновили подпись контейнера. В этой сборке:

modem.mdt = modem.b00 + modem.b01

Поэтому записывать предстояло три файла: modem.b19, modem.b01 и modem.mdt.

Здесь было отличие от EG25-GC из первой статьи: исходная цепочка сертификатов принадлежала Quectel. Прежде чем менять её, проверили состояние аппаратной аутентификации на самом модеме:

AT+QCFG="secbootstat"
+QCFG: "secbootstat",0

/sys/class/qtee/secboot_state
auth_disable

Хеш корневого сертификата в secboot_rootca_hash был нулевым. При таком исходном состоянии модем позволял загрузить образ с другой цепочкой.

Исходную QPSA/RSA-подпись проверили по открытому ключу из заводского образа. Для изменённого контейнера создали локальный конечный сертификат под опубликованной тестовой CA Qualcomm. Сохранили аттестационные поля HW_ID, SW_ID, OEM-параметры и даты исходного сертификата. Затем проверили новую подпись, цепочку и все 24 записи таблицы хешей.

Настройки Secure Boot и аппаратные предохранители оставались в исходном состоянии.

Запись и перезапуск

Раздел /firmware был смонтирован read-only. Свободными оставались примерно 7,3 МБ, а modem.b19 занимал 10,6 МБ. Для полного временного дубликата рядом с оригиналом места не хватало.

Сохранили три исходных файла в /cache модема и подготовили откат. В большом b19 изменили один байт на месте. Небольшие b01 и mdt заменили через временные файлы и rename. Проверили SHA-256, выполнили sync и вернули /firmware в read-only.

Перед перезапуском запустили на контроллере отдельный процесс проверки загрузки: при отказе DSP он должен был вернуть оригиналы. Затем перезапустили модем командой AT+CFUN=1,1.

После загрузки получили:

DSP state: ONLINE
crash_count: 0

Все три хеша совпали с подготовленным образом. Откат не потребовался, контроллер робота продолжал работать.

При завершении поправили последствие USB-переподключений: штатный vui_service держал дескрипторы старых AT- и GPS-портов. Его перезапустил штатный supervisor; сервис снова открыл действующие порты. После этого выключили ADB модема и вернули исходный состав USB-интерфейсов.

Регистрация в Билайне

После загрузки исправленной прошивки модем зарегистрировался в сети:

CREG: 0,5
CGREG: 0,5
CGATT: 1
COPS: 0,0,"beeline",0
QNWINFO: "EDGE","25099","GSM 900",33

5 в ответах регистрации означает роуминг. Это соответствует нашему профилю Orange: домашняя сеть — 20801, обслуживающая российская — 25099, Билайн. CGATT: 1 подтверждает присоединение к пакетной сети.

APN orange.m2m.spec остался прежним. После изменения проверки MCC та же eSIM, которая до этого оставалась в поиске, зарегистрировалась в российской сети.

View the original on Хабр →

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.