Docs · chapter 3
The config file
Updated 14 November 2026 · version 0.17
In short: one small JSON file says how a run is recorded. Every key is optional; with none, the whole run is recorded. Give it with --config run.json, or set the same keys in the window under Advanced settings.
1
The file
Five keys, and nothing else.
{
"trace_from": "call:kernel32!CreateFileW",
"stop_after": 120,
"exclude_modules": ["d3d11", "nvwgf2umx.dll"],
"patch_rules": [
{"id": "steady_clock", "mnemonic": "RDTSC", "steps": "load_imm r0,1; load_imm r3,0"},
{"id": "no-jobs", "thread": "ignore", "name": "Job*"}
]
}| Key | In plain words | Details |
|---|---|---|
"trace_from" | Start recording later. | A trigger (below). Until it is reached the program runs normally under the tracer and nothing is written. Recording starts at the first block run after the trigger; memory written before it is unknown to the debugger until the program touches it again. |
"stop_after" | Stop the program after some seconds. | 1 to 86400. The trace is saved first, as with Ctrl+C. A program that will not exit is killed 20 seconds later. |
"no_trace" | Run, record nothing. | true. The tracer and the patch rules still run: to test rules. launch only, and not with trace_from. |
"exclude_modules" | Keep some libraries out. | A list of names. Their code runs natively, at full speed, and is not in the capture. A name matches any module whose file name starts with it, in any case: "guard" matches guard32.dll and guard64.dll; write "guard64.dll" for just that one. Naming the program itself is refused. |
"patch_rules" | Change the program as it runs, choose the threads. | A list of rules, or the path of a rules file (one per line), relative to the config file. Patch and thread rules. |
Checked before anything runs
An unknown key, a value out of range, or patch rules that are not a list of objects (or a file that is missing) stop the run before it starts, and the message names it. A key that starts with
_ is ignored: use one for a comment, like "_why": "skip the splash screen".2
trace_from: where recording starts
Three kinds of trigger: an instruction, a byte pattern, a call.
| Trigger | Recording starts at | Example |
|---|---|---|
module+rva | That instruction of that module, wherever Windows loaded it. | "app.exe+0x1a2b0" |
sig:bytes | The first instruction whose bytes start so, anywhere, unpacked code included. ?? is any byte. | "sig:48 89 5C 24 ?? 57" |
call:module!export | The first call to that function. kernel32 and KernelBase name the same function: either works. | "call:kernel32!CreateProcessW" |
The N-th time
End a trigger with
#N: "call:kernel32!CreateFileW#3" starts at the third call. When the run ends without reaching the trigger, the last lines say so and no capture is written: there was nothing to record.3
Templates in the window
Advanced settings has ready-made settings for the usual questions. Pick one, change it, save your own.

| Template | What it sets |
|---|---|
| First 10 seconds / 30 seconds / 5 minutes | Record from the start, stop the program by itself after that time. |
| From the first file opened / written | trace_from on CreateFileW / WriteFile. |
| From the first web request / connection | trace_from on WinHttpSendRequest / connect. |
| From the first registry read | trace_from on RegOpenKeyExW. |
| From a library loaded / a worker thread / a child process | trace_from on LoadLibraryW / CreateThread / CreateProcessW. |
| From the first decryption | trace_from on BCryptDecrypt. |
| From a message box | trace_from on MessageBoxW: an error, a licence prompt. |
| From the code it unpacks | trace_from on VirtualProtect: packers and loaders. |
| Hide the tracer's slowness | Patch rules: RDTSC returns a constant time, CPUID answers zeros. |
| Without the graphics libraries / the .NET runtime | exclude_modules: they run at full speed, out of the capture. |
| Rules only, nothing recorded | no_trace with the rules: to test them. |
An agent connected to the window can read and set all of this too, templates included (its settings tool).
4
Examples
Record what happens once the program opens a file
{"trace_from": "call:kernel32!CreateFileW"}.\ProtoTTD.exe --config run.json launch app.exeThe [trace-from] line says which thread reached it, where, and at which call.
Join a running program for one minute
{"stop_after": 60}.\ProtoTTD.exe --config stop.json attach 1234A game, without its graphics driver, from the menu on
{
"_why": "the render libraries are noise for this question",
"exclude_modules": ["d3d11", "dxgi", "nvwgf2umx"],
"trace_from": "call:kernel32!CreateFileW#40",
"stop_after": 90
}
Protovision