Decompile React Native index.android.bundle

Decompile React Native index.android.bundle

Filibert Nosizwe Author: Filibert Nosizwe Date: 2022-10-05
Decompile React Native index.android.bundle

All you need to know about Decompile React Native index.android.bundle , in addintion to React-native 0.61.2 with hermes disassembling index.android.bundle , react native - unable to load script from assets 'index.android.bundle' , React Native app crash: Unable to load script from assets 'index.android.bundle' , react native - ENOENT: no such file or directory, open 'android/app/src/main/assets/index.android.bundle'

  1. Decompile React Native index.android.bundle
  2. Question:

    I am using React Native and integrated library react-native-obfuscating-transformer to obfuscate my code. Now after decompiling my APK, I believe my whole js code is under assets/index.android.bundle.

    How can I debundle it and see my code whether obfuscation worked or not.


    Solution 1:

    For Macbook

    brew install apktool
    

    after install apktool, unzip apk file by run this command on terminal like this:

    apktool  d /pathOfApkFile.apk
    

    After that you will get index.android.bundle file at pathOfApkFile/assets/index.android.bundle

    than you can use react-native-decompiler for decompile index.android.bundle file

    Decompile index.android.bundle File

    you can decompile index.android.bundle by run this command

    npx react-native-decompiler -i ./index.android.bundle -o ./output
    

    after that, you will get JS decompiled file in ./output directory

    JS Code Decompile

    React Native is already doing uglify js code.

    and react-native-obfuscating-transformer is also make complex uglifying code

    It is something like MD5 and SHA256 encryption and there is no the tool available right know when make machine learning and bruteforce to give us estimated code

    If you want to varify react-native-obfuscating-transformer is implemented or not then you can edit index.android.bundle and save code then implement react-native-obfuscating-transformer and edit and compare both file

    you can make more uglify code by adding flag in build.gradle called bundleInRelease: true and add Hermes which turns js bundle to bytecode for efficiency

    REF

    Note: There is no way to decompile index.android.bundle because this file contains uglify code which has many reverses possible of one line

    Java Code Decompile

    you can use DEX2JAR to convert apk to java code and you can view that code from JD-GUI

    you can see this VIDEO

    Solution 2:

    See https://android.jlelse.eu/getting-inside-apk-files-21dbd01529d4 :

    If your app is written on React Native, using the same apktool you can find index.android.bundle file inside assets folder of decompiled APK folder. To open it using IntelliJ IDEA, right click on the file, Associate with File Type… and choose JavaScript. And it is usual minified .js file.

    In other words, opening the .bundle file in an IDE such as Intellij will yield a minified .js file, which can then be formatted and compared with your source code. I hope this helps!

    Solution 3:

    There is a tool called APK Easy Tool download it from here, install it, and open it.

    enter image description here

    Select apk by choosing browse option and click on Extract apk, when it is extrcted click on decompiled apk directory, and open directory. you would see something like this

    enter image description here

    navigate inside Extracted APKs directory you would get the bundle.

    enter image description here

  3. React-native 0.61.2 with hermes disassembling index.android.bundle
  4. Question:

    I created a release build of my app with react-native 0.61.2 and enabled Hermes. In my Crashlytics I receive information about crashes along with stacktraces. Perviously I used to apply apktool to extract index.android.bundle from my apk, and it contained js code where I was able to find the issue by stacktrace.

    But now using Hermes index.android.bundle seems to contain bytecode rather than js and I wasted a day trying to disassemble it. The last thing I tried was hbcdump tool mentioned in https://github.com/facebook/hermes/blob/master/doc/BuildingAndRunning.md, but all I get is "Error: fail to deserializing bytecode: Wrong bytecode version. Expected 73 but got 62"

    What should I do to disassemble index.android.bundle created with Hermes? Any help is highly appreciated!


    Solution 1:

    Edit: As of Hermes v0.5.0, there's also a hermes-engine-cli NPM that contains a bytecode disassembler. It is only compatible with the corresponding hermes-engine version (i.e. hermes-engine-cli@0.5.0 works with hermes-engine@0.5.0).

    It's still primarily useful for compiler developers, and not for debugging app crashes.


    Hermes tools are not backwards compatible, so you need to check out the correct version first. For bytecode version 62, you can checkout the the v0.2.1 release with git checkout v0.2.1. For arbitrary bytecode versions, git log -p include/hermes/BCGen/HBC/BytecodeFileFormat.h will show which commits updated the format to which versions.

    Once built, you can use hbcdump myfile.hbc followed by disassemble at the prompt to show a disabled version of the file.

    Be aware that hbcdump is intended for developing/debugging compilers, in the same vein as javap -c and objdump -d. Here's the kind of output you can expect:

    Function<fizzbuzz>1(1 params, 22 registers, 0 symbols):
    Offset in debug table: src 0xd, vars 0x0
    fizzbuzz.js[1:21]
        LoadConstZero     r11
        LoadConstUInt8    r10, 15
        LoadConstUInt8    r9, 3
        LoadConstString   r8, "Fizzbuzz"
        LoadConstString   r7, "Fizz"
        LoadConstString   r6, "Buzz"
        GetGlobalObject   r5
        LoadConstUndefined r0
        LoadConstUInt8    r4, 1
        LoadConstUInt8    r3, 100
        LoadConstUInt8    r2, 5
        LoadConstZero     r1
    L2:
    fizzbuzz.js[1:21]
        Mod               r12, r1, r10
        Mov               r13, r8
        JStrictEqual      L1, r12, r11
        Mod               r12, r1, r9
        Mov               r13, r7
        JStrictEqual      L1, r12, r11
        Mod               r12, r1, r2
        Mov               r13, r6
        JStrictEqual      L1, r12, r11
        AddEmptyString    r13, r1
    L1:
    fizzbuzz.js[8:5]
        TryGetById        r12, r5, 1, "print"
        Call2             r12, r12, r0, r13
        AddN              r1, r1, r4
        JLessN            L2, r1, r3
        Ret               r0
    

  5. react native - unable to load script from assets 'index.android.bundle'
  6. Question:

    I'm new in react-native. I have run react native project on Ubuntu by using 'react-native run-android' command. And I got the error on emulator "Unable to load script from assets 'index.android.bundle'.Make sure your bundle is packaged correctly or you are running a package server."


    Solution 1:

    I also got this and I resolved this using following commands in your project directory:

    $ mkdir android/app/src/main/assets
    

    $ react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res

    $ react-native run-android
    

    Solution 2:

    Solution 3:

    In my case (embedding React Native as a new Activity into an existing Android Code Base), the problem was Android Studio had auto-imported the wrong BuildConfig.

    Wrong: import com.facebook.react.BuildConfig;

    Right: import com.mywebdomain.myapp.BuildConfig;

    This would apply to the wherever you are housing this block of code:

    mReactRootView = new ReactRootView(this);
    mReactInstanceManager = ReactInstanceManager.builder()
            .setApplication(getApplication())
            .setBundleAssetName("index.android.bundle")
            .setJSMainModulePath("index")
            .addPackage(new MainReactPackage())
            .setUseDeveloperSupport(BuildConfig.DEBUG)
            .setInitialLifecycleState(LifecycleState.RESUMED)
            .build();
    

  7. React Native app crash: Unable to load script from assets 'index.android.bundle'
  8. Question:

    I'm getting a crash on startup when running a React Native app on device, on release mode (debug mode works fine). The main error seems to be:

    AndroidRuntime: java.lang.RuntimeException: Unable to load script from assets 'index.android.bundle'. Make sure your bundle is packaged correctly or you're running a packager server.

    I've found various threads about this error but there are about old versions and none of the solutions provided was working.

    The log is as follow:

    12-16 19:20:28.581 29088 29109 E AndroidRuntime: FATAL EXCEPTION: Thread-3
    12-16 19:20:28.581 29088 29109 E AndroidRuntime: Process: net.cozic.joplin, PID: 29088
    12-16 19:20:28.581 29088 29109 E AndroidRuntime: java.lang.RuntimeException: Unable to load script from assets 'index.android.bundle'. Make sure your bundle is packaged correctly or you're running a packager server.
    12-16 19:20:28.581 29088 29109 E AndroidRuntime:        at com.facebook.react.bridge.CatalystInstanceImpl.jniLoadScriptFromAssets(Native Method)
    12-16 19:20:28.581 29088 29109 E AndroidRuntime:        at com.facebook.react.bridge.CatalystInstanceImpl.loadScriptFromAssets(CatalystInstanceImpl.java:216)
    12-16 19:20:28.581 29088 29109 E AndroidRuntime:        at com.facebook.react.bridge.JSBundleLoader$1.loadScript(JSBundleLoader.java:32)
    12-16 19:20:28.581 29088 29109 E AndroidRuntime:        at com.facebook.react.bridge.CatalystInstanceImpl.runJSBundle(CatalystInstanceImpl.java:243)
    12-16 19:20:28.581 29088 29109 E AndroidRuntime:        at com.facebook.react.ReactInstanceManager.createReactContext(ReactInstanceManager.java:1114)
    12-16 19:20:28.581 29088 29109 E AndroidRuntime:        at com.facebook.react.ReactInstanceManager.access$900(ReactInstanceManager.java:116)
    12-16 19:20:28.581 29088 29109 E AndroidRuntime:        at com.facebook.react.ReactInstanceManager$5.run(ReactInstanceManager.java:913)
    12-16 19:20:28.581 29088 29109 E AndroidRuntime:        at java.lang.Thread.run(Thread.java:761)
    12-16 19:20:28.582  1695  1707 W ActivityManager:   Force finishing activity net.cozic.joplin/.MainActivity
    

    This is my app/build.gradle file:

    apply plugin: "com.android.application"
    
    import com.android.build.OutputFile
    
    apply from: "../../node_modules/react-native/react.gradle"
    
    def enableSeparateBuildPerCPUArchitecture = false
    def enableProguardInReleaseBuilds = false
    
    android {
        compileSdkVersion rootProject.ext.compileSdkVersion
        buildToolsVersion rootProject.ext.buildToolsVersion
    
        defaultConfig {
            applicationId "net.cozic.joplin"
            minSdkVersion rootProject.ext.minSdkVersion
            targetSdkVersion rootProject.ext.targetSdkVersion
            versionCode 2097414
            versionName "1.0.178"
            ndk {
                abiFilters "armeabi-v7a", "x86"
            }
        }
        splits {
            abi {
                reset()
                enable enableSeparateBuildPerCPUArchitecture
                universalApk false  // If true, also generate a universal APK
                include "armeabi-v7a", "x86"
            }
        }
        signingConfigs {
            release {
                if (project.hasProperty('JOPLIN_RELEASE_STORE_FILE')) {
                    storeFile file(JOPLIN_RELEASE_STORE_FILE)
                    storePassword JOPLIN_RELEASE_STORE_PASSWORD
                    keyAlias JOPLIN_RELEASE_KEY_ALIAS
                    keyPassword JOPLIN_RELEASE_KEY_PASSWORD
                }
            }
        }
        buildTypes {
            release {
                minifyEnabled enableProguardInReleaseBuilds
                proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
                signingConfig signingConfigs.release
            }
        }
        // applicationVariants are e.g. debug, release
        applicationVariants.all { variant ->
            variant.outputs.each { output ->
                // For each separate APK per architecture, set a unique version code as described here:
                // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits
                def versionCodes = ["armeabi-v7a":1, "x86":2]
                def abi = output.getFilter(OutputFile.ABI)
                if (abi != null) {  // null for the universal-debug, universal-release variants
                    output.versionCodeOverride =
                            versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
                }
            }
        }
    }
    
    dependencies {
        implementation project(':react-native-firebase')
        implementation (project(':react-native-camera')) {
            exclude group: "com.google.android.gms"
        }
        implementation project(':react-native-file-viewer')
        implementation project(':react-native-securerandom')
        implementation project(':react-native-fs')
        implementation project(':react-native-image-picker')
        implementation project(':react-native-vector-icons')
        implementation project(':react-native-fs')
        implementation fileTree(dir: "libs", include: ["*.jar"])
        implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
        implementation "com.facebook.react:react-native:+"  // From node_modules
        implementation project(':react-native-sqlite-storage')
        implementation project(':rn-fetch-blob')
        implementation project(':react-native-document-picker')
        implementation project(':react-native-image-resizer')
        implementation project(':react-native-share-extension')
        implementation project(':react-native-version-info')
        implementation "com.facebook.react:react-native:+"
    
        implementation "com.google.android.gms:play-services-base:16.0.1" // For Firebase
        implementation "com.google.firebase:firebase-core:16.0.4" // For Firebase
        implementation "com.google.firebase:firebase-messaging:17.3.4" // For Firebase
        implementation 'me.leolin:ShortcutBadger:1.1.21@aar' // For Firebase - this line if you wish to use badge on Android
    
        compile ("com.android.support:support-v4:26.0.1") {
            force = true //<-- force dependency resolution to 26.0.1 in my case
        }
    }
    
    // Run this once to be able to run the application with BUCK
    // puts all compile dependencies into folder libs for BUCK to use
    task copyDownloadableDepsToLibs(type: Copy) {
        from configurations.compile
        into 'libs'
    }
    
    apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
    apply plugin: 'com.google.gms.google-services' // For Firebase
    

    And android/build.gradle:

    // Top-level build file where you can add configuration options common to all sub-projects/modules.
    
    buildscript {
        ext {
            buildToolsVersion = "27.0.3"
            minSdkVersion = 16
            compileSdkVersion = 27
            targetSdkVersion = 26
            supportLibVersion = "27.1.1"
        }
        repositories {
            jcenter()
            google()
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:3.2.0' // Upgraded from 3.1.4 to 3.2.0 for Firebase
            classpath 'com.google.gms:google-services:4.0.1' // For Firebase
    
            // NOTE: Do not place your application dependencies here; they belong
            // in the individual module build.gradle files
        }
    }
    
    allprojects {
        repositories {
            mavenLocal()
            google()
            jcenter() // Was added by me - still needed?
            maven {
                url "https://maven.google.com"
            }
            maven {
                // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
                url "$rootDir/../node_modules/react-native/android"
            }
        }
    }
    
    
    subprojects {
        afterEvaluate {project ->
            if (project.hasProperty("android")) {
                android {
                    compileSdkVersion 26
                    buildToolsVersion "27.0.3"
                }
            }
        }
    }
    
    
    task wrapper(type: Wrapper) {
        gradleVersion = '4.4'
        distributionUrl = distributionUrl.replace("bin", "all")
    }
    

    Any idea what could be the issue?

    Edit: I cannot downgrade gradle build tool from 3.2.0 to 3.1.4 as some answers suggest because 3.2.0 is required by the Firebase module.


    Solution 1:

    You should try to downgrade gradle build tool from 3.2.1 to 3.1.4

    Solution 2:

    Downgrading from gradle build tool 3.2.1 to 3.1.4 solved the issue for me too. It took me a couple of days to figure it out.

    Solution 3:

    The fix is upgrading RN to 0.57.5 or downgrading gradle to 3.1.4.

    For those who want a really neat workaround without having to upgrade/downgrade:

    In your app/build.gradle add jsBundleDirRelease:

    project.ext.react = [
        entryFile: "index.js",
        jsBundleDirRelease: "$buildDir/intermediates/merged_assets/release/mergeReleaseAssets/out"
    ]
    

  9. react native - ENOENT: no such file or directory, open 'android/app/src/main/assets/index.android.bundle'
  10. Question:

    When I run

    npx react-native run-android --variant=release 
    

    in RN 0.61.3 and I receive this error message.

    ENOENT: no such file or directory, open 'android/app/src/main/assets/index.android.bundle'
    

    The build works fine when debugging without the release variant.


    Solution 1:

    For some reason I needed to create the assets folder as per below.

    android/app/src/main/assets

    Solution 2:

    • Go to android/app/src/main/
    • Create one more folder of the name assets
      It will look like android/app/src/main/assets
    • Then run it. Absolutely workable.

    Solution 3:

    Right click the app folder New->Folder->Assests Folder

    enter image description here