Hacking Animal Restaurant
Recently I was playing Animal Restaurant and find it really cute and interesting. The game started off without much effort. Low-level items weren’t that expensive and didn’t took that much time to earn. But as the game progresses, it was close to impossible to earn as much fish without actually introducing some external inputs.
The naive method was to use an auto clicker to bot. I used “Auto Clicker” which can be downloaded from the Google Playstore. Setting up the automated taps wasn’t difficult. Create your required taps, moving them into position and setting the delay of each tap after another.
There were some anti-cheating mechanism in the game but they were easy to bypass with another additional tap. The delay of 1ms is enough to click the orders and 50ms for tapping the Promo button. I concluded that it was the best configuration and have tested it running the auto clicker a few nights.
It ran well, seeing the fishes increase by a magnitude in the morning felt good. Until I purchase a few items from the shop and it is empty again. Was it worth it? Leaving my phone running continuously (almost 8hrs straight). No, there should be an easier way to earn the fishes.
Modify the game
I tried mods created by others in the past before where official game files were modified to change the game mechanics be it increasing gold, experience points, etc. With the same mindset, I tried searching online if any have already create a mod for this game. There was none (excluding all the sketchy sites).
It is time for some DIY.
#
The approach I took can be summarised in the following steps.
- Download original APK onto computer
- Decompile APK
- Explore and understand decompiled files and directories
- Modify files to suit my needs (multiply fishes earned for example)
- Recompile APK
- Install recompiled APK on Android
- Test
Step 1 — Downloading Original APK
I used the website https://apkcombo.com/apk-downloader/ and inserted the link of Animal Restaurant and pressed the Download
button. A link will be generated and I saved the file to my computer as animal_restaurant.apk
.
Step 2 — Decompile APK
With the APK, I used apktool to decompile the file.
apktool d animal_restaurant.apk
A folder animal_restaurant
will be created and its directory should look like this.
|-- AndroidManifest.xml
|-- apktool.yml
|-- assets
|-- build
|-- dist
|-- lib
|-- original
|-- res
|-- smali
|-- smali_assets
|-- smali_classes2
`-- unknown
Step 3 — Explore and understand decompiled files and directories
As this is a game, most likely it is using some game engine. At the back of my mind, I guess it could be one of the widely used game engines — Unity or Cocos2d. Entering the lib
folder, there is a file libcocos2djs.so
. This confirms that it is using the game engine Cocos2d
. I don’t have any game programming background so everything is based on my guess and inference.
I remembered reading a little about cocos2d
in the past and that it has supports javascript
bindings and the library file libcocos2djs.so
has the letters js
at the back. Hence I guessed that the source code of the game is mainly in javascript. With that, I went looking for files with the extensions.js
.
Having no clue with the directory structure, I entered everyone of them and came across something interesting within subpackages/Script/index.js
. The file size was 1.2MB
and it look like a compiled source of the game. Below is a short snippet of what is inside.
It seems like the code was uglified and compiled but luckily the object and variable names were comprehendible.
Scrolling through the file, it I was certain that it is indeed the source files which handles the game logic. Hence I searched for money
, gold
, coins
and found a function createCoins
which is used by multiple objects.
Step 4 — Modify files
With the known function which I suppose create the fish when the customer is done eating, I searched for the function declaration and saw the following snippet. Guessing that the itemValue
is what the customer pays, I modified the line to t.itemValue = e + 9999;
. If this modification works, I should be able to see the effect when I collect the fish in the game.
Step 5 — Recompile APK
Saving my modifications, the next step is to recompile the apk. I usedapktool
to recompile.
apk b -f animal_restaurant> I: Using Apktool 2.4.1
> I: Smaling smali folder into classes.dex...
> I: Smaling smali_assets folder into assets.dex...
> I: Smaling smali_classes2 folder into classes2.dex...
> I: Building resources...
> I: Copying libs... (/lib)
> I: Building apk file...
> I: Copying unknown files/dir...
> I: Built apk...
Once done, the recompiled apk can be found in the folder animal_restaurant/dist/animal_restaurant.apk
. Before we can install it on our Android device, we have to sign the APK.
- Generate our cert.
keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000
2. Sign apk
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore animal_restaurant/dist/animal_restaurant.apk alias_name
Step 6 — Install recompiled APK on Android
There are different ways to install an APK on android. As I have Developer Options
enabled, I can use adb
to install the apk.
adb install animal_restaurant/dist/animal_restaurant.apk
If not, we can just copy the file into our device and install it using a file manager. Both works fine.
Step 7 — Test
With the recompiled apk installed, it was time to test our modified codes. I was excited seeing the game launched without crashing. When everything was loaded, I tapped on the fishes but the amount was like before. There was no increment of 9999
which I could tell.
At this point of time, I could only think of one possible reason — I modified the wrong function, there could be another function in charge of creating the coins and I have missed out.
But I suddenly remembered that the game went through some hot updates and that could have cause an override in the files I modified. With that though in mind, I searched for cocos2d hot update
and came across this page.
It states that there is a manifest which used to compare local and remote assets for any updates. Doing a fresh install, I noticed that the version I have is v6.2.4.g
. After an update it became v6.2.8.g
.
The manifest contains the following values and the key remoteVersionUrl
caught my attention.
{
"packageUrl": The local cache root path of the remote asset
"remoteVersionUrl": [optional] the path of the remote version of the file used to determine whether the server has a new version of the assets
"remoteManifestUrl": Path of the remote asset manifest file, including version information and all asset information
"version": the version of the asset
"engineVersion": engine version
"assets": all asset lists
"key": the relative path of the asset (relative to the asset root)
"md5": The md5 value represents the version information of the asset file
"compressed": [optional] If the value is true, the file is automatically downloaded after being extracted, currently only supports zip compression format
"size": [optional] The byte size of the file used to quickly get progress information
"searchPaths": A list of search paths that need to be added to FileUtils
}
I searched the string in the project file and found a file called 99447321–8016–4672-a8c4-ba13c7346ec2.manifest.
The file contained the path of the remote server and the path of all assets alongside with the file signature. If I can modify the file and point the update to download from my own server I can effectively upload my own modified index.js
in the game.
With that direction, changed packageUrl
, remoteManifestUrl
and remoteVersionUrl
.
It looks something like this after modification.
{"version":"6.2.4","packageUrl":"http://192.168.1.123/appAndroidGlobal","remoteManifestUrl":"http://192.168.1.123/appAndroidGlobal/project.manifest","remoteVersionUrl":"http://192.168.1.123/appAndroidGlobal/version.manifest",
With that, I also setup a proxy to direct all incoming request to my computer to the game’s server. The proxy server was written in nodejs
using an express
server. The idea was to proxy all files except the ones which I want to modify.
I rebuilt the game following the steps previously and after launching the game, I see the request made from the game to my proxy server which means the modification was working. As the game loads, it skipped the whole updating process and went straight into the game as my proxy server wasn’t fully ready yet to serve the files.
I didn’t expect to get into the game as the hot update failed. But here I am in the game, and when I collected the fishes I saw a huge increase in the amount of fishes I have. It was working.
With that, I stopped my proxy server and restarted the game to see whether the game runs even without an update server. Indeed it does work.
Download Modded APK
You can download my modded apk at this link.
md5: fee392d737ad715bb48807a872011c8d
Patch Summary
Watch the mod in action. It includes increase the fishes customer pay as well as reduce the number of taps required to get a customer in the shop.
To conclude, the game version used to modify the apk is v6.2.4.g
.
The steps required to get the mod to work
- Prevent Hot Reloading —
animal_restaurant/assets/res/raw-assets/99/99447321–8016–4672-a8c4-ba13c7346ec2.manifest - Modify game codes —
animal_restaurant/assets/subpackages/Script/index.js
References
- https://medium.com/@sandeepcirusanagunla/decompile-and-recompile-an-android-apk-using-apktool-3d84c2055a82
- https://medium.com/@gaikwadchetan93/monitoring-modifying-android-app-network-traffic-via-mitm-proxy-part-1-886f6324f705
- https://joyhooei.gitbooks.io/cocos-creator-docs/en/advanced-topics/assets-manager.html#technical-details