Reverse Engineering Bosch ME9: Az Immobilizer (WFS) Rendszer Teljes Anatómiája
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:
- Kriptográfiai réteg: A műszerfalról (Instrument Cluster) CAN-en érkező Challenge-Response ellenőrzés
- Állapotgép réteg: A
secacc_stateváltozó, amely a belső döntési logikát vezérli - Aktuátor réteg: A gyújtás és befecskendezés fizikai tiltása hengerenként
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ím | Méret | Szerep |
|---|---|---|---|
secacc_state | 0x8042E3 | 1B | Fő állapotgép: 0x33 / 0x66 / 0x77 / 0xAA |
secacc_mode | 0x8042E2 | 1B | Biztonsági hozzáférés módja |
service_mode | 0x8042E5 | 1B | Szerviz mód flag |
wfsbitsNV1_10ms | 0x7FD6EE | 1B | NV perzisztens bitfield (EEPROM tükör!) |
wfsbits1_10ms | 0x804644 | 1B | Volatile bitfield #1 |
wfsbits3_10ms | 0x804646 | 1B | Volatile bitfield #3 |
wfsbits4_10ms | 0x804647 | 1B | Volatile bitfield #4 |
wfsbits5_10ms | 0x804648 | 1B | Volatile bitfield #5 |
eep_request | 0x8042D9 | 1B | EEPROM művelet kérés kód (0x01-0x0A) |
cycles_ig_cnt | 0x7FD6E8 | 1B | Hátralevő indítási ciklusok (NV) |
inCodeCtr | 0x7FD6E9 | 1B | Hátralevő kódpróbálkozások (NV) |
B_ecudev | 0x7FAB65 | 1B | Fejlesztői mód flag |
B_kl15 | 0x7FB405 | 1B | Terminal 15 (gyújtás) állapota |
B_eculock | 0x7FA995 | 1B | ECU zárolás aktuátor |
B_stalock | 0x7FA996 | 1B | Starter 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:
immo_execute_ign_lock(0) lefut, a motor indítható.
immo_execute_ign_lock(0) lefut, a motor indítható.
| Állapot | Érték | Jelentés |
|---|---|---|
| LOCKED | 0x33 | Motor indítás tiltva. Ez az alapállapot. |
| LEARNING | 0x66 | Tanulási mód / várakozás CAN-es kódellenőrzésre |
| PRE-AUTH | 0x77 | SecurityAccess engedélyezve, de validáció még nem történt |
| UNLOCKED | 0xAA | Minden 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:
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:
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
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!)
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)
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:
| CMD | Funkció | Leírás |
|---|---|---|
0x81 | SecurityAccess belépés | LOCKED - LEARNING átmenet |
0x82 | Timer érték írás | AS timer beállítása (0x08-0x3F) |
0x83 | Challenge-Response | Kriptográfiai kódellenőrzés |
0x85 | Új kulcs tanítás | ISK programozás (0x20 subcommand) |
0x86 | Kezdeti beállítás | Tanulási mód belépés |
0x87 | secacc_mode váltás | Mód változtatás |
0x88 | service_mode váltás | Szerviz mód kapcsoló |
0x89 | Állapot lekérdezés | secacc_state visszaadása |
0x8A | Kulcs verifikáció | Challenge válaszadat |
0x8B | Konfig lekérdezés | secacc_mode, service_mode |
0x8C | Státuszbitek | wfsbits5, wfsbits3, wfsbits4 kódolva |
Command 0x83, Challenge-Response kódellenőrzés
Ez a rendszer kritikus pontja: a kriptográfiai validáció:
; = 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?
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!)
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:
; 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 bit | Aktuátor | Hatás |
|---|---|---|
Bit 0 | B_eculock | ECU általános zárolás flag |
Bit 4 | B_stalock | Starter relé blokkolása |
Bit 2 | Gyújtás cut | ENG_Ignition_Cut_Actuator, hengerenkénti letiltás |
Az ENG_Ignition_Cut_Actuator(), A végső szankció
; 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:
; 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.
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"
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 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
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:
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
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:
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:
- Csak az ignition lock-ot patchelné, a
secacc_statesosem jutna0xAA-ra - Csak az ISK írást engedélyezné, nem tudja feloldani az aktuátor zárolást
- Csak a kripto kulcsot cserélné, az EEPROM-ba nem tudja elmenteni
- Csak a DTC-t nyomná el, az állapotgép továbbra is LOCKED állapotban tartja az ECU-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()
; 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
- Sikeres auth volt -
secacc_state = 0xAA,wfsbitsNV1 bit 2 = 1- következő boot: UNLOCKED - Nem volt auth -
secacc_state = 0x33- következő boot: LOCKED
7. fázis: WFS_Shutdown_EEPROM_Save(), Perzisztens mentés
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 ]