Reverse Engineering Bosch ME9: ECU Identitás Kezelés és VIN-alapú Szoftvervédelem
A Ford Bosch ME9 motorvezérlő egységek nem csupán kalibrációs adatokat tartalmaznak, hanem a jármű identitásával kapcsolatos információkat is kezelnek. Ezek közül az egyik legfontosabb az alvázszám (VIN), amelyet a firmware az inicializáció során betölt egy RAM pufferbe, és amelyet később diagnosztikai és rendszerfunkciók használnak.
A firmware működésének reverse engineering elemzése során megfigyelhető, hogy az ECU több lehetséges forrásból is képes betölteni a VIN-t, konfigurációs flag-ektől függően. Ez a mechanizmus lehetőséget biztosít alternatív identitásforrás használatára, valamint tökéletes alapot ad egy saját, egyedi fejlesztésű, VIN-alapú szoftvervédelem (licencelés) implementálására.
VIN tárolási helyek a Bosch ME9 architektúrában
A firmware két különböző memóriaterületen képes VIN adatot tárolni:
- Elsődleges forrás: EEPROM. Az elsődleges és legfontosabb VIN forrás a külső soros EEPROM chip. Az application inicializáció során a firmware betölti az EEPROM tartalmát egy RAM tükörbe, majd ebből másolja át a VIN karaktereket a belső
vinm9datapufferbe. Ez tekinthető az ECU elsődleges identitásforrásának. - Alternatív forrás: Flash kalibráció (VINEW mező). A kalibrációs területen létezik egy
VINEWnevű mező, amely szintén tartalmazhat VIN adatot. Ez egy általános Bosch funkció, de nem minden firmware-ben van használatban (ST-benFFértékekkel van kitöltve). A firmware konfigurációs flag-ek alapján választ arról, hogy ezt a mezőt használja-e, vagy az EEPROM-ból származó VIN-t.
Bizonyos konfigurációk esetén (ha a dsgpLocBitsini flag megfelelő bitje aktív, amelyet az EEPROM-ból betöltött állapotbyte és a CWDSGP kalibrációs maszk együtt határoz meg, és a mező nem FF), az ECU a kalibrációs VIN-t olvassa be.
A VIN betöltési mechanizmus reverse engineering szempontból
Az application inicializáció során (a RAM init és az EEPROM tükör betöltése után, de a diagnosztika teljes indulása előtt) az alábbi assembly rutin felelős a VIN karakterek átmásolásáért a központi RAM pufferbe:
subi r4, r13, 0x298e ; r4 = vinm9data RAM puffer rlwinm r31, r31, 0, 0x1c, 0x1c ; konfigurációs flag maszkolása vin_copy_loop: cmpwi r31, 0 beq use_eeprom_vin ; Flash kalibráció VIN olvasása subi r12, r2, 0x297c rlwinm r11, r7, 0, 0x18, 0x1f lbzx r5, r12, r11 b store_vin_byte use_eeprom_vin: ; EEPROM VIN olvasása rlwinm r12, r7, 0, 0x18, 0x1f add r12, r30, r12 lbz r5, 0x2(r12) store_vin_byte: stbx r5, r4, r12
A kritikus döntési pont a rlwinm r31, r31, 0, 0x1c, 0x1c utasítás. Ez egyetlen bitet maszkol ki (amely a dsgpLocBitsini RAM változóból származik), és meghatározza a forrást. Ha a bit 0, az EEPROM VIN kerül használatra. Ha nem 0, a kalibrációs VINEW mező.
A vinm9data RAM puffer és a Forrás Patchelése
A másolás után a VIN a 0x7FD6.. RAM címen található a saját ecu-mban (mérete 17 byte). Ez lesz a firmware által használt központi VIN referencia, amelyet a diagnosztikai szolgáltatások és egyéb firmware modulok használnak.
A VIN forrás kiválasztása teljes mértékben kontrollálható és rögzíthető egyetlen assembly utasítás módosításával:
; Eredeti kód: rlwinm r31, r31, 0, 0x1c, 0x1c ; Patchelt verzió: li r31, 0
Ez a módosítás garantálja, hogy a firmware mindig az EEPROM-ban tárolt elsődleges VIN-t használja, függetlenül a kalibrációs adatoktól (CWDSGP maszktól) vagy egyéb konfigurációs flag-ektől. Ez egy determinisztikus és stabil megoldás.
Custom VIN-alapú szoftvervédelem implementálása
Mivel a VIN inicializáció során egy jól meghatározott RAM pufferbe kerül, a VIN másoló ciklus vége ideális "hook" pont egy egyedi licencellenőrzési mechanizmus bevezetésére. Ezen a ponton az ECU már garantáltan tartalmazza a jármű valós identitását.
; ... (Gyári másoló ciklus vége) ... cmpwi r12, 0x10 ; Elértük a 17. karaktert? ble vin_copy_loop ; Ha nem, ugrás vissza bl VIN_license_check ; ---> CUSTOM LICENC RUTIN HÍVÁSA <--- subi r4, r13, 0x297d ; Gyári inicializáció folytatódik b gyari_folytatas
A saját fejlesztésű VIN_license_check rutin három fő biztonsági rétegre épül:
1. VIN-derived identity hash (FNV-1a)
A 17 karakteres alvázszám hatékony kezelése érdekében a rutin egy 32-bites FNV-1a hash algoritmust futtat le a RAM pufferen. Ez nem egy egyszerű checksum, hanem egy gyorsan számolható, egyedi "identitás ujjlenyomat".
calculate_fnvv1a_hash: lis r12, 0x811c ; FNV_offset_basis ori r12, r12, 0x9dc5 lis r11, 0x0100 ; FNV_prime ori r11, r11, 0x0193 mtspr CTR, r4 ; r4 = 0x11 (17 byte) li r10, 0x0 hash_loop: lbzx r9, r3, r10 ; Karakter beolvasása xor r12, r12, r9 mullw r12, r12, r11 addi r10, r10, 0x1 bdnz hash_loop or r3, r12, r12 ; Hash eredménye r3-ban blr
2. Kód Integritás és Fragmentálás
A védelem kikerülésének leggyakoribb módja a feltételvizsgálatok (ugrások) NOP-olása. Ennek kivédésére a rendszer kiszámítja a védendő custom funkció (pl. Map Switcher) futtatható kódjának ellenőrzőösszegét (checksum). A kód-checksumot a rendszer összekapcsolja a VIN hash-el, majd az eredményt három különálló RAM változóba (fragmentumba) menti el, bitforgatással és XOR kulcsokkal kódolva a memóriavizsgálat megnehezítése érdekében.
; ... (Kód ellenőrzőösszeg számítás r27-ben) ... xor r31, r29, r27 ; VIN hash (r29) és Kód szumma (r27) egyesítése stb r31, RAM_fragment_A(r13) rlwinm r30, r31, 0x10, 0x0, 0x1f xori r30, r31, 0xaa stb r30, RAM_fragment_B(r13) rlwinm r30, r31, 0x10, 0x0, 0x1f xori r30, r31, 0x55 stb r30, RAM_fragment_C(r13)
3. Feltétel nélküli kiértékelés (Stealth Validation)
A védett funkció (pl. Map Switcher) meghívásakor a kód nem tartalmaz hagyományos elágazásokat a védelem kiértékelésére. Ehelyett a három fragmentum visszafejtéséből származó különbségeket számítja ki. A kapott eredményt matematikai úton (cntlzw és srawi utasításokkal) 1-es vagy 0-s szorzóvá alakítja.
mapswitch_entry: lbz r10, RAM_fragment_A(r13) lbz r11, RAM_fragment_B(r13) lbz r12, RAM_fragment_C(r13) xori r11, r11, 0xaa ; Kulcs visszafejtése xori r12, r12, 0x55 ; Kulcs visszafejtése subf r0, r10, r11 ; r11 - r10 subf r8, r10, r12 ; r12 - r10 or. r0, r0, r8 ; Ha érvényes, r0 = 0 cntlzw r9, r0 ; Vezető nullák száma. Ha r0=0 -> r9=32. srawi r9, r9, 0x5 ; Bit eltolás. Ha r9=32 -> Eredmény: 1. Egyébként: 0.
A kapott r9 regiszter értékét a kód a kiválasztott térkép indexével szorozza meg. Érvényes identitás esetén a szorzó 1, így a funkció aktiválódik. Érvénytelen identitás vagy jogosulatlan kódmódosítás esetén a szorzó 0, amely determinisztikusan letiltja az egyedi funkciókat (gyári üzemmódot kikényszerítve), anélkül, hogy hibakódokat generálna.
Ez a mechanizmus determinisztikus és jármű-specifikus szoftveraktiválást tesz lehetővé.
← VISSZA A LOGOKHOZ