Research by; Yaara Shriki and Roman Zaikin
To celebrate this year’s April Fool’s Day, some of you may have noticed that Google added an interactive snake game inside its Google Maps application for Android and IOS.
The Check Point Research team, although usually pretty busy investigating the latest cyber threats, found themselves somewhat distracted by the addictive game, though got increasingly frustrated when they kept losing… So a curious thought arose, why not hack our way into winning! 🙂
So, the more mischievous among us went ahead and looked into how they could reverse engineer the app by using remote debugging. In short, their efforts paid off and it wasn’t long before they had successfully achieved the task of never losing – and had even added some simple AI that would auto-play the game for them.
In this blog we will describe in detail how this was done:
First, we launched the app in a virtual device using Genymotion and navigated to the snake game which is located on the menu from the top right hand corner.
It seems like the game is rendered in a WebView, so we opened chrome developer tools remote debugging which looks like this:
First, the function ‘fa()’ initiates the board with the dimensions 20×20:
this.height = this.width = 20;
Our main goal here then was to find and change the function that is responsible for determining when we crash into a wall or into ourselves so we can’t lose. As we saw before, the variables width and height represent the game board dimensions, so we searched for width and height inside the source code and found the following function F(a, b):
Function F(a, b) seems to check if the coordinates of our snake’s body are within the limits of the board. One option is to remove the conditions in the function altogether so it always returns true, thus putting us in ‘God Mode’ where we can go through walls without dying.
To do that we pressed on “inspect” in the remote console and changed the function F(a, b) to the following:
Now if we play the game, we can go through walls like this:
Figure 1: God Mode
This is all very nice and all, but we would still have to actually play the game and pick up people in order to win points. Our next hack solves that problem.
By reversing the call stack we see many calls to the function wa(a). If we look deeper into this function, we see it is recursive and that it is responsible for requesting the animation frames. wa(a) calls the functions xa(a, b) and ya(a) which render the game pieces (train and people) and board, in respect.
Let’s take a look at function xa(a, b):
We can see it takes two arguments: ‘a’ and ‘b’. ‘a’ is part of a global variable Q which holds interesting information about our game, including an array that represents the game board (Figure 2), where we can see the train (M), people and landmarks (K). This function also calculates our score and keeps it in c.i, which is also equivalent to Q.b.
Figure 2: Game board array
Which represents the following board:
Figure 3: Game board
xa(a) also calls the function sa(a) (Figure 4) which generates random coordinates each time a new person is created. If we were to call this function more than just one time we could create as many people as we wanted (Figure 5).
Figure 4: calling the function sa(a)
Figure 5: The results of the call, creating as many people as we like
Notice that even if we call sa(a) more than once and pick up a person our score does not change. Function ka(a, b) (Figure 6) is called when the train picks passengers up. So we are going to change the function so that every time it is called it will increase our score by 10 points and update the score on the screen.
Figure 6: Updated Function
The coordinates of each part of the train are listed in Q.b.o.b, where the first element represents the first cart in the train.
Figure 7: Array of train carts
We will need that to create a simple Artifical Intelligence. Let’s start with the logic:
Figure 8: The AI Logic
Our snake will perform a state machine:
To see the full code, visit our GitHub.
See the video for demonstration: