Google Maps Snake
Обратная разработка первоапрельской «Змейки» от Google.
Возможно, кто-то из вас заметил, что Google на 1 апреля добавила в приложение Google Maps для Android и iOS интерактивную игру «Змейка».
Специалисты Check Point обычно заняты исследованием последних киберугроз, но здесь очень увлеклись этой игрой, правда, сильно расстраивались из-за проигрышей… поэтому возникла логичная мысль: почему бы её не взломать!
Таким образом, наши самые озорные сотрудники начали думать над обратной разработкой приложения с помощью удалённой отладки. В общем, у них получилось, и вскоре мы успешно выполнили задачу никогда не проигрывать — и даже добавили простой ИИ, который сам играет в игру.
В этой заметке подробно опишем хак.
Сначала мы открыли приложение на виртуальном устройстве через Genymotion и запустили «Змейку», которая находится в меню в правом верхнем углу.
Похоже, что игра отображается в WebView, поэтому мы запустили удалённую отладку в инструментах разработчика Chrome:
Затем перешли на сайт и нашли на вкладке с исходниками файл v18.js, а в нём несколько интересных функций.
Во-первых, функция fa() инициирует поле размером 20×20:
Наша главная цель — найти и изменить функцию, которая определяет, когда змейка врезается в стену или в себя, чтобы отключить возможность проигрыша. Переменные width и height представляют размеры игрового поля, поэтому мы поискали width и height внутри исходного кода и нашли функцию F(a, b):
Похоже, F(a, b) проверяет, находятся ли координаты тела змеи в пределах поля. Один из вариантов — полностью удалить условия в функции, чтобы она всегда возвращала истину, тем самым переводя нас в «режим Бога», где мы можем проходить сквозь стены, не умирая.
Для этого мы нажали кнопку Inspect в удалённой консоли и изменили функцию F(a, b) на следующую:
Теперь мы можем проходить сквозь стены:
Это всё очень хорошо, но нам по-прежнему придётся играть, самостоятельно подбирая людей, чтобы зарабатывать очки. Следующий хак решит эту проблему.
В стеке вызовов много вызовов функции wa(a). Если изучить эту функцию, то мы увидим, что она рекурсивна и отвечает за запрос кадров анимации. wa(a) вызывает функции xa(a, b) и ya(a), которые отображают игровые фигуры (поезд, люди) и поле, соответственно.
Рассмотрим функцию xa(a, b):
Она принимает два аргумента: ‘a’ и ‘b’. Первый является частью глобальной переменной Q, которая содержит интересную информацию о нашей игре, включая массив, который представляет собой игровое поле (рис. 2), где мы видим поезд (М), людей и объекты (K). Функция также вычисляет счёт и сохраняет его в c.i, что также эквивалентно Q.b.
Данный массив соответствует такому полю:
xa(a) также обращается к функции sa(a) на рис. 4, которая генерирует случайные координаты при каждом создании нового человека. Если вызывать функцию более одного раза, то можно создать сколько угодно людей (рис. 5).
Как здесь:
Обратите внимание, что даже если вызывать sa(a) более одного раза и забирать человека, счёт не меняется. При подборе пассажира вызывается функция ka(a, b) на рис. 6. Таким образом, её нужно изменить, чтобы при каждом вызове она добавляла 10 очков и обновляла счёт на экране.
Координаты каждой части поезда указаны в Q.b.o.b, где первый элемент представляет собой первый вагончик в поезде.
Это понадобится для создания простого ИИ. Начнём с его логики:
Змейка представляет собой машину состояний (конечный автомат):
- На X=19 идём вниз, пока не доберёмся до Y=19.
- На X=19 и Y=19 идём влево до X=0.
- Переходим к машине состояний для зигзагов:
- Вверх на одну клетку и направо до X=18.
- Вверх на одну клетку и налево до X=0.
- Назад к шагу А.
- На Y=0 идём направо до X=19.
- Возвращаемся к шагу 1.
Полный код опубликован на GitHub.
Видео:
Источник: habr