Overview
To get familiar with Ghidra reverse engineering on embedded, I decided yesterday to take on reverse engineering my VR30 ECM. This page details the approaches I have taken so far, and my next steps.
Background research
First step to any project like this is background research. This allows me to get datasheets and other information that might be useful, as well as target flash dump size.
Manufacturer | Hitachi |
Microcontroller | SH72531 |
Flash Size | 2MB |
Obtaining the binary
The plan
I wrote a simple program to escalate up to diagnostic session level 0xFB, detect how large the accessible flash was (NACK at nonexistent blocks), and then use UDS 0x23 (Data Upload from ECU) to execute a read of the entire flash using ISO-TP. The program was run on my own ESP32-based 12v CAN PCB and binaries were saved locally to SPIFFS. This program was tested and worked successfully on my friend’s untuned G37 with a similar Renesas-based Hitachi ECM.
Plan fell apart
When I first tried it on my car, I got a NACK across all blocks attempted with a security access error. Being tuned, I figured that the current tuning software provider had more than likely changed the seed/key algorithm and enabled read-protect.
Upon flashing to stock and trying again, it appears that Nissan itself does in fact secure ECU flash reads behind the UDS seed/key system, not just writes. I need to test this on another untuned ECM to verify its not left disabled by the tuning suite (as the license is left behind). While the seed/key system is a task to tackle later in Ghidra, I have an idea for a way around it for now.
Possible Solution
I started writing an ESP32 program for a “CAN in the middle” module that connects to a diagnostic tool (CONSULT III+ or a tuning dongle) through a terminated bus, with a second bus connected to the vehicle. When the tester initiates communication, the module will be in full passthrough. Once the module sees positive acknowledgement for escalation to the desired level, it disables tester passthrough and I can begin using the elevated session. The module also sends tester present messages to maintain session elevation if I don’t send anything. Additionally, the module BLOCKS all programming attempts (0x34 UDS & 0xA4 Proprietary Tuning Platform) from the tester.
Flash Process Analysis
I did a quick review of the CAN log from an ECM flash process using my current tuning platform. A few notes:
- At its core, the OEM flash process appears to be UDS seed/key auth (0x27) to security level 249, followed by a series of UDS ISO-TP ECU uploads (0x35)
- I spotted repeated access of a local variable containing “DABCDNODEx” that I saw in the G37 binary as well. The G37 also uses a Renesys-based Hitachi controller. Maybe a family name? It appears it wants to know this before trying the seed/key exchange.
- It appears that even when flashing to “stock” my current tuning provider leaves behind a struct in unused flash containing details such as file name, flash date, flash count, and I suspect license. This is read back using an OEM ECU download call – likely to validate the module is licensed to be flashed.
- It also appears that my tuning provider applies a patch or stub using the OEM flash process, calls two services (I suspect reboot), and then switches over to using proprietary (likely encrypted) diagnostic flash calls.
Next Steps
- (DONE) Order a bench ECM: used ECM for a bench setup
- Won’t brick my only form of transportation if I screw up
- Can be opened for component documentation and possible hardware attacks
- “Clean slate” that eliminates variables from the existing tuning platform
- Test and implement the CAN in the middle module so I can take advantage of elevated diagnostic sessions on the ECM.
- Full flash read (0x35)
- Read all local IDs (0x21)
- Load binary into Ghidra
- Determine seed/key algorithm and implement programmatically
- Apply a Ghidra patch and upload it to the bench ECM