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)
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…
11:48
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.
11:48
PDF
picture_2.pdf
75 kB PDF75 kB — Click to view
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
11:48
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)
11:48
image.png
image.png
11:49
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.)
11:49
image.png
image.png
11:49
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.
11:49
image.png
image.png
11:49
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!
== Adding features ==