We built a free BMW tuning flasher to give the community real control.

RFTX_TUNING

New Member
Apr 27, 2025
3
8
0
Why I Built RFTX

For a long time, flashing your BMW meant paying high fees for licenses, apps, and locked tools.

I’m a car enthusiast, just like many of you. I built RFTX to make tuning more accessible — no expensive apps, no unnecessary license costs, no barriers.

With RFTX:

  • You only need a basic OBD cable.

  • No license fees or subscriptions.

  • Real control over your car without hidden costs.
RFTX is built for the 17-year-old tuning his first 335i.
It’s for the guy building his dream 700hp single turbo project.
It’s for the M3 and M4 owners who deserve to flash without getting overcharged.

RFTX is built by the community, for the community — and it will remain free, always.
https://rftx-tuning.github.io/WEBSITE/
 

carabuser

Captain
Vendor
Oct 2, 2019
1,063
1
1,225
0
UK
Ride
Z4 35i & 335i
Very interesting. Does the flasher handle all the logic changes that are required on the N54 to target above 18psi? If not, does it allow program modifications in the binary to be written or is it calibration only?
 

fstbtstr

Specialist
Apr 14, 2024
59
52
0
This is great, however, I don't see a source code. Would be ideal if it was possible to build it from the source and not just get some binary file.
 

3xpent

New Member
Mar 15, 2025
4
3
0
I don't know. From an abstract point of view it seems quite OK, it has UDS read / write / erase memory, as well as some implementation of security access.

But when looking deeper at the code, I have doubts. Especially originating from the security access implementation. While I am new to this topic (as in "after market ECU flashing" but not in automotive EE in general) and don't know whether it's legit or not it doesn't seem legit to me. Security Access can't be just some static XOR or CRC checksum (https://github.com/RFTX-TUNING/RFTX...eca389d1715efd3de9a31119/RFTX_FLASHER.py#L848). There needs to be more than this. Even in these 15+ years old platforms.

In my opinion this is a GenAI based fake.
 

RTA

Specialist
Jun 17, 2020
60
27
0
review by AI:

Below is a “walk-through plus reality-check” of the script you shared, with a focus on BMW N54 (MSD80 / MSD81) flashing and the thorny topic of security bypass for custom tunes.


1. High-level architecture​

LayerWhat the script doesFit for MSD80/81
Serial-CAN transportOpens a PC COM port at 500 kbit/s and speaks a home-grown CAN framing: 4-byte ID + 1-byte DLC + data.✔️ MSD80/81 really do communicate on 500 kbit/s HS-CAN, but K-DCAN cables present as FTDI/CH340 and speak either Lawicel “SLCAN” or ELM327 ASCII. A raw 5-byte header is not what they understand, so you would need a microcontroller on the other end that purpose-builds this framing.
ISO-TP (ISO 15765-2)Manual implementation of single-frame, first-frame, flow-control & consecutive-frame logic (including timing).✔️ Conceptually correct. ❗ Edge-cases (eg. STmin ≥ 0xF1, block-size = 0) and error handling are only partly covered.
Diagnostic protocolsFalls back from UDS → KWP2000, then provides helpers for TesterPresent, SessionControl, SecurityAccess, Read/WriteMemory, RoutineControl, etc.✔️ MSD80/81 use KWP2000 on CAN (not UDS). The KWP paths are present.
Flashing logic– Detect ECU type from ID
– Enter programming session
– Perform SecurityAccess (seed/key)
– Erase sector(s)
– RequestDownload / WriteMemory
– TransferData / RequestTransferExit
– Verify by reading back
✔️ Flow is right.
❗ BMW’s factory tools actually use “RequestDownload / TransferData” even for KWP2000 ECUs, not KWP 0x3D WriteMemory. The script mixes both styles and may not match what the MSD80 bootloader accepts.
CLI & GUI stubsargparse main(), plus large PyQt imports that are currently unused.Harmless clutter, but no functional problem.


2. Security bypass: will the XOR/CRC trick open MSD80/81?​

Short answer: No.

  • BMW seed-key is proprietary. For MSD80/81 (and all N54-era Bosch ME(MS) ECUs) the key is 16-bit but derived via a non-linear algorithm that BMW never published. Reverse-engineered public tools (e.g. bimmerlabs bootmod3 loader, DSflash, bflash) use tables or per-ECU formulas that are not the simple
    python
    CopyEdit
    key = ((seed ^ 0x5A3C) + 0x7F1B) & 0xFFFF
    that you hard-coded. Therefore _send_kwp_command(0x27, [0x02, key_hi, key_lo]) will be rejected with NRC 0x35 InvalidKey.
  • MG1/MD1 & MEVD17.x really use 32-bit seeds with CRC-based keys, but the polynomial and post-processing again differ from the generic 0x4C11DB7 CRC you coded.
Bottom line: the “security_algorithm” field in ECU_MEMORY_MAPS needs a real per-type implementation or a plug-in interface so users can drop in their own seed→key function.


3. Read/Write Memory services for MSD80/81​

ServiceSpecScript implementationIssues
ReadMemoryByAddress (0x23)Typical “31 xx aa aa aa ll” where xx is length of address, aa… address bytes, ll length of data.You send [addr(4B), size(1B)] (total 5 payload bytes).❗ Missing the addressLength and sizeLength prefix bytes – the ECU will NAK with 0x13.
WriteMemoryByAddress (0x3D)Same prefix rules as above, plus data.You send [addr(4B)] + data with no lengths.❗ Likely rejected.

For large transfers BMW actually expects:

  1. StartRoutine 0x31 FF00 (erase),
  2. RequestDownload (0x34) with format byte & lengths,
  3. TransferData (0x36) chunks,
  4. RequestTransferExit (0x37),
exactly how you implemented in the UDS path, not in the KWP path. You would need to port that chunked downloader to the KWP branch.


4. Memory map accuracy​

The sector layout you define (Bootloader @ 0x800000, Calibration @ 0x810000, Program @ 0x850000) is plausible for MSD80/81, but:

  • On real ECUs those addresses are logical addresses; the bootloader expects them without the 0x8 offset (e.g. starts at 0x000000).
  • Sector sizes sometimes differ across software releases (77 kB cal area common).
  • Program code is normally 128 kB aligned.
    These mismatches do not brick the ECU—your erase/write commands would merely NAK—but verification will fail.

5. Transport layer caveats​

  1. K-DCAN cable framing:
    FTDI+Lawicel = ASCII like t6F11FF7...\r.
    ELM327 = ATCRA 6F9, ATSH 6F1.
    Your raw binary framing only works with a flashed STM32/Teensy that you control.
  2. Bus timing & watchdog:
    Sending TesterPresent every 2 s is fine, but some MSD80 bootloaders require it every 1 s during erase. Also STmin handling below 0x7F should be 0–127 ms (you treat them as ms, good).
  3. Flow-control window:
    You honour block-size but never send a second FC frame if the ECU wants one. Most Bosch bootloaders use BS=0, so you are fine.

6. What will happen if you run it?​

  • Detects ECU (positive).
  • Fails at 0x27 SecurityAccess (negative response 0x35).
  • If you code-hack the key algorithm, the next blocker will be incorrect 0x3D/0x23 framing → NRC 0x13.
  • Even with framing fixed, you need KWP “RequestDownload/TransferData” not 0x3D to program flash.
  • Assuming those are fixed, flashing will work, but the verify step calls _read_memory() which again uses the incorrect 0x23 framing → verification fails.

7. Recommendations to reach a working N54 flasher​

  1. Use python-can with candleLight USB, ValueCAN, or KVASER so you avoid inventing a CAN framing.
  2. Swap in a proven seed-key algo. Community-known XOR table for MSD80/81 exists (search for “msd80 seed key algorithm” on github).
  3. Port UDS-style download routine to KWP: use 0x34/0x36/0x37 even under KWP.
  4. Fix Read/WriteMemory address-length prefixes if you still want the 0x23/0x3D fall-back.
  5. Make the memory map configurable (read 0x1A ECU ID and load a JSON) because tune files for N54 often use patched layouts.
  6. Remove GUI imports or wrap them in if __name__ == '__main__' and --gui to keep the CLI lightweight.

Verdict​

As it stands the code is a solid educational scaffold but will not flash an MSD80/81 safely—the security access math, KWP framing, and transport framing need real-world fixes. Once those are addressed, the general structure (session → security → erase → download → verify → reset) is correct and can absolutely power a custom N54 tuning suite.
 
  • Wow
  • Like
Reactions: pbondar and wheela