openremap cook
Compare a stock (unmodified) ECU binary and a tuned ECU binary. Every byte
that changed between them is recorded — its offset, original value (ob),
new value (mb), and a short context anchor (ctx) that is used to find
the right location even if the offset has shifted slightly in a different
software revision.
The result is saved as a recipe file with the .remap extension. That recipe
is the input for all validate and tune commands.
Usage
openremap cook <ORIGINAL> <MODIFIED> [OPTIONS]
Arguments
| Argument | Required | Description |
|---|---|---|
ORIGINAL |
Yes | The unmodified (stock) ECU binary. Must end in .bin or .ori. |
MODIFIED |
Yes | The tuned ECU binary. Must end in .bin or .ori. |
The order matters — ORIGINAL always comes first, MODIFIED second.
Options
| Option | Short | Default | Description |
|---|---|---|---|
--output PATH |
-o |
stdout | File path to write the recipe JSON to. If omitted, the recipe is printed to the screen. |
--context-size N |
-c |
32 |
Number of bytes of context to capture before each changed block (8–128). A larger value gives the patcher a better anchor when offsets have shifted. |
--pretty / --compact |
--pretty |
Pretty-print the JSON with indentation, or write it as a single compact line. | |
--annotate-maps / --no-annotate-maps |
--annotate-maps |
Annotate the recipe with a schema 4.4 maps layer (map descriptors + instruction refs). On by default; --no-annotate-maps emits the lean 4.3 format. |
|
--allow-non-unique |
off | Produce the recipe even when context anchors repeat in the stock binary — the recipe is stamped same-file-only (metadata.portability), and tune/validate refuse it on any binary whose sha256 differs from the source (override with tune --force). |
|
--help |
Show help and exit. |
Examples
# Cook a recipe and save it to a file
openremap cook stock.bin stage1.bin --output recipe.remap
# Cook and print the recipe to the screen (useful for inspection)
openremap cook stock.bin stage1.bin
# Use a wider context window — recommended when you plan to apply the recipe
# to ECUs that may be on a slightly different software revision
openremap cook stock.bin stage1.bin --context-size 64 --output recipe.remap
# Compact output — smaller file, harder to read
openremap cook stock.bin stage1.bin --compact --output recipe.remap
Example output
Cooking recipe from stock.bin vs stage1.bin …
✅ Recipe built successfully
ECU Bosch · EDC17
Match Key EDC17::08001505827522B
Format Version 4.4
Instructions 277
Bytes Changed 43,577
Original stock.bin
Modified stage1.bin
Recipe saved to recipe.remap
What to look for
| Field | What it tells you |
|---|---|
| ECU | Manufacturer and family extracted from the original binary. Should match what openremap identify reported. |
| Match Key | The identity string embedded in the recipe. Any target binary you apply this recipe to must have the same match key, or validate before will warn you. |
| Instructions | Number of changed byte blocks found. Zero means the two files are identical — check you passed the right files in the right order. |
| Bytes Changed | Total number of bytes that differ. Gives a rough sense of how large the tune is. |
Good result
Instructionsis greater than zero.ECUshows a recognised manufacturer and family (notUnknown).Match Keyis populated — a missing match key means recipes built from this binary cannot be matched to target ECUs reliably.
Needs attention
- Zero instructions — the two files are identical. Make sure you passed the stock binary first and the tuned binary second, and that you have the right files.
ECUshowsUnknown— the original binary's ECU family is not yet supported. The recipe is still built correctly (all byte differences are captured), but there will be no match key, which meansvalidate beforeandtunewill not be able to confirm the target is the right ECU.- A read error — check that both file paths exist and that both files
end in
.binor.ori.
Region tags (advisory)
Every instruction is tagged with the flash-layout region its edit lands in
(region field: calibration / code / erased / mixed / unknown).
Edits outside a calibration region carry a CODE_AREA flag and cook
prints a warning:
⚠ 41 instruction(s) outside the calibration region (code/erased/mixed
flash area): 0x291703, 0x29174B, 0x291777 … and 35 more
These edits may not apply to other revisions of this ECU.
Region labels are structural estimates.
This is a portability signal: calibration-table edits usually apply across
revisions of an ECU; code-area edits often do not. The tags are advisory
only — they never filter instructions, never block a cook, and tune
ignores them. The layout is structural inference, so a wrong estimate can
only produce a wrong tag or warning — never a wrong recipe. When no
calibration region is detected, instructions are tagged unknown and
nothing is flagged. The layout scan is shared with --annotate-maps (one
scan serves both map annotation and region tags), so the default cook adds
only ~0.2 s on a 4 MB pair; with --no-annotate-maps the region tags pay
for their own scan (~2.5–3 s on a 4 MB binary).
How it works
cook reads both files entirely into memory, then walks through them byte
by byte to find every position where they differ. Consecutive changed bytes
are grouped into a single instruction block. For each block it records:
offset— where in the binary the change startsob— the original bytes (hex-encoded)mb— the modified bytes (hex-encoded)ctx— a short slice of bytes immediately before the change, used as an anchor during tuning to locate the block even if the offset has shifted
The ECU identity (manufacturer, family, match_key, etc.) is extracted
from the original binary using the same extractor registry that powers
openremap identify.
The full recipe format is documented in docs/recipe-format.md.
Notes
cookis completely read-only with respect to its inputs. Neither the original nor the modified binary is ever changed.- Both files must be the same size. If they differ in length,
cookwill exit with an error — size differences indicate a fundamentally different binary layout that the byte-diff approach cannot handle. - The recipe JSON is human-readable. Open it in any text editor to inspect exactly what the tune changes before applying it to anything.
See also
- Recipe format spec — full field reference for
.remapfiles - Tune command — one-shot validate → apply → verify
- Validate command — individual validation steps