Reversing APKs
Decompiling and understanding unknown APKs, using dynamic and static testing
Decompiling
For Android apps, there are a few different common formats. A pretty common way is apps coded in Java, where compiling is turning that source code into Java bytecode. After this, the Java code along with the resources it needs is converted into a Dalvik Executable (DEX) file. You can see this DEX format as the machine code, and another language called Smali is basically assembly: the human-readable version of machine code while staying pretty low level.
When you want to do static analysis on an APK file, you will first need to decompile it to make any sense of the code. There are a few useful tools for this, and the first one is apktool. It is a general-purpose tool for unpacking and rebuilding APKs that gets almost everything from the APK. The main use is turning an APK file into Smali code, meaning the readable assembly:
Other folders/files you might need could be ignored by apktool
, so it is always a good idea to unpack the APK itself, as it is just a special ZIP file. We can simply unzip
the file to get all the raw content:
Java
Reading Smali code is like reading raw assembly, but often this is not what the app was written in, so there is another process to actually decompile an APK into a JAR file. This tool for this is named dex2jar, and we will use it on the .apk
file:
When we have a JAR file, the next step is to unpack and decompile that into .java
source files. A simple tool that does this for all files in a JAR is procyon. Simply run it on the .jar
file created earlier and specify an output directory:
This can take a while for a big application, but after it is finished you can open the directory it created with a Code Editor like IntelliJ and read all the Java source files.
React Native
Sometimes the decompiled Java code simply does not make any sense, or you see lots of references to "React". When this is the case, it could be that the application was not written in Java, but in a JavaScript framework like React Native. Luckily, there are also tools for decompiling the bundle this creates into semi-readable JavaScript code.
To check if you are dealing with React Native, check for a assets/index.android.bundle
file in your unzipped APK. If that exists, you can use react-native-decompiler to decompile it into multiple JavaScript files.
Because this bundle is heavily packed, there is a lot of code that serves no use to us, and names are mostly lost. But the best bet is to simply take a quick glance at all the files to see if you recognize anything. Searching for strings is also very useful if you know some strings when you start the app in an emulator.
Tip: You might see a lot of require('./[number]')
code, this simply means it imports a module from the file named [number].js
.
C# with .NET
Another possibility is C# with .NET as the language the app was written in. You can detect this by finding an assemblies/
folder in the unzipped APK. This folder will contain many .dll
files, but these files are compressed and not easily readable yet. To decompress the assemblies and allow other tools to work with them use xamarin-decompress:
This will turn .dll
files into .decompressed.dll
files in the same directory, which can be easily Reverse Engineered using tools like dnSpy. For more information on reversing from here on out see Reversing C# - .NET / Unity. It can decompile these files to almost perfect C# source code.
Automatic tool
Quickly decompiling an APK file can be quite a hassle, which is originally why I made my default apk
tool that can do all the things shown above, but automatically by detecting the existence of certain files. I run it every time I come across an APK file I want to Reverse Engineer:
For an example of how this tool works and what it does, see this video:
App Resources
In the code, you might find hex numbers similar to 0x7f100213
. These numbers refer to resources of the app, stored with it in the APK.
When you have your APK project open in Android Studio, simply make sure you have the .apk
file open from the left side, and you can see a list of files in the middle. Click on the resources.arsc
file and it will show you all the Resource Types and contents in a table. Here you can find what resource matches the hex address you found earlier to find what content it points to.
Most of the strings and some other categories will be visible here, but you also might find just a path starting with res/
. This means the value can be found in the res/
directory inside of the APK, which is also visible in Android Studio right above the resources.arsc
file.
To view the real contents simply select the file in there, or to get the raw data outside Android Studio use the local res/
folder in the unzipped APK.
Last updated