> For the complete documentation index, see [llms.txt](https://docs.orchard.airoverflow.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.orchard.airoverflow.com/guides/frida.md).

# Frida: scripts and logs

Every `Sandbox` handle has a `frida` resource. It manages frida-server on the device and runs frida scripts. All calls use the `frida` capability.

## Check and control the server

Use `status` to see the state of frida-server. Use `install`, `start` and `stop` to control it. `install` is slow, because it downloads packages.

{% tabs %}
{% tab title="Python" %}

```python
sb = orchard.sandbox("my-pixel")
sb.frida.status()     # {installed, running, version, port, listening, connect_hint}
sb.frida.install()    # install frida-server, then start it
sb.frida.start()
sb.frida.stop()
```

{% endtab %}

{% tab title="TypeScript" %}

```ts
const sb = orchard.sandbox("my-pixel");
await sb.frida.status();
await sb.frida.install();
await sb.frida.start();
await sb.frida.stop();
```

{% endtab %}
{% endtabs %}

## Run a script

`inject` runs a frida script against a process. It runs the script for `timeout` seconds (1 to 30), then it detaches. The result holds the script output in `messages`. The output is the `send()` and `console.log` calls from the script. `inject` works on Android devices.

{% tabs %}
{% tab title="Python" %}

```python
script = """
Java.perform(function () {
  const Log = Java.use('android.util.Log');
  Log.d.overload('java.lang.String', 'java.lang.String').implementation = function (tag, msg) {
    send({ tag: tag, msg: msg });
    return this.d(tag, msg);
  };
});
"""
result = sb.frida.inject(script, process="com.example.app", timeout=10)
for message in result["messages"]:
    print(message)

# Or read the script from a file:
sb.frida.run_script("hooks/log.js", process="com.example.app")
```

{% endtab %}

{% tab title="TypeScript" %}

```ts
const result = await sb.frida.inject(script, "com.example.app", 10);
console.log(result);   // { ok, process, pid, messages, ... }
```

{% endtab %}
{% endtabs %}

## Verify frida works

`verify` attaches to a process and traces it. It proves that frida and the Stalker tracer work. On iOS it runs the Stalker check. The result holds the trace counts and the script `messages`.

{% tabs %}
{% tab title="Python" %}

```python
sb.frida.verify()                 # pick a busy process
sb.frida.verify("SpringBoard")    # a named process
```

{% endtab %}

{% tab title="TypeScript" %}

```ts
await sb.frida.verify();
await sb.frida.verify("SpringBoard");
```

{% endtab %}
{% endtabs %}

## Stream script messages live

`inject` returns the output once, after the run. `stream` instead sends each message as the script produces it. It opens a live channel, so you see output in real time, and it keeps the frida session attached until you leave the block. Set `timeout` to 0 to stream until you close the channel. `stream` works on Android devices.

Each message is a frida frame. The `type` field tells you the kind. It is `send` for a `send()` call, `log` for a `console.log` line, `error` for a script error, or `orchard` for a status note such as the attach confirmation.

{% tabs %}
{% tab title="Python" %}

```python
script = "setInterval(() => send({ t: Date.now() }), 1000);"
with sb.frida.stream(script, process="com.example.app") as messages:
    for message in messages:
        print(message)        # {'type': 'send', 'payload': {'t': ...}}

# Or read the script from a file:
with sb.frida.stream_script("hooks/trace.js", process="com.example.app") as s:
    for message in s:
        print(message)
```

{% endtab %}

{% tab title="TypeScript" %}

```ts
const messages = sb.frida.stream(script, "com.example.app");
for await (const message of messages) {
  console.log(message);
}
```

{% endtab %}
{% endtabs %}

## Stream device logs

Frida `console.log` output on Android also goes to logcat. To watch the whole device log, open the device log channel. It streams until you close it.

{% tabs %}
{% tab title="Python" %}

```python
with sb.logs() as stream:
    for line in stream:
        print(line)
```

{% endtab %}

{% tab title="TypeScript" %}

```ts
for await (const line of sb.logs()) {
  console.log(line);
}
```

{% endtab %}
{% endtabs %}

See [Live channels](/guides/live-channels.md) for more on log streaming.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

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

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.orchard.airoverflow.com/guides/frida.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
