Dynamic instrumentation using Frida

This section shows the usage of a tool called Frida to perform dynamic instrumentation of Android applications.

What is Frida?

Frida is an open source dynamic instrumentation toolkit that enables reverse engineers and programmers to debug a running process. It's a client-server model that uses Frida core and Google v8 engine to hook a process.

Unlike the Xposed framework, it's very easy to use and doesn't need extensive programming and there is no need to restart the device either. With a wide range of platform support on Android, iOS, Linux, Mac, and Windows and powerful APIs, it's one of the best tools to create reverse engineering tools during penetration testing. Frida currently has API bindings for Python, node.js, and .NET and provides them if you would like to create bindings for other programming languages.

Prerequisites

As discussed in Chapter 1, Setting Up the Lab, we need the following to get Frida working with our test app:

  • A rooted Android phone or emulator
  • An installed Frida-server onto an Android device
  • An installed Frida-client on your desktop
  • A tested frida-ps –R command to see a process listing

To demonstrate the capabilities of Frida, we will use a slightly modified version of the app we have used for the Xposed framework. However, the package name of the vulnerable app is still: com.androidpentesting.hackingandroidvulnapp1

The modified code is shown as following:

Prerequisites

The preceding code contains a modified version of setOutput which only returns true or false. When setOutput is called, the value of i is passed to it which is initialized to 0. If the value of i is set to 1, this application will display the text Cracked. But, since the initialized value is 0, this app always displays the text Cant crack it.

Let's now use Frida to print the Cracked message on to the activity; however, we won't be doing coding like we did in the Xposed framework section. Frida by nature is a dynamic instrumentation toolkit designed to solve this problem with minimal coding.

Once you install this app, launch it and you should see the familiar screen we saw earlier.

Frida provides lots of features and functionality like hooking functions, modifying function arguments, sending messages, receiving messages, and much more. Covering all of these will take a full chapter in itself; however, we will cover enough to get you started with the more advanced topics in Frida.

Let's see an example of modifying the implementation of our setOutput to always return true irrespective of variable i's value.

Steps to perform dynamic hooking with Frida

We need to follow these steps to accomplish modifying our setOutput method:

  1. Attach the Frida client to the app process using an attached API.
  2. Identify the class which contains the functionality you want to analyse/modify.
  3. Identify the API/method you want to hook.
  4. Create JavaScript script to push to the process using a create_script call.
  5. Push the JavaScript code to the process using the script.load method.
  6. Trigger the code and see the results.

We connect to our process using the following code:

session = frida.get_remote_device().attach("com.androidpentesting.hackingandroidvulnapp1")

Next we need to identify the class. In our case, we only have one class, namely the MainActivity class and the function we are trying to hook is setOutput. We can use the following code snippets to accomplish that:

Java.perform(function () {
    var Activity = Java.use("com.androidpentesting.hackingandroidvulnapp1.MainActivity");
    Activity.setOutput.implementation = function () {
      send("setOutput() got called! Let's always return true");
       return true;
     };
});

Since we are trying to make setOutput always return true, we have changed the implementation of our call by using the .implementation function. The send call sends a message to the client side on our desktop from the process here, which is used for sending messages.

You can read more about the Frida's JavaScript API at:

http://www.frida.re/docs/javascript-api/#java

We can also modify the arguments to the methods and if needed can instantiate new objects to pass an argument to the method.

The entire hook.py, which will hook our setOutput method using Frida looks like the following:

import frida
import sys

def on_message(message, data):
            print message
 
code ="""
Java.perform(function () {
    var Activity = Java.use("com.androidpentesting.hackingandroidvulnapp1.MainActivity");
    Activity.setOutput.implementation = function () {
        send("setOutput() got called! Let's return always true");
        return true;
    };
});
"""
session = frida.get_remote_device().attach("com.androidpentesting.hackingandroidvulnapp1")
script = session.create_script(code)
script.on('message', on_message)

print "Executing the JS code"

script.load()
sys.stdin.read()

Let's run this Python script and trigger the onClick event of our Crack Me button on the app:

C:hackingAndroid>python hook.py
Executing the JS code
{u'type': u'send', u'payload': u"setOutput() got called! Let's return always true"}
{u'type': u'send', u'payload': u"setOutput() got called! Let's return always true"}

As you can see, I have pressed the Crack Me button twice and every time we press that button setOutput got called and our hook always returned true.

Steps to perform dynamic hooking with Frida

As we can see, we have successfully changed the behavior of the app with dynamic instrumentation using Frida without any reboots or without us having to write lengthy code. We suggest you explore Frida's well written documentation and examples on their official page.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.131.10