# Calling Methods

## 📌Static vs non-static (Instance) methods

| Feature                     | **Static Method**                                         | **Non-Static Method**                                   |
| --------------------------- | --------------------------------------------------------- | ------------------------------------------------------- |
| **Definition**              | Belongs to the class itself                               | Belongs to an instance of the class                     |
| **Access**                  | Called using the class name (`ClassName.method()`)        | Called on an object instance (`this.method()`)          |
| **Frida Hooking**           | **Hooked directly using** `varName.method.implementation` | Hooked using `this.method(...)` inside `implementation` |
| **Requires Instantiation?** | ❌ No (Doesn't need an object)                             | ✅ Yes (Must have an object of the class)                |
| **Example in Java**         | `public static void myMethod() {}`                        | `public void myMethod() {}`                             |
| **Example in Frida**        | `varName.staticMethod.implementation = function() {...};` | `this.instanceMethod();`                                |

## *��*&#x43;alling Different Types of Methods in Frida

In Frida, you can interact with methods in Android apps, both static and instance methods. This section covers how to call these methods using Frida's JavaScript API.

### ��*Calling Static Methods*

Static methods are called on the class itself. Here's the skeleton we can use to call a static method:

```jsx
Java.perform(function() {
    // Get a reference to the MainActivity class
    var <class_reference> = Java.use("<package_name>.<className>");
    // Calling the static method nextLevel()
    <class_reference>.<static_method>();
});
```

* ***Ex***

<figure><img src="/files/8MDxUkuwiCIDKQB5uiyd" alt="" width="563"><figcaption></figcaption></figure>

### 📍Calling Instance Methods

To call a **non-static (instance) method**, you must first create an instance of the class. For example:

```java
public class MyClass {
    public void myMethod() { /* ... */ }
}

// Correct usage:
MyClass obj = new MyClass();  // Create instance
obj.myMethod();               // Call instance method
```

Instance methods are called on instances of the class. **There are two approaches to calling instance methods in Frida**:

* **Approach 1: Creating a New Instance**

  ```jsx
  Java.perform(function() {
  		// Get a reference to the target class
      var class_reference = Java.use("<package_name>.<class>");
      // Create a new instance of the class
      var class_instance = class_reference.$new(); // Class Object
      // Call an instance method on the created object
      class_instance.<method>(); // Calling the method
  });
  ```
* **Approach 2: Finding Existing Instances and Overriding Properties**

  ```jsx
  Java.perform(function() {
      Java.scheduleOnMainThread(function() {
          Java.choose('packageName.ClassName', {
              onMatch: function(instance) {
                  try {
                      // Modify instance property
                      instance.propertyName.value = newValue;

                      // Call an instance method
                      instance.methodName();
                  } catch (e) {
                      console.error("Error: " + e.message);
                  }
              },
              onComplete: function() {
                  console.log("Finished scanning for instances");
              }
          });
      });
  });
  ```
* Use this approach when dealing with Android framework components like **`Activity`**, **`Fragment`**, **`Service`**, or **`BroadcastReceiver`**.

### <mark style="background-color:red;">**Invoking Methods on an Existing Instance**</mark>

<figure><img src="/files/hfEGsI3eHYq8xQTrLtQo" alt=""><figcaption></figcaption></figure>

In the *MainActivity*, there is a method called **flag** that is not invoked anywhere in the program. This method decrypts the flag and sets it in the textview. It’s a **AES** decrypt function. Additionally, we need to pass the value 1337 as an argument to bypass the if check. We encountered a similar situation in our previous post, but this time, it’s within *MainActivity*. Why not create another instance of *MainActivity* and call this method? Let’s try that.

<figure><img src="/files/24qVA3TouBEar58kpAgb" alt=""><figcaption></figcaption></figure>

* **Why Can’t We Create a New Instance of `MainActivity`?**
  * When you create a new instance of **`MainActivity`** manually (e.g., using **`Java.use`** and **`$new()`**), you bypass the Android system’s lifecycle management.
  * Without going through **`onCreate()`**, **`onStart()`**, and **`onResume()`**, the activity won’t be properly initialized:
    * It won’t have access to the application context.
    * It won’t be attached to the UI thread or have a valid **`Looper`** (required for UI updates).
    * Any dependencies (e.g., views, resources) won’t be set up.
* **Solution: Using an Existing Instance**
  * Instead of creating a new instance of **`MainActivity`**, we can use **Frida** to find and interact with the Android system's **existing instance** of **`MainActivity`**.
  * **How does Frida help?**
    * Frida allows you to hook into the running app and inspect its memory.
    * Using the **`Java.choose`** API, you can locate all instances of a specific class (in this case, **`MainActivity`**) at runtime.
  * ***Skeleton***:

    ```java
    Java.performNow(function() {
      Java.choose('<Package>.<Class_Name>', {
        onMatch: function(instance) {
          // TODO
        },
        onComplete: function() {}
      });
    });
    ```
  * ***Code***:

    ```java
    Java.performNow(function() {
      Java.choose('com.mobilehackinglab.FridaFive.MainActivity', {
        onMatch: function(instance) { // "instance" is the instance for the MainActivity
          console.log("Instance found");
          instance.flag(1337); // Calling the function
        },
        onComplete: function() {}
      });
    });
    ```

***

***


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://e1mazahy.gitbook.io/tomesec/droidtomesec/android-pentesting/frida/calling-methods.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
