If you have an android native app with dynamic rendered content, reverse engineering can be tough. Thats why we can use Frida and ADB

So what is Frida, exactly?

User Guide

It’s Greasemonkey for native apps, or, put in more technical terms, it’s a dynamic code instrumentation toolkit. It lets you inject snippets of JavaScript or your own library into native apps on Windows, macOS, GNU/Linux, iOS, Android, and QNX. Frida also provides you with some simple tools built on top of the Frida API. These can be used as-is, tweaked to your needs, or serve as examples of how to use the API.

Android Debug Bridge (adb)

User Guide

Android Debug Bridge (adb) is a versatile command-line tool that lets you communicate with a device. The adb command facilitates a variety of device actions, such as installing and debugging apps, and it provides access to a Unix shell that you can use to run a variety of commands on a device. It is a client-server program that includes three components:

  • A client, which sends commands. The client runs on your development machine. You can invoke a client from a command-line terminal by issuing an adb command.
  • A daemon (adbd), which runs commands on a device. The daemon runs as a background process on each device.
  • A server, which manages communication between the client and the daemon. The server runs as a background process on your development machine.

Now as we got the basics covered we can jump over to Android Studio and start a VM with the AVD Manager.

As son as the VM started, we hop over to the terminal and can use the following commands

adb root

# Upload local files to Android VM
adb push 'fida-server' '/data/local/tmp/'

# Start Frida server in background
adb shell "/data/local/tmp/frida-server &"

# Run app with injected code
frida -U -l crackmenative.js -f com.app.example

# Forward traffic
adb forward tcp:1234 tcp:1234

# Start GDB Server
adb shell "/data/local/tmp/gdbserver --attach localhost:1234 <PID>" 

# Connect to GDB Server
gdb> target remote 127.0.0.1:1234 </code></pre>

The crackmenative.js would the look something like this:

console.log("Script loaded successfully ");
Java.perform(function(){ 
    console.log("Inside java perform function");

    //Initialize classes
    var BuildConfig = Java.use("com.app.exmple.BuildConfig")
    var RootCheck = Java.use("com.app.exmple.RootCheck")
    var LoginViewModel = Java.use("com.app.exmple.ui.LoginViewModel")
    var LoginResult = Java.use("com.app.exmple.ui.LoginResult")
    var LoggedInUser = Java.use("com.app.exmple.data.LoggedInUser")
    var MainActivity = Java.use("com.app.exmple.MainActivity")

    //Root ckeck hook & bypass
    RootCheck.a.implementation = function(){
        return false
    }
    RootCheck.b.implementation = function(){
        return false
    }
    RootCheck.c.implementation = function(){
        return false
    }

    //Root ckeck hook & bypass
    Interceptor.attach(Module.findExportByName("libc.so", "strstr"), {

        onEnter: function (args) {
            this.haystack = args&#91;0];
            this.needle   = args&#91;1];
            this.frida    = Boolean(0);

            this.haystack = Memory.readUtf8String(this.haystack);
            this.needle   = Memory.readUtf8String(this.needle);

            if ( this.haystack.indexOf("frida") != -1 || this.haystack.indexOf("xposed") != -1 ) {
                this.frida = Boolean(1);
            }
        },

        onLeave: function (retval) {
            if (this.frida) {
                retval.replace(0);
            }

            return retval;
        }
    });

    //Listen if specific function from library is called
    var check = Module.findExportByName("libnative-lib.so", "Java_com_app_exmple_ui_LoginViewModel_checkPw");
    console.log("MODULE FOUND: " + check);
    var comp = ptr(check).add(378);

    Interceptor.attach(comp, {
        onEnter(args) {
            var flag = "";

            var x0 = &#91;
                121, 134, 239, 213, 16, 28, 184, 101, 150, 60,
                170, 49, 159, 189, 241, 146, 141, 22, 205, 223,
                218, 210, 99, 219, 34, 84, 156, 237, 26, 94,
                178, 230, 27, 180, 72, 32, 102, 192, 178, 234,
                228, 38, 37, 142, 242, 142, 133, 159, 142, 33
            ]

            for(var x=0; x<27; x++){
                var edx = ptr(this.context.edx).add(ptr(4*x)).readPointer();
                var edi = ptr(this.context.edi).add(ptr(4*x)).readPointer();
                var esi = ptr(this.context.esi).add(ptr(-4*x)).readPointer();
                var c = edi ^ x0&#91;x] ^ esi ^ edx
                flag += String.fromCharCode(c)
            }

            console.log(flag)
        },
    });

});

More to be done… Maybe

Last modified: January 19, 2022

Author

Comments

Write a Reply or Comment

Your email address will not be published.