Pentesting

APK decompilers

JD-Gui

First famous gui Java decompiler, you could use it to investigate the Java code from the APK once you have obtained it.

Jadx

Buildin Java (multi-platform)and at this moment I think it's the recommended one. Just download the latest version and execute it from the bin folder:

jadx-gui

Using the GUI you can perform text search, go to the functions definitions (CTRL + left click on the function) and cross refs (right click --> Find Usage)

If you only want the java code but without using a GUI a very easy way is to use the jadx cli tool:

jadx app.apk

Some interesting options of jadx (GUI and CLI versions) are:

-d <path to output dir>
--no-res #No resources
--no-src #No source code
--no-imports #Always write entire package name (very useful to know where is the function that you might want to hook)

GDA is also a powerful and fast reverse analysis platform. Which does not only supports the basic decompiling operation, but also many excellent functions like Malicious behavior detection, Privacy leaking detection, Vulnerability detection, Path solving, Packer identification, Variable tracking analysis, Deobfuscation, Python& Java scripts, Device memory extraction, Data decryption and encryption etc.

Only for Windows.

Another interesting tool to make a Static analysis is: bytecode-viewer. It allows you to decompile the APK using several decompilers at the same time. Then, you can see for example, 2 different Java decompilers and one Smali decompiler. It allows you also to modify the code:

If you modify the code, then you can export it. One bad thing of bytecode-viewer is that it doesn't have references or cross-references.

Enjarify

Enjarify is a tool for translating Dalvik bytecode to equivalent Java bytecode. This allows Java analysis tools to analyze Android applications. Dex2jar is an older tool that also tries to translate Dalvik to Java bytecode. It works reasonably well most of the time, but a lot of obscure features or edge cases will cause it to fail or even silently produce incorrect results. By contrast, Enjarify is designed to work in as many cases as possible, even for code where Dex2jar would fail. Among other things, Enjarify correctly handles unicode class names, constants used as multiple types, implicit casts, exception handlers jumping into normal control flow, classes that reference too many constants, very long methods, exception handlers after a catchall handler, and static initial values of the wrong type.

CFR

CFR will decompile modern Java features - including much of Java 9, 12 & 14, but is written entirely in Java 6, so will work anywhere! (FAQ) - It'll even make a decent go of turning class files from other JVM languages back into java!

That JAR file can be used as follows:

java -jar ./cfr.jar "$JARFILE" --outputdir "$OUTDIR"

For larger JAR files I found it to run out of memory. You can simply adapt the size of the memory allocation pool of the JVM if that happens to you, too.

java -Xmx4G -jar ./cfr.jar "$JARFILE" --outputdir "$OUTDIR"

This example will allow a maximum of 4GB to be allocated.

In the output directory, you will find the decompiled .java files, together with a summary of the decompilation

Next up is Fernflower, which is part of IntelliJ IDEA. Everyone mentions that it is an analytical decompiler (as stated in their project description), but nobody points out what this actually means. I only found this Stackoverflow question, which unfortunately remains unanswered as of today.

Anyway, since there are no self-contained releases, you need to build it yourself. As a Gradle-based project, you can clone it and then run the following command given that Gradle is installed on your machine.

cd ./plugins/java-decompiler/engine && gradle jar

Here, we first switch our working directory to the root directory of Fernflower. Then, we instruct Gradle to build the file ./build/libs/fernflower.jar.

The invocation of Fernflower is similar to that of CFR.

java -jar ./fernflower.jar "$JARFILE" "$OUTDIR"

Among the decompilers described here, this is the only one that outputs the generated .java files in a JAR file. You can easily extract the source files using unzip.

Krakatau

Remember Enjarify from above? The very same author is also the developer of a decompiler named Krakatau.

In contrast to the other projects, this one is written in Python. And I think this is the reason why it’s a bit different from the others.

Let me cite from the README of the project.

Next, make sure you have jars containing defintions (sic!) for any external classes (i.e. libraries) that might be referenced by the jar you are trying to decompile. This includes the standard library classes (i.e. JRT).

And according to the description, these standard library classes come with up to version 8 of Java in the form of the file rt.jar. For later versions, the author provides jrt-extractor, which can generate this file for us.

So we download that tool and run the following commands.

cd ./jrt-extractor
javac JRTExtractor.java
java -ea JRTExtractor

This should have written a file rt.jar inside the directory.

Given this file, we can run Krakatau as follows.

./Krakatau/decompile.py -out "$OUTDIR" -skip -nauto -path ./jrt-extractor/rt.jar "$JARFILE"

Let me refer to the project’s GitHub for an explanation of the parameters. Just note that for any libraries used by your JAR file, Krakatau will require you to add it as a JAR file to the -path flag.

procyon

Once installed, the usage is straightforward.

procyon -jar "$JARFILE" -o "$OUTDIR"

References