Changes

Jump to navigation Jump to search
15,144 bytes added ,  01:26, 24 November 2020
The ecu in any car is designed to control how the engine operates. Car manufacturers want their engines to produce power, while still being fuel efficient, reliable, quiet, etc. The way they accomplish this is by defining "maps" which contain modifiable parameters that the ecu will use to make decisions on how the engine should be working. In the case of the Simos18, there are both measured values and modeled values in these maps.
= Primary Control Strategy =
The accelerator pedal tells the ecu how much torque the driver wants the engine to produce.
That driver input is referenced against a table that defines the maximum torque available at any given RPM.
That target torque value is referenced against other maps which define how much airflow, followed fuel and timing, the ecu should target to achieve the driver request torque value.
 
The way the ECU chooses to achieve different levels of performance are called "combustion modes". Refer to the FR page 1673 for more detailed combustion mode definitions.
= Simos Information =
There are six blocks:
PMU0 (2MB)
#SBOOT – supplier boot (0x0000 0000 -> 0x0001 BFFF)
#CBOOT – customer boot (0x0001 C000 - > 0x0003 FFFF)
#ASW1 – Application SW part #1 (0x0004 0000 -> 0x0013 FFFF)
#ASW2 – Application SW part #2 (0x0014 0000 -> 0x001F FFFF)
#PMU1 (1MB)
#CAL – Calibration (0x0020 0000 -> 0x0027 FFFF)
#ASW3 – Application SW part #3 (0x0028 0000 -> 0x002F FFFF)
*PMU0 (2MB)**1. SBOOT – supplier boot (0x0000 0000 -> 0x0001 C000) [112K]**2. CBOOT – customer boot (0x0001 C000 - > 0x0004 0000) [144K]**3. ASW1 – Application SW part #1 (0x0004 0000 -> 0x0014 0000) [1024K]**4. ASW2 – Application SW part #2 (0x0014 0000 -> 0x0020 0000) [768K]*PMU1 (1MB)**5. CAL – Calibration (0x0020 0000 -> 0x0028 0000) [512K]**6. ASW3 – Application SW part #3 (0x0028 0000 -> 0x0030 0000) [512K]  Their logical locations in software:*SBOOT: 0x80000000-0x8001C000*CBOOT: 0x8001C000-0x80040000*ASW1: 0x80040000-0x80140000*ASW2: 0x80140000-0x80880000*ASW3: 0x80880000-0x808FFC00*CAL: 0xA0800000 === Each blocks block's purpose ===
==== SBOOT ====
SBOOT is not a field replaceable unit, so can’t be flashed over with OBD and you can ignore it for all intents and purposes since you can’t really modify it. The other five can be replaced via OBD and are subject to modifying.
CBOOT does all the flashing. Basically when you want to reflash via OBD, the ECU reboots into CBOOT and runs all the re-flashing procedures etc out of CBOOT. Once complete, it reboots again into ASW. ASW, the application software, is what controls the combustion process in your petrol engine. CBOOT has nothing to do with ASW. You can’t flash from ASW, you have to go into CBOOT for that. Both CBOOT and ASW have their own UDS comm stack, so when CBOOT is active it uses its own comm stack for CAN messages and similarly when ASW is active its using its own separate comm stack as well
==== ASW ====
ASW is the "Application Software" and contains all of the engine management software itself. This is the software that reads sensor data, and makes decisions.
 
==== CAL ====
This is the calibration data. The "maps" and "tables" that affect the way the car runs.
== Calibration changes ==
It's important to understand that while making changes to the ECU, there's literally hundreds of different tables that may be referenced at any given time or situation. The process of identifying what tables should be used to achieve a given result includes reverse engineering the process that the ECU uses to make certain decisions. One example of this fact is that while anybody familiar with tuning this ECU knows (by know) about the Max clutch torque tables, they probably don't realize that there's more than than one (15?). These tables are (likely) used in different situations/combustions modes (as outlined by ECUTek). Some tools will link all of them together as a single abstract table so that they all get updated simultaneously, since that's probably the goal of the tuner anyway. If we ever have access to open source tools (technically we do already) for modifying our calibrations, that linking is highly unlikely (and will complicate the tuning process greatly).
=== Definitions files ===
Definitions files are essentially a "map" to where the maps are located within the calibration data. They give software the ability to display maps in a human readable way. They're proprietary (in the case of factory definitions files), or they're built by hand using the factory definitions as a model.
== Flashing the ECU ==
The first flashing procedure includes a process which overrides the restrictions that exist in the factory ASW and effectively unlocks the ECU. This allows the tuner to modify the calibration block and flash it to the ECU without triggering the ASW to reject anything. <strong>This process is proprietary. Tools like Flashtec, Alientech, bFlash etc have their own way of accomplishing this.</strong> Once the ECU is unlocked, any table located in the calibration block can be modified and the entire calibration block reflashed to the ECU as a single action. If you've ever been through the process of flashing calibration changes - they go much faster than the initial flashing process (as they're only changing 1/5th of the overall data).
 
=== Unlocking the ECU ===
This is the factory OEM flash routine (aka FRF)
 
The numbers with the $xy suffix are UDS Service Routines, occasionally referred to in hex notation (0x31, 0x37, 0x2C, etc)
 
picture_1.pdf
123 kB PDF123 kB — Click to view
 
*$31 eraseMemory
**What is says. Deletes the entire CAL area so the whole block is grey to represent this.
*$34 requestDownload
**Ask to initiate a data transfer
*$36 requestDownload
**Actually move the bytes from the flash tool to the ECU
*$37 requestTransferExit
**Terminate the transfer after all bytes have been copied over. If you look the picture now, you’ll see that the blue data transferred doesn’t quite fill up the flash block. There is still a little bit of grey space remaining. That’s intentional, the flash block really is bigger than the blue CAL data. That little bit of spare space is used in the next steps.
*$31 checkMemory
**“Performs checks to write security keys for reprogrammed components. Security keys in flash memory to secure the reprogramming session if checksum and coherence are fitting. They are tested at start-up of the ECU. If one of the Security Keys is not valid, the applicative software is inhibited and there is no system operation”. So that’s the OKAY bytes written in green. NB – it’s a routine in the ECU that writes these OKAY bytes onto the flash after all checks are successful (checkMemory). Once the block has got the OKAY bytes, the block is allowed to be used. The OKAY bytes are written into the flash just after the blue data. If you look at a full 4MB file, you can see the OKAY bytes yourself just after the end of the CAL data. If there’s something invalid about the CAL data, then the check won’t write the OKAY bytes and the block is invalid…
 
 
And this is the initial exploit (this is just one step of several in what the tools do. There are some subsequent steps as well. This just gets some non-OEM code onto the ECU. In subsequent steps that non-OEM code will do further stuff)
The normal sequence is Erase, Write, Check.
 
 
picture_2.pdf
 
Because the Erase wipes both the Data AND the Okay bytes, once you’ve erased and sent the new data across you have to run the check to rewrite the Okay bytes and make the entire thing valid again. But now if you look very carefully, when the tool sends some patched ASW immediately again, it DOESN’T erase first. And because it doesn’t erase first, the Okay bytes are still there…
But there are some restrictions if you are going to write WITHOUT erasing. I found this in the Infineon documentation:
“The erased state of a flash cell is ZERO. After programming a ONE to a cell, only an erase can bring it back to ZERO. Writing a second time to the same cell with a ZERO does not change the ONE. But a ZERO can always be programmed to a ONE”
That means that you can only put additional stuff in a blank area, you can’t change existing areas. I think like this:
Flash after "Erase, Write, Check"
Write this to Flash again without
"Erase"
Flash ends up being a combination of the
two writes
t h i s i s t h e o r i g i n a l
s o u r c e c o d e 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 a p a t c h 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
=
t h i s i s t h e o r i g i n a l
s o u r c e c o d e 0 0 0 0 0
0 0 0 0 0 a p a t c h 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 
 
 
Okay, the next thing is CBOOT. The CBOOT handles the flashing but there are actually two CBOOT used in the process (CBOOT_temp and CBOOT_actual)
 
image.png
image.png
 
 
Whilst you can directly update CAL, ASWx and CBOOT_temp via OBD flash routines, you can’t reach CBOOT_actual. You can only reach it indirectly. This is a safety thing. The flash routines are executing out of CBOOT_actual. It doesn’t matter how many times you mess up the blocks on the left, you just simply reboot, start execution out of CBOOT_actual and try again until you get it correct. But if you messed up CBOOT actual, then you’ve got nothing that works to reboot into. It’s bricked.
Thus the indirect way to update CBOOT is to OBD write to CBOOT_temp. Then CBOOT_temp gets checked over very carefully to ensure it is totally intact, no corruption, checksums okay and crypto signature all valid etc. And only then does an internal routine move CBOOT_temp to CBOOT_actual
You can read about this in detail in the FR – it’s explained in Section 21.2 ECRP-ECU Customer reprogramming (Appl. Inc.)
 
image.png
image.png
 
So now building up the story, step by step. The first step talked about writing without erasing. Second was the concept of CBOOT_temp and CBOOT_actual. Thirdly is below.
 
image.png
image.png
 
 
You can directly reach ASW1 via OBD. You can inject some extra code into ASW1 by write without erase. Limitation is you can only add, not delete or modify… Then when the ECU reboots into ASW1, the extra code in ASW1 does a low-level flash write to the flash memory location of CBOOT_actual (0x8000xxxx). It’s also subject to the same limitations because it’s not doing a delete, it’s writing on top of what’s already present. Basically it’s trying to change just a few bytes in CBOOT_actual.
No point in changing them in CBOOT_temp – the _temp to _actual checks will catch any suspicious changes before _temp is allowed to be copied over to _actual. You have to change _actual itself.
So eventually after all this you end up with some changes in CBOOT_actual, having gone via ASW1.
What do the few changed bytes in CBOOT_actual do? They switch off crypto signature checking, allowing modified files to be flashed via the OEM process :blush:
Just a few notes at this point in the flashing process
The first initial software blocks sent from tool to ecu are most likely to be stock blocks, just returning the ecu to the stock software. If the tool is going to be trying to crack the ecu and exploit stuff, it doesn’t want to be colliding with weird code that a previous tool / another tool vendor has potentially already left behind… No, you want to start greenfield, with known software and utterly predictable behaviour. Set it back to stock and start from there, the OEM software will always go back on because it’s always signed legitimately and check summed correctly.
When transferring from tool to ecu, the software blocks (CAL, ASWx, CBOOT) are compressed one-at-a-time by a LZSS algo and then the compressed files are encrypted with an AES key. Finally these AES-encrypted, compressed files are sent from the tool to the ECU with the ISO-TP multiblock packet size set to the biggest size possible (4095 bytes at a time). Get it across as fast as possible, small file in the biggest chunks possible (obviously inside the ecu it then decrypts and un-compresses them).
But what I’ve seen when the tools do the WriteWithoutErase exploit, the block is NOT compressed. It’s only AES encrypted. And the ISO-TP packet size is stepped down from 4000 to just a 100-or-so bytes per packet. So you have a big (uncompressed) file being sent a little bit at a time. And to make it worse, it’s like an old fashioned reel of tape! You can’t specify just an address in the middle. It always starts at the beginning and plods along to the very end, even if it was just 100 bytes in the middle you were trying to write. So that’s the file mostly filled with zeroes. It’s gonna start at the beginning, plod along through all the zeroes which won’t change anything, get to a few bytes and write them, then carry on with more zeroes until it reaches the end.
That makes it really slow and I think this slowness is deliberate. I believe that when you are trying to write data to a flash substrate that hasn’t been freshly erased, it can take time for the bytes to ‘soak’ into the flash. It’s not freshly erased and just sitting there waiting. Instead it’s already got some contents and now you’re writing to it again. Maybe it takes longer to sink in and for the binary state to change… So that is your thirty to forty-five minutes waiting around time when the crack first happens.
Those checks I mentioned that set the green OKAY bytes in the pictures I drew. Those checks only happen when you ‘step through the front door’. They don’t happen again. Just a once-off when the file is first pushed onto the ECU through the OBD front door. After it’s written to the flash, no point in checking it again, it already passed once and caused the OKAY bytes to be written. Simply the presence of the OKAY bytes suffices to say it was checked. That’s why if you can somehow change the code and leave the OKAY bytes intact, the code will not be checked again and your changes will go undetected!
 
 
Now you’ve reached the point, after a lot of effort, that you can write modified stuff down to the ecu. Great. But what if this is the second or third or nth time you want to flash. Clearly you don’t need to patch the ecu every single time, just the first time. No one want to sit around for 45 minutes unnecessarily. So wouldn’t it be nice to somehow check if the ECU has already been patched and we can just skip straight to sending modified files. Or discover if it was never patched and we have to start from scratch. Maybe a friend brings their ecu along and you don’t know the history. You need a way to talk to the ECU…
So now I must digress back to UDS again.
You’ve see services $2C, $22 and $23 for logging. There’s another service $3E TesterPresent. It is simply a heartbeat sent from any OBD tool to the ECU periodically every few 100ms and reminds the ECU that the tool is still there. Just a little tap on the shoulder. Useful for things like elevated security levels – if the tool had requested an elevated privilege level (Service $27 SeedKey) and the ECU then went into that privilege mode, but then the tool disappeared for some reason (flat battery/disconnected cable) then the ECU would notice the missing heartbeat, tear down the elevated privilege session and go back to a basic diagnostic mode waiting for the next connect.
A regular ISO/SAE UDS hearbeat is really simple. The format is always the same as well:
0x02 0x3E 0x00:
2 – it’s 2 bytes in length. Mandated by the UDS standards. Anything other than 2 in this field returns an error
3E – the first byte, it’s service $3E
00 – the second byte, it’s allowed to be 00 or 80 (acknowledgement required/not required)
So many third party tools re-task the UDS heartbeat message for their own purposes. What they’ve done is to slightly ‘corrupt’ the heartbeat request/reply, to use it beyond the original intention:
0x03 0x3E 0x00 0x01
3 - it’s 3 bytes in length.
3E - the first byte, it’s service $3E
00 - the second byte, it’s allowed to be 00 or 80 (acknowledgement required/not required)
01 – an extra byte, tacked upon the end. This could represent Command #1
So now you send this modified heartbeat. Firstly, the length is different now, 3 bytes instead of 2 bytes. So an unpatched stock ECU would reply with an Error 13 – incorrectMessageLengthOrInvalidFor
mat because the ISO/SAE standard is just 2 bytes always . But a patched ECU (with suitable patching in the UDS stack) would accept this and reply with a positive response instead. And there you have it, the tool can learn whether the ECU is previously patched or stock by simply send a little heartbeat message and seeing if the reply is positive or negative.
In addition, you can use that extra byte at the end to trigger something inside the ECU as well (as long as there is corresponding patching to accept it). In the example above, the extra byte being a value of 0x01 could mean invoke activity #1. A value of 0x02 might mean invoke activity #2. All driven by the tool. The clever bit here is that it’s a combination of external tool and ecu patches. It’s not enough just to have the patches inside the ECU, you also need the external tool to trigger those patches inside the ECU otherwise they just sit there waiting.
 
Next chapter of the story
So now the ECU is wide open. After several steps (and going around the houses via ASW), finally a couple of bytes (yes, it really is just two) have been changed in CBOOT_actual which bypass the RSA signature checks. The ECU will now accept any modified file (i.e. signature not matching contents) that you throw at it, moreover you can just use the factory flash sequence of UDS commands to send the modified files. You don’t need a fancy tool costing £££ thousands either, anything that can send the UDS commands will do the job.
So the pendulum has swung too far if you are a tool vendor! And now they dial it back a bit and make sure that it’s their tool in control again and you have to use their tool.
So whilst the ECU is wide open with RSA signature checks bypassed, the flash tools send down a CBOOT with a number of changes:
A patched heartbeat
Remember UDS command $31 02 02 checkMemory, described much earlier? The one that does a bunch of checks and write the green OKAY bytes? Well, there’s a patch that does the same thing but it doesn’t do any checks beforehand, it just blindly writes the OKAY bytes
And the RSA signature checking is re-activated (the two bytes are reverted)
The ECU reboots, comes up running this modified CBOOT (and although it’s modified it runs quite happily because no checks are done after the fact. The checks are only done once when it passes through the front door on the way in via OBD).
The active RSA signature checks prevent you from sending down any more modified files. Err - but then how do you send a modified CAL?
Remember again that modified UDS heartbeat $3E? Tacking a byte onto the end? And using that byte to represent some command?
Well, you send over the modified CAL using the same UDS flash sequence commands Erase, then Write, all legitimately ($34, $36 etc). The CAL ends up on the flash inside the ECU and the final step is to get the OKAY bytes. At this point, instead of running the OEM $31 02 02 checkMemory which will fail because the file is modified and not write the OKAY bytes, the tools send a modified heartbeat. A patch inside the ECU recognises the modified heartbeat and blindly writes the OKAY bytes for CAL. Then as far as the ECU is concerned, all is fine, the OKAY bytes are there and everything is perfect.
And the tool vendor is happy because you’ve had to use their tool to do this and their modified heartbeat comms channel and whatever command byte sequence they put in :blush:
== Adding features ==
26

edits

Navigation menu