[Перевод] Обратная разработка первоапрельской «Змейки» от Google

6528f8687ec814cb2ae33bfc63f46f97.jpg

Возможно, кто-то из вас заметил, что Google на 1 апреля добавила в приложение Google Maps для Android и iOS интерактивную игру «Змейка».

Специалисты Check Point обычно заняты исследованием последних киберугроз, но здесь очень увлеклись этой игрой, правда, сильно расстраивались из-за проигрышей… поэтому возникла логичная мысль: почему бы её не взломать!
Таким образом, наши самые озорные сотрудники начали думать над обратной разработкой приложения с помощью удалённой отладки. В общем, у них получилось, и вскоре мы успешно выполнили задачу никогда не проигрывать — и даже добавили простой ИИ, который сам играет в игру.

b62c71fc418fcb097b52c4245eeb4d6c.jpg
865187d2b602ab168bdfafd147e64598.png

В этой заметке подробно опишем хак.

Сначала мы открыли приложение на виртуальном устройстве через Genymotion и запустили «Змейку», которая находится в меню в правом верхнем углу.

Похоже, что игра отображается в WebView, поэтому мы запустили удалённую отладку в инструментах разработчика Chrome:

51335db2aeb6fec60fce9f3b15ad8dc5.png

Затем перешли на сайт и нашли на вкладке с исходниками файл v18.js, а в нём несколько интересных функций.

Во-первых, функция fa () инициирует поле размером 20×20:

this.height = this.width = 20;


Наша главная цель — найти и изменить функцию, которая определяет, когда змейка врезается в стену или в себя, чтобы отключить возможность проигрыша. Переменные width и height представляют размеры игрового поля, поэтому мы поискали width и height внутри исходного кода и нашли функцию F (a, b):

7db8754aa46203e12e8cc609cd7c106e.png

Похоже, F (a, b) проверяет, находятся ли координаты тела змеи в пределах поля. Один из вариантов — полностью удалить условия в функции, чтобы она всегда возвращала истину, тем самым переводя нас в «режим Бога», где мы можем проходить сквозь стены, не умирая.

Для этого мы нажали кнопку Inspect в удалённой консоли и изменили функцию F (a, b) на следующую:

21e14d452d2b31afdec5ca293cc2eb86.png

Теперь мы можем проходить сквозь стены:

5e17c827d93c1e9dffbc3e73c9be1998.png


Рис. 1. Режим Бога

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

В стеке вызовов много вызовов функции wa (a). Если изучить эту функцию, то мы увидим, что она рекурсивна и отвечает за запрос кадров анимации. wa (a) вызывает функции xa (a, b) и ya (a), которые отображают игровые фигуры (поезд, люди) и поле, соответственно.

Рассмотрим функцию xa (a, b):

bd052498424b070f1927505e064bb65c.png

Она принимает два аргумента: 'a' и 'b'. Первый является частью глобальной переменной Q, которая содержит интересную информацию о нашей игре, включая массив, который представляет собой игровое поле (рис. 2), где мы видим поезд (М), людей и объекты (K). Функция также вычисляет счёт и сохраняет его в c.i, что также эквивалентно Q.b.

3426db7294084bde0b602e57ac0a9b71.png


Рис. 2. Массив игрового поля

Данный массив соответствует такому полю:

70a08f84e4494a9b822c72b3d33ebc2e.png


Рис. 3. Игровое поле

xa (a) также обращается к функции sa (a) на рис. 4, которая генерирует случайные координаты при каждом создании нового человека. Если вызывать функцию более одного раза, то можно создать сколько угодно людей (рис. 5).

18238f358816860cf2de195f0428b335.png


Рис. 4. Вызов функции sa (a)

Как здесь:

c8fc01d3b7c183913a11a30183772a47.png


Рис. 5. Вызов функции с созданием любого количества людей на карте

Обратите внимание, что даже если вызывать sa (a) более одного раза и забирать человека, счёт не меняется. При подборе пассажира вызывается функция ka (a, b) на рис. 6. Таким образом, её нужно изменить, чтобы при каждом вызове она добавляла 10 очков и обновляла счёт на экране.

e9609115944b21a2e324b99c46d9c094.png


Рис. 6. Обновлённая функция

Координаты каждой части поезда указаны в Q.b.o.b, где первый элемент представляет собой первый вагончик в поезде.

4e6d8e0ea5fc7dc12186a5a27ee63f08.png


Рис. 7. Массив вагончиков

Это понадобится для создания простого ИИ. Начнём с его логики:

d25e30214681ad9d0469982f9a596830.jpg


Рис. 8. Логика ИИ

Змейка представляет собой машину состояний (конечный автомат):

  1. На X=19 идём вниз, пока не доберёмся до Y=19.
  2. На X=19 и Y=19 идём влево до X=0.
  3. Переходим к машине состояний для зигзагов:
    1. Вверх на одну клетку и направо до X=18.
    2. Вверх на одну клетку и налево до X=0.
    3. Назад к шагу А.
  4. На Y=0 идём направо до X=19.
  5. Возвращаемся к шагу 1.


Полный код опубликован на GitHub.

Видео:

© Habrahabr.ru