Nach ungefähr 15 Stunden Arbeit teile ich mal meine Ergebnisse
Mazda 626 GE V6 ECU Reverse Engineering
Gehäuse und Label - leider nicht vollständig sichtbar
Es geht um das reverse Engineering einer ECU "KL05D" - ich meine es müsste für einen KLDE sein, vermutlich Facelift? (Ich bin sicher Rx7 kann hier direkt Klarheit schaffen).
Ein Kollege erzählte mir von Ghidra, einem Reverse-Engineering Repo der NSA (ja, DER NationalSecurityAgency) mit der man unzählige Microcontroller-ROMs reverse engineeren kann. Und um das mal zu testen hab ich was gesucht, mit dem man das machen könnte. Dabei war das einzige was mir in den Sinn kam ein KL05D Steuergerät, das ich noch rumliegen hatte, weil MarS damals nichts damit anzufangen wusste.
Also war der logische Schritt:
Sichtung der Bauteile
PCBA Oberseite der Steuereinheit innerhalb des Steuergerätes
Zu sehen ist erstmal die MCU, die Beschriftung sagt was von DENSO, das ist erstmal sehr schlecht, da Denso überhaupt keine MCUs hergestellt hat - das spricht also hart für einen gelabelten Mikroprozessor. Mithilfe der Bezeichnung "SC402617FN" lässt sich aber doch etwas finden - HIER fand sich eine gute Basis für den Anfang.
"All I have figured out is that the chip number is SC402655CFN185 made by Motorola, and also made by Freescale as SC90078EFR2. From forums on miata.net there is an indication that this chip is based on the 68HC11 platform."
HC11 ist ein sehr guter Hinweis - laut einigen Quellen steht das "SC" für "SemiCustom" - was das bedeutet durfte ich noch herausfinden. Am ehesten passt also der "MC68HC711P2CFN4" Link zum Datenblatt
Für den HC11 gibt es auch ein Ghidra-Decoder-Repo - ultra nice. Link zum Repo
Somit steht dem Auslöten des EPROMs nichts sinnvolles mehr im Wege, gesagt getan und den Inhalt gedumpt. Link zum Dump
Bevor wir zum Schritt der Firmware-Analyse gehen sind aber noch viele Hardwareinformationen notwendig.
Dazu eine kurze Zwischeninformation wie so ein System arbeitet
Systemexkurs - Mikroprozessor
Es handelt sich bei der Architektur um eine der "Von Neumann Architektur". Das bedeutet erstmal grob, dass sich ROM, RAM, IOs, Timer, ADCs etc alle den gleichen Speicherbereich teilen, es gibt hier keine getrennten Speicher. Das heißt grob, dass es nur einen großen Adressbereich gibt, in dem wir alles finden. Das ist deutlich einfacher nachzuvollziehen.
Der Mikroprozessor hat einen 16-bit Adressbus und einen 8-Bit Datenbus. Im Prinzip wird mit dem Adressbus der jeweilige externe Baustein aktiviert und adressiert und dann über den Datenbus eingelesen. Die externen Komponenten teilen sich hier den Adress- und Datenbus.
Um es leichter verständlich zu machen: Das Programm sagt "Hole Daten aus der Adresse 0x2400", dann schaltet der Adressbus die Leitungen auf diese Adresse, in diesem Fall aktiviert sich der Timer-Baustein und gibt seine Daten auf dem Datenbus aus, die im Mikroprozessor eingelesen werden.
Daher ist es sehr wichtig zu wissen welcher Baustein mit welcher Adresse aktiviert wird um zu wissen in welcher Adresse welche Daten auffindbar sind, denn hierüber werden höchstwahrscheinlich die Einspritzventile, Zündung, Magnetventile u.s.w. angesteuert.
Weiter gehts...
Das System hier besteht aus einem externen ROM (EPROM, hier liegt das Programm, Konstanten, Lookup-Table, Kennwerte etc), einem externen RAM (Arbeitsspeicher), mindestens einem Input-Buffer, einem PIA (stellt quasi zwei externe 8-Bit GPIO-Ports zur verfügung, also 16 Ein/Ausgänge), einem programmierbarem Timer-Baustein (diesem kann man zeitkritische Aufgaben geben, der dann seine Ausgänge in bestimmten Konfigurationen schaltet).
Anhand der Adressleitungen konnte ich die einzelnen Adressbereiche identifizieren.
Dabei erstmal die einzelnen Komponenten identifizieren - hilft erstmal eine Übersicht zu schaffen was überhaupt realistisch an den Bussen hängt.
- IC1: SC402655CFN185 (MC68HC711P2CFN4 mit Custom-Pinout)
IC3: 74HC541 - 8-Input Buffer - Stellt 8 Eingänge von außen zur Verfügung
IC4: HC63BP21P - PIA, Parallel I/O Device - Stellt zwei 8-Bit Ports (GPIOs) zur Verfügung
IC5+IC800: SE123 - Leider Denso proprietäres Zeug - anhand des Pinouts aber nachvollziehbar, dass es sich hier um einen Levelshifter von 5V auf 12V handelt
IC6: D151821-0020 - Wieder Denso-Proprietär, es gibt eine Mirror-Quelle: hier
IC7: HD63B40P - Programmierbarer Timer-Baustein mit Ausgängen
IC8: 74HC595AP - 8-Bit-Shiftregister mit Latchfunktion -> Weitere 8 "langsame" Ausgänge
IC9: 74HC74AP - Dual-D-FlipFlop - Funktion noch unbekannt, wahrscheinlich Bus-Logik zur Synchronisierung o.ä.
IC10: TC5564APL - 8kByte RAM
IC11: 27C256 - 32kByte ROM
IC13: TC4051BP - Kanal Analog-Multiplexer/Demultiplexer -> Erweiterung der Analogen Eingänge
IC17: 74HC138AP - 3 zu 8 Adress-Dekoder -> wichtig für die Memory-Map
IC20: 74HC00AP - Quad-NAND-Gate -> Sehr wahrscheinlich für Selektierung einzelner Bausteine
IC21: TLC272 - Dual-CMOS-Operationsverstärker -> SIgnalaufbereitung
Nun ist die Adresszuordnung wichtig für die Firmware. Das heißt, ich muss nachprüfen wo welche Adressleitungen hingehen um nachzuvollziehen unter welcher Adresse welcher IC erreichbar ist.
Habe ich "kurzerhand" alle Bauteile vom PCB entfernt und eingescant:
PCB Ober- und Unterseite der Steuereinheit innerhalb des Steuergerätes
Damit kann man dann wunderbar die Leitungen markieren und nachverfolgen, das ganze sieht dann so aus:
Reverse Engineering der Hardware im Prozess
Zuerst einmal: Leider passt zwar der Footprint und das Gehäuse im Datenblatt der vermuteten MCU perfekt auf die vorhandene, aber leider ist das Pinout komplett anders. Hier passt gar nichts. Das heißt aber nicht, dass es nicht so ist, sondern nur, dass Denso hier vermutlich ein anderes Pinout bestellt hat. Hauptsache proprietär, yay.
Daraus entstanden dann folgende Map-Erkenntnisse:
- 0x0000-0x007F: MCU Interne Register (nach Datenblatt)
0x0080-0x047F: Interner SRAM, 1kByte (nach Datenblatt)
0x0D80-0x0FFF: Interner EEPROM (nach Datenblatt)
0x1000-0x10FF: Interne Register (nach Ghidra)
0x2000-0x23FF: IC7 Timer Register (Hardwareseitig ermittelt)
0x2400–0x27FF: IC4 HD63BP21 PIA (Hardwareseitig ermittelt)
0x2800–0x2BFF: IC3 74HC541 Input-Port (Hardwareseitig ermittelt)
0x2C00–0x2FFF: IC10 externer RAM (Hardwareseitig ermittelt)
0x8000-0xffff: ROM
(0xBE40-0xBFFF: Bootstrap und special Vectors - spielt vermutlich nur in einem Programmiermodus eine Rolle(nach Datenblatt))
Damit haben wir schon eine ziemlich gute Memory-Map. Hier wird sich dann einiges im Code aufklären, was hier wohl plausibel ist u.s.w.
Für die GPIOs und Timer sollten noch die Signale ermittelt werden, dann kann man im Code direkt mappen was Einspritzdüsen, Zündung, Magnetventiile etc sind.
Schwierig sind leider interne GPIOs und der ADC, da das Pinout leider gar nicht zum Datenblatt passt und man nur weiß "Pin 55", aber nicht "PortA:1" - das muss man dann rätseln - wird aber sicherlich machbar sein. Wenn man im Pseudocode sowas sieht wie "Rev >= 4000 dann 0x2401:7 ==1", dann ist klar, dass das VRIS1 ist.
Analyse des ROMs
Der eigentlich spannende Teil kommt jetzt: Die Firmware-Analyse.
Mithilfe der bereits ermittelten Adressbereiche kann man also schonmal im Code relativ gut sehen welche Registerzugriffe wohl was sein könnten. Allerdings ist dieser Prozess schwer hier zu beschreiben, weshalb ich da eher nur bedingt drauf eingehen werde und eher den aktuellen Stand mitteile, so wie neue Erkenntnisse. Wenn der Stand interessiert, der kann sich gern im GitHub-Repo umschauen, da ist das Ghidra-Projekt enthalten, so wie alle anderen Erkenntnisse die ich so gesammelt habe.
Aktuellster Stand (07.05.2026)
Neben den bereits erwähnten Memory-Maps habe ich bisher folgende Funktionen gefunden:
- IC7-Timer Programmierung
diverse Interrupt-Routinen (noch unbekannt)
ADC-Result-Adressen / Multiplexing-Abfrage (sprich ich weiß wo die gemessenen Analogwerte liegen)
Lookup-Table für Verzögerungen von 6 Kanälen (vrmtl Einspritzdüsen)
Einem Fallback-Bit (Schätze Notlauf)
Ausleseroutine von IC4
Injektoren-Routinen
Camshaft-Position
Wozu eigentlich?
Zuerst war das nur reines Interesse ob es überhaupt machbar wäre, dann verselbstständigte sich das ganze und nun bin ich schon ziemlich weit. Darum kamen natürlich auch diverse Fragen auf, was der Kern des ganzen werden könnte.
Was kann man denn jetzt mit den Infos anfangen?: Eigentlich sehr simpel. Wir könnten die Firmware beliebig umprogrammieren, das Mapping anpassen, wann was passiert, VRIS dauerhaft an. Theoretisch ließe sich die ECU auch um weitere Eingänge erweitern, da noch viel frei ist. Aber das für mich interessanteste ist ein anderer Fakt:
Durch die Architektur mit dem externen Adress- und Datenbus eröffnet sich eine ganz interessante Möglichkeit: Das Mitlesen der Daten. Das Ziel dieses Projektes wäre ein Adapter, der statt des EPROMs gesteckt wird mit einem Mikrocontroller, der den Inhalt des ROMs hat und diesen emuliert, außerdem kann er alle Register mitlesen.
Das bedeutet:
- Live-Daten
Live-Anpassung des Mappings
Live-Anpassung der Firmware
GitHub-Repo
Alle meine Erkenntnisse und gesammelten Daten werde ich in dieses Repository einpflegen. Das umfasst auch die Datenblätter, Bilder, Firmware, Ghidra-Projekt, Stromlaufpläne u.s.w.
https://github.com/Battlecake91/Mazda_626_ECU_ReverseEngineering/tree/master
