Frida Tutorial 2 - HackTricks

# Frida Tutorial 2

> [!TIP] Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
> Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

> Support HackTricks
> - Check the subscription plans!
> - Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
> - Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.

This is a summary of the post: https://11x256.github.io/Frida-hooking-android-part-2/ (Parts 2, 3 & 4)
APKs and Source code: https://github.com/11x256/frida-android-examples

The part 1 is so easy.

Some parts of the original code doesn't work and have been modified here.

## Part 2

Here you can see an example of how to hook 2 functions with the same name but different parameters.
Also, you are going to learn how to call a function with your own parameters.
And finally, there is an example of how to find an instance of a class and make it call a function.

    //s2.js
    console.log("Script loaded successfully ");
    Java.perform(function x() {
        console.log("Inside java perform function");
        var my_class = Java.use("com.example.a11x256.frida_test.my_activity");
        //Hook "fun" with parameters (int, int)
        my_class.fun.overload("int", "int").implementation = function (x, y) { //hooking the old function
            console.log("original call: fun(" + x + ", " + y + ")");
            var ret_value = this.fun(2, 5);
            return ret_value;
        };
        //Hook "fun" with paramater(String)
        var string_class = Java.use("java.lang.String");
        my_class.fun.overload("java.lang.String").implementation = function (x) { //hooking the new function
            console.log("*")
            //Create a new String and call the function with your input.
            var my_string = string_class.$new("My TeSt String#####");
            console.log("Original arg: " + x);
            var ret = this.fun(my_string);
            console.log("Return value: " + ret);
            console.log("*")
            return ret;
        };
        //Find an instance of the class and call "secret" function.
        Java.choose("com.example.a11x256.frida_test.my_activity", {
            onMatch: function (instance) {
                console.log(tring, and the it has"Found instance: " + instance);
                console.log("Result of secret func: " + instance.secret());
            },
            onComplete: function () { }
        });
    });

You can see that to create a String first is has referenced the class java.lang.String and then it has created a $new object of that class with a String as content. This is the correct way to create a new object of a class. But, in this case, you could just pass to `this.fun()` any String like: `this.fun("hey there!")`

### Python

    //loader.py
    import frida
    import time

    device = frida.get_usb_device()
    pid = device.spawn(["com.example.a11x256.frida_test"])
    device.resume(pid)
    time.sleep(1) #Without it Java.perform silently fails
    session = device.attach(pid)
    script = session.create_script(open("s2.js").read())
    script.load()

    #prevent the python script from terminating
    raw_input()

    python loader.py

## Part 3

### Python

Now you are going to see how to send commands to the hooked app via Python to call function:

    //loader.py
    import time
    import frida

    def my_message_handler(message, payload):
        print message
        print payload

    device = frida.get_usb_device()
    pid = device.spawn(["com.example.a11x256.frida_test"])
    device.resume(pid)
    time.sleep(1)  # Without it Java.perform silently fails
    session = device.attach(pid)
    with open("s3.js") as f:
        script = session.create_script(f.read())
    script.on("message", my_message_handler)
    script.load()

    command = ""
    while 1 == 1:
        command = raw_input("Enter command:\n1: Exit\n2: Call secret function\n3: Hook Secret\nchoice:")
        if command == "1":
            break
        elif command == "2":
            script.exports.callsecretfunction()
        elif command == "3":
            script.exports.hooksecretfunction()

The command "1" will exit, the command "2" will find and instance of the class and call the private function secret() and command "3" will hook the function secret() so it return a different string.

The, if you call "2" you will get the real secret, but if you call "3" and then "2" you will get the fake secret.

### JS

    console.log("Script loaded successfully ")
    var instances_array = []
    function callSecretFun() {
      Java.perform(function () {
        if (instances_array.length == 0) {
          // if array is empty
          Java.choose("com.example.a11x256.frida_test.my_activity", {
            onMatch: function (instance) {
              console.log("Found instance: " + instance)
              instances_array.push(instance)
              console.log("Result of secret func: " + instance.secret())
            },
            onComplete: function () {},
          })
        } else {
          //else if the array has some values
          console.log("Result of secret func: " + instances_array[0].secret())
        }
      })
    }

    function hookSecret() {
      Java.perform(function () {
        var my_class = Java.use("com.example.a11x256.frida_test.my_activity")
        var string_class = Java.use("java.lang.String")
        my_class.secret.overload().implementation = function () {
          var my_string = string_class.$new("TE ENGANNNNEEE")
          return my_string
        }
      })
    }
    rpc.exports = {
      callsecretfunction: callSecretFun,
      hooksecretfunction: hookSecret,
    }

## Part 4

Here you will see how to make Python and JS interact using JSONs objects. JS use the `send()` function to send data to the python cliente, and Python uses `post()` functions to send data to ths JS script. The JS will block the execution until is receives s response from Python.

### Python

    //loader.py
    import time
    import frida

    def my_message_handler(message, payload):
        print message
        print payload
        if message["type"] == "send":
            print message["payload"]
            data = message["payload"].split(":")[1].strip()
            print 'message:', message
            data = data.decode("base64")
            user, pw = data.split(":")
            data = ("admin" + ":" + pw).encode("base64")
            print "encoded data:", data
            script.post({"my_data": data})  # send JSON object
            print "Modified data sent"

    device = frida.get_usb_device()
    pid = device.spawn(["com.example.a11x256.frida_test"])
    device.resume(pid)
    time.sleep(1)
    session = device.attach(pid)
    with open("s4.js") as f:
        script = session.create_script(f.read())
    script.on("message", my_message_handler)  # register the message handler
    script.load()
    raw_input()

### JS

    console.log("Script loaded successfully ")
    Java.perform(function () {
      var tv_class = Java.use("android.widget.TextView")
      tv_class.setText.overload("java.lang.CharSequence").implementation =
        function (x) {
          var string_to_send = x.toString()
          var string_to_recv = ""
          send(string_to_send) // send data to python code
          recv(function (received_json_object) {
            string_to_recv = received_json_object.my_data
          }).wait() //block execution till the message is received
          console.log("Final string_to_recv: " + string_to_recv)
          return this.setText(string_to_recv)
        }
    })

There is a part 5 that I am not going to explain because there isn't anything new. But if you want to read it is here: https://11x256.github.io/Frida-hooking-android-part-5/

> [!TIP] Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
> Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

> Support HackTricks
> - Check the subscription plans!
> - Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
> - Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.