APS Logo APS_TUNING [ ABOUT ] [ BLOG ]
[ VISSZA A LOGOKHOZ ]

Reverse Engineering Bosch ME9: Az Immobilizer (WFS) Rendszer Teljes Anatómiája

TIMESTAMP: 2026.02.28 | TARGET: BOSCH ME9.0 (Ford Focus ST/RS) | AUTHOR: APS TUNING

Amikor egy tuningolt motorvezérlőt más autóba akarunk áthelyezni, előbb-utóbb szembe fogunk találni a rendszer legfontosabb kapuőrével: az immobilizer állapotgéppel. Értsük meg pontosan, hogyan dönti el az ECU, hogy szabad-e a motorindítás!

Ebben a bejegyzésben a teljes Ford/Bosch ME9 WFS (Wegfahrsperre, Német: indításgátló) rendszert boncolgatjuk: a bootolástól a motorindításon át a leállításig, minden állapotátmenettel, assembly kódrészlettel és EEPROM logikával.

Az Immobilizer szerepe a rendszerben

Az immobilizer feladata egyszerű: megakadályozni a motor indítását, ha a kulcs kriptográfiai azonosítása sikertelen. A Ford/Bosch ME9-ben ez egy többrétegű védelem:

Ez a három réteg egymástól független, egy patch, ami csak az egyiket kerüli ki, a másik kettő által még mindig blokkolva lesz. Erről a fejlesztői mód (B_ecudev) kapcsán később még részletesen szólok.

A központi állapotváltozók

Mielőtt belevágnánk a kódba, ismerjük meg azokat a változókat, amelyek az egész rendszert vezérlik. Mindegyik a r13 (SDA Base = 0x7FFFF0) regiszterhez relatív:

VáltozóRAM címMéretSzerep
secacc_state0x8042E31BFő állapotgép: 0x33 / 0x66 / 0x77 / 0xAA
secacc_mode0x8042E21BBiztonsági hozzáférés módja
service_mode0x8042E51BSzerviz mód flag
wfsbitsNV1_10ms0x7FD6EE1BNV perzisztens bitfield (EEPROM tükör!)
wfsbits1_10ms0x8046441BVolatile bitfield #1
wfsbits3_10ms0x8046461BVolatile bitfield #3
wfsbits4_10ms0x8046471BVolatile bitfield #4
wfsbits5_10ms0x8046481BVolatile bitfield #5
eep_request0x8042D91BEEPROM művelet kérés kód (0x01-0x0A)
cycles_ig_cnt0x7FD6E81BHátralevő indítási ciklusok (NV)
inCodeCtr0x7FD6E91BHátralevő kódpróbálkozások (NV)
B_ecudev0x7FAB651BFejlesztői mód flag
B_kl150x7FB4051BTerminal 15 (gyújtás) állapota
B_eculock0x7FA9951BECU zárolás aktuátor
B_stalock0x7FA9961BStarter zárolás aktuátor

Figyeljük meg a két RAM tartomány közötti alapvető különbséget: a 0x80xxxx volatile RAM, leállításkor elveszik. A 0x7FDxxx az EEPROM tükör (RAM Mirror), a korábbi bejegyzésben leírt NVRAM menedzser menti. A wfsbitsNV1_10ms a 0x7FD6EE címen helyezkedik el, tehát ez az EEPROM tükör része! Ez kritikus: ez az egyetlen WFS bitfield, ami túlél egy ECU újraindítást.

A secacc_state állapotgép

A rendszer szíve a secacc_state változó, amely négy állapotot vehet fel:

secacc_state ÁLLAPOTGÉP
0x33
LOCKED
...
0x66
LEARNING
...
0x77
PRE-AUTH
CAN 0x83 OK
...
0xAA
UNLOCKED
VISSZAZÁROLÁS: Timeout, hibás kód, vagy CAN 0x81 megszakítás esetén a PRE-AUTH fázisból.
LEÁLLÍTÁS: Motor leállítása (KL15 OFF) vagy ECU reset esetén.
ENGEDÉLYEZÉS: A 0xAA állapotnál az immo_execute_ign_lock(0) lefut, a motor indítható.
                       
               
                    VISSZAZÁROLÁS (0x33):                     Timeout, hibás kód, vagy CAN 0x81 megszakítás esetén a PRE-AUTH fázisból.                
               
                    LEÁLLÍTÁS (0x33):                     Motor leállítása (Terminal 15 OFF) vagy ECU reset esetén az UNLOCKED állapotból.                
               
                    ENGEDÉLYEZÉS:                     A 0xAA állapot elérésekor az immo_execute_ign_lock(0) lefut, a motor indítható.                
           
       
ÁllapotÉrtékJelentés
LOCKED0x33Motor indítás tiltva. Ez az alapállapot.
LEARNING0x66Tanulási mód / várakozás CAN-es kódellenőrzésre
PRE-AUTH0x77SecurityAccess engedélyezve, de validáció még nem történt
UNLOCKED0xAAMinden rendben, motor szabadon indítható

1. fázis: Boot, a WFS_Boot_Init_EEPROM() rutin

Az ECU bekapcsolásakor az első WFS-releváns rutin a WFS_Boot_Init_EEPROM() (cím: 0x000CB780). Ennek a rutinnak egyetlen feladata: eldönteni, hogy az ECU zárolva vagy feloldva induljon.

A döntés kulcsa a wfsbitsNV1_10ms perzisztens bitfield, amelyet az NVRAM menedzser már betöltött az EEPROM-ból a RAM tükörbe:

WFS_Boot_Init_EEPROM(), Boot állapot meghatározás @ 0x000CB80C
lbz r4, -0x2912(r13) ; r4 = wfsbitsNV1_10ms (EEPROM tükörből!)
rlwinm. r10, r4, 0, 29, 29 ; Bit 2 tesztelése: volt sikeres auth az előző ciklusban?
beq BOOT_LOCKED

; Bit 2 SET - Előző ciklusban sikeres volt az immo - gyors unlock
li r3, 0xAA ; secacc_state = UNLOCKED
b STORE_STATE

BOOT_LOCKED:
; Bit 2 CLEAR - Nincs érvényes korábbi auth - zárolva indulunk
li r3, 0x33 ; secacc_state = LOCKED

A wfsbitsNV1_10ms bit 2 egy "emlékeztető" flag: ha az előző motorindítási ciklusban az immo sikeresen feloldotta az ECU-t, ez a bit 1-re áll, és a leállítási fázisban az NVRAM menedzser elmenti az EEPROM-ba. Így a következő bootkor az ECU azonnal 0xAA (UNLOCKED) állapotban indul.

A Power-Fail inicializáció

Ha az ECU cond_for_powerfail flag-je aktív (váratlan tápkimaradás), a rendszer extra lépéseket is végrehajt:

Power-Fail Recovery, Kripto Seed és Számlálók @ 0x000CB7A8
li r4, 0 ; Kripto seed és számlálók nullázása
stb r4, -0x2928(r13) ; seed[0] = 0x00
li r11, 0x10
stb r11, -0x2927(r13) ; seed[1] = 0x10
li r10, 0x34
li r9, 0x56
li r12, 0x78
li r11, 0x9A
stb r10, -0x2926(r13) ; seed[2] = 0x34
stb r9, -0x2925(r13) ; seed[3] = 0x56
stb r12, -0x2924(r13) ; seed[4] = 0x78
stb r11, -0x2923(r13) ; seed[5] = 0x9A

stb r4, -0x2917(r13) ; inCodeCtr = 0
stb r4, -0x2918(r13) ; cycles_ig_cnt = 0
stb r4, -0x2916(r13) ; pre_ena_ctr = 0

Ez a fix seed ({0x00, 0x10, 0x34, 0x56, 0x78, 0x9A}) a kripto-algoritmus kiindulópontja. Power-fail után a rendszer defenzíven viselkedik: mindhárom NV számláló (cycles_ig_cnt, inCodeCtr, pre_ena_ctr) nullázódik, a kulcs-azonosítás újrakezdése kötelező. Érdekes részlet: a normál boot egy korábbi init rutinban (0x000C4948) ugyanezeket a számlálókat előbb visszatölti az EEPROM mirror-ból, de power-fail esetén ez a rutin felülíródik a fenti nullázás által. Két lépéses biztonsági mechanizmus: normál boot esetén a mirror-load megtörténik és érvényes marad, power-fail esetén defenzív reset.

2. fázis: WFS_Ignition_Cycle_Sequencer(), A fő immobilizer állapotgép

A WFS_State_Updater_Main() 10ms task az WFS_Ignition_Cycle_Sequencer() függvényt (cím: 0x0010B49C) hívja meg, amely egy klasszikus állapotgép a DAT_007FA402 változó alapján.

State 0, Gyújtás detektálás

WFS_Ignition_Cycle_Sequencer() State 0, Bekapcsolás érzékelés @ 0x0010B4DC
lbz r12, -0x4BEB(r13) ; r12 = B_kl15 (Terminal 15, gyújtás állapot)
cmpwi r12, 0
beq KL15_OFF ; Ha KL15 == 0 - gyújtás nincs - reset

; = Gyújtás BE - Inicializáció =
li r12, 1
stb r12, -0x5BEE(r13) ; State - 1

; wfsbits4: bit 0 és bit 1 törlése
lbz r11, 0x4647(r13) ; r11 = wfsbits4_10ms
rlwinm r5, r11, 0, 24, 30 ; Bit 0 clear (& 0xFE)
rlwinm r10, r5, 0, 31, 29 ; Bit 1 clear (& 0xFD)
stb r10, 0x4647(r13)

; wfsbits5 bit 7 SET - WFS_Ignition_Cycle_Sequencer aktív jelzés
lbz r12, 0x4648(r13)
ori r12, r12, 0x80
stb r12, 0x4648(r13)

; wfsbits3 bit 2,3 SET - CAN kommunikáció engedélyezés
lbz r11, 0x4646(r13)
ori r10, r11, 0x0C
stb r10, 0x4646(r13)

; cycles_ig_cnt dekrementálás
lbz r5, -0x2918(r13) ; r5 = cycles_ig_cnt
cmpwi r5, 0
ble skip_decrement
addi r12, r5, 0xFF ; r12 = cycles_ig_cnt - 1
stb r12, -0x2918(r13)

A State 0 megvárja, amíg a gyújtás bekapcsol, majd inicializálja az összes kommunikációs flag-et, és továbblép State 1-re. A cycles_ig_cnt egy biztonsági számláló: ha elfogynak a ciklusok, az ECU visszazárolódik.

State 3, Motor futásának ellenőrzése (Visszazárolás!)

WFS_Ignition_Cycle_Sequencer() State 3, Motor fut, de nem szabad! @ 0x0010B70C
lhz r12, -0x4852(r13) ; r12 = nmot_w (fordulatszám)
cmpwi r12, 0
beq FORCE_LOCK

lbz r12, -0x54BF(r13) ; r12 = B_nmot (motor forgat flag)
cmpwi r12, 0
beq EXIT

; = MOTOR FOROG, DE AZ IMMO NEM ENGEDÉLYEZTE - VISSZAZÁROLÁS! =
lbz r12, -0x2912(r13) ; wfsbitsNV1_10ms
li r11, 0x33
rlwinm r12, r12, 0, 30, 28 ; Bit 1 és Bit 2 TÖRLÉSE
stb r12, -0x2912(r13)
stb r11, 0x42E3(r13) ; secacc_state = 0x33 (LOCKED!)

lbz r10, 0x4644(r13)
ori r10, r10, 0x40 ; Bit 6 SET - "motor közbeni zárolás"
stb r10, 0x4644(r13)
⚠ FIGYELEM! Ha a motor forog (B_nmot == 1), például ha az ECU a B_stalock változóval tiltja az önindítót, de a járművet tolásra vagy húzásra megforgatják, miközben az immo nincs UNLOCKED állapotban, a rendszer védelmi visszazárolást hajt végre: secacc_state, 0x33, és a wfsbitsNV1 bit 1 és 2 törlődik. Ennek következtében a következő bootkor is LOCKED állapottal indul az ECU.

3. fázis: A CAN Dispatcher, WFS_CAN_Dispatcher()

A CAN buszról érkező WFS parancsok feldolgozása a WFS_CAN_Dispatcher() (cím: 0x0010C688) rutinban történik:

CMDFunkcióLeírás
0x81SecurityAccess belépésLOCKED - LEARNING átmenet
0x82Timer érték írásAS timer beállítása (0x08-0x3F)
0x83Challenge-ResponseKriptográfiai kódellenőrzés
0x85Új kulcs tanításISK programozás (0x20 subcommand)
0x86Kezdeti beállításTanulási mód belépés
0x87secacc_mode váltásMód változtatás
0x88service_mode váltásSzerviz mód kapcsoló
0x89Állapot lekérdezéssecacc_state visszaadása
0x8AKulcs verifikációChallenge válaszadat
0x8BKonfig lekérdezéssecacc_mode, service_mode
0x8CStátuszbitekwfsbits5, wfsbits3, wfsbits4 kódolva

Command 0x83, Challenge-Response kódellenőrzés

Ez a rendszer kritikus pontja: a kriptográfiai validáció:

CAN CMD 0x83, Kód ellenőrzés @ 0x0010C888
; = Challenge kalkuláció =
lbz r12, -0x5BCE(r13) ; CAN adat byte 1 (instrument cluster válasz)
stb r12, -0x5BC6(r13) ; Mentés az összehasonlító pufferbe
lbz r11, -0x5BCD(r13) ; CAN adat byte 2
stb r11, -0x5BC7(r13)

lbz r4, -0x2913(r13) ; kripto paraméter
addi r3, r13, 0x42C9 ; Cél puffer
addi r5, r13, 0x42C6 ; Forrás puffer
bl FUN_0010afc4 ; >>> KRIPTO KALKULÁCIÓ <<<

; = Összehasonlítás =
lbz r11, 0x42C7(r13) ; Kalkulált byte 1
lbz r10, -0x5BC6(r13) ; Kapott byte 1
cmpw r11, r10
bne CODE_MISMATCH ; Nem egyezik - hibás!

lbz r12, 0x42C6(r13) ; Kalkulált byte 2
lbz r11, -0x5BC7(r13) ; Kapott byte 2
cmpw r12, r11
bne CODE_MISMATCH

; = SIKERES MATCH - UNLOCK! =
li r11, 0xAA
stb r11, 0x42E3(r13) ; secacc_state = 0xAA - UNLOCKED!

lbz r10, -0x2912(r13) ; wfsbitsNV1_10ms
ori r10, r10, 0x04 ; Bit 2 SET - "sikeresen autentikálva"
stb r10, -0x2912(r13) ; NV mentés - következő bootkor UNLOCKED!

Két bájt összehasonlítás, ha mindkettő egyezik, az ECU feloldódik. A kritikus lépés a wfsbitsNV1 |= 0x04: ez biztosítja, hogy a következő bootkor a WFS_Boot_Init_EEPROM() UNLOCKED állapottal indítson.

Mi történik hibás kódnál?

CAN CMD 0x83, Hibás kód kezelés
CODE_MISMATCH:
lbz r12, -0x2917(r13) ; r12 = inCodeCtr
addi r30, r12, 0xFF ; r30 = inCodeCtr - 1
rlwinm. r11, r30, 0, 24, 31 ; Byte-ra vágás + tesztelés
stb r30, -0x2917(r13)
bgt DONE_0x83 ; Ha még van próbálkozás - kilépés

; = ELFOGYTAK - ZÁROLÁS! =
ori r31, r31, 0x20 ; wfsbits1 bit 5 SET - "permanent lock"
li r10, 0x33
stb r10, 0x42E3(r13) ; secacc_state = 0x33 (LOCKED!)
⚠ Vigyázz!: Ha az inCodeCtr eléri a nullát, az ECU zárolódik az adott ciklusban. A wfsbits1 bit 5 jelzi a "kód-próbálkozás kimerülés" miatti zárolást.

4. fázis: A "Végrehajtó", immo_execute_ignition_lock()

Az immo_execute_ign_lock() (cím: 0x000A39E4) fordítja le az állapotgép döntését fizikai beavatkozásra:

immo_execute_ign_lock(), A "Végrehajtó" rutin @ 0x000A39E4
; Bemenet: r3 = ignition lock word (0x0000 = szabad, 0xFFFF = lock)

cmpwi r3, 0
beq NO_LOCK ; r3 == 0 - motor szabad

lbz r12, -0x549B(r13) ; r12 = B_ecudev
cmpwi r12, 0
beq LOCK_PATH ; B_ecudev == 0 - normál - zárolás!

; B_ecudev != 0: Fejlesztői mód - utolsó check
lbz r12, 0x4648(r13) ; wfsbits5_10ms
rlwinm. r12, r12, 0, 29, 29 ; Bit 2 test
bne LOCK_PATH ; Ha SET - explicit lock!

NO_LOCK:
li r3, 0x0000
b APPLY_LOCK

LOCK_PATH:
ori r3, r3, 0xFFFF ; Teljes lock maszk

APPLY_LOCK:
; Bit 0 - B_eculock | Bit 4 - B_stalock | Bit 2 - Gyújtás cut
rlwinm. r12, r3, 0, 31, 31 ; Bit 0 - B_eculock
; ... bit dekódolás ...
rlwinm. r12, r3, 0, 29, 29 ; Bit 2 - gyújtás cut
beq IGN_CUT_PATH
bl FUN_00114870 ; Alternatív lock
b RETURN
IGN_CUT_PATH:
bl ENG_Ignition_Cut_Actuator ; Gyújtás cut!
Lock word bitAktuátorHatás
Bit 0B_eculockECU általános zárolás flag
Bit 4B_stalockStarter relé blokkolása
Bit 2Gyújtás cutENG_Ignition_Cut_Actuator, hengerenkénti letiltás

Az ENG_Ignition_Cut_Actuator(), A végső szankció

ENG_Ignition_Cut_Actuator() @ 0x001148DC
; Bemenet: r3 = henger index (0-9)
subi r4, r13, 0x7AB3 ; r4 = ht2ktigni_fdPatArray báziscím
add r5, r4, r12 ; r5 = célhenger offsetje
li r10, 0
stb r10, 0(r5) ; Célhenger = 0 (NINCS SZIKRA!)

; Összesített minta (OR összes henger)
loop:
lbzu r12, 1(r4)
or r5, r5, r12
bdnz loop

stb r5, -0x4B42(r13) ; ht2ktigni_fdOutPattern
; Ha OutPattern == 0 - ht2ktigni state = 0x6565 (gyújtás OFF)

Ha az OR eredménye nulla (egyetlen henger sem kap szikrát), a gyújtás rendszer 0x6565 állapotba kerül, a motor leáll.

Gyári megerősítés: A Bosch Funktionsrahmen

A fenti assembly-ből visszafejtett architektúrát a Bosch saját belső dokumentációja is megerősíti. A HT2KTIGNI 1.40.0 Funktionsrahmen (a VW/Audi Ea827 TSI MED9 platformhoz) tartalmazza az Ausblendbitmaske (fadeout bitmask) táblázatot:

HT2KTIGNI Ausblendbitmaske, Gyújtás letiltási források
; Index Konstans Forrás
 0 IGN_FDOUT_NACHL Nachlauf (utánfutás)
 1 IGN_FDOUT_WFS immobilizer ◄── EZ AZ!
 2 IGN_FDOUT_NLZOFF supervisor
 3 IGN_FDOUT_COMPTST compression-test
 4 IGN_FDOUT_DMDZAG Aussetzergenerator (misfiring detection)
 5 IGN_FDOUT_AIRBAG airbag
 6 IGN_FDOUT_WDA (tartalék)
 7 IGN_FDOUT_RDE Rücklauferkennung (visszaforgás detektálás)
 8 IGN_FDOUT_NLPH Phasengebernotlauf (CPS vészüzem)
 9 IGN_FDOUT_CUSTOM0 (egyedi)

Amikor az ENG_Ignition_Cut_Actuator-t hívjuk r3 = 1 paraméterrel, az a ht2ktigni_fdPatArray[1]-et nullázza, ami a Funktionsrahmen szerint az IGN_FDOUT_WFS, az immobilizer fadeout csatornája. A 10 elemű tömb (amit a kódban a cmpwi r12, 10 / bge EXIT boundary check-kel véd) pontosan ez a 10 fadeout forrás (0-9).

A Funktionsrahmen blokk-diagramja is visszaköszön: a CopyArray lépés a hengerorientált tömböt kronologikus sorrendbe másolja, utána a B_ff flag dönti el, hogy MultSpark vagy SingSpark módban adja ki a TPU-nak. A mi OR-akkumulátorunk (ht2ktigni_fdOutPattern) pontosan ezt az összesített mintát képzi, amit a Funktionsrahmen ht2ktigni-ht2ktignisyns szakasza ír le.

Bosch Funktionsrahmen, HT2KTIGNI 1.40.0 (Ea827 TSI / MED9)
Bosch Funktionsrahmen HT2KTIGNI - Ausblendbitmaske és gyújtásvezérlés blokk-diagram

A VW/Audi platform MED9-es Funktionsrahmenje. Az immobilizer rendszer itt nem PATS (Passive Anti-Theft System, ahogy a Ford hívja), hanem WFS (Wegfahrsperre) néven fut, de a végrehajtó réteg, a "hóhér" ugyanaz: ht2ktigni_fdPatArray fadeout tömb, hengerenkénti nullázás, OR akkumuláció, és ha minden henger minta nulla, a gyújtás rendszer leáll. A Bosch motorvezérlő szoftver-architektúra közös alap, a gyártóspecifikus rész csupán a CAN protokoll és a kulcsmenedzsment.

5. fázis: A "Végrehajtó megkötözése", B_ecudev fejlesztői mód

A fejlesztőpadokon (ETAS, INCA) az immobilizer komoly akadály lenne. A B_ecudev (0x7FAB65) flag négy független kapuőrt nyit egyszerre:

Kapuőr 1: A Kripto Bypass, A "Pad-kulcs"

EEPROM init, PCM kulcs betöltés @ 0x000C48B4
lbz r10, -0x549B(r13) ; r10 = B_ecudev
cmpwi r10, 0
beq LOAD_FROM_EEPROM ; B_ecudev == 0 - valódi kulcsok

; = FEJLESZTŐI MÓD: Fix "dummy" kulcsok a Flash-ből =
lis r3, 0xF
subi r3, r3, 0x3DC0 ; r3 = 0x000EC240
lbz r11, 0(r3) ; - 0xAB
stb r11, 0x42E7(r13)
lbz r10, 1(r3) ; - 0x23
stb r10, 0x42E8(r13)
; ... {0xCA, 0x45, 0x61, 0x77, 0xFE, 0xAC} ...

LOAD_FROM_EEPROM:
; NORMÁL MÓD: Kulcsok az EEPROM tükörből (0x7FD7C3-0x7FD7CA)
lbz r12, 0xCB(r4)
stb r12, 0x42E7(r13)
; ... 7 további bájt ...

Fejlesztői módban az ECU a ROM-ba égetett {0xAB, 0x23, 0xCA, 0x45, 0x61, 0x77, 0xFE, 0xAC} kulcsot használja. Az ETAS/INCA ismeri ezt az univerzális kulcsot.

Kapuőr 2: Az ISK Újraírás Engedélyezése

if (B_ecudev == 0) - ISK írás TILTVA (normál gyártási ECU)
if (B_ecudev != 0) - ISK írás ENGEDÉLYEZVE (fejlesztői ECU)

Ez védi a gyártási ECU-kat attól, hogy valaki a CAN buszon keresztül új kulcsot tanítson be.

Kapuőr 3: Az Ignition Lock Bypass

if (B_ecudev != 0 ÉS wfsbits5_bit2 == 0) - NINCS LOCK - Motor fut!

Kapuőr 4: A DTC Suppression

A negyedik kapuőr nem az állapotgépet vagy az aktuátort érinti, hanem a diagnosztikai hibakód-bejegyzést. A FUN_001492a0 (a WFS_Powerdown_Lock-ból hívva) felelős a WFS-hez tartozó DTC (Z_wfs @ 0x80464A) fault memory-ba írásáért:

FUN_001492a0, DTC SET dispatcher (a 4. kapuőrrel) @ 0x001492B4
lbz r11, 0x4648(r13) ; wfsbits5_10ms
rlwinm. r11, r11, 0, 29, 29 ; bit 2 (explicit lock) test
bne CHECK_INPUT ; explicit lock aktív, normál útvonal

lbz r12, -0x549B(r13) ; B_ecudev
cmpwi r12, 0
bne DTC_CLEAR ; dev mode + nincs explicit lock, DTC SUPPRESS

CHECK_INPUT:
cmpwi r3, 0 ; caller bemenete (kell-e fault?)
beq DTC_CLEAR
li r3, 1 ; SET DTC
b STORE

DTC_CLEAR:
li r3, 0 ; nincs DTC bejegyzés
if (B_ecudev != 0 ÉS wfsbits5_bit2 == 0) - WFS DTC ELNYOMVA, akármit kér a hívó

A fejlesztőpadokon dolgozó Bosch fejlesztők session-jei sokszor sok órás teszt-iterációk. Ha minden iterációban WFS DTC keletkezne a fault memory-ba, az fcmEnd számláló pár perc alatt elérné a 0x14 (20) korlátot, és komplex slot-management indulna a fault overflow miatt. A 4. kapuőr ezt teljesen elkerüli, dev módban a fault memory tisztán marad.

Hogyan aktiválódik a B_ecudev?

A B_ecudev nem egyszerű flag, hanem egy 6 byte-os signature ellenőrzés eredménye. Két különböző init dispatch pontból (0x000F4958 és 0x000F53A0) fut le, mindkettő ugyanazt a kódot hajtja végre a flash 0x00002BC0 címén:

B_ecudev signature check @ 0x000CAA90 és 0x00189A30 (két példány!)
lis r3, 0x0
addi r3, r3, 0x2BC0 ; r3 = 0x00002BC0 (flash header area)

lbz r11, 0(r3)
cmpwi r11, 0xB3
bne PRODUCTION

lbz r12, 1(r3)
cmpwi r12, 0x7F
bne PRODUCTION

lbz r12, 2(r3)
cmpwi r12, 0xC4
bne PRODUCTION

lbz r12, 3(r3)
cmpwi r12, 0x3B
bne PRODUCTION

lbz r12, 4(r3)
cmpwi r12, 0x80
bne PRODUCTION

lbz r12, 5(r3)
cmpwi r12, 0x4C
bne PRODUCTION

li r3, 1 ; minden byte stimmel, DEV MODE
b STORE

PRODUCTION:
li r3, 0 ; signature nem egyezik, PRODUCTION MODE

STORE:
stb r3, -0x549B(r13) ; B_ecudev

A flash 0x00002BC0 címen lévő 6 byte-nak pontosan ezt kell tartalmaznia: B3 7F C4 3B 80 4C. Ha igen, B_ecudev = 1 (dev mode, mind a négy kapuőr nyitva). Ha bármelyik byte eltér (pl. üres flash FF FF FF FF FF FF), B_ecudev = 0, production ECU. A cím a boot/header területen helyezkedik el, még a tényleges application kód előtt, pontosan ott, ahol a Ford fejlesztői tooling (ETAS INCA) build-időben odaírhatta a magic byte-okat anélkül, hogy a kalibrációhoz hozzá kellene nyúlni.

Anti-tamper: a két write site

A signature ellenőrzés kétszer fut le bootkor, két különböző init dispatch entry-ből (PTR_LAB_000f4958 és PTR_LAB_000f53a0). Ez nem véletlen, hanem szándékos anti-tamper minta: ha valaki RAM-ban próbálná átírni a B_ecudev-et (pl. JTAG emulátorral, debug pad-en), a második init überschreibolja a hamis 1-et 0-ra, hacsak nem a flash signature-t változtatja meg ténylegesen. RAM-szinten elérhetetlen.

Miért négy kapu?

A Bosch szándékosan szeparálta a védelmi rétegeket. Ha egy támadó megtalálná az egyik bypass-t:

A B_ecudev az egyetlen "mesterkulcs", amely mind a négyet egyszerre nyitja, és a fejlesztők gondoltak arra is, hogy egy nyitott ECU se generáljon DTC zajt a development board-on. Konzisztens runtime képet kell adnia: nem csak a funkcionális feloldás, hanem a hibajelentés is csendes. Ezt csak a 0x00002BC0 címen lévő 6 byte-os signature ellenőrzése állítja be, a gyártási tooling pedig nem ír ide érvényes mintát, ezért a sorozatgyártott ECU-kban a B_ecudev permanensen nulla.

6. fázis: Powerdown, WFS_Powerdown_Lock()

WFS_Powerdown_Lock() @ 0x00189D38
; Ha a timer lejárt ÉS az auth sikeres volt:
li r12, 0xAA
stb r12, 0x42E3(r13) ; secacc_state = UNLOCKED
lbz r11, -0x2912(r13) ; wfsbitsNV1_10ms
ori r11, r11, 0x04 ; Bit 2 SET - Következő bootkor UNLOCKED!
stb r11, -0x2912(r13)

SHUTDOWN_LOCK:
; Ha nem volt auth - visszazárolás
li r12, 0x33
stb r12, 0x42E3(r13) ; secacc_state = LOCKED

7. fázis: WFS_Shutdown_EEPROM_Save(), Perzisztens mentés

WFS_Shutdown_EEPROM_Save() @ 0x000D7AE8
lbz r31, -0x2912(r13) ; wfsbitsNV1_10ms
rlwinm. r11, r31, 0, 31, 31 ; Bit 0 test: mentés már megtörtént?
bne SKIP_SAVE

rlwinm r31, r31, 0, 31, 29 ; Bit 1 CLEAR
stb r31, -0x2912(r13)

subi r3, r13, 0x291F ; ISK puffer
subi r4, r13, 0x2928 ; Kripto seed
bl FUN_0010b84c ; ISK hash újraszámítás

ori r9, r31, 0x01 ; Bit 0 SET - "mentés megtörtént"
stb r9, -0x2912(r13)

li r31, 1
stb r31, 0x42D9(r13) ; eep_request = 1 - ISK mentés
stb r31, 0x42DA(r13) ; Tag byte = 1

Ez a rutin az egyik bejegyzésemben leírt EEPROM Tükör mechanizmust használja. A wfsbitsNV1 bit 0 egy "egyszer mentés" flag: biztosítja, hogy a szekvencia csak egyszer fusson le.

Összefoglalás, A teljes indítási folyamat

Fázis / Esemény Funkció / Rutin Feltétel és eredmény
BOOT
(Tápfeszültség ráadása)
WFS_Boot_Init_EEPROM() wfsbitsNV1 bit 2 == 1: 0xAA (Gyors boot / Unlocked)
wfsbitsNV1 bit 2 == 0: 0x33 (Zárolva)
10ms TASK
(Fő ütemező)
WFS_Ignition_Cycle_Sequencer() State 0 Gyújtás ON: lépés State 1-re
WFS_Ignition_Cycle_Sequencer() State 1 EEPROM kész: lépés State 2-re (20s timer indul)
WFS_Ignition_Cycle_Sequencer() State 2 CAN handshake várakozás
CAN ÜZENET
(Cluster felől ECU felé)
CMD 0x81 (SecurityAccess) eredmény: secacc_state = 0x66 (Learning)
CMD 0x83 (Challenge-Response) MATCH: secacc_state = 0xAA, wfsbitsNV1 |= 0x04
MISMATCH: inCodeCtr-- (ha eléri a 0-t: LOCK 0x33)
MOTOR INDÍTÁS
(secacc_state == 0xAA)
immo_execute_ign_lock(0) eredmény: B_eculock = 0, B_stalock = 0
ENG_Ignition_Cut_Actuator eredmény: gyújtás engedélyezve (szikra aktív)
WFS_Ignition_Cycle_Sequencer() State 5 nmot ≥ threshold: lépés State 3-ra
LEÁLLÍTÁS
(Terminal 15 OFF)
WFS_Powerdown_Lock() eredmény: secacc_state és wfsbitsNV1 állapotok frissítése
WFS_Shutdown_EEPROM_Save() eredmény: ISK hash újraszámítás + EEPROM mentés jelzése
NVRAM Menedzser eredmény: fizikai EEPROM írás a Power Latch fázis alatt

Záró gondolat

Nem az célom, hogy itt az immobilizer bypass lehetőségeket megmutassam. Ehelyett értsük meg az állapotgépet, és dolgozzunk vele.

[ VISSZA A LOGOKHOZ ]