Version 5 of the ICQ Protocol Copyright ©1999 Henrik Isaksson Последняя модернизация 24 октября 1999 Содержание Об этом документе Пакеты Клиент - Сервер CMD_ACK (10) CMD_SEND_MESSAGE (270) CMD_LOGIN (1000) CMD_REG_NEW_USER (1020) CMD_CONTACT_LIST (1030) CMD_SEARCH_UIN (1050) CMD_SEARCH_USER (1060) CMD_KEEP_ALIVE (1070) CMD_SEND_TEXT_CODE (1080) CMD_ACK_MESSAGES (1090) CMD_LOGIN_1 (1100) CMD_MSG_TO_NEW_USER (1110) CMD_INFO_REQ (1120) CMD_EXT_INFO_REQ (1130) CMD_CHANGE_PW (1180) CMD_NEW_USER_INFO (1190) CMD_UPDATE_EXT_INFO (1200) CMD_QUERY_SERVERS (1210) CMD_QUERY_ADDONS (1220) CMD_STATUS_CHANGE (1240) CMD_NEW_USER_1 (1260) CMD_UPDATE_INFO (1290) CMD_AUTH_UPDATE (1300) CMD_KEEP_ALIVE2 (1310) CMD_LOGIN_2 (1320) CMD_ADD_TO_LIST (1340) CMD_RAND_SET (1380) CMD_RAND_SEARCH (1390) CMD_META_USER (1610) CMD_INVIS_LIST (1700) CMD_VIS_LIST (1710) CMD_UPDATE_LIST (1720) Пакеты Сервер - Клиент SRV_ACK (10) SRV_GO_AWAY (40) SRV_NEW_UIN (70) SRV_LOGIN_REPLY (90) SRV_BAD_PASS (100) SRV_USER_ONLINE (110) SRV_USER_OFFLINE (120) SRV_QUERY (130) SRV_USER_FOUND (140) SRV_END_OF_SEARCH (160) SRV_NEW_USER (180) SRV_UPDATE_EXT (200) SRV_RECV_MESSAGE (220) SRV_X2 (230) SRV_NOT_CONNECTED (240) SRV_TRY_AGAIN (250) SRV_SYS_DELIVERED_MESS (260) SRV_INFO_REPLY (280) SRV_EXT_INFO_REPLY (290) SRV_STATUS_UPDATE (420) SRV_SYSTEM_MESSAGE (450) SRV_UPDATE_SUCCESS (480) SRV_UPDATE_FAIL (490) SRV_AUTH_UPDATE (500) SRV_MULTI_PACKET (530) SRV_X1 (540) SRV_RAND_USER (590) SRV_META_USER (990) Расчет контрольной суммы Шифрование 1. Об этом документе Это - неофициальная спецификация, основанная на спецификации Magnus Ihses для версии 2 протокола ICQ, Mattew Smith's MICQ, описанием шифрования,сделанном Sebastien Dault, и на дискуссии по icq-devel в списке рассылки. Если Вы хотите прочесть документ по второй версии протокола ICQ или подписаться на рассылку, то воспользуйтесь следующим линком: http://www.student.nada.kth.se/~d95-mih/icq/ Все трэйдмарки, упомянутые в этом тексте, принадлежат его владельцу Номер соглашения 0x12345678 Число, записанное в десятично-шестнадцатеричной форме 78 56 34 12 Шестнадцатиричное значение (1234) Десятеричное значение 2. Пакеты Клиент - Сервер Пакеты Клиент - Сервер посылаются с использованием протокола UDP ICQ серверу.Каждый UDP-пакет начинается со следующего заголовка: Заголовок ICQ-пакета (со стороны Клиента) Длина Содержание (если установлено) Сигнатура Описание 2 байта 05 00 VERSION Версия протокола 4 байта 00 00 00 00 ZERO просто устанавливается в ноль, цель непонятна 4 байта xx xx xx xx UIN Ваш (клиентский) номер ICQ 4 байта xx xx xx xx SESSION_ID Используется, чтобы предотвратить spoofing - см. ниже 2 байта xx xx COMMAND 2 байта xx xx SEQ_NUM1 Стартовать со случайного числа 2 байта xx xx SEQ_NUM2 Стартовать с 1 4 байта xx xx xx xx CHECKCODE переменная xx ... PARAMETERS Параметры посылаемой команды Пакеты, посылаемые от клиента к серверу, зашифрованы до их посылки, в отличие от пакетов, посылаемых от сервера клиенту, которые не шифруются. Для более подробной информации относительно шифровки/расшифровывания смотрите Sebastien Dault's document. Session_ID - случайное число, выбранное, когда послан login-пакет, оно сохраняется до log out. Этот номер должен быть одним и тем же для каждого посланного вами пакета, иначе сервер проигнорирует их. Session_id (идентификатор сеанса) также будет послан вам назад сервером с каждым полученным вами пакетом - таким способом вы сможете определить, исходит ли пакет из сервера или же это "spoofed" пачка (сравнив идентификаторы полученного и посланного пакетов). Порядковые номера (sequence numbers) используются, чтобы удостовериться в том, что пакеты действительно достигают получателя, и приходят один раз. Когда вы посылаете пакет серверу, вы должны получить квитанцию (SRV_ACK) с сервера, если вы ее не получили, необходимо отправить пакет еще раз (метод квитирования). Если вы получаете два или более пакетов с тем же самым порядковым номером, вам следует проигнорировать все пакеты, кроме первого. Аналогично, сервер ожидает, что вы пошлете квитанцию после каждого полученного вами пакета с сервера, кроме SRV_ACK. См. SRV_ACK и CMD_ACK. SEQ_NUM1 устанавливает случайное число в login-пакете, и затем проставляет это число, каждый раз увеличенное на 1, в каждом последующем пакете (например если login-пакет имеет SEQ_NUM1=123, то следующий отосланный вами пакет имеет SEQ_NUM1=124). SEQ_NUM2 устанавливает в login-пакете число 1, и затем проставляет это число, каждый раз увеличенное на 1, в каждом последующем посылаемом вами пакете - но не для всех пакетов - например CMD_KEEP_ALIVE всегда должен содержать SEQ_NUM2=0 CMD_ACK 0A 00 (10) Эта команда посылается, чтобы подтвердить получение пакета, посланного вам с сервера. Длина Содержание Сигнатура Описание 4 байта xx xx xx xx RANDOM Случайное число Примечание! Порядковый номер в заголовке пакета содержит порядковый номер полученного с сервера пакета (квитанции) CMD_SEND_MESSAGE 0E 01 (270) Эта команда используется, чтоб послать сообщение пользователям, находящимся в off-line или в режиме Invisible. Параметры Длина Содержание Сигнатура Описание 4 байта xx xx xx xx RECIEVER_UIN номер аси пользователя, которому отсылается сообщение 2 байта см. ниже MESSAGE_TYPE тип сообщения 2 байта xx xx MESSAGE_LENGTH длина сообщения, включающего заключительный NULL-байт переменная xx...00 MESSAGE_TEXT текст сообщения, заканчивающийся NULL MESSAGE_TYPE может быть одним из следующих: Сигнатура Значение Описание MSG_TXT 01 00 Обычное текстовое сообщение MSG_URL 04 00 URL-сообщение, состоит из 2-х частей, разделенных 0xFE. Первая - описание URL MSG_AUTH_REQ 06 00 Запрос на добавление пользователя в контакт лист. Состоит из 5 частей, разделенных 0xFE - ник, имя, фамилия, эл.адрес, причина MSG_AUTH 08 00 Разрешение добавить пользователя в контакт лист MSG_USER_ADDED 0C 00 Сообщение о том, что пользователь был добавлен в контакт лист. Состоит из 4 частей, разделенных 0xFE - ник, имя, фамилия, эл.адрес MSG_CONTACTS 13 00 Послан Contact. Это сообщение состоит из нескольких ников и номеров ICQ, разделенных 0xFE. Первая часть сообщения - число контактов (пары nickname/UIN) в сообщении, записанное в ASCII-коде, завершается 0xFE CMD_LOGIN E8 03 (1000) Этот пакет используется для подключения (log) к серверу, которое должно быть выполнено до исполнения всех остальных команд, кроме тех, которые используются для регистрации нового пользователя. Параметры Длина Содержание Сигнатура Описание 4 байта xx xx xx xx TIME время (NULL), число секунд, начиная с 1января 1979 г. 4 байта xx xx xx xx PORT порт для TCP-соединения 2 байта xx xx PASS_LENGTH длина пароля, включающая NULL переменная xx...00 PASSWORD строка, содержащая пароль и заканчивающаяся NULL 4 байта xx xx xx xx X1 неизвестно, обычно d5 00 00 00 4 байта xx xx xx xx IP IP 1 байта xx X2 Обычно 0x04, 0x06 значит, что вы не вводите TCP-соединения 4 байта xx xx xx xx STATUS Статус, см. CMD_CHANGE_STATUS для описания 4 байта xx xx xx xx X3 неизвестно, обычно 06 00 00 00 4 байта xx xx xx xx X4 неизвестно, обычно 00 00 00 00 4 байта xx xx xx xx X5 неизвестно, обычно 08 00 00 00 4 байта xx xx xx xx X6 неизвестно, обычно 50 00 00 00 4 байта xx xx xx xx X7 неизвестно, обычно 03 00 00 00 4 байта xx xx xx xx X8 неизвестно, случайное ? Когда login-пакет приходит на сервер, предполагаем, что он корректен, вам будет отправлена квитанция-уведомление о получении (SRV_ACK) и login (SRV_LOGIN_REPLY). CMD_REG_NEW_USER FC 03 (1020) Эта команда посылается на сервер без предварительного log в него. UIN-поле заголовка пакета содержит NULL Сервер подтвердит этот пакет и ответит пакетом SRV_NEW_USER, который содежит ваш новый UIN, с которым вы должны немедленно залогиниться (послать CMD_LOGIN с вашим новым UIN и паролем). Когда вы успешно залогинитесь (SRV_LOGIN_REPLY), вы должны использовать команду CMD_NEW_USER_INFO для установки основной информации, такой как ваш ник например. Параметры Длина Содержание Сигнатура Описание 2 байта xx xx PASS_LENGTH длина пароля (максимум 9 символов) переменная xx...00 PASS пароль для вашего нового аккаунта 4 байта A0 00 00 00 UNKNOWN1 неизвестно 4 байта 61 24 00 00 UNKNOWN2 неизвестно 4 байта 00 00 A0 00 UNKNOWN3 неизвестно 4 байта 00 00 00 00 UNKNOWN4 неизвестно CMD_CONTACT_LIST 06 04 (1030) Эта команда используется для информирования сервера о пользователях, от которых вы хотите получить online/offline событие Параметры Длина Содержание Сигнатура Описание 1 байт xx NUM_CONTACTS количество UIN в этом пакете 4 байта xx xx xx xx UIN_1 1-й UIN в вашем контакт листе ... ... ... ... 4 байта xx xx xx xx UIN_n последний UIN в вашем контакт листе Примечание! Максимальное число пользователей - 120 из-за длины ICQ - пакета в 450 байт, если ваш контакт лист содержит большее число пользователей, вам следует отправить этот пакет несколько раз. CMD_SEARCH_UIN 1A 04 (1050) Параметры Длина Содержание Сигнатура Описание 2 байта xx xx SEARCH_SEQ см. инже 4 байта xx xx xx xx SEARCH_UIN искомый UIN CMD_SEARCH_USER 24 04 (1060) Поиск пользователя. Сервер отвечает SRV_USER_FOUND для каждого найденного пользователя и SRV_END_OF_SEARCH. Параметры Длина Содержание Сигнатура Описание 2 байта xx xx NICK_LENGTH длина ника (включая NULL) переменная xx...00 NICK Ник, заканчивающийся NULL 2 байта xx xx FIRST_LENGTH длина имени (включая NULL) переменная xx...00 FIRST Имя, заканчивающееся NULL 2 байта xx xx LAST_LENGTH длина фамилии (включая NULL) переменная xx...00 LAST Фамилия, заканчивающаяся NULL 2 байта xx xx EMAIL_LENGTH длина эл.адреса (включая NULL) переменная xx...00 EMAIL Эл. адрес, заканчивающийся NULL CMD_KEEP_ALIVE 2E 04 (1070) Эта команда должна посылаться серверу каждые 2 минуты. Если она не будет послана. то сервер примет, что вы находитесь off-line. Длина Содержание Сигнатура Описание 4 байта xx xx xx xx RANDOM Случайное число CMD_SEND_TEXT_CODE 38 04 (1080) Этот пакет используется для отправки серверу специальных команд как текста. Параметры Длина Содержание Сигнатура Описание 2 байта xx xx LENGTH длина текстовой команды, включая NULL-байт переменная xx.. TEXT_CODE текст кода, заканчивающаяся NULL 2 байта 05 00 X1 неизвестно, обычно 05 00 Возможные значения TEXT_CODE: TEXT_CODE Описание B_USER_DISCONNECTED Отсоединиться от сервера B_MESSAGE_ACK Сказать серверу ответить немедленно, используется, если у вас проблемы с подключением B_KEEPALIVE_ACK Неизвестно, возможно сходно с B_MESSAGE_ACK Примечание! При посылке этой команды поле SEQ_NUM2 заголовка пакета должно содержать ноль. CMD_ACK_MESSAGES 42 04 (1090) Удаляет с сервера старые сообщения. Обычно используется, когда получено SRV_X2 Длина Содержание Сигнатура Описание 4 байта xx xx xx xx RANDOM Случайное число CMD_LOGIN_1 4C 04 (1100) Во время логина посылается неизвестный пакет. Не появляется при использовании ICQ99. Длина Содержание Сигнатура Описание 4 байта xx xx xx xx RANDOM Случайное число CMD_MSG_TO_NEW_USER 56 04 (1110) CMD_INFO_REQ 60 04 (1120) Запрашивает основную информацию о пользователе. Длина Содержание Сигнатура Описание 4 байта xx xx xx xx UIN UIN пользователя, чье инфо вы запрашиваете Сервер ответит SRV_INFO_REPLY CMD_EXT_INFO_REQ 6A 04 (1130) Запрашивает расширенную информацию о пользователе. Длина Содержание Сигнатура Описание 4 байта xx xx xx xx UIN UIN пользователя, чье инфо вы запрашиваете Сервер ответит SRV_EXT_INFO_REPLY CMD_CHANGE_PW 9C 04 (1180) Сменить пароль входа. Эта команда устаревает. Используйте вместо нее CMD_META_USER CMD_NEW_USER_INFO A6 04 (1190) Отсылает основную информацию о новом зарегистрированном пользователе. Эта команда отсылается, когда вы залогинились в первый раз под своим новым UIN. Смотри CMD_REG_NEW_USER. Параметры Длина Содержание Сигнатура Описание 2 байта xx xx NICK_LENGTH длина ника (включая NULL) переменная xx...00 NICK Ник, заканчивающийся NULL 2 байта xx xx FIRST_LENGTH длина имени (включая NULL) переменная xx...00 FIRST Имя, заканчивающееся NULL 2 байта xx xx LAST_LENGTH длина фамилии (включая NULL) переменная xx...00 LAST Фамилия, заканчивающаяся NULL 2 байта xx xx EMAIL_LENGTH длина эл.адреса (включая NULL) переменная xx...00 EMAIL Эл. адрес, заканчивающийся NULL 1 байт 01 UNKNOWN1 Неизвестно 1 байт 01 UNKNOWN2 Неизвестно 1 байт 01 UNKNOWN3 Неизвестно CMD_UPDATE_EXT_INFO B0 04 (1200) CMD_QUERY_SERVERS BA 04 (1210) Запрашивает сервер об адресах других серверов CMD_QUERY_ADDONS С4 04 (1220) Запрашивает сервер об глобально-определенных компонентах CMD_STATUS_CHANGE D8 04 (1240) Изменяет online статус пользователя (Away, Invisible и др.) Параметры Длина Содержание Сигнатура Описание 4 байта xx xx xx xx STATUS Новый статус - см.ниже Статусы Сигнатура Значение Описание STATUS_ONLINE 00 00 00 00 User is online STATUS_AWAY 01 00 00 00 User is away STATUS_DND 13 00 00 00 Do Not Disturb STATUS_INVISIBLE 00 01 00 00 User is invisible STATUS_OCCUPIED 10 00 00 00 Occupied STATUS_NA 04 00 00 00 Not Available STATUS_CHAT 20 00 00 00 Free for chat STATUS_DND и STATUS_NA могут быть объединены со STATUS_AWAY в зависимости от того, какую версию ICQ вы используете. CMD_NEW_USER_1 EC 04 (1260) Запрашивает разрешение на добавление нового пользователя. CMD_UPDATE_INFO 02 05 (1290) Обновляет ваше Info на серверах базы данных пользователей ICQ Параметры Длина Содержание Сигнатура Описание 2 байта xx xx NICK_LENGTH длина ника (включая NULL) переменная xx...00 NICK Ник, заканчивающийся NULL 2 байта xx xx FIRST_LENGTH длина имени (включая NULL) переменная xx...00 FIRST Имя, заканчивающееся NULL 2 байта xx xx LAST_LENGTH длина фамилии (включая NULL) переменная xx...00 LAST Фамилия, заканчивающаяся NULL 2 байта xx xx EMAIL_LENGTH длина эл.адреса (включая NULL) переменная xx...00 EMAIL Эл. адрес, заканчивающийся NULL CMD_AUTH_UPDATE 14 05 (1300) Обновляет ваш статус авторизации (т.е. позволяете ли вы пользователям добавить вас в их контакт лист?) Параметры Длина Содержание Сигнатура Описание 4 байта xx xx xx xx AUTHORIZE TRUE - авторизация не запрашивается, FALSE - запрашивается CMD_KEEP_ALIVE2 1E 05 (1310) В ранних версиях эта команда посылалась серверу наряду с командой CMD_KEEP_ALIVE. В ICQ99b уже не используется. Длина Содержание Сигнатура Описание 4 байта xx xx xx xx RANDOM Случайное число CMD_LOGIN_2 28 05 (1320) В ранних версиях эта команда использовалась во время логина. CMD_ADD_TO_LIST 3C 05 (1340) Добавить пользователя в контакт лист. После использования этой команды вы получите данные о статусе пользователя в дополнение к тем, что уже находятся в вашем контакт листе. Длина Содержание Сигнатура Описание 4 байта xx xx xx xx UIN UIN пользователя, которого вы хотите добавить в свой контакт лист CMD_RAND_SET 64 05 (1380) Определяет, в какой группе вы хотите быть объявленным для Random Chat Длина Содержание Сигнатура Описание 4 байта xx xx xx xx RAND_GROUP См. CMD_RAND_SEARCH CMD_RAND_SEARCH 6E 05 (1390) Поиск случайного пользователя Длина Содержание Сигнатура Описание 4 байта xx xx xx xx RAND_GROUP См. ниже RAND_GROUP должно иметь одно из следующих значений: Name Value General 1 Romance 2 Games 3 Students 4 20 something 6 30 something 7 40 something 8 50+ 9 Man chat requesting women 10 Woman chat requesting men 11 CMD_META_USER 4A 06 (1610) CMD_INVIS_LIST A4 06 (1700) Эта команда информирует сервер о тех пользователях, которых вы занесли в Invisible список, даже если вы не находитесь в статусе Invisible Параметры Длина Содержание Сигнатура Описание 1 байт xx NUM_USERS количество UIN в этом пакете 4 байта xx xx xx xx UIN_1 1-й UIN в вашем контакт листе ... ... ... ... 4 байта xx xx xx xx UIN_n последний UIN в вашем контакт листе Примечание! Максимальное число пользователей - 120 из-за длины ICQ - пакета в 450 байт, если ваш контакт лист содержит большее число пользователей, вам следует отправить этот пакет несколько раз. CMD_VIS_LIST AE 06 (1710) Эта команда информирует сервер о тех пользователях, которых вы занесли в Visible список, находясь в режиме Invisible Параметры Длина Содержание Сигнатура Описание 1 байт xx NUM_USERS количество UIN в этом пакете 4 байта xx xx xx xx UIN_1 1-й UIN в вашем контакт листе ... ... ... ... 4 байта xx xx xx xx UIN_n последний UIN в вашем контакт листе Примечание! Максимальное число пользователей - 120 из-за длины ICQ - пакета в 450 байт, если ваш контакт лист содержит большее число пользователей, вам следует отправить этот пакет несколько раз. CMD_UPDATE_LIST B8 06 (1720) Эта команда информирует сервер об изменениях в ваших Invisible/Visible списках Параметры Длина Содержание Сигнатура Описание 4 байта xx xx xx xx UIN UIN добавленного или удаленного из списка пользователя 1 байт xx LIST Список до изменения, 01-Invisible, 02-Visible 1 байт xx REMADD 00 - пользователь удален, 01- пользователь добавлен в список 3. Пакеты Сервер - Клиент Каждый сервер-клиентский UDP-пакет имеет следующий заголовок: Заголовок ICQ-пакета (со стороны Сервера) Длина Содержание (если установлено) Сигнатура Описание 2 байта 05 00 VERSION Версия протокола 1 байт 00 ZERO неизвестно 4 байта xx xx xx xx SESSION_ID Такое же как в вашем login-пакете 2 байта xx xx COMMAND 2 байта xx xx SEQ_NUM1 Последовательность 1 2 байта xx xx SEQ_NUM2 Последовательность 2 4 байта xx xx xx xx UIN Ваш (клиентский) номер ICQ 4 байта xx xx xx xx CHECKCODE переменная xx ... PARAMETERS Параметры посылаемой команды Эти пакеты всегда не шифрованы. Для подробного описания полей см. раздел Клиент-сервер SRV_ACK 0A 00 (10) Квитанция на команду, посланную серверу. Пока эта квитанция не получена, вы должна продолжать посылать на сервер свою команду, с приемлемой задержкой. Клиент Mirabilis посылает команду 6 раз с задержкой в 10 секунд. Затем посылается CMD_SEND_TEXT_CODE с B_MESSAGE_ACK. Параметров нет. Порядковые номера в заголовке содержат порядковые номера клиентский подтвержденных пакетов. SRV_GO_AWAY 28 00 (40) Сообщение от сервера об ошибке. Вам следует дисконнектиться и повторить попытку подключения к серверу. Параметров нет. SRV_NEW_UIN 46 00 (70) Новый UIN, запрошенный CMD_REG_NEW_USER, был сохранен для вас. UIN - это поле UIN в заголовке. После получения вы должны законнектиться к серверу, используя новый UIN для завершения регистрации (нормальная процедура входа). Параметров нет. SRV_LOGIN_REPLY 5A 00 (90) Этот пакет отсылается сервером в случае, если он корректно получил команду CMD_LOGIN. Параметры Длина Содержание Сигнатура Описание 4 байта 8C 00 00 00 X1 неизвестно (dec: 140) 2 байта F0 00 X2 неизвестно (dec: 240) 2 байта 0A 00 X3 неизвестно (dec: 10) 2 байта 0A 00 X4 неизвестно (dec: 10) 2 байта 05 00 X5 неизвестно (dec: 5, версия?) 4 байта xx xx xx xx IP Ваш IP 4 байта xx xx xx xx X6 неизвестно SRV_BAD_PASS 64 00 (100) Пароль в login-пакете был неверный. Если вы уверены в его правильности, проверьте длину пароля и удостоверьтесь, что он заканчивается NULL. Параметров нет. SRV_USER_ONLINE 6E 00 (110) Пользователь из вашего контакт листа сменил свой статус так, что теперь вы можете его видеть (т.е. он сменил свой статус Invisible или offline на любой другой) Параметры Длина Содержание Сигнатура Описание 4 байта xx xx xx xx UIN UIN пользователя, сменившего статус 4 байта xx xx xx xx IP IP-адрес пользователя 4 байта xx xx xx xx PORT порт, используемый пользователем для соединения 4 байта xx xx xx xx REAL_IP реальный IP-адрес пользователя 1 байт xx X1 неизвестно, обычно 04 4 байта xx xx xx xx STATUS Новый статус пользователя, см. CMD_STATUS_CHANGE 4 байта xx xx xx xx X2 неизвестно 4 байта xx xx xx xx X3 неизвестно 4 байта xx xx xx xx X4 неизвестно 4 байта xx xx xx xx X5 неизвестно 4 байта xx xx xx xx X6 неизвестно 4 байта xx xx xx xx X7 неизвестно SRV_USER_OFFLINE 78 00 (120) Пользователь из вашего контакт листа ушел в офф-лайн Длина Содержание Сигнатура Описание 4 байта xx xx xx xx UIN UIN пользователя, ушедшего в офф-лайн SRV_QUERY 82 00 (130) Ответ на CMD_QUERY_SERVES и CMD_QUERY_ADDONS. SRV_USER_FOUND 8C 00 (140) Пользователь, соответствующий критериям выбора в ранее посланной команде CMD_SEARCH_USER или CMD_SEARCH_UIN, найден. Если было найдено несколько пользователей, вы получите пакет для каждого из них. Параметры Длина Содержание Сигнатура Описание 4 байта xx xx xx xx UIN UIN найденного пользователя 2 байта xx xx NICK_LENGTH длина ника (включая NULL) переменная xx...00 NICK Ник, заканчивающийся NULL 2 байта xx xx FIRST_LENGTH длина имени (включая NULL) переменная xx...00 FIRST Имя, заканчивающееся NULL 2 байта xx xx LAST_LENGTH длина фамилии (включая NULL) переменная xx...00 LAST Фамилия, заканчивающаяся NULL 2 байта xx xx EMAIL_LENGTH длина эл.адреса (включая NULL) переменная xx...00 EMAIL Эл. адрес, заканчивающийся NULL 1 байт xx AUTHORIZE Статус автороизации пользователя, см. ниже AUTHORIZE может содержать только 00 или 01. 00 значит, что клиенту нужно послать запрос об авторизации, перед тем, как добавить пользователя в контакт лист, 01 - посылать запрос не надо. SRV_END_OF_SEARCH A0 00 (160) Пользователь не найден или найдено слишком много пользователей. Длина Содержание Сигнатура Описание 1 байт xx TOO_MANY Было найдено слишком много пользователей Если TOO_MANY равно 00, то вы получите всех подходящих пользователей из базы данных. Если 01, то в базе данных очень много пользователей, удовлетворяющих критериям поиска, но они вам посланы не будут. Предел - 40 пользователей. SRV_RECV_MESSAGE DC 00 (220) Этот пакет шлется вам во время вашего логина на сервер, если на сервере есть для вас какие-либо пакеты (так называемые "оффлайн-сообщения") Длина Содержание Сигнатура Описание 4 байта xx xx xx xx UIN UIN отправителя 2 байта xx xx YEAR год, когда было послано сообщение 1 байт xx MONTH месяц, когда было послано сообщение 1 байт xx DAY день месяца 1 байт xx HOUR час, когда было послано сообщение 1 байт xx MINUTE минута 2 байта xx xx MESSAGE_TYPE тип сообщения, см. ниже 2 байта xx xx MESSAGE_LENGTH длина сообщения (включая NULL) переменная xx...00 MESSAGE_TEXT текст сообщения MESSAGE_TYPE может иметь одно из следующих значений: Сигнатура Значение Описание MSG_TXT 01 00 Обычное текстовое сообщение MSG_URL 04 00 URL-сообщение, состоит из 2-х частей, разделенных 0xFE. Первая - описание URL MSG_AUTH_REQ 06 00 Запрос на добавление пользователя в контакт лист. Состоит из 5 частей, разделенных 0xFE - ник, имя, фамилия, эл.адрес, причина MSG_AUTH 08 00 Разрешение добавить пользователя в контакт лист MSG_USER_ADDED 0C 00 Сообщение о том, что пользователь был добавлен в контакт лист. Состоит из 4 частей, разделенных 0xFE - ник, имя, фамилия, эл.адрес MSG_CONTACTS 13 00 Послан Contact. Это сообщение состоит из нескольких ников и номеров ICQ, разделенных 0xFE. Первая часть сообщения - число контактов (пары nickname/UIN) в сообщении, записанное в ASCII-коде, завершается 0xFE Образец URL-сообщения: 0000: 78 56 34 12 CF 07 04 0E 0D 07 04 00 16 00 4D 69 xV4...........Mi 0010: 72 61 62 69 6C 69 73 FE 77 77 77 2E 69 63 71 2E rabilis.www.icq.com 0020: 63 6F 6D 00 Цветной текст - это MESSAGE_TEXT. Зеленые номера показывают описание URL ('Mirabilis'). Синие номера показывают непосредственно сам URL. Красный байт разделяет эти две строки, и заключительный желтый байт (00) - NULL - окончание Часть сообщения, написанная черным цветом, содержит следующие сведения: UIN: 0x12345678 Date: 1999-04-14 Time: 13:07 Type: MSG_URL Length: 22 bytes SRV_UPDATE_SUCCESS E0 01 (480) Команда CMD_UPDATE_INFO по изменению вашего info была успешно выполнена SRV_UPDATE_FAIL E0 01 (480) Команда CMD_UPDATE_INFO по изменению вашего info не была выполнена SRV_MULTI_PACKET 12 02 (530) Одновременно послано несколько пакетов. Сервер использует этот пакет всегда, когда послан более, чем один пакет. Параметры Длина Содержание Сигнатура Описание 1 байт xx NUM_PACKETS кол-во пакетов 2 байта xx xx SIZE_1 размер первого пакета переменная 05...00... PKT_1 1-й пакет 2 байта xx xx SIZE_2 размер второго пакета переменная 05...00... PKT_2 2-й пакет ... ... ... ... 2 байта xx xx SIZE_n размер n-го пакета переменная 05...00... PKT_n n-й пакет Поля CHECK всех входящих пакетов все установлены в NULL. Квитирование должно быть выполнено только к SRV_MULTI, а не ко всем инкапсулированным пакетам. SRV_META_USER DE 03 (990) Ответ на CMD_META_USER. Параметры Длина Содержание Сигнатура Описание 2 байта xx xx SUBCMD Подкоманда, см. ниже 1 байт xx RESULT Результат выполнения функции - удачное или неудачное завершение, см. ниже переменная xx... DATA Запрашиваемые вами данные, см. ниже RESULT : 0x0A - удачное завершение, 0x32 - неудачное SUBCMD и DATA META_USER_FOUND - 9A 01 (xx) DATA для подкоманды META_USER_FOUND Длина Содержание Сигнатура Описание 4 байта xx xx xx xx UIN UIN найденного пользователя 2 байта xx xx NICK_LENGTH длина ника (включая NULL) переменная xx...00 NICK Ник, заканчивающийся NULL 2 байта xx xx FIRST_LENGTH длина имени (включая NULL) переменная xx...00 FIRST Имя, заканчивающееся NULL 2 байта xx xx LAST_LENGTH длина фамилии (включая NULL) переменная xx...00 LAST Фамилия, заканчивающаяся NULL 2 байта xx xx EMAIL_LENGTH длина эл.адреса (включая NULL) переменная xx...00 EMAIL Эл. адрес, заканчивающийся NULL 1 байт xx AUTHORIZE Статус автороизации пользователя, см. ниже 2 байта xx xx X2 неизвестно 4 байта xx xx xx xx X3 неизвестно AUTHORIZE может содержать только 0x00 или 0x01. 0x00 значит, что клиенту нужно послать запрос об авторизации, перед тем, как добавить пользователя в контакт лист, 0x01 - посылать запрос не надо. META_ABOUT - E6 00 (xx) DATA для подкоманды META_ABOUT Длина Содержание Сигнатура Описание 2 байта xx xx ABOUT_LENGTH длина строки переменная xx ...00 ABOUT строка META_USER_INFO - C8 00 (xx) DATA для подкоманды META_USER_INFO Длина Содержание Сигнатура Описание 4 байта xx xx xx xx UIN UIN пользователя 2 байта xx xx NICK_LENGTH длина ника переменная xx...00 NICK Ник 2 байта xx xx FIRST_LENGTH длина имени переменная xx...00 FIRST Имя 2 байта xx xx LAST_LENGTH длина фамилии переменная xx...00 LAST Фамилия 2 байта xx xx PRIMARY_LENGTH длина эл.адреса переменная xx...00 PRIMARY_EMAIL Эл. адрес 2 байта xx xx SECONDARY_LENGTH длина второго эл.адреса переменная xx...00 SECONDARY_EMAIL Второй эл.адрес 2 байта xx xx OLD_LENGTH длина старого эл.адреса переменная xx...00 OLD_EMAIL старый эл.адрес 2 байта xx xx CITY_LENGTH длина названия города переменная xx...00 CITY город 2 байта xx xx STATE_LENGTH длина названия штата переменная xx...00 STATE штат 2 байта xx xx PHONE_LENGTH длина номера телефона переменная xx...00 PHONE номер телефона 2 байта xx xx FAX_LENGTH длина номера факса переменная xx...00 FAX номер факса 2 байта xx xx STREET_LENGTH длина названия улицы переменная xx...00 STREET название улицы 2 байта xx xx CELL_LENGTH длина номера сотового телефона переменная xx...00 CELLULAR номер сотового телефона 4 байта xx xx xx xx ZIPCODE Zip код 2 байта xx xx COUNTRY Страна 1 байт xx TIMEZONE Часовой пояс 1 байт xx AUTHORIZE Нужен ли запрос на авторизацию (0x00 - нужен, 0x01 - нет) 1 байт xx WEBAWARE Статус пользователя в Web 1 байт xx HIDEIP Не показывать IP пользователя 4. Расчет контрольной суммы Контрольная сумма вычисляется до шифрования пакета. Вычисление NUMBER1 B8 = байт в позиции 8 пакета. (начиная с позиции 0) B4 = байт в позиции 4 пакета. B2 = байт в позиции 2 пакета. B6 = байт в позиции 6 пакета Соединяем эти части вместе и получаем NUMBER1: NUMBER1 = 0x B8 B4 B2 B6 (B8 = MSB, B6 = LSB) Вот фрагмент кода на С: unsigned long number1; number1 = packet[8]; number1 <<= 8; number1 |= packet[4]; number1 <<= 8; number1 |= packet[2]; number1 <<= 8; number1 |= packet[6]; Следующее вычисление PL - длина пакета R1 - случайное число между 0x18 и PL R2 - другое случайное число между 0 и 0xFF C-код: int r1, r2; r1 = 0x18 + rand() % (PL - 0x18); r2 = rand() % 0xFF; Вычисление NUMBER2 X4=R1 X3=NOT(байт в позиции X4 в пакете) X2=R2 X1=NOT(байт в позиции X2 в ТАБЛИЦЕ) (см. секцию ТАБЛИЦЫ) NUMBER2 = 0x X4 X3 X2 X1 (X4 = MSB, X1 = LSB) Пример C-кода: unsigned long number2; number2 = r1; number2 <<= 8; number2 |= packet[r1]; number2 <<= 8; number2 |= r2; number2 <<= 8; number2 |= table[r2]; number2 ^= 0xff00ff; Сейчас вы можете подсчитать контрольную сумму:CHECKCODE = NUMBER1 XOR NUMBER2 C-код: unsigned long cc = number1 ^ number2ТАБЛИЦА Алгоритм использует данную таблицу констант. TABLE[x] означает число в позиции X таблицы (начиная с позиции 0) POS DATA ASCII --- ----------------------------------------------- ---------------- 00 - 59 60 37 6B 65 62 46 48 53 61 4C 59 60 57 5B 3D Y`7kebFHSaLY`W[= 10 - 5E 34 6D 36 50 3F 6F 67 53 61 4C 59 40 47 63 39 ^4m6P?ogSaLY@Gc9 20 - 50 5F 5F 3F 6F 47 43 69 48 33 31 64 35 5A 4A 42 P__?oGCiH31d5ZJB 30 - 56 40 67 53 41 07 6C 49 58 3B 4D 46 68 43 69 48 V@gSA.lIX;MFhCiH 40 - 33 31 44 65 62 46 48 53 41 07 6C 69 48 33 51 54 31DebFHSA.liH3QT 50 - 5D 4E 6C 49 38 4B 55 4A 62 46 48 33 51 34 6D 36 ]NlI8KUJbFH3Q4m6 60 - 50 5F 5F 5F 3F 6F 47 63 59 40 67 33 31 64 35 5A P___?oGcY@g31d5Z 70 - 6A 52 6E 3C 51 34 6D 36 50 5F 5F 3F 4F 37 4B 35 jRn.Q4m6P__?O7K5 80 - 5A 4A 62 66 58 3B 4D 66 58 5B 5D 4E 6C 49 58 3B ZJbfX;MfX[]NlIX; 90 - 4D 66 58 3B 4D 46 48 53 61 4C 59 40 67 33 31 64 MfX;MFHSaLY@g31d A0 - 55 6A 32 3E 44 45 52 6E 3C 31 64 55 6A 52 4E 6C Uj2.DERn.1dUjRNl B0 - 69 48 53 61 4C 39 30 6F 47 63 59 60 57 5B 3D 3E iHSaL90oGcY`W[=. C0 - 64 35 3A 3A 5A 6A 52 4E 6C 69 48 53 61 6C 49 58 d5::ZjRNliHSalIX D0 - 3B 4D 46 68 63 39 50 5F 5F 3F 6F 67 53 41 25 41 ;MFhc9P__?ogSA%A E0 - 3C 51 54 3D 5E 54 5D 4E 4C 39 50 5F 5F 5F 3F 6F .QT=^T]NL9P___?o F0 - 47 43 69 48 33 51 54 5D 6E 3C 31 64 35 5A 00 00 GCiH3QT]n.1d5Z.. --- ----------------------------------------------- ---------------- The Table in C static const BYTE table[] = { 0x59, 0x60, 0x37, 0x6B, 0x65, 0x62, 0x46, 0x48, 0x53, 0x61, 0x4C, 0x59, 0x60, 0x57, 0x5B, 0x3D, 0x5E, 0x34, 0x6D, 0x36, 0x50, 0x3F, 0x6F, 0x67, 0x53, 0x61, 0x4C, 0x59, 0x40, 0x47, 0x63, 0x39, 0x50, 0x5F, 0x5F, 0x3F, 0x6F, 0x47, 0x43, 0x69, 0x48, 0x33, 0x31, 0x64, 0x35, 0x5A, 0x4A, 0x42, 0x56, 0x40, 0x67, 0x53, 0x41, 0x07, 0x6C, 0x49, 0x58, 0x3B, 0x4D, 0x46, 0x68, 0x43, 0x69, 0x48, 0x33, 0x31, 0x44, 0x65, 0x62, 0x46, 0x48, 0x53, 0x41, 0x07, 0x6C, 0x69, 0x48, 0x33, 0x51, 0x54, 0x5D, 0x4E, 0x6C, 0x49, 0x38, 0x4B, 0x55, 0x4A, 0x62, 0x46, 0x48, 0x33, 0x51, 0x34, 0x6D, 0x36, 0x50, 0x5F, 0x5F, 0x5F, 0x3F, 0x6F, 0x47, 0x63, 0x59, 0x40, 0x67, 0x33, 0x31, 0x64, 0x35, 0x5A, 0x6A, 0x52, 0x6E, 0x3C, 0x51, 0x34, 0x6D, 0x36, 0x50, 0x5F, 0x5F, 0x3F, 0x4F, 0x37, 0x4B, 0x35, 0x5A, 0x4A, 0x62, 0x66, 0x58, 0x3B, 0x4D, 0x66, 0x58, 0x5B, 0x5D, 0x4E, 0x6C, 0x49, 0x58, 0x3B, 0x4D, 0x66, 0x58, 0x3B, 0x4D, 0x46, 0x48, 0x53, 0x61, 0x4C, 0x59, 0x40, 0x67, 0x33, 0x31, 0x64, 0x55, 0x6A, 0x32, 0x3E, 0x44, 0x45, 0x52, 0x6E, 0x3C, 0x31, 0x64, 0x55, 0x6A, 0x52, 0x4E, 0x6C, 0x69, 0x48, 0x53, 0x61, 0x4C, 0x39, 0x30, 0x6F, 0x47, 0x63, 0x59, 0x60, 0x57, 0x5B, 0x3D, 0x3E, 0x64, 0x35, 0x3A, 0x3A, 0x5A, 0x6A, 0x52, 0x4E, 0x6C, 0x69, 0x48, 0x53, 0x61, 0x6C, 0x49, 0x58, 0x3B, 0x4D, 0x46, 0x68, 0x63, 0x39, 0x50, 0x5F, 0x5F, 0x3F, 0x6F, 0x67, 0x53, 0x41, 0x25, 0x41, 0x3C, 0x51, 0x54, 0x3D, 0x5E, 0x54, 0x5D, 0x4E, 0x4C, 0x39, 0x50, 0x5F, 0x5F, 0x5F, 0x3F, 0x6F, 0x47, 0x43, 0x69, 0x48, 0x33, 0x51, 0x54, 0x5D, 0x6E, 0x3C, 0x31, 0x64, 0x35, 0x5A, 0x00, 0x00, };5. Шифрование Выполните следующие действия: Подсчитайте контрольную сумму (см. главу 4) Установите PL=длина пакета Вычислите код шифрования: CODE = (LONG) (PL * 0x68656C6C) + CHECKCODE (округлите) Для каждой записи типа longword (32 бита) в структуре, начинающейся с адреса 0x0A, выполняется операция XOR для значения предварительно вычисленной суммы CODE и байта в соответствующей позиции таблицы. (Например для записи (longword) по адресу 0x0A должно быть вычислено значение операции исключающего ИЛИ с значением по адресу 0x0A в таблице сложенным с CODE.) Итак, пакет зашифрован. Теперь надо поместить контрольную сумму в пакет, так чтобы сервер смог расшифровать его. /* Encrypting the packet. Assuming that checkcode has been calculated as previously described, and that pl = packet length. The packet to encrypt is pointed to by pkpptr. */ code = pl * 0x68656c6c + checkcode; for(pos=0xa;pos < (pl + 3);pos+=4) { pktptr[pos]^ = code + table[pos & 0xFF]; } /* Scrambling the checkcode. Assuming that cc holds the checkcode. */ ULONG a[6]; a[1] = cc & 0x0000001F; a[2] = cc & 0x03E003E0; a[3] = cc & 0xF8000400; a[4] = cc & 0x0000F800; a[5] = cc & 0x041F0000; a[1] <<= 0x0C; a[2] <<= 0x01; a[3] >>= 0x0A; a[4] <<= 0x10; a[5] >>= 0x0F; checkcodetoinsert = a[1] + a[2] + a[3] + a[4] + a[5];