Important
Данный репозиторий является неофициальным и реализован на основе анализа сетевого трафика и предположений.
Про проблему 7‑го байта см. в конце.
API клиентской части Max.
У Max существует два API:
- WSS (WebSocket) - для web‑версии
- TLS - для приложений
Базовая логика у них во многом одинаковая, поэтому выбор между ними остаётся за вами.
Наиболее простой API с понятной структурой и самым лёгким способом анализа.
Анализ можно проводить прямо в браузере с помощью панели разработчика:
-
Зайти на сайт: https://web.max.ru
-
Открыть консоль разработчика:
Ctrl + Shift + J, либо- ПКМ → Проверить
-
Перейти во вкладку Network.
-
(Опционально) В фильтрах сверху выбрать Socket.
-
Перезагрузить страницу.
-
Найти и открыть WebSocket‑подключение:
- если выполнен пункт 4 - оно будет первым и единственным.
-
Перейти во вкладку Messages.
На этом всё - далее остаётся анализировать смысл пакетов, порядок их отправки и структуру.
Отдельно описывать формат пакетов, на мой взгляд, не имеет смысла - он достаточно очевиден.
Здесь начинается самое интересное. В отличие от Web‑версии, в приложении нет простого пути анализа, а структура пакетов заметно усложнена.
Далее описание ориентировано на Windows‑версию.
-
Скачать Windows‑версию приложения:
-
Установить приложение.
- Я использовал виртуальную машину, но это не принципиально.
-
Подготовить инструмент для анализа трафика.
- В данном описании используется mitmproxy.
-
Скачать Windows‑версию:
-
Установить приложение.
-
Запустить mitmweb (веб‑интерфейс - более удобен).
Файл сертификата:
C:\Users\%User%\.mitmproxy\mitmproxy-ca-cert.cer
Параметры установки:
- Устанавливать для: Локального компьютера
- Хранилище: Доверенные корневые центры сертификации
В интерфейсе mitmproxy:
-
Перейти во вкладку Capture.
-
Включить Local Applications.
-
Выбрать
max.exe. -
Перейти во вкладку Flow List.
-
Очистить список:
- File → Clear All
-
(Опционально) Перезапустить Max.
Готово.
В mitmproxy, после выбора соединения, в правом верхнем углу можно выбрать режим View.
Наиболее полезные режимы:
- Hex Dump
- Hex Stream
Для анализа Hex Stream удобно использовать сервис:
- https://hexed.it - отличный инструмент для работы с бинарными данными.
Размер заголовка: 10 байт.
| Байты | Описание |
|---|---|
| 1 | Версия протокола (за всё время анализа не менялась) |
| 2 | cmd - тип команды |
| 3..4 | seq - номер пакета (начинается с 1, ответ приходит с тем же seq) |
| 5..6 | opcode - тип пакета |
| 7 | Неизвестное поле |
| 8..10 | Длина payload в байтах |
| 11.. | Payload |
- Обычно кодируется в формате MsgPack.
- Если значение 7‑го байта ≠ 0, то в начале
payloadприсутствуют 2 дополнительных неизвестных байта.
Note
Актуально и для WebSocket
| Значение | Описание |
|---|---|
| 0 | Запрос |
| 1 | Ответ |
| 3 | Ошибка |
(w)- предположение на основе web‑версии
| Opcode | Описание |
|---|---|
| 1 | Статус клиента (период отправки - 1 секунда) |
| 5 | События - действия клиента (w) |
| 6 | Информация о клиенте |
| 11 | Отправка номера телефона (аутентификация) |
| 12 | Проверка кода из SMS |
| 13 | Вход по токену (повторный вход) |
| 19 | Синхронизировать по токену (w) |
| 26 | Секции по ID (w) |
| 27 | Эмодзи (w) |
| 28 | Эмодзи по ID (w) |
| 32 | Контакт по ID (w) |
| 35 | Последнее время онлайн контакта по ID (w) |
| 36 | Список заблокированных контактов (w) |
| 48 | Информация о чате по ID (w) |
| 49 | История чата по ID (w) |
| 50 | Действие с каналом (например, отметить прочитанным) (w) |
| 64 | Отправить сообщения (w) |
| 75 | Подписка на чат (клиент просматривает чат) (w) |
| 79 | Истории (w) |
| 83 | Получить видео по ID (w) |
| 96 | Сессии клиента (входы, устройства и т.п.) (w) |
| 130 | Событие, связанное с чатом (от сервера) (w) |
| 177 | ??? (w) |
| 178 | Добавить реакцию на сообщение (w) |
| 180 | Реакции на сообщениях (w) |
| 272 | Папки (w) |
| 288 | Запрос QR-кода для входа (w) |
| 288 | Статус QR-кода по trackId (w) |
| 291 | Вход по trackId после сканирования QR-кода (w) |
| 292 | Запрос от сервера: показать баннер |
Пару матов про 7‑й байт.
Желание сделать API у меня было давно, но я так его и не реализовал. Основная причина - 7‑й байт заголовка.
Если значение 7‑го байта не равно нулю, то:
- в начале
payloadпоявляются 2 неизвестных байта; payloadперестаёт адекватно декодироваться как MsgPack.
Я не имею ни малейшего понятия, что это за байт и в чём его смысл.
Я сломал голову, пытаясь его проанализировать, но безуспешно.
Пробовал использовать нейросети для анализа пакетов - но они слишком тупые для таких задач.
Единственный реальный способ разобраться - декомпиляция приложения, но я всё же хочу ещё увидеть солнце, так что этим заниматься не собираюсь.
На данный момент у меня есть лишь два предположения:
- Это некий вид сжатия.
- Это некое шифрование.
Скорее всего, оба предположения неверны, потому что:
-
в случае сжатия:
- 7‑й байт встречается даже в маленьких пакетах, где сжатие бессмысленно,
- а в больших пакетах его может не быть;
-
в случае шифрования:
- пакет всё ещё частично читаем,
- и частично декодируется как MsgPack.
Выглядит это так, будто payload просто побит.