29 марта 2013 г.

Реверсим протокол онлайн игры.

Давно не писал статей, как то не было подходящих и интересных тем. Но тут я просматривал свой список TODO и в конце обнаружил, всю в пыли, заметку про то что было бы неплохо разобрать какойнить протокол онлайн игры.
Для чего, это вообще надо? Ну в основном иследование протокола игр используется для написания ботов, управлялок, кликеров, спамилок и трейдботов. Все перечисленное не одобряется администрацией онлайн игр, по этому если вас обнаружат, то скорей всего вы получите перманентный бан.
Поковырявшись пару дней, протокол был реверснут. Я не будут описывать все 100% команд которые используются в этой игре, ибо не вижу смысла, так как цель этой статьи рассказать, как и какими инструментами лучше всего реверсить протокол обмена между сервером и клиентом в онлайн играх.

Итак для начала, что будем иследовать? Я пошел на сайт со списокм онлайн игр(первый сайт который вывалил гугл). Список достаточно уныл там, но хоть такой. Из списка были выбраны 2 игры это Dofus от мегазла рунета mail.ru и Ragnarok Online неофициальный. Ибо на официальном используется богомерзкий Frost, с которым мне было разбираться откровенно лень. Обе игры весят в районе 1 гига и в принципе не сильно отличаются друг от друга по сложности протокола.

Из этого я выбрал Dofus за двухмерность и более простой протокол.
Какие инструменты нам понадобятся для исследования:
WPE Pro - программа для перехвата трафика. Работает следующем образом, инжектится в программу в которой надо перехватывать трафик, снимает данные, которые потом самое главное можно отправить повторно и посмотреть что получится. Качается с этого сайта. Детектится антивирусами как Hackers.Tools и блокируется, так что лучше ее добавить в белый список антивируса если не страшно заразить компьютер какойнить гадостью. :)
Notepad или для олдфагов листочек бумажки с ручкой - для записи и разбора отловленных пакетов.
Мозг - чтобы понять чтож содержится в пакете.

Итак, вооружившись всем этим регистрируемся на сайте, чтобы получить аккаунт для игры. Запускаем клиента Dofus и создаем персонажа пока не войдем в саму игру. Запускаем WPE Pro, в Target Program выбираем процесс который называется Dofus_Mod.exe.
Вее готово для сканирования.
Первым делом необходимо понять, шифруется ли пакет данных. Для этого можно попробовать сказать, что нибудь в общий чат и посмотреть, что будет в пакете.
Так и поступим.
Нажимаем в WPE Pro кнопку Start Logging и пишем что нибудь в чат.
Например слово vasya.

Нажимаем на кнопку Stop Logging в WPE Pro с права появится панель с отловленными пакетами следующего вида.


Видим наше слово "vasya" в открытом виде, значит протокол не шифруется и это хорошо не надо будет заморачиваться с расшифровкой.
Send - указывает на данные, что были отправлены на сервер.
Recv - это данные которые приняты с сервера.
Теперь более подробно про пакет который отправляет клиент на сервер.
Выглядит он следующим образом
0D - это идентификатор чата
75 - это идентификатор отправки данных
08 - это размер текста с ноль терминатором в конце
00 - не очень понятные данные, но изменение ничего не дает
05 - не очень понятные данные, но изменение ничего не дает
далее идет текст в 16чном виде и ноль терминатор в конце

Попробуем изменить и отправить его заново, посмотрим, что получится.
Поменяем vasya на petya.
Для этого нажимаем правой кнопкой на send пакете и выбираем Send, откроется окно отправки аналогичного пакета, где меняем слово vasya на petya выглядит это приблизительно так:

Нажимаем кнопочку Play как в магнитофонах и смотрим в игру.

Отлично, все работает и данные отправляются. Дальше заставим покрутиться нашего персонажа на месте. Делаем, все тоже самое что в предыдущих шагах.
И получаем следующие данные:

Тут я прокрутился 2 раза, чтобы лишний раз не запускать снифер.
И собственно я видел 2 Send и 2 Recv.
Сравнив их и посмотрев можно обнаружить следующее:
0E С5 - идентификатор поворота 
01 - насколько я понимаю это опять размер данных
01 - куда в текущий момент повернут персонаж, опытным методом установленно, что значение может принимать от 00 до 07, если подставить туда другие данные, то сервер отключает клиента.

Ну и последнее, для полного щастя, надо научиться ходить, для этого нам необходимо набрать статистику, двигаясь по клеткам.
Проделываем шаги для того чтобы начать захватывать пакеты и начинаем ходить в разные стороны, анализируя.
0E D9 0A 00 02 11 39 11 47 04 D8 00 02 - шаг вниз на 1 клетку
0E D9 0A 00 02 51 39 51 2A 04 D8 00 02 - шаг в верх на 1 клетку из начальной позиции
0E D9 0A 00 02 31 39 31 46 04 D8 00 02 - шаг в лево на 1 клетку из начальной позиции
0E D9 0A 00 02 71 39 71 2B 04 D8 00 02 - шаг в право на 1 клетку из начальной позиции
Теперь разбираем пакет 0E D9 0A 00 02 11 39 11 47 04 D8 00 02.
0E - это идентификатор ходьбы
D9 - это идентификатор, что пакет был отправлен от клиента серверу
0A - размер пакета данных, можно посчитать 10 байт
00 02 - неизвестные данные
11 - это насколько я понимаю направление движения, где первая цифра это направление в которую смотрит в текущий момент персонаж
39 - координата где в текущий момент находится персонаж
11 - это насколько я понимаю направление движения, где первая цифра это направление в которую будет смотреть персонаж после окончания движения
47 - координата куда прибудет персонаж.
04 D8 00 02 - неизвестные данные

С протоколом ходьбы на шаг разобрались, теперь надо попробовать походить подальше.
Сделаем 3 шага в одном направлении например и посмотрим как меняются данные.
0E D9 0A 00 02 11 39 11 47 04 D8 00 02 - первый шаг
0E D9 0A 00 02 11 47 11 56 04 D8 00 02 - второй шаг
0E D9 0A 00 02 11 56 11 64 04 D8 00 02 - третий шаг
Меня смутили координаты, 1 шаг разница между данными  
1 шаг: 47 - 39 = E
2 шаг: 56- 47 = F
3 шаг: 64 - 56 = E
Если половить пакеты дальше, то закономерность повторяется, тайный смысл в этом я пока не углядел, может быть знание откроется мне дальше, когда я буду писать управлялку персонажем.

Поэкспериментировав я пришел к выводу, что для ходьбы необходимо получить 2 значения, это исходня точка и конечная точка. Но одна проблема возникла, клиент во время работы совершенно не опрашивает сервер где в текущий момент находится персонаж. А эти данные нам необходимы для того чтобы узнать изначальную координату.
Что же делать... 
Сделаем предположение, что для отрисовки персонажа в клиенте при заходе в мир, клиент должен как то запросить эти данные от сервера. Попробуем зайти в игру с выбора персонажа после логина и отловим все пакеты в поисках комбинации 1 39 которая является координатой где сейчас находится персонаж.
И находим такой Recv пакет. В скрине я его выделил отдельно.
Выделено место в пакете, где указана позиция(01 39) персонажа. За ним идет цифра 03 - это в какую сторону повернут персонаж.
А Send пакет идущий перед Recv - это именно тот пакет который возбуждает сервер отдать пакет с  координатами. Если передвигать персонажа и посылать пакет Send который указан на скрине, то можно увидеть как меняется позиция в пакете пришедшем с сервера.

Итак, в текущий момент у нас есть данные, чтобы говорить в общий чат, ходить по карте и крутиться на месте в разные стороны. Теперь можно написать управлялку персонажа, а это уже будет основа на которой можно будет написать бота.
НО! Это будет в следующей статье(которая уже готовится), так, что ждите и да прибудет с вами дзен.

8 комментариев:

  1. А если пакеты зашифрованы как расшифровать?

    ОтветитьУдалить
  2. А тут уже нужен дебагер. Ставим брякпоинт на send и receive, ищем функцию кодирования/декодирования пакета. И тут варианта 2:
    1. Хучим эту функцию прямо в игре и отправляем свои данные используя код игры при помощи инжектов.(черевато попасть на какогонить гварда который будет чекать контрольную сумму)
    2. Грабим функцию кодирования/декодирования и пишем свой прокси/управлялку(безопасный, но гемморойный вариант).

    ОтветитьУдалить
  3. Было бы очень круто, если бы вы показали похожий пример с расшифровкой пакетов, важность такого гайда в 1000 раз больше)

    ОтветитьУдалить
  4. Во всем интернете не смог найти примера по расшифровке пакета за пару дней поиска, я уже думаю что это не возможно :D

    ОтветитьУдалить
    Ответы
    1. Попробуй поглядеть статью https://habrahabr.ru/post/212351/ Тут в принципе достаточно понятно описывается как понять какая функция шифрует трафик и как ее использовать.

      Удалить
    2. тяжеловато для человека, который не видел раньше OllyDbg, за 4 часа так и остался на том месте где ищется функция sendto
      [IMG]http://s1.radikale.ru/uploads/2017/3/13/18f621e65728cb87d17835b817b0411f-full.jpg[/IMG]
      есть вроде-как 3 функции(которые на WS начинаются), одна из которых мне нужна, наверное, выбираю например первую(методом тыка изучал программу, нажал на "Analyse code" так вроде легче читать)
      [IMG]http://s1.radikale.ru/uploads/2017/3/13/0f9a3ed2f8297867b415bfb08319ce70-full.jpg[/IMG]
      [IMG]http://s1.radikale.ru/uploads/2017/3/13/2620c8dcc1d6d0478cbfc9d97cae3f40-full.jpg[/IMG]
      [IMG]http://s1.radikale.ru/uploads/2017/3/13/c019e0e15ed020c4ba276f53b6ea8efc-full.jpg[/IMG]

      но ни одна из них не принимает аргументов как это было в гайде на хабре(сужу потому что есть в поле comments )

      установил пока брейкпоинт только на первом, и делаю какое-то действие в игре(нажимаю кнопку создать персонажа) пакеты идут те что мне надо (вылавливал эти пакеты с помощью WPE pro),
      но OllyDbg не остановился, значит это точно не та функция
      вторая функция остановилась один раз, когда я ничего не делал в игре, и не останавливался, когда я создавал перса. Значит тоже не та.
      На третей Olly не устанавливался, но в низу программы начало появляться какое-то сообщение
      [IMG]http://s1.radikale.ru/uploads/2017/3/14/ebf25e4540fea1753f11f493ed623f4b-full.jpg[/IMG]
      43 события в секунду

      думаю это столько раз он использовал эту функцию, наверно

      только что понял что я ставил не те брейкпоинты, в гайди написанно логирующие ставить, я ставил обычные "Memory..."

      теперь пытаюсь ставить логирующие брейкпоинты
      [IMG]http://s1.radikale.ru/uploads/2017/3/14/315f715e4e2595e5c818af4de8e1dde9-full.jpg[/IMG]
      видно что окно отличается от того что было в гайде, нету поля log fuction argument, следовательно функция не принимает параметров, чего, думаю, быть не может.
      и такое окно у всех функций трех функций, значит не они отвечают за передачу пакетов?

      Сразу хочу извинится за, возможно, бредовые мысли, просто сильно хочу разобраться что и как


      Удалить
    3. завтра буду дальше разбираться, может что-нибудь получиться

      Удалить