React native android js execution

by
3 views fac71b51...

Description

React native android js execution. tested with Hermes JavaScript bytecode, version 96. You can view the output with `adb logcat "*:S" ReactNativeJS:I -v raw`

How to Use

Download the script and run it with Frida CLI:

Download Script

Then run with Frida:

frida -U -f YOUR_PACKAGE_NAME -l react-native-android-js-execution.js

Replace YOUR_PACKAGE_NAME with the target app's package name.

Source Code

JavaScript
// all taken from https://pilfer.github.io/mobile-reverse-engineering/react-native/

// This is the app identifier you're trying to hook
const package_name = 'com.example.app';

// Write the hermes-hook.js payload to file
const f = new File(`/data/data/${package_name}/files/hermes-hook.js`, 'w');
f.write(`console.log(JSON.stringify(this.process)); console.log('hello from React Native!');`);
f.close();

if (Java.available) {
    Java.perform(() => {
        const waitForClass = (className, callback) => {
            const interval = setInterval(() => {
                try {
                    Java.use(className);
                    clearInterval(interval);
                    callback();
                } catch (e) {
                    // Class not yet available, keep waiting
                }
            }, 10);
        };


        const hookJS = () => {
            try {
                const func = Java.use('com.facebook.react.bridge.CatalystInstanceImpl').loadScriptFromAssets;

                func.implementation = function(assetManager, assetURL, z) {
                    // Store for later I guess

                    this.loadScriptFromAssets(assetManager, assetURL, z);
                    this.loadScriptFromFile(`/data/data/${package_name}/files/hermes-hook.js`, `/data/data/${package_name}/files/hermes-hook.js`, z);
                };
            } catch (e) {
                console.error(e);
            }
        };

        // We have to wait for SoLoader.init to be called before we can hook into the JS runtime.
        // There's a few overloads, so we have to hook into all of them and then call our hookJS function.
        waitForClass('com.facebook.soloader.SoLoader', () => {
            let SoLoader = Java.use('com.facebook.soloader.SoLoader');
            SoLoader.init.overload('android.content.Context', 'int').implementation = function(context, i) {
                this.init(context, i);
                hookJS();
            };

            SoLoader.init.overload('android.content.Context', 'int', 'com.facebook.soloader.SoFileLoader').implementation = function(context, i, soFileLoader) {
                this.init(context, i, soFileLoader);
                hookJS();
            };

            SoLoader.init.overload('android.content.Context', 'int', 'com.facebook.soloader.SoFileLoader', '[Ljava.lang.String;').implementation = function(context, i, soFileLoader, strArr) {
                this.init(context, i, soFileLoader, strArr);
                hookJS();
            };

            SoLoader.init.overload('android.content.Context', 'boolean').implementation = function(context, z) {
                this.init(context, z);
                hookJS();
            };
        });
    });
}
Share this script:
Twitter LinkedIn

Comments

Login or Sign up to leave a comment.
Loading comments...