diff --git a/README.md b/README.md index 1c7c4b1..28fba28 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,7 @@ copy the completion file into `~/.config/fish/completions` like so: ### frida-itrace file format -File starts with a 4-byte magic: "ITRC" -https://github.com/frida/frida-tools/blob/1ea077fdb49440e5807cf25fae41e389e3d2bd4a/frida_tools/itracer.py#L365-L366 +File starts with a 4-byte magic: "ITR2" Then, following that, there are two different types of records, MESSAGE and CHUNK. Each record starts with a big-endian uint32 specifying the type of @@ -27,42 +26,18 @@ record, where 1 means MESSAGE, 2 means CHUNK. - `data_size`: uint32 (big-endian) - `data_values`: uint8[data_size] -Generated [here](https://github.com/frida/frida-tools/blob/1ea077fdb49440e5807cf25fae41e389e3d2bd4a/frida_tools/itracer.py#L451-L458). +There are two different kinds of MESSAGEs: -There are three different kinds of MESSAGEs: - -- ["itrace:start"](https://github.com/frida/frida-tools/blob/1ea077fdb49440e5807cf25fae41e389e3d2bd4a/agents/itracer/agent.ts#L68-L76): - Signals that the trace is starting, providing the initial register values. - Contains register names and sizes in the JSON portion, and register values in - the data portion. - Generated [here](https://github.com/frida-packages/frida-itrace/blob/ad7780bde9e518e325d7aaf848e9a29e1a53b7d2/lib/backend.ts#L341-L359). +- "itrace:lost": Signals that records were dropped because the buffer was + full. The JSON portion contains the total number of records lost so far. - "itrace:end": Signals that the endpoint was reached, when specifying a range with an end address included. -- "itrace:compile": Signals that a basic block was discovered, providing the - schema of future CHUNKs pertaining to it. - Generated [here](https://github.com/frida-packages/frida-itrace/blob/ad7780bde9e518e325d7aaf848e9a29e1a53b7d2/lib/backend.ts#L277-L323) - and by the [code](https://github.com/frida-packages/frida-itrace/blob/ad7780bde9e518e325d7aaf848e9a29e1a53b7d2/lib/backend.ts#L398-L401) - above it that computes the "writes" array. - - The "writes" array contains tuples (arrays) that look like this: - - (block_offset, cpu_ctx_offset) - - Where `block_offset` is how many bytes into the basic block the write happens, - and `cpu_ctx_offset` is the index into the registers declared by - "itrace:start". #### CHUNK - `size`: uint32 (big-endian) - `data`: uint8[size] -Generated [here](https://github.com/frida/frida-tools/blob/1ea077fdb49440e5807cf25fae41e389e3d2bd4a/frida_tools/itracer.py#L464-L465). - -The CHUNK records combine to a stream of raw register values at different parts -of the given basic block. Each record looks like this: - -- `block_start_address`: uint64 (target-endian, i.e. little-endian on arm64) -- `link_register_value`: uint64 (target-endian) -- `block_register_values`: uint64[n], where n depends on the specific basic - block. (See above docs on "itrace:compile" and its "writes" array.) +The CHUNK records combine to the stream of trace records and events written to +frida-itrace's ringbuffer, as documented in its +[buffer format](https://github.com/frida-packages/frida-itrace#buffer-format). diff --git a/agents/itracer/agent.ts b/agents/itracer/agent.ts index 62d1441..a0a61bd 100644 --- a/agents/itracer/agent.ts +++ b/agents/itracer/agent.ts @@ -65,18 +65,9 @@ class Agent { const session = new TraceSession(strategy, this.buffer!); this.session = session; - session.events.on("start", (regSpecs, regValues) => { - send({ type: "itrace:start", payload: regSpecs }, regValues); - }); session.events.on("end", () => { send({ type: "itrace:end" }); }); - session.events.on("compile", block => { - send({ type: "itrace:compile", payload: block }); - }); - session.events.on("panic", message => { - console.error(message); - }); session.open(); } diff --git a/agents/itracer/package-lock.json b/agents/itracer/package-lock.json index 7e7e957..76eed1d 100644 --- a/agents/itracer/package-lock.json +++ b/agents/itracer/package-lock.json @@ -8,7 +8,7 @@ "name": "itracer-agent", "version": "1.0.0", "dependencies": { - "frida-itrace": "^4.1.0" + "frida-itrace": "^7.0.0" }, "devDependencies": { "@types/frida-gum": "^19.13.0", @@ -446,9 +446,9 @@ "license": "MIT" }, "node_modules/frida-itrace": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/frida-itrace/-/frida-itrace-4.1.0.tgz", - "integrity": "sha512-FdtRvjEl2FXnw2VhQn+hBBW/KfCDnNApVuqILKLzd7+brAYSfwj4WbSmV2SLYQj1iUkVLtu6R4Nh7SksOGETUg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/frida-itrace/-/frida-itrace-7.0.0.tgz", + "integrity": "sha512-QjQjKE/wTlapFvPeGVPGS4hZB1zj0M4PbMwCGeEd1ak9onzLISDN2lxpJh34sCM4Jxbsdbjtzbo4iV4T8H3vUQ==", "license": "MIT", "dependencies": { "tiny-typed-emitter": "^2.1.0" @@ -881,9 +881,9 @@ "dev": true }, "frida-itrace": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/frida-itrace/-/frida-itrace-4.1.0.tgz", - "integrity": "sha512-FdtRvjEl2FXnw2VhQn+hBBW/KfCDnNApVuqILKLzd7+brAYSfwj4WbSmV2SLYQj1iUkVLtu6R4Nh7SksOGETUg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/frida-itrace/-/frida-itrace-7.0.0.tgz", + "integrity": "sha512-QjQjKE/wTlapFvPeGVPGS4hZB1zj0M4PbMwCGeEd1ak9onzLISDN2lxpJh34sCM4Jxbsdbjtzbo4iV4T8H3vUQ==", "requires": { "tiny-typed-emitter": "^2.1.0" } diff --git a/agents/itracer/package.json b/agents/itracer/package.json index 68de0cd..9244a41 100644 --- a/agents/itracer/package.json +++ b/agents/itracer/package.json @@ -15,6 +15,6 @@ "frida-compile": "^17.0.0" }, "dependencies": { - "frida-itrace": "^4.1.0" + "frida-itrace": "^7.0.0" } } diff --git a/frida_tools/itracer.py b/frida_tools/itracer.py index 3da1386..b755ffe 100644 --- a/frida_tools/itracer.py +++ b/frida_tools/itracer.py @@ -186,14 +186,12 @@ def main() -> None: except: pass - def on_trace_progress(self, total_blocks: int, total_bytes: int) -> None: - blocks_suffix = "s" if total_blocks != 1 else "" + def on_trace_progress(self, total_bytes: int) -> None: self._cli.message = FormattedText( [ ("bold", "Tracing!"), ("", " Collected "), ("fg:green bold", human_readable_size(total_bytes)), - ("", f" from {total_blocks} basic block{blocks_suffix}"), ] ) self._cli.app.invalidate() @@ -295,7 +293,7 @@ class InstructionTracerUI(ABC): def on_trace_stopped(self, error_message: Optional[str] = None) -> None: raise NotImplementedError - def on_trace_progress(self, total_blocks: int, total_bytes: int) -> None: + def on_trace_progress(self, total_bytes: int) -> None: pass def _on_script_created(self, script: frida.core.Script) -> None: @@ -303,13 +301,12 @@ class InstructionTracerUI(ABC): class InstructionTracer: - FILE_MAGIC = b"ITRC" + FILE_MAGIC = b"ITR2" def __init__(self, reactor: Reactor) -> None: self._reactor = reactor self._outfile = None self._ui: Optional[InstructionTracerUI] = None - self._total_blocks = 0 self._tracer_script: Optional[frida.core.Script] = None self._reader_script: Optional[frida.core.Script] = None self._reader_api = None @@ -432,9 +429,6 @@ class InstructionTracer: else: self._write_message(message, data) - if mtype == "itrace:compile": - self._total_blocks += 1 - self._update_progress() if mtype == "itrace:end": @@ -443,7 +437,7 @@ class InstructionTracer: return True def _update_progress(self) -> None: - self._ui.on_trace_progress(self._total_blocks, self._outfile.tell()) + self._ui.on_trace_progress(self._outfile.tell()) def _write_message(self, message, data) -> None: f = self._outfile