openremap 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. openremap-0.1.0/.github/workflows/ci.yml +39 -0
  2. openremap-0.1.0/.gitignore +36 -0
  3. openremap-0.1.0/CONTRIBUTING.md +311 -0
  4. openremap-0.1.0/DISCLAIMER.md +206 -0
  5. openremap-0.1.0/LICENSE +21 -0
  6. openremap-0.1.0/PKG-INFO +189 -0
  7. openremap-0.1.0/README.md +144 -0
  8. openremap-0.1.0/docs/about.md +272 -0
  9. openremap-0.1.0/docs/cli.md +84 -0
  10. openremap-0.1.0/docs/commands/cook.md +145 -0
  11. openremap-0.1.0/docs/commands/identify.md +151 -0
  12. openremap-0.1.0/docs/commands/scan.md +216 -0
  13. openremap-0.1.0/docs/commands/tune.md +199 -0
  14. openremap-0.1.0/docs/commands/validate.md +292 -0
  15. openremap-0.1.0/docs/commands/workflow.md +79 -0
  16. openremap-0.1.0/docs/recipe-format.md +176 -0
  17. openremap-0.1.0/docs/setup.md +350 -0
  18. openremap-0.1.0/pyproject.toml +50 -0
  19. openremap-0.1.0/src/openremap/__init__.py +7 -0
  20. openremap-0.1.0/src/openremap/cli/__init__.py +0 -0
  21. openremap-0.1.0/src/openremap/cli/commands/__init__.py +0 -0
  22. openremap-0.1.0/src/openremap/cli/commands/cook.py +224 -0
  23. openremap-0.1.0/src/openremap/cli/commands/identify.py +180 -0
  24. openremap-0.1.0/src/openremap/cli/commands/patch.py +366 -0
  25. openremap-0.1.0/src/openremap/cli/commands/scan.py +551 -0
  26. openremap-0.1.0/src/openremap/cli/commands/tune.py +378 -0
  27. openremap-0.1.0/src/openremap/cli/commands/validate.py +598 -0
  28. openremap-0.1.0/src/openremap/cli/commands/workflow.py +302 -0
  29. openremap-0.1.0/src/openremap/cli/main.py +127 -0
  30. openremap-0.1.0/src/openremap/tuning/__init__.py +0 -0
  31. openremap-0.1.0/src/openremap/tuning/manufacturers/__init__.py +32 -0
  32. openremap-0.1.0/src/openremap/tuning/manufacturers/base.py +322 -0
  33. openremap-0.1.0/src/openremap/tuning/manufacturers/bosch/__init__.py +142 -0
  34. openremap-0.1.0/src/openremap/tuning/manufacturers/bosch/edc1/__init__.py +0 -0
  35. openremap-0.1.0/src/openremap/tuning/manufacturers/bosch/edc1/extractor.py +359 -0
  36. openremap-0.1.0/src/openremap/tuning/manufacturers/bosch/edc15/__init__.py +3 -0
  37. openremap-0.1.0/src/openremap/tuning/manufacturers/bosch/edc15/extractor.py +253 -0
  38. openremap-0.1.0/src/openremap/tuning/manufacturers/bosch/edc15/patterns.py +186 -0
  39. openremap-0.1.0/src/openremap/tuning/manufacturers/bosch/edc16/__init__.py +3 -0
  40. openremap-0.1.0/src/openremap/tuning/manufacturers/bosch/edc16/extractor.py +423 -0
  41. openremap-0.1.0/src/openremap/tuning/manufacturers/bosch/edc16/patterns.py +300 -0
  42. openremap-0.1.0/src/openremap/tuning/manufacturers/bosch/edc17/__init__.py +3 -0
  43. openremap-0.1.0/src/openremap/tuning/manufacturers/bosch/edc17/extractor.py +410 -0
  44. openremap-0.1.0/src/openremap/tuning/manufacturers/bosch/edc17/patterns.py +265 -0
  45. openremap-0.1.0/src/openremap/tuning/manufacturers/bosch/edc3x/__init__.py +0 -0
  46. openremap-0.1.0/src/openremap/tuning/manufacturers/bosch/edc3x/extractor.py +578 -0
  47. openremap-0.1.0/src/openremap/tuning/manufacturers/bosch/lh/__init__.py +3 -0
  48. openremap-0.1.0/src/openremap/tuning/manufacturers/bosch/lh/extractor.py +364 -0
  49. openremap-0.1.0/src/openremap/tuning/manufacturers/bosch/m1x/__init__.py +3 -0
  50. openremap-0.1.0/src/openremap/tuning/manufacturers/bosch/m1x/extractor.py +632 -0
  51. openremap-0.1.0/src/openremap/tuning/manufacturers/bosch/m1x55/__init__.py +3 -0
  52. openremap-0.1.0/src/openremap/tuning/manufacturers/bosch/m1x55/extractor.py +323 -0
  53. openremap-0.1.0/src/openremap/tuning/manufacturers/bosch/m2x/__init__.py +3 -0
  54. openremap-0.1.0/src/openremap/tuning/manufacturers/bosch/m2x/extractor.py +335 -0
  55. openremap-0.1.0/src/openremap/tuning/manufacturers/bosch/m3x/__init__.py +3 -0
  56. openremap-0.1.0/src/openremap/tuning/manufacturers/bosch/m3x/extractor.py +572 -0
  57. openremap-0.1.0/src/openremap/tuning/manufacturers/bosch/m5x/__init__.py +3 -0
  58. openremap-0.1.0/src/openremap/tuning/manufacturers/bosch/m5x/extractor.py +399 -0
  59. openremap-0.1.0/src/openremap/tuning/manufacturers/bosch/m5x/patterns.py +239 -0
  60. openremap-0.1.0/src/openremap/tuning/manufacturers/bosch/me7/__init__.py +3 -0
  61. openremap-0.1.0/src/openremap/tuning/manufacturers/bosch/me7/extractor.py +525 -0
  62. openremap-0.1.0/src/openremap/tuning/manufacturers/bosch/me7/patterns.py +276 -0
  63. openremap-0.1.0/src/openremap/tuning/manufacturers/bosch/motronic_legacy/__init__.py +0 -0
  64. openremap-0.1.0/src/openremap/tuning/manufacturers/bosch/motronic_legacy/extractor.py +583 -0
  65. openremap-0.1.0/src/openremap/tuning/schemas/__init__.py +0 -0
  66. openremap-0.1.0/src/openremap/tuning/schemas/analyzer.py +94 -0
  67. openremap-0.1.0/src/openremap/tuning/schemas/patcher.py +192 -0
  68. openremap-0.1.0/src/openremap/tuning/services/__init__.py +0 -0
  69. openremap-0.1.0/src/openremap/tuning/services/identifier.py +90 -0
  70. openremap-0.1.0/src/openremap/tuning/services/patcher.py +356 -0
  71. openremap-0.1.0/src/openremap/tuning/services/recipe_builder.py +272 -0
  72. openremap-0.1.0/src/openremap/tuning/services/validate_exists.py +334 -0
  73. openremap-0.1.0/src/openremap/tuning/services/validate_patched.py +273 -0
  74. openremap-0.1.0/src/openremap/tuning/services/validate_strict.py +264 -0
  75. openremap-0.1.0/tests/__init__.py +0 -0
  76. openremap-0.1.0/tests/conftest.py +98 -0
  77. openremap-0.1.0/tests/tuning/__init__.py +0 -0
  78. openremap-0.1.0/tests/tuning/manufacturers/__init__.py +0 -0
  79. openremap-0.1.0/tests/tuning/manufacturers/test_edc15_extractor.py +1042 -0
  80. openremap-0.1.0/tests/tuning/manufacturers/test_edc17_extractor.py +864 -0
  81. openremap-0.1.0/tests/tuning/manufacturers/test_me7_extractor.py +875 -0
  82. openremap-0.1.0/tests/tuning/test_identifier.py +406 -0
  83. openremap-0.1.0/tests/tuning/test_patcher.py +830 -0
  84. openremap-0.1.0/tests/tuning/test_recipe_builder.py +531 -0
  85. openremap-0.1.0/tests/tuning/test_validate_exists.py +669 -0
  86. openremap-0.1.0/tests/tuning/test_validate_patched.py +625 -0
  87. openremap-0.1.0/tests/tuning/test_validate_strict.py +459 -0
@@ -0,0 +1,39 @@
1
+ # ──────────────────────────────────────────────────────────────────────────────
2
+ # CI — run the full test suite on every push and pull request
3
+ # ──────────────────────────────────────────────────────────────────────────────
4
+
5
+ name: CI
6
+
7
+ on:
8
+ push:
9
+ branches: ["master", "main"]
10
+ pull_request:
11
+ branches: ["master", "main"]
12
+
13
+ jobs:
14
+ test:
15
+ name: Run tests (Python ${{ matrix.python-version }})
16
+ runs-on: ubuntu-latest
17
+
18
+ strategy:
19
+ fail-fast: false
20
+ matrix:
21
+ python-version: ["3.14"]
22
+
23
+ steps:
24
+ - name: Checkout
25
+ uses: actions/checkout@v4
26
+
27
+ - name: Install uv
28
+ uses: astral-sh/setup-uv@v5
29
+ with:
30
+ enable-cache: true
31
+
32
+ - name: Set up Python ${{ matrix.python-version }}
33
+ run: uv python install ${{ matrix.python-version }}
34
+
35
+ - name: Install dependencies
36
+ run: uv sync --dev
37
+
38
+ - name: Run tests
39
+ run: uv run pytest --tb=short -q
@@ -0,0 +1,36 @@
1
+ # ── Python generated ─────────────────────────────────────────────────────────
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info/
8
+ .pytest_cache/
9
+
10
+ # ── Virtual environment ───────────────────────────────────────────────────────
11
+ .venv/
12
+
13
+ # ── Environment variables — never commit secrets ──────────────────────────────
14
+ .env
15
+ .env.*
16
+ !server/.env.example
17
+
18
+ # ── Logs ─────────────────────────────────────────────────────────────────────
19
+ logs/
20
+ *.log
21
+
22
+ # ── ECU binary files — never commit real ECU binaries ────────────────────────
23
+ *.bin
24
+ *.ori
25
+ *.BIN
26
+ *.ORI
27
+
28
+ # Private sample binaries — never commit real ECU binaries
29
+ server/samples/
30
+ testing/
31
+
32
+ # ── Legacy code (reference only, not part of any package) ────────────────────
33
+ src/legacy/
34
+
35
+ # ── Personal notes and to-do lists ───────────────────────────────────────────
36
+ todo/
@@ -0,0 +1,311 @@
1
+ # Contributing to OpenRemap
2
+
3
+ First off, thank you for taking the time to contribute. This project is designed from the ground up to be extended — especially by people who have hands-on experience with ECU families that are not yet supported.
4
+
5
+ Every part of the codebase that matters for contributors is covered below.
6
+
7
+ ---
8
+
9
+ ## 🛡️ Contributor Safety Notice
10
+
11
+ **Please read this before contributing anything.** To keep OpenRemap sustainable, legally sound, and trustworthy as an open-source project, all contributors must follow these rules.
12
+
13
+ ### No Binary Distribution
14
+
15
+ Never upload, attach, or link to ECU binary files (`.bin`, `.ori`, `.kp`, `.ols`) in pull requests, issues, or any other part of this repository. ECU firmware is proprietary intellectual property. Do not add any binary files to this repository.
16
+
17
+ ### Original Heuristics Only
18
+
19
+ All extraction patterns, byte sequences, and regex logic you contribute must be the result of your own independent research or derived from publicly available documentation. Do not copy detection logic, offsets, or patterns from other tools without verifying they are openly licensed.
20
+
21
+ ### No Reverse-Engineered Commercial Logic
22
+
23
+ Do not submit code, offsets, or algorithms that have been reverse-engineered from commercial or closed-source tuning software (WinOLS, ECM Titanium, Alientech, KESS, and similar). If you are unsure whether your source is acceptable, open an issue and ask before submitting.
24
+
25
+ ### No Damos or A2L Derived Logic
26
+
27
+ Damos (`.dam`) and A2L files are proprietary Bosch calibration data formats that describe the exact memory layout, addresses, and scaling of ECU parameters. They are not publicly available and are covered by strict NDAs and licensing agreements.
28
+
29
+ All extraction patterns, byte offsets, and detection logic contributed to this project must be derived from **your own independent analysis of binary files** — not from Damos, A2L, or any other proprietary calibration data source. If anyone asks, and they may, your patterns came from staring at hex dumps, not from a calibration file someone emailed you.
30
+
31
+ This is not a technicality. Submitting logic derived from proprietary calibration data exposes both you and the project to serious intellectual property claims.
32
+
33
+ ### Research Focus — No Emissions Delete Tools
34
+
35
+ This project is strictly for research and educational purposes. Pull requests that implement or enable the bypassing of emissions systems, DPF/EGR delete functionality, or any other modification that is illegal under environmental regulations will not be accepted.
36
+
37
+ ### Independent Verification Reminder
38
+
39
+ Any output produced by this tool — recipes, patched binaries, or identification results — must be verified by a qualified professional and run through a standalone checksum corrector before being flashed to any vehicle. If your contribution changes patch behaviour or output format, update the documentation accordingly.
40
+
41
+ ---
42
+
43
+ ## Table of Contents
44
+
45
+ - [🛡️ Contributor Safety Notice](#️-contributor-safety-notice)
46
+ - [Ways to Contribute](#ways-to-contribute)
47
+ - [Getting the Project Running Locally](#getting-the-project-running-locally)
48
+ - [The Most Valuable Contribution: Adding a New ECU Extractor](#the-most-valuable-contribution-adding-a-new-ecu-extractor)
49
+ - [Other Contributions](#other-contributions)
50
+ - [Code Style](#code-style)
51
+ - [Submitting a Pull Request](#submitting-a-pull-request)
52
+ - [Reporting a Bug or Wrong Identification](#reporting-a-bug-or-wrong-identification)
53
+ - [A Note on ECU Binary Files](#a-note-on-ecu-binary-files)
54
+
55
+ ---
56
+
57
+ ## Ways to Contribute
58
+
59
+ | Type | Examples |
60
+ |---|---|
61
+ | **New extractor** | Add support for Siemens SID, Delphi DCM, Marelli MJD, Denso, Continental |
62
+ | **Improve an existing extractor** | Fix a wrong pattern, handle an edge-case variant, improve the match key |
63
+ | **Bug fix** | Fix a crash, a wrong identification result, a validation logic error |
64
+ | **Tests** | Write `pytest` tests for any extractor or service |
65
+ | **Documentation** | Improve the README, add docstrings, fix typos |
66
+ | **Recipe format** | Propose and implement improvements to the recipe JSON structure |
67
+
68
+ ---
69
+
70
+ ## Getting the Project Running Locally
71
+
72
+ ### Prerequisites
73
+
74
+ - Python 3.14+
75
+ - [uv](https://github.com/astral-sh/uv)
76
+
77
+ ### Steps
78
+
79
+ ```bash
80
+ # 1. Fork the repo on GitHub, then clone your fork
81
+ git clone https://github.com/your-username/openremap.git
82
+ cd openremap
83
+
84
+ # 2. Install all dependencies
85
+ uv sync
86
+
87
+ # 3. Run the test suite to confirm everything works
88
+ uv run pytest
89
+ ```
90
+
91
+ That's all that is needed to work on the engine and CLI. No server, no database, no environment file required.
92
+
93
+ ---
94
+
95
+ ## The Most Valuable Contribution: Adding a New ECU Extractor
96
+
97
+ This is the single most impactful thing you can contribute. The entire pipeline — identification, recipe building, validation, patching — is manufacturer-agnostic. Adding a new extractor makes all of it work for a new family automatically.
98
+
99
+ ### How the extractor system works
100
+
101
+ Every extractor lives in `src/openremap/tuning/manufacturers/<brand>/<family>/extractor.py` and subclasses `BaseManufacturerExtractor`. When a binary is submitted, the registry calls `can_handle()` on each extractor in priority order and delegates all extraction to the first one that returns `True`.
102
+
103
+ The base class (`src/openremap/tuning/manufacturers/base.py`) is well-documented. Read it before you start — it explains `can_handle()`, `extract()`, `build_match_key()`, and the opt-in fallback mechanism in detail.
104
+
105
+ ### Step-by-step guide
106
+
107
+ **1. Create the package directory**
108
+
109
+ ```
110
+ src/openremap/tuning/manufacturers/<brand>/<family>/
111
+ ├── __init__.py (empty)
112
+ ├── extractor.py (your implementation)
113
+ └── patterns.py (regex patterns and search regions — optional but recommended)
114
+ ```
115
+
116
+ For example, a Siemens SID206 extractor would live at:
117
+ ```
118
+ src/openremap/tuning/manufacturers/siemens/sid206/extractor.py
119
+ ```
120
+
121
+ **2. Implement the extractor**
122
+
123
+ ```python
124
+ from openremap.tuning.manufacturers.base import BaseManufacturerExtractor
125
+ from typing import Dict, List
126
+
127
+ class SiemensSID206Extractor(BaseManufacturerExtractor):
128
+
129
+ @property
130
+ def name(self) -> str:
131
+ return "Siemens"
132
+
133
+ @property
134
+ def supported_families(self) -> List[str]:
135
+ return ["SID206"]
136
+
137
+ def can_handle(self, data: bytes) -> bool:
138
+ # Fast, bounded check only — this is called on every binary.
139
+ # Scan only the first few KB unless you have a strong reason not to.
140
+ # Return True if you are confident this binary belongs to your family.
141
+ return b"SID206" in data[:0x10000]
142
+
143
+ def extract(self, data: bytes, filename: str = "unknown.bin") -> Dict:
144
+ # Return a dict compatible with ECUIdentitySchema.
145
+ # Required: file_size, md5, sha256_first_64kb
146
+ # Optional but valuable: manufacturer, ecu_family, ecu_variant,
147
+ # software_version, hardware_number, calibration_id, match_key
148
+ import hashlib
149
+ return {
150
+ "manufacturer": self.name,
151
+ "file_size": len(data),
152
+ "md5": hashlib.md5(data).hexdigest(),
153
+ "sha256_first_64kb": hashlib.sha256(data[:0x10000]).hexdigest(),
154
+ "ecu_family": "SID206",
155
+ "ecu_variant": None,
156
+ "software_version": None, # extract from binary
157
+ "hardware_number": None, # extract from binary
158
+ "calibration_id": None, # extract from binary
159
+ "match_key": self.build_match_key(
160
+ ecu_family="SID206",
161
+ software_version=None, # pass what you extracted
162
+ ),
163
+ }
164
+ ```
165
+
166
+ **3. Register your extractor in the brand `__init__.py`**
167
+
168
+ If the brand already exists (e.g. Bosch), open `src/openremap/tuning/manufacturers/bosch/__init__.py` and add your extractor to the `EXTRACTORS` list in the correct priority position (most specific first).
169
+
170
+ If it is a new brand, create `src/openremap/tuning/manufacturers/<brand>/__init__.py`:
171
+
172
+ ```python
173
+ from openremap.tuning.manufacturers.siemens.sid206.extractor import SiemensSID206Extractor
174
+ from openremap.tuning.manufacturers.base import BaseManufacturerExtractor
175
+
176
+ EXTRACTORS: list[BaseManufacturerExtractor] = [
177
+ SiemensSID206Extractor(),
178
+ ]
179
+ ```
180
+
181
+ **4. Register the brand in the top-level registry**
182
+
183
+ Open `src/openremap/tuning/manufacturers/__init__.py` and add your brand:
184
+
185
+ ```python
186
+ from openremap.tuning.manufacturers import bosch, siemens # add your brand here
187
+
188
+ EXTRACTORS: list[BaseManufacturerExtractor] = [
189
+ *bosch.EXTRACTORS,
190
+ *siemens.EXTRACTORS, # add your brand here
191
+ ]
192
+ ```
193
+
194
+ **5. Verify it works**
195
+
196
+ Run the CLI against a binary of the target family and confirm the correct `manufacturer`, `ecu_family`, and `match_key` come back:
197
+
198
+ ```bash
199
+ uv run openremap identify your_binary.bin
200
+ ```
201
+
202
+ Then cook a recipe from a stock and a modified binary to verify the `ecu` block is populated correctly:
203
+
204
+ ```bash
205
+ uv run openremap cook stock.bin modified.bin --output recipe.json
206
+ ```
207
+
208
+ ### Tips for writing a good `can_handle()`
209
+
210
+ - **Keep it fast.** `can_handle()` is called on every uploaded binary for every registered extractor. Scan bounded regions (`data[:0x10000]`) rather than the full file where possible.
211
+ - **Be exclusive, not just inclusive.** If your family shares signatures with another (e.g. both have a `b"Bosch"` string), add explicit guards to reject the other family's binaries. Look at `BoschExtractor.can_handle()` for a worked example of layered exclusion guards.
212
+ - **File size is a strong discriminator.** Many older ECU families have a fixed, known file size (32 KB, 64 KB, 256 KB, etc.). Use it as a fast pre-filter.
213
+
214
+ ### Tips for writing a good `extract()`
215
+
216
+ - **Extract `software_version` if at all possible.** It is the primary component of `match_key`. Without it, recipe matching relies on the fallback field, which is less reliable.
217
+ - **Use `_run_all_patterns()` and `_search()` from the base class.** They handle region slicing, regex iteration, error suppression, and deduplication for you.
218
+ - **Separate patterns into `patterns.py`.** Keeping regex byte patterns in a dedicated file makes the extractor logic easier to read and the patterns easier to update independently.
219
+ - **Use `build_match_key()` from the base class.** Don't construct the key string manually — the base method normalises whitespace and handles the `ecu_variant` vs `ecu_family` priority for you.
220
+
221
+ ---
222
+
223
+ ## Other Contributions
224
+
225
+ ### Fixing an existing extractor
226
+
227
+ If an extractor identifies a binary incorrectly (wrong family, wrong software version, wrong match key), please open an issue first describing the binary (file size, any visible ASCII strings near offset 0) and what the extractor returns vs. what it should return. If you can share the binary privately, that will speed things up significantly.
228
+
229
+ ### Writing tests
230
+
231
+ Tests live in `tests/` and are run with `uv run pytest`. Good test targets:
232
+
233
+ - `ECUStrictValidator` — feed it a recipe and a matching vs. non-matching binary and assert the warnings and summary.
234
+ - `ECUDiffAnalyzer` — feed it two known binaries and assert the instruction count and a few specific offsets.
235
+ - Individual extractor `can_handle()` — assert it returns `True` for correct family bytes and `False` for bytes from other families.
236
+
237
+ New test files belong under:
238
+
239
+ ```
240
+ tests/
241
+ ├── conftest.py
242
+ ├── tuning/
243
+ │ ├── test_validate_strict.py
244
+ │ ├── test_recipe_builder.py
245
+ │ └── manufacturers/
246
+ │ └── bosch/
247
+ │ └── test_edc17_extractor.py
248
+ ```
249
+
250
+ Run tests with:
251
+
252
+ ```bash
253
+ uv run pytest
254
+ ```
255
+
256
+ ---
257
+
258
+ ## Code Style
259
+
260
+ - **Python 3.14+ type hints everywhere.** Use `str | None` rather than `Optional[str]` for new code.
261
+ - **Docstrings on all public methods.** Follow the style already present in `base.py` and the validator services — short summary line, then `Args:` / `Returns:` blocks where the function is non-trivial.
262
+ - **No bare `except`.** Catch specific exceptions or use `except Exception` with a comment explaining why.
263
+ - **No abbreviations in variable names** unless they are universally understood in the domain (`ob`, `mb`, `ctx`, `ecu`, `sw`).
264
+ - **Hex strings are always uppercase.** Use `.hex().upper()` and uppercase literals (`"AABBCCDD"`, not `"aabbccdd"`).
265
+
266
+ ---
267
+
268
+ ## Submitting a Pull Request
269
+
270
+ 1. **Fork** the repository and create a branch from `master`:
271
+ ```bash
272
+ git checkout -b feat/siemens-sid206-extractor
273
+ ```
274
+
275
+ 2. **Make your changes.** Keep each PR focused on one thing — one extractor, one bug fix, one feature. Mixed PRs are harder to review and slower to merge.
276
+
277
+ 3. **Test your changes** manually against at least one real binary of the target family, or write automated tests if you can.
278
+
279
+ 4. **Write a clear PR description** that answers:
280
+ - What does this PR do?
281
+ - Which ECU families / binaries does it affect?
282
+ - How did you test it?
283
+ - Any known limitations or edge cases?
284
+
285
+ 5. **Open the PR** against the `master` branch.
286
+
287
+ ---
288
+
289
+ ## Reporting a Bug or Wrong Identification
290
+
291
+ Open a GitHub Issue and include:
292
+
293
+ - The CLI command you ran or the endpoint you called
294
+ - The output you got
295
+ - What you expected instead
296
+ - The file size of the binary (do **not** attach the binary itself — see below)
297
+ - Any printable ASCII strings visible near the start of the file, if you are comfortable sharing them
298
+
299
+ For identification bugs, the file size and the first few readable strings from the binary header are usually enough to diagnose the problem without needing the file.
300
+
301
+ ---
302
+
303
+ ## A Note on ECU Binary Files
304
+
305
+ **Do not attach ECU binary files to issues or pull requests.**
306
+
307
+ ECU firmware is proprietary. The binaries contain intellectual property belonging to the ECU manufacturer (Bosch, Siemens, Delphi, etc.) and potentially the vehicle OEM. Distributing them publicly — even for debugging — is legally risky for you and for this project.
308
+
309
+ If you need to share a binary to reproduce a bug, do so privately (e.g. via a direct message to a maintainer) and only after confirming you are the legal owner of the data.
310
+
311
+ There are no binary files in this repository. All tests use synthetic in-memory data generated by the test helpers in `tests/conftest.py`.
@@ -0,0 +1,206 @@
1
+ # Disclaimer
2
+
3
+ ## Research and Educational Use Only
4
+
5
+ OpenRemap is experimental software developed for **research, educational, and
6
+ development purposes only**. It is not a commercial product, it has not been
7
+ certified or validated for use in any safety-critical or production environment,
8
+ and it is not intended for use on road-registered vehicles.
9
+
10
+ ---
11
+
12
+ ## Right to Repair
13
+
14
+ OpenRemap is built in the spirit of the **Right to Repair** movement. Vehicle
15
+ owners have a legitimate interest in understanding, analysing, and archiving
16
+ the firmware on hardware they legally own.
17
+
18
+ In the United States, the **DMCA (Digital Millennium Copyright Act)** grants
19
+ exemptions that allow vehicle owners to access and modify the software on their
20
+ own vehicles for the purpose of diagnosis, repair, and personalisation. These
21
+ exemptions have been renewed and expanded by the Copyright Office, most recently
22
+ in 2021.
23
+
24
+ In the European Union, the **Right to Repair Regulation (EU) 2024/1781** and
25
+ related directives affirm the right of consumers and independent repairers to
26
+ access tools and information necessary to maintain their own property.
27
+
28
+ OpenRemap does not circumvent any security system. It operates on binary files
29
+ that the user already legally possesses. Its purpose is to make the contents of
30
+ those files understandable, comparable, and reproducible — not to enable
31
+ unauthorised access to any vehicle or system.
32
+
33
+ **This framing applies only to vehicles and ECUs that you legally own or have
34
+ explicit authorisation to work on.** Using this tool on hardware you do not own
35
+ or are not authorised to modify is outside the scope of this project and is your
36
+ sole legal responsibility.
37
+
38
+ ---
39
+
40
+ ## No Warranty. No Guarantee of Correctness.
41
+
42
+ This software is provided **"as is"**, without warranty of any kind — express or
43
+ implied. This includes, but is not limited to, any warranty that:
44
+
45
+ - ECU identification is correct for a given binary
46
+ - Recipes are free from errors or omissions
47
+ - Patched binaries are safe, functional, or suitable for any purpose
48
+ - The software behaves as documented in all cases
49
+
50
+ The authors make no representations about the accuracy, completeness, or
51
+ reliability of any output produced by this software. **Use it at your own risk.**
52
+
53
+ ---
54
+
55
+ ## Professional Review is Required Before Flashing
56
+
57
+ **Any binary file produced or modified by this software must be reviewed and
58
+ verified by a qualified automotive engineer or professional ECU tuner before
59
+ it is flashed to any vehicle.**
60
+
61
+ This is not optional. The software includes post-patch validation tools to aid
62
+ this review process — but those tools are not a substitute for professional
63
+ judgement. You are responsible for ensuring that any modified firmware is safe
64
+ and appropriate for the specific vehicle and ECU it will be installed on.
65
+
66
+ Flashing incorrect, corrupted, or incompatible firmware to a vehicle ECU can
67
+ result in:
68
+
69
+ - Permanent damage to the ECU
70
+ - Engine damage
71
+ - Loss of vehicle function
72
+ - Safety hazards to the driver, passengers, and others
73
+
74
+ The authors accept no responsibility for any damage, loss, or harm arising from
75
+ the use of this software or any output it produces.
76
+
77
+ ---
78
+
79
+ ## ⚠️ Checksum Verification is Mandatory
80
+
81
+ > **Do not flash any binary — patched or otherwise — without first running an
82
+ > independent checksum verification.**
83
+
84
+ This is the single most important step between this tool and a vehicle. Every
85
+ ECU family uses one or more checksum algorithms to verify the integrity of its
86
+ firmware. If a checksum does not match, the ECU will reject the file, fail to
87
+ start, or enter a recovery mode — at best. At worst, it will flash corrupted
88
+ firmware silently.
89
+
90
+ **What `openremap` does NOT do:**
91
+
92
+ - It does not calculate or correct ECU checksums
93
+ - `openremap validate tuned` confirms that recipe bytes were written correctly
94
+ — it does not verify that the resulting binary is a valid, flashable image
95
+
96
+ **What you must do before flashing:**
97
+
98
+ 1. Open the tuned binary in a professional-grade tool — **WinOLS**, **ECM Titanium**,
99
+ **Alientech KESS**, or an equivalent
100
+ 2. Run the tool's checksum correction function for the specific ECU family
101
+ 3. Confirm the binary passes integrity validation before touching any vehicle
102
+
103
+ Skipping this step can result in a permanently bricked ECU. There is no
104
+ software recovery from a bad flash on most production ECUs.
105
+
106
+ ---
107
+
108
+ ## Legal Responsibility Rests With the User
109
+
110
+ The legal status of modifying ECU firmware varies significantly by country,
111
+ region, and intended use. Depending on your jurisdiction, modifying engine
112
+ management software may:
113
+
114
+ - Violate **vehicle type approval** regulations (EU)
115
+ - Violate **emissions laws** such as the Clean Air Act (United States)
116
+ - Invalidate **roadworthiness certifications** (UK MOT, German TÜV, and equivalents)
117
+ - Void the vehicle manufacturer's **warranty**
118
+ - Be subject to additional regulations specific to your region
119
+
120
+ **It is your sole responsibility** to understand and comply with all applicable
121
+ laws and regulations before using this software or applying any output it
122
+ produces to a vehicle. The authors of OpenRemap provide no legal guidance and
123
+ accept no liability for regulatory or legal consequences arising from the use of
124
+ this software.
125
+
126
+ ---
127
+
128
+ ## Limitation of Liability
129
+
130
+ To the maximum extent permitted by applicable law, in no event shall the
131
+ authors, contributors, or copyright holders of OpenRemap be liable for any
132
+ direct, indirect, incidental, special, exemplary, or consequential damages
133
+ — including but not limited to loss of use, data, revenue, or profits;
134
+ vehicle damage; ECU damage; personal injury; or business interruption —
135
+ however caused and on any theory of liability, whether in contract, strict
136
+ liability, or tort, arising in any way out of the use of or inability to use
137
+ this software, even if advised of the possibility of such damage.
138
+
139
+ ---
140
+
141
+ ## Anti-Tampering
142
+
143
+ OpenRemap must not be used to perform or facilitate any of the following.
144
+ These are not tuning activities — they are criminal offences in most jurisdictions
145
+ and are explicitly outside the scope of this project:
146
+
147
+ - **Odometer fraud** — altering mileage data stored in an ECU or instrument cluster
148
+ - **Immobilizer bypass** — disabling or circumventing factory anti-theft systems
149
+ - **Safety system tampering** — modifying or disabling airbags, ABS, ESC, seatbelt
150
+ pretensioners, or any other active or passive safety system
151
+ - **Speed limiter removal on commercial vehicles** — where governed by law
152
+ (EU Regulation 2019/2144 and equivalents)
153
+ - **Theft facilitation** — any use that assists in the theft of a vehicle or its
154
+ components
155
+
156
+ The authors reserve the right to refuse contributions, close issues, and remove
157
+ forks that appear to pursue any of the above purposes. If you discover that this
158
+ tool is being used for any of these activities, please report it via the
159
+ repository's security contact.
160
+
161
+ ---
162
+
163
+ ## Interoperability
164
+
165
+ OpenRemap is developed and distributed under the principle of **software
166
+ interoperability** as recognised by:
167
+
168
+ - **EU Directive 2009/24/EC, Article 6** — which permits the reproduction and
169
+ translation of software code where indispensable to obtain interoperability
170
+ of an independently created program with other programs
171
+ - **DMCA Section 1201(f)** — which provides an exemption for reverse engineering
172
+ undertaken solely for the purpose of achieving interoperability of an
173
+ independently created computer program
174
+ - **DMCA Section 1201(j) exemption renewals (2021)** — which extend interoperability
175
+ and repair rights specifically to motorised land vehicles
176
+
177
+ This tool does not circumvent any copy protection or access control mechanism.
178
+ It operates exclusively on binary files that the user already legally possesses.
179
+ Its purpose is to make the contents of those files readable, comparable, and
180
+ reproducible using independently created, open-source software — which is the
181
+ definition of interoperability as intended by these provisions.
182
+
183
+ Contributors who develop extraction patterns and identification logic do so
184
+ under the same interoperability principles. Pattern matching against a binary
185
+ file you legally hold is not a circumvention act — it is the foundation of
186
+ every compatible tool in this ecosystem.
187
+
188
+ ---
189
+
190
+ ## Summary
191
+
192
+ | | |
193
+ |---|---|
194
+ | **Intended use** | Research, education, and development only |
195
+ | **Right to Repair** | Supported — for hardware you legally own or are authorised to work on |
196
+ | **Interoperability** | Covered under EU Directive 2009/24/EC Art. 6 and DMCA §1201(f) |
197
+ | **Anti-tampering** | Odometer fraud, immobilizer bypass, safety system disabling — prohibited |
198
+ | **Professional review** | Required before flashing any output to a vehicle |
199
+ | **Checksum verification** | Mandatory — use WinOLS, ECM Titanium, or equivalent |
200
+ | **Checksum correction** | Not performed by this tool — must be done externally |
201
+ | **Legal compliance** | Your responsibility — laws vary by jurisdiction |
202
+ | **Warranty** | None |
203
+ | **Liability** | None accepted by the authors |
204
+
205
+ If you are unsure whether using this software is legal or appropriate for your
206
+ situation, **do not use it**. Consult a qualified professional first.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Pinelo92
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.