# Frida Tutorial 2

**From**: [https://11x256.github.io/Frida-hooking-android-part-2/](https://11x256.github.io/Frida-hooking-android-part-2/) \(Parts 2, 3 & 4\)  
**APKs and Source code**: [https://github.com/11x256/frida-android-examples](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**.

```javascript
//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

```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()
```

```text
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:

```python
//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

```javascript
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

```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

```javascript
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/](https://11x256.github.io/Frida-hooking-android-part-5/)

