> For the complete documentation index, see [llms.txt](https://davidjosearaujo.gitbook.io/notes-mcs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://davidjosearaujo.gitbook.io/notes-mcs/reverse-engineering/android-dynamic-analysis/frida.md).

# FRIDA

## How?

Set of tools (framework) for Dynamic Code Instrumentation.

* Instruments the Application Code with hooks.
* Not specific for Android, and may be used on other applications and Operating Systems.

### Allows for

* Tracing network communications at the method level.
* Understand how the application behaves.
* Manipulate the methods called, arguments and return codes.

Frida-core injecting a Google V8 JS Engine into the App scope.

* Frida-core Written in C.
* GumJS (the JS part) is packed as a shared library and loaded into the app.

GumJS has access to the application memory.

* Can be hooked to methods and intercept calls, even native APIs.

GumJS API allows interaction with GumJS from an external client.

* Because GumJS resides in the application address space, it has full access to its structures.

## Embedded Mode

Frida agent is embedded as a dependency of an existing application library.

* Requires the application to have an `.so`
* `libfrida-gadget.so` is injected into the existing library and loaded at the same time.

Alternative: the existing library is modified to load the additional library.

* Requires patching the code in a function will be called (e.g. `JNI_OnLoad`).

Alternative: patching the smali code to load the library.

* Obtain APK.
* Extract smali.
* Change smali.
* Pack it and install.

The method implies that the application is repacked/resigned.

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

```
$ apktool d app.apk
$ cp libfrida-gadget.so target/lib/arm
$ python3
>>> import lief
>>> native = lief.parse(“target/lib/arm/libsomething.so”)
>>> native.add_library(“libfrida-gadget.so”)
>>> native.write(“target/lib/arm/libsomething.so”)
>>> exit
$ apktool b target
… sign … install
```

### Smali

* Unpack the app using apktool.
* Patch the `smali` with.

```
const-string v0, "frida-gadget"
invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
```

* Where? In the main activity constructor.
  * Even in as a static property of the class.
* repack, sign, install.

### Caveats

Applications may search for the library name as an anti-debug technique.

* May need to change the library name.

Must use a version compatible with the target architecture.

An agent may only be loaded after the JNI library is loaded or the code is reached.

* After `System.loadLibrary(“lib.so”)`

An agent may impose the need for permissions to access the INTERNET.

* Manifest may need to be updated.

## Injected Mode

Run a Frida Server which injects the agent into the target process.

* The server provides an API for remote use.
* The server injects the agents into applications.

Requires the smartphone to be rooted or to be an emulator.

* To run the server and inject applications.

Cannot be used in production builds, only in development.

* When in an Emulator, use a base without WITHOUT “Google Services”.

### How it works?

* Create an Agent: it’s an `.so` with some custom code.
* Start a server that will be ready to attach to processes.
* Injection:
  * Create a thread in the remote process using `ptrace`.
    * `PTRACE_ATTACH`, `PRACE_GETREGS`
  * Allocate memory for a bootstrapping code.
    * The minimal amount of code that is required for pulling the agent.
  * Write bootstrapper to memory.
  * Execute bootstrapper in the remote process.
    * Open communication channel to server (FIFO).
    * Loads the agent from a shared library (.so).
    * Executes the agent.
    * Closes communication channel (the agent will expose an API).

<figure><img src="/files/14vUWzIumrv42v5sTkJL" alt=""><figcaption></figcaption></figure>

Required functionality:

* `ptrace` - Process tracing.
* `mmap` - Map files to memory. In particular, the agent .so.
* `dlopen` - Open the .so with the agent.
* `dlsym` - Retrieves addresses of loaded symbols.
* `signal` - To handle system signals.

```bash
### On the first PC terminal

# wget frida-server from github

adb push frida-server /data/local/tmp
adb shell
su
cd /data/local/tmp
chmod +x frida-server
./frida-server

### On the second PC terminal
# List processes
$ frida-ps -U
```

Command line tools: frida, frida-trace, frida-ps, frida-discover.

Python interface.

* Provides a more advanced, programmatic interface.
* Allows predictable and repeatable instrumentation.

How to instrument code: using JS that overloads existing functions.

* Large repository at [Frida CodeShare](https://codeshare.frida.re/)

## Example

#### Objective: make `b.checkAppSignature` return false.

```java
int d1 = b.checkAppSignature(this);
if(d1 < 1){
    Toast.makeText(context,"Application Tampered",Toast.LENGTH_LONG).show();
    this.finishAffinity();
}
try{
```

`Java.perform`: executes the given payload.

Snippet provides an alternative implementation of the method.

```java
Java.perform(function(){
    Java.use("com.re.lab1.b").checkAppSignature.implementation = function(a) {
        console.log("Signature will fail");
        return 0;
    };
});
```

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

```java
cursor = secureDB.rawQuery("SELECT * FROM a;",null);
cursor.moveToFirst();

if(pp.equalsIgnoreCase(cursor.getString(0))){
    Toast.makeText(MainActivity.this, "Right Pin, Congratulations", Toast.LENGTH_SHORT).show();
    pin1.removeAllViews();
    String xo = getResources().getString(R.string.google_api_key);
    a mo = new a();
    xo = mo.func1(xo,xo.substring(4));
    xo = a.func2(xo);
    xo = a.func3(xo.substring(1),xo);
    xo = a.func4(xo,xo,xo.substring(2));
    tv1.setText("Flag: "+xo);
}else{
    Toast.makeText(MainActivity.this, "Incorrect Pin, "+(max_tries+1-i)+" attempts remaining", T
}
```

`pp` has the pin provided.

The cursor has the value obtained from the DB.

#### Objective: reimplement `Java.lang.String.equalsIgnoreCase` so that it returns true, and prints the correct ping

```java
Java.perform(function(){
    Java.use("java.lang.String").equalsIgnoreCase.implementation = function(a) {
        console.log("Real PIN: " + a);
        return true;
    };
});
```

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

## Interceptors

Intecept calls to a function.

Define two events where code can be executed.

* **OnEnter**: When the function is called.
* **OnLeave**: After the function returns.

Can be used as a generic logger, or to trigger other actions.

* Can intercept calls on lower layers of the application stack.
  * Data that is to be written, SQL queries, etc…

```java
function foo(){
    Interceptor.attach(Module.findExportByName(“libc.so”, “open”), {
        onEnter: function(args){
            console.log(“Entering the function”);
        },
        onLeave: function(args){
            console.log(“Leaving the function”);
        },
    });
}
```
