JADX Decompiler

repository·master·Indexed 10 days ago

https://github.com/skylot/jadx

A powerful tool for decompiling Android Dex and JAR files into readable Java source code. It features a command-line interface (CLI) and a graphical user interface (GUI) for analyzing Android applications and Java bytecode. JADX supports various input formats including .apk, .dex, .jar, .class, .smali, .zip, .aar, .arsc, .aab, .xapk, and .apkm, and provides advanced features such as deobfuscation, call graph generation via jadx-analysis, and a plugin system.

Tokens
5.4K
Snippets
20
Records
28
Agent score
96%

What's inside JADX

  1. Overview of jadx zip

    master
    The jadx-zip module provides a custom ZIP reader implementation designed to mitigate tampering and provide additional security checks during the decompression process. It is used as a specialized component within the JADX ecosystem to handle ZIP files more securely than standard implementations.
  2. Use jadx-app-commons utilities

    master

    The jadx-app-commons module provides shared utilities used across JADX applications (both CLI and GUI). It is designed for application-level logic rather than core code analysis.

    Key utilities include:

    • JadxCommonFiles: A wrapper around the dev.dirs:directories library that provides cross-platform access to 'config' and 'cache' directories.
    • JadxCommonEnv: Utility functions for interacting with environment variables.
  3. Generate SmaliTokenMarker using JFlex

    master

    To generate the SmaliTokenMarker class, use the JFlex command-line tool. You must provide the flex specification file (SmaliTokenMaker.flex) and specify a skeleton file (e.g., skeleton.default) using the --skel flag.

    jflex SmaliTokenMaker.flex --skel skeleton.default
  4. Build JADX from source

    master

    To build JADX from source, you must have JDK 17 or higher installed. Use Gradle to run the dist task, which generates the distribution files.

    After building, the runnable scripts are located in build/jadx/bin and a zip archive is created in build/jadx-<version>.zip.

    git clone https://github.com/skylot/jadx.git
    cd jadx
    ./gradlew dist
  5. Install Jadx plugins from GitHub releases

    master

    You can install Jadx plugins directly from GitHub release artifacts using a specific URI pattern. This allows you to specify the owner, repository, version, and an optional artifact name prefix.

    Pattern: github:<owner>:<repo>[:<version>][:<artifact name prefix>]

    Rules:

    • <version> is optional and should match the release name.
    • <artifact name prefix> is optional. The plugin expects an artifact following the pattern <artifact name prefix>[-<release-version-name>].jar.
    • If no prefix is provided, the default is the repository name.
    # Examples
    github:skylot:jadx
    github:skylot:jadx:sample-plugin
    github:skylot:jadx:0.1.0
  6. Use JADX CLI and GUI

    master

    JADX provides two main interfaces:

    • jadx: The command line version for automated or script-based decompilation.
    • jadx-gui: The UI version for interactive code exploration, featuring syntax highlighting, jump-to-declaration, full-text search, and a Smali debugger.

    If you download the release zip, navigate to the bin directory to run these tools. On Windows, you can run the .bat files.

    # Command line version
    ./jadx
    
    # UI version
    ./jadx-gui
  7. Decompile files with JADX CLI

    master

    Use the jadx command to decompile various file formats including .apk, .dex, .jar, .class, .smali, .zip, .aar, .arsc, .aab, .xapk, and .apkm.

    Basic Syntax: jadx [command] [options] <input files>

    Common Options:

    • -d, --output-dir: Specify the output directory.
    • -r, --no-res: Do not decode resources.
    • -s, --no-src: Do not decompile source code.
    • --output-format: Set to java (default) or json.
    • --deobf: Activate deobfuscation.
    • -j, --threads-count: Number of processing threads (default: 16).
    # Decompile an APK to an output directory
    jadx -d out classes.dex
    
    # Decompile with specific rename flags
    jadx --rename-flags "valid, printable" classes.dex
    
    # Set log level to error
    jadx --log-level ERROR app.apk
    
    # Disable checksum verification for dex input
    jadx -Pdex-input.verify-checksum=no app.apk
  8. Install JADX

    master

    You can install JADX using various package managers depending on your operating system:

    • Arch Linux: Use pacman or the AUR.
    • macOS: Use Homebrew.
    • Flathub: Use Flatpak.

    Note: Ensure you have Java 11 or later (64-bit) installed on your system.

    # Arch Linux
    sudo pacman -S jadx
    
    # macOS
    brew install jadx
    
    # Flathub
    flatpak install flathub com.github.skylot.jadx
  9. Generate a call graph using jadx-analysis

    master

    You can use the jadx-analysis utilities to analyze code and generate a full application usage/call graph. This involves initializing JadxArgs, loading the file with JadxDecompiler, and using the JadxCallGraph.builder to construct the graph with specific filters.

    Key builder options include:

    • .includePackages(String...): Filters nodes by specific package names.
    • .resolvedOnly(boolean): When set to true, only adds nodes from the application code, excluding calls to framework or library code.

    Once built, you can iterate over callGraph.edges() to inspect connections and use writeDot(Path) or writeJson(Path) to export the graph.

    JadxArgs args = new JadxArgs();
    args.addInputFile(new File("input.apk"));
    try (JadxDecompiler jadx = new JadxDecompiler(args)) {
      jadx.load();
    
      ICallGraph callGraph = JadxCallGraph.builder(jadx)
        .includePackages("com.example") // filter nodes by package
        .resolvedOnly(true) // add nodes only from app (exclude framework/lib calls)
        .build();
    
      for (ICallGraphEdge edge : callGraph.edges()) {
        if (edge.isResolved()) {
          System.out.printf("Edge from '%s' to '%s'%n", edge.from(), edge.to());
        }
      }
      callGraph.writeDot(Path.of("test.dot")); // export to '.dot'
      callGraph.writeJson(Path.of("test.json")); // export to JSON
    }