
Думаю, многие олды сейчас разделятся на два лагеря: одни будут считать Агент адварью, другие с теплотой вспомнят сей мессенджер, в котором они встретили свою вторую половинку. Для меня он тоже имеет место в воспоминаниях, это была первая программа для общения, с помощью которой я оставался «на коротке» с родителями. Поэтому вооружившись современными языками программирования и минимальным знанием того, как бинарные протоколы вообще работают, отправился восстанавливать Агент.
Разработка протокола и сервера
Реверс-инженеринг начался именно с воспоминаний. Об этой идее два года назад я рассказал своему другу Михаилу @synzr, а он не оказался против вместе со мной отреверсить протокол, с помощью которого программа и общается с сервером.
Первый ресурс, куда мы пошли смотреть - официальная документация к протоколу, любезно выложенная самими Мэйлру, а отправной точкой стали пара клиентов на J2ME и Windows. Вообще, протокол официально называется MMP, но сами Мэйлру активно использовали аббревиатуру MRA (Mail.Ru Agent) или MRIM (Mail.Ru Instant Messenger).
Вместе с документацией поставлялся Header-файл, где были расписаны числовые значения всех команд. И мы начали делать сервер-эмулятор... Он писал на NodeJS, а я своими культяпками писал именно симулятор, чтобы разобраться в протоколе.
Деталей уже не вспомню, к сожалению, но долгое время я не мог разобраться со списком контактов, так как они попросту переусложнены. Хотя если и знать, как оно работает, то на самом деле в них не так и трудно разобраться. Далеко сразу забегать не буду, сразу объясню что да как.
Протокол состоит в основном из UL и LPS. UL - это 32-битный unsigned int с всегда фиксированной длинной в 4 байта. LPS состоит сразу из двух частей: UL с длинной строки и сама строка без завершающего нуля. Из этих двух разных кирпичиков и собирается пакет.
Заголовок состоит из одиннадцати UL'ов.
Примерное значение | Описание |
0xDEADBEEF | Магический заголовок. Разделяет пакеты между друг другом. Всегда "мёртвая говядина" |
0x00010008 | Версия протокола |
0x8 | Очередь пакета. В некоторых версиях генерируется случайно |
0x1001 | Сама команда. В примере - `MRIM_CS_HELLO` |
0x4 | Размер данных без заголовка |
N/A | IP адрес клиента. В документации он так и описан, но де-факто не используется |
N/A | Порт клиента, с которого произошёл коннект к серверу. В документации он так и описан, но де-факто не используется |
Неиспользуемое заполняется нулями. Размер заголовка всегда равен 44 байтам. А, ну и порядок байт у них Little Endian. Это главное, что нужно о протоколе знать.
За пару дней мы реализовали самые базовые команды: Приветствие (MRIM_CS_HELLO, отправляет частоту "пинга"), вход в аккаунт, контакты, взаимодействие с ними, поиск и сообщения. Всё это проверялось на Агенте 4.10, в котором был очень скудный функционал.

Интересно то, что в том самом файле заголовка команда для входа и для контактов обозначены как MRIM_CS_LOGIN2 и MRIM_CS_CONTACT_LIST2, т.е. была ещё у них и первая версия. Значительно позже я начал разбираться в этом вопросе, и оказалось, что это действительно так. Агент появился в 2004 году, и к его реализации... очень много вопросов. И в нём пришлось разбираться самому — официальная документация была очень старой и неполной.
Во-первых, первая версия не умела в мессенджер. Вообще. Там были только ссылки на меилрушные сервисы. Он появился только в 1.5 в самом зачаточном виде.


Контакты появились только в 2.0. В их реализации плохо всё. Там страшный бинарный формат.
1. 2560 байт зарезервировано для групп
2. Внутри блока групп - 128 байт информации о ней
3. Контакты идут после 2560 байт
4. Длина контактов тоже фиксирована - 256 байт
В группе идёт флаг группы, пробел, и его название. На 128 байте всегда байт 0xA
В контакте ещё хуже. Там примерно такой формат:
{Флаги пользователя} {Индекс группы} {Почта пользователя} {Длинна ника в HEX}{Ник}
Последние 4 байта контакта - серверный флаг. 0001, значит, контакт авторизован. И наоборот, нули, значит нет.
С выходом Агента 4.2 это безобразие заменили на более элегантный формат, который я описал в своей документации. Но суть в том, что данные теперь нормально разделяются через маски. Они передаются через строку и довольно просто объясняются - u это UL, а s это LPS. В версии 4.10 у групп маска us, а у контактов uussuus. В группах: флаги и название, а у контактов это флаги, индекс группы, почта контакта, имя, флаг авторизации, статус, и номер телефона. В новом крупном обновлении Агента эти маски просто обновляются, а в блоке контакта добавляются дополнительные пункты.
В Агенте 5.0, например, появились Икс-статусы, и соответственно, к маске добавились sssus: uri статуса, заголовок статуса, его описание, маска доступных функций (с помощью них агент определяет, что умеет клиент) и юзер-агент клиента.
В 5.5 добавился функционал микроблога, и к маске контактов добавилось uuusss: 64-битный айди поста в двух UL, время в Unix-time, текст, и два зарезервированных LPS. Суть, думаю, понятна.
В версии Агента 5.1 появилась поддержка Юникода. Но это не простой UTF-8, если бы. Там использовался UTF-16LE, где каждый символ всегда равнялся двум байтам, будь-то это кириллица или латиница.

За ним пошла реализация передачи файлов, микроблога, аватарок, и отдельных моментов и поведения некоторых клиентов. В зачаточном виде осталась реализация групповых чатов (конференций). Для реализации некоторых функций пришлось реверсить клиенты, шуршать интернет, или подглядывать в чужие реализации (например, в Miranda NG и myagent-im).

Патчер и установщик
Потом, нам надоело постоянно копаться в реестре и файле hosts, просто чтобы всё перебросить на наш сервер. Поэтому вместе с юзером n0cha3 сделали патчер, который подменяет мёртвые айпишники и доменные имена на наши собственные.
В Windows это делается довольно просто. Через DLL хукается функция gethostbyname для получения домена из WinSocks, и её аргументы просто заменяются на собственные. Кашпировскому, кстати, такой модифицированный файл не понравился, и он его считает трояном.

Вместе со встроенным установщиком лезло всякое г... Нерабочий Спутник@Mail.ru или Guard@Mail.ru. Без моего участия ещё два моих товарища, @Eversiege и motionarium сделали кастомный установщик на основе Inno Setup, в котором всё было заранее пропатчено, вырезано лишнее, и добавлено немного нашего контента. Дизайн установщика делал chelka0.
Запуск на публику
Под новый год 2026 года запустили в публичный доступ проект Renaissance. Открыли сайт, исходники сервера на GitHub и выложили документацию (более полная, чем то, что нам давали сами Mail.ru).
Довольно быстро скриншоты рабочего Агента разошлись в Твиттере. Как я упоминал в начале статьи, люди разделились на два лагеря: на ненависть и на любовь.


Сайт постарались сверстать в том же духе, что и оригинал. Вместо гетеросексуальных пар мы вставили наших друзей-гиков: встретились на "Электрозаводской" и пофоткались на профессиональную камеру, взяв с собой прикольные девайсы.


Что по итогу?
В ретроспективе протокол Агента — это буквально то, на чём даже сейчас построены продукты VK. Недавнее расследование по поводу MAX это и подтвердило, пакеты составляются схожим образом, как и в MRIM, только данные уже составляются через MessagePack. Там тоже есть версия протокола, команды и последовательность:‑)
Разбирать его было интересно. На удивление, это довольно простой протокол, в сравнении с тем же OSCAR: всего лишь два типа данных и минимальный набор команд для работы клиентов. Если вы смогли осилить MRIM, то и всё остальное будет даваться легко.
Некоторые решения меня, поражают до сих пор. Ясно было видно, что Агент пытался со старым протоколом идти в ногу со временем, и на некоторых командах была сотня костылей.
Если вдруг стало интересно, то вы можете зарегистрироваться на нашем сервере. Если хотите поднять его на локалке, то все исходники и инструкции выложены на GitHub, там же можно покопаться в протоколе. Вэлком!
