Added Reverse-Engineering Toolkit

This commit is contained in:
2025-08-27 23:28:43 +02:00
parent 04705ce666
commit 27993d72ee
13 changed files with 2249 additions and 0 deletions

View File

@@ -0,0 +1,272 @@
# Kettenöler CAN Reverse-Engineering Toolkit
Toolsuite (GUI + CLI) zum Analysieren von CAN-Logs im **Kettenöler-Format**.
Funktionen: Logs **splitten** (pro CAN-ID), **explorative Visualisierung** (8-/16-Bit, LE/BE), **Batch-Analysen** über viele `.trace`, **Ranking** plausibler Signale und **Range-Fit** (lineare Abbildung `phys = raw*scale + offset`), optional **unsupervised** ohne vorgegebene Range.
---
## Features (Überblick)
* **Einheitliche GUI** (`main.py`) mit globalem Header (Workdir, Ordnerstruktur, Log-Auswahl).
* **Gemeinsame Trace-Auswahl** in allen Trace-Tabs (gleiches Panel, synchronisiert über Tabs):
* **ID Explorer** (Multi-Select)
* **Traces Batch-Analyse** (Multi-Select oder kompletter Ordner)
* **Range-Fit** (Single-Select, supervised *oder* unsupervised)
* **Splitter**: Logs → `.trace` pro CAN-ID (`traces/…`, inkl. `overview_ids.csv`).
* **Einzel-ID-Explorer**: Plots aller Byte-Kanäle (8-Bit) und Nachbar-Wortkombis (16-Bit LE/BE) + Kurzstatistik.
* **Batch-Analyzer**: Kennzahlen/Plots für alle `.trace` in einem Ordner, globales Ranking.
* **Range-/Unsupervised-Fit**:
* *Supervised*: findet `scale` & `offset` für Zielbereich `[rmin, rmax]` (Offset via Intervall-Überdeckung, Scale aus plausibler Menge).
* *Unsupervised*: identifiziert „ruhige“ physikalische Kandidaten ohne Range (Smoothness/Varianz/Rate/Spannweite).
* **Output-Hygiene**: Ergebnisse stets unter `analyze_out/<timestamp>_<tool>/…`, optionale Zeitstempel-Unterordner verhindern Überschreiben.
* **Projektdatei** (`Projekt.json`): speichert Workdir, Subfolder, Log-Auswahl, aktiven Traces-Ordner, etc.
* **„Neuester Split“**-Button: springt in den jüngsten Unterordner von `traces/`.
---
## Repository-Komponenten
* **GUI**
* `main.py` zentrales Frontend mit Tabs (Multi-Log Analyse, ID Explorer, Traces Batch-Analyse, Range-Fit).
* **CLI-Tools**
* `can_split_by_id.py` Splittet Logs nach CAN-ID → `.trace`.
* `id_signal_explorer.py` Visualisiert/analysiert eine `.trace` (8-Bit, 16-Bit LE/BE) + `summary_stats.csv`.
* `trace_batch_analyzer.py` Batch-Analyse für viele `.trace` + globales Ranking.
* `trace_signal_fitter.py` **Range-Fit** (scale/offset) **oder** **Unsupervised-Fit** (ohne Range).
> Optional/Alt: `can_universal_signal_finder.py` ursprünglicher Multi-Log-Analyzer (Ranking auf Rohdatenebene).
---
## Installation
* **Python** ≥ 3.10
* Abhängigkeiten: `pandas`, `numpy`, `matplotlib`
* Setup:
```bash
python3 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
```
---
## Logformat (Kettenöler)
Eine Zeile pro Frame:
```
<timestamp_ms> <TX|RX> 0x<ID_HEX> <DLC> <byte0> <byte1> ... <byte7>
```
Beispiel:
```
123456 RX 0x208 8 11 22 33 44 55 66 77 88
```
---
## Projekt-/Ordnerstruktur
Ein **Workdir** bündelt alles zu einem Fahrzeug/Projekt:
```
<Workdir>/
Projekt.json # GUI-Einstellungen
logs/ # Input-Logs
traces/ # per-ID .trace (vom Split)
analyze_out/ # Ergebnisse; je Run eigener Timestamp-Unterordner
```
**Namenskonventionen**
* Split-Ergebnisse: `traces/<timestamp?>/0x<ID>_<ursprungslog>.trace`
* Outputs: `analyze_out/<YYYYMMDD_HHMMSS>_<tool>/…`
---
## Modelle-Ordner & Git
Wenn du pro Modell arbeitest, z. B.:
```
models/
Triumph 2023/
logs/
traces/
analyze_out/
Projekt.json
```
Lege in `models/` folgende **`.gitignore`** ab, damit `traces/` und `analyze_out/` **in jedem Modell-Unterordner** ignoriert werden `logs/` und `.json` bleiben versioniert:
```gitignore
*/traces/
*/traces/**
*/analyze_out/
*/analyze_out/**
traces/
traces/**
analyze_out/
analyze_out/**
# optional: typos
*/analyze.out/
*/analyze.out/**
analyze.out/
analyze.out/**
```
Leere Ordner wie `logs/` ggf. mit `.gitkeep` befüllen.
---
## GUI-Benutzung
```bash
python3 main.py
```
### Globaler Header (immer oben)
* **Workdir** wählen, **Logs scannen** → Liste aller gefundenen Logfiles (Multi-Select).
* Subfolder einstellen: `logs`, `traces`, `analyze_out` (alle **parallel** im Workdir).
* **Projekt speichern/laden** (`Projekt.json`).
* Beim Workdir-Wechsel/Projekt-Laden setzt die GUI den **aktiven Traces-Ordner** automatisch auf `traces/` bzw. den **jüngsten** Unterordner.
### Einheitliches Trace-Panel (in allen Trace-Tabs)
* Links: Liste der `.trace`
* Rechts: **Traces-Ordner wählen**, **Workdir/traces**, **Neuester Split**, **Refresh**, (optional **Alle**, **Keine**)
* Änderungen am Ordner/Liste wirken **sofort in allen Tabs**.
### Tab: Multi-Log Analyse
* Ranking direkt aus Logs (Include/Exclude-IDs, optional Range mit `scale/offset`).
* Output: `analyze_out/<ts>_multilog/…`
* Optional: „Jede Logdatei separat“ → je Log eigener Unterordner.
### Tab: ID Explorer
* **Split** (aus Header-Logauswahl): Logs → `.trace` nach `traces[/<ts>]`, plus `overview_ids.csv`.
Danach wird der neue Traces-Pfad **automatisch aktiviert**.
* **Einzel-ID Analyse** (Multi-Select):
* Plots: Byte\[0..7] (8-Bit) + LE/BE für Paare (0-1 … 6-7)
* `summary_stats.csv` pro Trace
* Output: `analyze_out/<ts>_id_explore/…`
### Tab: Traces Batch-Analyse
* Nutzt die gemeinsame Trace-Liste.
* **Ohne Auswahl** → kompletter Ordner; **mit Auswahl** → es wird ein Subset-Ordner gebaut (Hardlinks/Kopie) und nur dieses analysiert.
* Parameter: `--rx-only`, `scale`, `offset`, `range-min/max`, `top`, `--plots`.
* Output:
* je Trace: `*_combostats.csv` (+ Plots),
* global: `summary_top_combinations.csv`
* unter `analyze_out/<ts>_trace_batch/…`
### Tab: Range-Fit (Single-Select)
* **Zwei Modi**:
1. **Supervised** (Range-Min/Max gesetzt): findet `scale` & `offset`, maximiert **Hit-Ratio** im Zielbereich.
Output: `<trace>_encoding_candidates.csv` + phys-Plots (Top-N).
2. **Unsupervised** (Range leer): bewertet Kandidaten nach **Smoothness**, **Spannweite**, **Varianz**, **Rate**, **Uniqueness**.
Output: `<trace>_unsupervised_candidates.csv` + Roh-Plots (Top-N).
* Optionen: `nur RX`, `negative Scale erlauben` (nur supervised), `Min. Hit-Ratio`, `Min. Smoothness`, `Plots Top-N`, `Output-Label`.
* Output: `analyze_out/<ts>_rangefit/…`
---
## CLI-Quickstart
### 1) Splitten
```bash
python3 can_split_by_id.py logs/run1.log logs/run2.log \
--outdir <Workdir>/traces/20250827_1200 \
--rx-only
```
### 2) Einzel-ID-Explorer
```bash
python3 id_signal_explorer.py <Workdir>/traces/20250827_1200/0x208_run1.trace \
--outdir <Workdir>/analyze_out/20250827_1210_id_explore
```
### 3) Batch-Analyse
```bash
python3 trace_batch_analyzer.py \
--traces-dir <Workdir>/traces/20250827_1200 \
--outdir <Workdir>/analyze_out/20250827_1220_trace_batch \
--rx-only --plots --top 8 \
--range-min 31 --range-max 80
```
### 4) Range-/Unsupervised-Fit (eine `.trace`)
```bash
# Supervised (z. B. Kühlmittel 31..80°C)
python3 trace_signal_fitter.py <trace> \
--rmin 31 --rmax 80 \
--outdir <Workdir>/analyze_out/20250827_1230_rangefit \
--plots-top 8 --min-hit 0.5 --allow-neg-scale
# Unsupervised (ohne Range)
python3 trace_signal_fitter.py <trace> \
--outdir <Workdir>/analyze_out/20250827_1240_unsupervised \
--plots-top 8 --min-smooth 0.2
```
---
## Algorithmen & Heuristiken
* **Kombinationen**:
* 8-Bit: `D0..D7`
* 16-Bit (adjazent): LE & BE für Paare `(0,1)…(6,7)`
*(32-Bit & bit-gepackte Felder: auf der Roadmap)*
* **Prefilter** (für „ruhige“ physikalische Größen):
Mindestanzahl Samples, nicht (nahezu) konstant, keine exzessiven Sprünge (p95 der |Δ| relativ zur Spannweite).
* **Range-Fit**:
Für jeden Kandidaten `raw` wird über eine Menge plausibler **Scales** gesucht; für jedes `scale` wird das **Offset** via **Intervall-Überdeckung** bestimmt (`rmin ≤ scale*raw_i + offset ≤ rmax`). Ranking: Hit-Ratio ↓, dann Glattheit (p95 phys) ↑, Rate ↓, n ↓.
* **Unsupervised**:
**Smoothness** = `1 clamp(p95(|Δ|)/span, 0..1)`; zusätzlich **span**, **var**, **rate**, **uniq\_ratio**. Ranking auf diese Metriken.
---
## Tipps & Troubleshooting
* **Keine Kandidaten (Range-Fit)**: `--min-hit` senken, `--allow-neg-scale` testen, Range prüfen, längeres/variableres Log nutzen.
* **Alles wird gefiltert (Unsupervised)**: `--min-smooth` senken; ggf. `--rx-only` aktivieren.
* **Leere/komische Plots**: DLC < 8 teils keine 16-Bit-Kombis; Frames sehr selten Rate niedrig.
* **Ordner stets sauber**: Zeitstempel-Unterordner aktiv lassen; pro Run eigene Artefakte.
---
## Roadmap
* 32-Bit-Kombinationen, bit-gepackte Felder.
* Histogramme, Autokorrelation, Ausreißer-Detektoren.
* vordefinierte Signal-Profile (z. B. *WheelSpeed*, *CoolantTemp*).
---
## Lizenz / Haftung
Nur zu Analyse-/Reverse-Engineering-Zwecken. Nutzung auf eigene Verantwortung.