Reverse engineering and modifying an Android game (.apk) — CTF

CurlS
The Startup
Published in
8 min readJan 9, 2020

Recently I solved a CTF style challenge where the user was given an .apk file with the goal to find the flag. It turned out that it was a very basic retro game where one had to collect all available keys in order to get the flag. Some of the keys were outside the game area, thus the only way to solve the challenge was to take a deeper look into the .apk file and understand the game logic.

UI — starting point

In the below summary I will outline one way how to modify an existing .apk file, respectively modifying the source code of the app, recompile it and install it on an Android emulator. Luckily, the code was not obfuscated with a tool like ProGuard.

Game Information

The goal of the retro game is to collect all keys. Some of the keys are hidden behind the outer walls or are located outside of the game area. The Android game figure can only be moved via the navigation button on the UI. In order to break an inner wall, the player can lay bombs which will explode after 3 seconds. Some of the outer walls are destroyable, too.

Introduction

There are different ways so solve this challenge. I only did static analysis of the content of the .apk/source code. An .apk file basically represents a mobile application as it is installed on a mobile device and contains all data required to operate correctly (compiled code, resources, signature, manifest, etc.). It is of advantage to have basic knowledge of the Java programming language (or similar) in order to understand the logic of the game.

Native Binaries
As no native code analysis was needed for solving this challenge this topic is out of scope. The shared objects files reside mostly in the lib folder and would need to be analysed with an disassembler like ghidra/hopper or similar.

There are many open source tools for reverse engineering/pentesting Android apps. Check out these summaries here and here . Some helpful tools for static analysis are:

Tools

apktool
Can be fetched from Apktool website and be used to decompile/recompile apps and their resources. Using apktool, the classes.dex file is converted into an intermediary language called smali. The smali code is not easy to read (at least for me), but still one can get an idea of what the application is doing. apktool can decode resources to nearly original form and rebuild them after making some changes.

jadx-gui
Loading the .apk file into jadx-gui gives one the possibility to look at the decompiled Java source codes and to browse through the different classes/methods, etc. The Java code might not be perfect though, but still much better then reading the smali code.

The very cool feature of jadx is the string/symbol search and the find usage option. Once .apk file is loaded the UI looks like this:

UI jadx-gui

Link:
https://github.com/skylot/jadx
https://github.com/skylot/jadx/wiki/jadx-gui-features-overview

Smali/Baksmali
bak/smali is actually used byt apktool under the hood. With baksmali one can disassemble the java classes into editable forms (smali). To assemble all classes to a readable form for android (classes.dex) smali can be used.

Java — Dalvik Bytecode — Smali

If the goal is to make changes in the source code, the modification can be done within the smali code.

Links:
https://github.com/JesusFreke/smali
https://bitbucket.org/JesusFreke/smali/downloads/

Dex2Jar
This tool works similarly like jadx-gui. It converts Dalvik Bytecode to Java Bytecode for further analysis of the Java source code JD-GUI can be used as a standalone graphical utility to display the Jave source code. It comes pre-installed on Kali-Linux or you can get it here.

ByteCode Viewer
This is a user friendly open source Java reverse engineering suite, similar to Jadx. The view settings can be customized. It is pretty cool, to have the Java and smali code next to each other for comparison.
java-jar Bytecode-Viewer-2.9.x.jar

UI ByteCode Viewer

Links:
https://bytecodeviewer.com/
https://github.com/Konloch/bytecode-viewer/

APK package content

.apk package content

/classes.dex: contains the logic we are interested in
/assets/*: application related files (images, etc.)
/res/*: all resources that are not compiled into resources.arsc
/lib/*: native libraries, divided into architecture specific subfolders
/META-INF/*: APK metadata, signature information
/AndroidManifext.xml: app manifest (see below for detailed information)
/resources.arsc: precompiled resources (strings, colors, styles, etc.)

Getting started with the static analysis

So as outlined below, in order to get the flag it is important to get access to the source code, which is an easy task as we have many open source tools we can use. Just a note from beside: The strings tool does not show any flag, neither does the strings.xml file within the folder /res/values/. In order to output all xml files (after decompiling) one can use find . -name \*.xml.

AndroidManifest.xml: This is the main configuration file used by all android applications. When reverse engineering an .apk the manifest gives a good starting point as to (i) information to entry point (tells us which classes to reverse first), (ii) activities, (iii) services running in the background, (iv) permission levels, (v) receivers, etc.

Let’s first have a look into the source code and then the necessary steps to perform.

Java Code:

After analysing the code, it is pretty clear where possible modifications on the code can be made in order to get the flag in an easy way. As it is the .smali file which has to be modified, I chose a function which allows me to do that in an easy way -> change the time value in the sleep function. With this change I prolonged the time for the explosion of the bomb within the game which at the end allows me to play the game in one go.

ApplicationActivity.smali

Furthermore, the code gives insight about the stored keys and destroyable walls:

The location of the keys:

addkeys(0.0f, 3.0f);  //hidden behind outer wall
addkeys(-3.0f, 4.0f); //outside of game area
addkeys(13.0f, 1.0f); //outside of game area
addkeys(13.0f, 7.0f); //outside of game area
addkeys(5.0f, 5.0f);
addkeys(5.0f, 8.0f);

The location of the destroyable walls:

addDestroyableWall(3.0f, 1.0f);
addDestroyableWall(1.0f, 3.0f);
addDestroyableWall(1.0f, 4.0f);
addDestroyableWall(1.0f, 5.0f);
addDestroyableWall(1.0f, 6.0f);
addDestroyableWall(1.0f, 8.0f);
addDestroyableWall(4.0f, 1.0f);
...

layBomb function
The Thread.sleep() method is used to pause the main thread execution for 3 seconds. This is the function I will be manipulating in the .smali file.

public void layBomb(float x, float y) {
addBomb(x, y);
try {
Thread.sleep(3000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
...

How to modify a compiled Android application

I came to the conclusion, that the easiest way was to decompile the app, make changes on the smali source code and to recompile it. Thus, is is important to study the Java code beforehand and to know what changes are needed.

Emulator

On my Kali Linux I installed Android SDK emulator in order to test/play around with the game app.

Installation: sudo apt-get install libgl1-mesa-dev. See detailed description here.

Step by Step

  1. Decompile .apk file with apktool
    apktool d <application.apk>
    The application folder will be created and all output of apktool is in there. We are interested in the smali files and navigate into the respective folder with the smali files. In my case it is: cd smali/de/mo/projekt/bomberman. Remember that behind the hood baksmali was used!
  2. At this point I exactly know which smali file I want to change (output from my static code analysis). Open the smali file with any simple editor. (In my case it was BombermanActivity.smali).
  3. Make necessary modifications on smali files. In my case, I chose to adapt the sleep time in order to play the game in one shot (see above printscreen, too). I changed the value from 0xbb8 to 0x2328. below and saved the file.
    Line 2534: -> const-wide/16 v6, 0xbb8
    Line 2535: ->
    Line 2536: -> :try_start_0
    Line 2537: -> invoke-static {v6, v7}, Ljava/lang/Thread;->sleep(J)V
    Line 2538 <…>
  4. Recompile apk with apktool b [folder name] -o modifiedAPK.apk. The folder name was defined in step 1 (default -> name of apk.file). We now have a new recompiled apk file with the changed smali code (modifiedAPK.apk).
  5. I had to create a certificate and sign the modifiedAPK.apk in order to re-install it on the Android emulator, as after the modification the checksum and the signature were not valid. Please note, that the content of the META-INF folder might need to be deleted beforehand.
keytool -genkey -v -keystore my-release-key.keystore -keyalg RSA -keysize 2048 -validity 10000jarsigner -verbose -sigalg MD5withRSA -digestalg SHA1 -keystore my-release-key.keystore modifiedAPK.apk

5. After execution of these two commands the files CERT.RSA and CERT.SF should have been created within the META-INF folder.

6. Install modified .apk on device, respectively on Android Emulator by drag and drop of the .apk file.

7. Enjoy and play and get the flag. Now with the changed source code, I can easily play the game as the bomb explosion is delayed by 6 seconds. Please note, we exactly know where the keys are stored and which walls can be destroyed from our static analysis overview (see above). Packed with all these information, it should be very easy to play the game until end.

Of course the code can be manipulated at many different places in the source code, I just decided to change the sleep time function as this is a simple replacement in the smali code.

Flag after sucessfully collected all keys

Note 1: It is of course also possible to get the content from the .apk file and to convert only the .dex file into human readable representation, make the changes, and convert back to .dex:
baksmali d application.apk -o smaliClasses
smali a smaliClasses -o classes.dex

Note 2: apktool is a more general tool for decoding and rebuilding an .apk file. It uses bak/smali under the hood. bak/smali is for DEX files.

Links:
How to modifiy an apk file
Repackaging APK file using baksmali and smali

This was a fun and easy challenge to solve. I hope it can be of help for others who are new into this topic. I can highly recommend the online workshop Intro to Android App Reverse Engineering workshop from Maddie Stone: https://maddiestone.github.io/AndroidAppRE/

I had the opportunity to attend her 2-day workshop in December 2019 organized by Blackhoodie for which I am very grateful.

As always, any feedback is much appreciated.

--

--

CurlS
The Startup

Working in Infosec. Interested in many things, from technical perspective -> security, ctfs, coding, reverse engineering,… and in general -> love life. She.