Android Apk Decompile

0 views
Skip to first unread message

Henrietta Naughton

unread,
Aug 3, 2024, 4:38:36 PM8/3/24
to spurlitela

An Android Package file (.apk) is a compressed archive file that contains all of the data and resources needed by an application to run on your Android device. APK file is typically created when the developer wants to share the app with others or to upload it on Google Play. Basically, an APK file is used to install an app onto your phone or tablet.

APK decompilation is the process of reverse engineering an APK file to retrieve its source code. APK decompilation is useful for understanding how an Android app works, especially if you're interested in ethical hacking or penetration testing.

Decompiling or reverse-engineering an APK file is not as complicated as it sounds. There are several free and open source APK decompiler tools available for doing this. But, the three most popular ones are:

For example, JADX is quick and convenient but sometimes resource files are partially missing in its output. So, JADX has some reliability issues. On the other hand, Apktool returns source code in detail with complete resource files.

If you want to discover all the available options (i.e. open source, online, Windows, Mac, Linux, and Android apps) then definitely check out this ultimate list of best APK decompiler tools. Here, you'll get information about the features as well as the pros/cons of each APK decompiler.

Basically, JADX is packed with a command-line utility as well as a GUI application. The Command line utility is mostly used when you want to provide an APK decompiler as a service. Whereas, the JADX GUI app is more convenient to decompile a specific APK and view its source code and resources in a better user interface.

This will unpack the package into a directory named game-apktool. It will also decode various XML files such as AndroidManifest.xml. And it will translate the code into Smali which is a kind of assembler language.

Now I have a game-procyon directory with the easy to read but not always entirely correct Java code of the game. The game-apktool directory is more complete, and its Smali code is more reliable because closer to the source.

Components not listed in the manifest can be exposed as well. For example, Content.registerReceiver() will add a receiver dynamically. In this game I also found a dynamic receiver which would accept data without proper validation.

So this class is being called via the Java reflection API which complicates affairs. A search for the class name in the game-apktool directory finds it in the global-metadata.dat file. The conclusion is: this is being called from inside the Unity engine. So there is no way around understanding its code as well. This is relevant for the impact of the vulnerabilities above as well.

I found articles explaining that Unity is based on .NET and there is supposed to be a file assets/bin/Data/Managed/Assembly-CSharp.dll in the package. Unity then uses Mono to run .NET code. Sounds good as .NET code is compiled to an intermediate language which can be decompiled fairly well, similarly to compiled Java.

Trouble is: there is no such file in this game. In fact, there are no DLL files at all here. The names of the DLL files appear in some asset files, which led me to the crazy suspicion that the DLL files are stored as assets and unpacked at runtime. A detour through the assets file format allowed me to extract the files contained here and confirmed that the DLLs are merely being referenced.

Finally I realized that the game developers used il2cpp here which provides an alternative to executing via Mono. This approach compiles code from the intermediate language further into native code. Here, the result was a library called libil2cpp.so. Most strings used here were stored separately in a global-metadata.dat file.

The tool of choice to make sense of libil2cpp.so appears to be Il2CppInspector. While it cannot revert the compilation, it will recover the entire class structure of the managed code. So it will provide the correct name and parameters for each function in the library.

A look into il2cpp-codegen.h reveals that this is the IL2CPP_RUNTIME_CLASS_INIT macro and the function called here is named il2cpp::vm::Runtime::ClassInit. Another one-time initialization block that can be ignored.

If my understood from your analysis is correct, you could retrieve some information, but not everything as it is relatively confusing translated from what it was originally designed in C# and in the end you had to guess quite often, right?

I'm trying to reproduce your steps in a similar game but I'm not able to successfully have Ghidra working with it and there are not many similar stuff on this, do you think you can explain a little better the process? Maybe even add some details in the original blog post..

There is no generic advise to be provided here. I only looked at one game, using one compilation process. My understanding is that the process is highly customizable and with other games you might find something very different.

Hello, thank you for the very thorough article, I ran into an issue with the APK I was trying to decompile. If anyone perhaps knows what I could do to fix it, I would really appreciate any and all advice, thank you!

I was able to successfully decompile the APK using both methods mentioned in the article. However, I was unable to find the Assembly-CSharp.dll, or the libil2cpp.so files. I was able to find the global-metadata.dat file, and that seemed to be readable by IL2CPPInspector, however I could not find the binary file that actually contained the data. I looked for every extension I could think of (exe, dll, so, out, bin) to no avail, and I was kind of stumped. I looked around the entire output of the decompilation, and I was not able to find anything that seemed useful, not even a linux mapping .txt file. I know the project was made in Unity, and it seems like it was compiled with ProGuard enabled. Could it be possible that my decompilation was only partially successful? If not, is there possibly an alternative way of packaging these APK's that I could possibly be missing? I figured that because I was able to find the "global-metadata.dat" file, I needed to find a "libil2cpp.so" counterpart, but I am stumped. Thanks!

JD-Core is a JAVA decompiler written in JAVA. JD-Core is a standalone JAVA library containing the JAVA decompiler of "Java Decompiler project". It support Java 1.1.8 to Java 10.0, including Lambda expressions, method references and default methods. JD-Core is the engine of JD-GUI.

APK stands for Android Application Package. It is an extension of a file that can be installed on android devices. APK is the executable file in the android device in the entire project that is generated after compiling lots of files in android studio. It is a very challenging task of generating source files from their compiled version. Android Studio generates the APK file by compiling AndroidManifest.xml, .java, or .kt files, layout files, various media files, and many more different files. Below are the steps to decompile the APK file that is getting the source files from Android Application Package. Android studio packs the files into the .dex extension and combining that .dex files generate the APK files.

@TheCoolest (or any other devs) - can you tell more about dtb structure, etc or is that explained anywhere else (some wiki, etc, where to start). I guess dtb used by CoreElec is not the same as /dev/dtb extracted (with dd command), from original Android firmware so far I noticed CE dtb is smaller.

@giaur500 With the 4.9 kernel, the DTBs for generic devices are based on the source of the original android ones. We removed some unused sections, and changed some others (such as audio related ones) to make them work properly with CE. Certain boxes, with non-standard hardware have more modification to make said hardware work.
All DTS files are located in the amlogic-4.9 branch. Our changes are an overlay over the original sources.

Maybe your v.3 box uses a different type of SoC, either not by Amlogic at all, which means CE will not work on it at all, or something newer that needs the Amlogic-ng build rather than the old Amlogic build.

Hello, I am new both in the forum and in the world of android tv. I have a stuuc s1 max 4gb of ram with soc s905x4. I have extracted the dtb from android and I would like someone to adapt it for corelect or a tutorial to adapt it myself. Thanks and great job.
dtb (256 KB)

I'd like to make clear that I'm talking about avoiding the decompilation of the apk file itself, I know there are some tricks to make the code harder to understand, as using Proguard to obfuscate the code or not storing raw values (I'll also implement them), but what I want to know if there's some way in which if someone where to obtain the apk and put it on an Android decompiler he couldn't get the code (at least in some cases).

This looks hard at first but I don't think its impossible, I renember that years ago some desktop applications where able to detect that were being decompiled, and not allowing its code to be taken, if I renember well they could at least detect they were being detected by some decompiler like OllyDbg. I don't see a reason why it shouldn't be possible with an apk file.

PD: Not sure if this goes here or in reverseengineering, I think the question is in reality about anti reverse engineering which I think is a subfield of information security. But I'd like to ask an admin to move it there if needed.

and then invoking the natives with JNI. It would still be flawful but at least better than using the pure code. I'm not a proficient Java developer, but a similiar feature in C# would be DllImport. It won't prevent you from being debugged but it's harder to debug, especially against script kiddies.

OllyDbg is a debugger, not a decompiler.From your question, I see what you want is Android anti-debugging protection, then you could find some examples in the following articles: -security.gitbook.io/mobile-security-testing-guide/android-testing-guide/0x05j-testing-resiliency-against-reverse-engineering#testing-anti-debugging-detection-mstg-resilience-2

c80f0f1006
Reply all
Reply to author
Forward
0 new messages