# Frida スクリプトの永続化

FIRERPA は Frida スクリプトを永続化する機能を提供します。関連するインターフェースを通じて簡単にスクリプトをインジェクトでき、FIRERPA のスクリプトマネージャーがインジェクトされたスクリプトを自動的に管理します。スクリプトが異常終了したり、アプリのプロセスが終了したりしても、FIRERPA は次回アプリを開いた際に自動的にスクリプトを再インジェクトします。この機能はバージョン 7.80 で導入されました。

## スクリプトのインストール

このインターフェースを使用して、スクリプトを関連アプリケーションにインストールできます。アプリケーションにインストールされたスクリプトは、インストール後すぐにインジェクトされます。インストールされたスクリプトは自動的にスクリプトマネージャーに追加され、マネージャーが常に監視し、再インジェクトを行います。

```{attention}
スクリプトマネージャーは、各アプリに対して同時に1つのスクリプトしかインジェクトできません。同じアプリケーションに複数のスクリプトを一度にインジェクトすることはできません。
```

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

`script` パラメータはインジェクトする Frida スクリプトの内容（バイトコードをサポート）です。`runtime` は対応するランタイムで、デフォルトは `qjs` です。`standup` パラメータは、アプリのプロセスが起動してから5秒後にのみインジェクションを行うことを意味します（時間はプロセスの作成時から計算されます）。このパラメータは最低1秒、最高300秒で、アプリケーションプロセスへの早すぎるインジェクションによるクラッシュやその他の競合状態の問題を避けるためです。spawn モードの場合、このパラメータは常に 0 であるべきです。

このインターフェースは spawn モードのインジェクションもサポートしていますが、spawn モードを使用すると UI 操作フローが中断される可能性があることに注意してください（同時に UI を操作する必要がある場合）。spawn モードを使用すると、スクリプトが異常終了したりアプリケーションが終了した場合、このモードは自動的にアプリケーションを再起動するため、画面操作に干渉する可能性があります。spawn モードを使用する場合は、以下のパラメータを使用してください。

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

spawn モードと通常モードには違いがあることに注意が必要です。通常モードでは、アプリケーションが何らかの理由で終了した場合、アプリケーションが起動するまでインジェクションは実行されず、勝手にアプリケーションを起動することはありません。そのため、コードまたは手動でアプリケーションを起動しないとインジェクションが継続されない場合があります。一方、spawn モードでは、アプリケーションが終了しても自動的にアプリケーションを起動してインジェクションを実行します。

## アンインストール

このインターフェースは、アプリケーションにインストールされている Frida スクリプトを削除します。スクリプトはアプリケーションプロセスからデタッチされ、同時に FIRERPA のスクリプトマネージャーはそのスクリプトのヘルスステータスを監視しなくなり、スクリプト異常後の再インジェクションなどの関連操作も行わなくなります。

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

## インストール状態の確認

このインターフェースは、アプリケーションにスクリプトが既にインストールされているかどうかを確認するために使用されます。この状態に基づいて再インストールが必要かどうかを判断できます。

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

## インジェクション状態の確認

このインターフェースは、インストールしたスクリプトが現在アプリケーションプロセスにインジェクトされているかどうかを確認するために使用されます。スクリプトをインストールしても、アプリケーションが起動していない、またはスクリプトにエラーがあるなどの理由で、スクリプトがアプリケーションプロセスにインジェクトされていない場合があります。この戻り値に基づいて、関連アプリケーションを起動する必要があるか、またはインジェクトするスクリプトに構文エラーがないかを確認できます。

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

## スクリプトログの表示

スクリプト内の `console.log` などの関連コンソールログやスクリプトのエラーメッセージはすべて表示可能です。ただし、事前に起動時に設定を行う必要があります。ログファイルの設定方法については `ログの表示` の章を参照してください。ここでは、ログファイルを `/data/local/tmp/server.log` に正しく設定したと仮定します。これにより、スクリプトのログを確認したいときに以下のコマンドを実行すると、すべてのインジェクトされたスクリプトのログ情報がフィルタリングされます。`tail -f` などの他のコマンドを使用して、ログを継続的に追跡することもできます。

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

## オフライン永続化

オフライン永続化とは、FRIDA スクリプトを設定ファイルとしてスマートフォンに配置し、FIRERPA の起動時に自動的に FRIDA スクリプトをロードさせることを指します。上記で説明した API インターフェースを使用してインジェクションやキャンセルなどの操作を行う必要は全くなく、特定のフォーマットでスクリプトファイルを作成し、所定のディレクトリに配置するだけです。この機能はディレクトリ監視をサポートしており、スクリプトのリアルタイムなロード、アンロード、更新が可能です。スクリプトディレクトリ内での直接編集や変更もリアルタイムに適用されます。以下は、YAML を使用した簡単なスクリプト永続化設定です。この設定のスクリプト内容は `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
```

上記のサンプルスクリプト設定における各設定項目の詳細な説明

| フィールド    | 説明                                                                |
|------------|---------------------------------------------------------------------|
| enable     | このスクリプトを有効にするかどうか                                                       |
| application| スクリプトをインジェクトするアプリケーションID（例：com.android.setting）                           |
| version    | スクリプトがサポートするアプリケーションのバージョン（"N/A" はバージョンを問わない）                        |
| user       | マルチスペースアプリの場合、マルチスペースアプリのユーザーIDを指定します（通常は 999）              |
| script     | スクリプトの内容（Base64）。テキストまたはバイナリをサポート（テンプレートに従って記述してください） |
| runtime    | スクリプトのランタイム（qjs、v8）                                                      |
| standup    | インジェクションを遅延させる時間（プロセス起動時から計算）                                 |
| spawn      | spawn モードを使用する（standup は無視されます）                                 |
| encode     | スクリプトにデータレポート機能がある場合、ここでエンコーディングを指定します（zlib/none）                     |
| emit       | スクリプトにデータレポート機能がある場合、ここで送信先を指定します                                   |

`emit` データレポート機能の詳細については、`Frida を使用したデータレポート` の章を参照してください。

以上が、完全なオフラインスクリプトの例です。作成後、上記内容の設定ファイルを `{file_name}.yaml` という名前で保存し、デバイスの `/data/usr/modules/script` フォルダに配置してください。システムが自動的に設定をロードします。システムは `/data/usr/modules/script` ディレクトリの変更を自動的に検出し、YAML 設定を更新または削除すると、システムも自動的にスクリプトのインジェクションを更新またはキャンセルします。