# Persisting Frida Scripts

FIRERPA provides the ability to persist Frida scripts. You can conveniently inject scripts through relevant interfaces, and FIRERPA's script manager will automatically manage the injected scripts. Even if your script exits abnormally, or the app process exits, FIRERPA will automatically re-inject the script the next time your app is opened.

## Installing Scripts

Install the script to the target application. After installation, the script will be injected into the application immediately. The installed script automatically enters the script manager, which continuously monitors and re-injects the script when its state requires it.

```{attention}
The script manager allows only one script to be injected per application at a time; you cannot inject multiple scripts into the same application simultaneously.
```

```python
app = d.application("com.android.settings")
app.attach_script(script, runtime=ScriptRuntime.RUNTIME_QJS, standup=5)
```

The `script` parameter is the content of the Frida script you want to inject (supports bytecode), the `runtime` parameter specifies the corresponding runtime environment (default `qjs`), and the `standup` parameter indicates a delayed injection time, meaning injection occurs only 5 seconds after the application process starts (timing begins from process creation). The minimum value for this parameter is 1 second, maximum 300 seconds, to avoid injecting too early into the process and causing crashes or other race condition issues. In spawn mode, this parameter should always be set to 0.
<br>
<br>
This interface also supports injection in spawn mode, but note that using spawn mode may interrupt your UI operation flow, because once you use spawn mode, in the event of an injection script error or the app exiting, the mode automatically restarts the application, thus interfering with your interface operations. If you need to use spawn mode, please use the following parameters.

```python
app = d.application("com.android.settings")
app.attach_script(script, runtime=ScriptRuntime.RUNTIME_QJS, spawn=True, standup=0)
```

Note that spawn mode differs from normal mode: In normal mode, if the application exits for some reason, normal mode waits for the application to start before injecting, and will not launch the application on its own, so you may need to start the application manually or through code to continue injection. In spawn mode, however, even if the application exits, it will automatically restart the application and perform injection.

## Uninstalling

Remove the Frida script that has been installed in the application; the script will also be unloaded from the application process. At the same time, FIRERPA's script manager will no longer monitor the script's running state, nor will it re-inject after a script error.

```python
app = d.application("com.android.settings")
app.detach_script()
```

## Check if Installed

Determine whether a script is installed for the application. You can use the return value to decide whether to reinstall.

```python
app = d.application("com.android.settings")
app.is_attached_script()
```

## Check if Injected

Check whether the installed script is currently injected into the application process. Because even after installation, if the application is not running or the script has errors, the script may not be injected into the process. You can use the return value to determine whether to start the relevant application or check the injected script for syntax errors.

```python
app = d.application("com.android.settings")
app.is_script_alive()
```

## View Script Logs

Console logs such as `console.log` from your script, as well as script error messages, can be viewed, but you need to configure logging when FIRERPA starts. Please refer to the [View Logs](./service-logs.md) section to learn how to set up log files. Assume you have set the log file to `/data/local/tmp/server.log`. When you need to view script logs, you can run the following command, which filters out all log information from injected scripts. You can also continuously trace logs using commands like `tail -f`.

```bash
grep SCRIPT /data/local/tmp/server.log
```

## Offline Persistence

Offline persistence means you can place Frida scripts as configuration files on the phone, and FIRERPA will automatically load your Frida scripts after startup. You do not need to use the above API interfaces for injection, cancellation, etc.; simply write the script file in a specific format and place it in a fixed directory. This feature monitors the directory in real time, loading, unloading, and updating scripts dynamically. Directly editing files in the script directory also takes effect in real time. Below is a simple YAML configuration example; the script content corresponding to this configuration is `console.log("Hello From Yaml Script")`.

```yaml
enable: true
application: "com.android.settings"
version: "2.10"
user: 0
runtime: "qjs"
script: !!binary "Y29uc29sZS5sb2coIkhlbGxvIEZyb20gWWFtbCBTY3JpcHQiKQ=="
emit: "http://myserver/reportData"
encode: "none"
standup: 10
spawn: false
```

```{hint}
The above is a complete example of an offline script. After writing, save the configuration as `{file_name}.yaml` and place it in the `~/modules/script` folder on the device; the system will automatically load your configuration. The system automatically detects changes in the `~/modules/script` directory; if you update or delete a YAML configuration, the system will accordingly update or cancel the script injection automatically.
```

### Field Descriptions

| Field       | Description                                                                 |
|-------------|-----------------------------------------------------------------------------|
| enable      | Whether to enable this script                                               |
| application | The application ID to inject the script into (e.g., com.android.settings)   |
| version     | Supported application version for the injected script (`"N/A"` means any version) |
| user        | For multi-user apps, specify the corresponding user ID (usually 999)        |
| script      | Script content (base64 encoded), supports text or binary format (please write according to the template) |
| runtime     | Script runtime (qjs, v8)                                                    |
| standup     | Delay injection time (calculated from process start)                        |
| spawn       | Use spawn mode (if enabled, standup is ignored)                             |
| encode      | Encoding method for data reporting (zlib or none)                           |
| emit        | Target URL for data reporting                                               |

For more on the emit data reporting feature, please refer to the [Using Frida to Report Data](./frida-report.md) section.