Engine Control Units

Engine ECUs are the target of an active reverse-engineering community, driven by the aftermarket tuning scene and interest in the trust chains that protect factory firmware. The Simos 18, built around the Infineon TriCore TC1791, is the most thoroughly documented case in public research.

Simos 18

Simos 18 SBOOT

Bri3d (Brian Ledbetter), GitHub 2020+ [1]

The Simos 18 ECU runs on the Infineon TC1791S. Its flash is internal to the processor and protected by passwords burned into a One Time Programmed (OTP) region during manufacturing, so reading flash requires an exploit rather than a direct hardware access.

The supplier bootloader (SBOOT) occupies the lowest 0x14000 bytes of program flash, checks CBOOT validity flags during startup, and promotes verified CBOOT updates when present. It also exposes a recovery shell, entered by applying two phase-shifted 3.2 kHz PWM signals to two harness pins at boot; the TriCore GPTA peripheral checks the phase offset and, if correct, opens a command shell over ISO-TP on CAN.

The shell requires a seed/key exchange. The ECU generates 256 bytes via a Mersenne Twister PRNG, encrypts them with an RSA public key, and sends the ciphertext. The intended flow requires the RSA private key. In practice the PRNG is seeded only from the system timer, making the seed space at most 2^31. With tight CAN timing the tester can predict the timer value and brute-force the window in seconds on a laptop.

Once past that gate, the pre-signature CRC validator accepts a weakly bounded address header. The start-address bounds check is missing, allowing the checksum to cover the OTP region. Because CRC32 is reversible, four bytes at a time can be back-calculated from the checksum; iterating across the password area with CPU resets between steps recovers the flash-access passwords.

Two 3.2 kHz PWM signals with a quarter-period phase offset, as required to enter the Simos 18 SBOOT recovery shell. Figure from Brian Ledbetter (bri3d), 2020 (Simos18_SBOOT).Two 3.2 kHz PWM signals with a quarter-period phase offset, as required to enter the Simos 18 SBOOT recovery shell. Figure from Brian Ledbetter (bri3d), 2020 (Simos18_SBOOT).

Simos 18 CBOOT and VW_Flash

Bri3d (Brian Ledbetter), GitHub 2020+ [2]

CBOOT is VW's standard firmware update interface, implementing the UDS flashing sequence described in the ECU Flashing chapter: extended session, SA2 seed/key, erase, block download with Encryption A (AES-128-CBC) and Compression A (LZSS), and RSA signature verification. Each block's OK flag lives immediately after the block in flash, outside the erased range.

The vulnerability is a state-machine oversight: CBOOT requires Erase before Download but does not check that the downloaded block matches the erased one. A tester can erase block N and then download into block M. Because the TriCore flash controller writes directly to program flash as chunks arrive, the data lands in M while M's OK flag remains untouched. The subsequent CRC and RSA check fails, but CBOOT still considers M valid on the next boot, yielding arbitrary code execution in a block the trust chain treats as signed.

Writing into non-erased TriCore flash is constrained: bits can only flip from zero to one, and ECC codes carry the same limit. The practical method is to target runs of 0x00 bytes (NOP on TriCore) and write a jump plus a small payload into that space, keeping ECC consistent.

Building on both exploit chains, bri3d released VW_Flash, an open-source Python toolkit that automates the full flashing pipeline for Simos 18 and several other VW Group ECUs, handling SA2 key computation, FRF/ODX parsing, Encryption A, Compression A, and the UDS transfer sequence.

References