Originally posted by tdott
View Post
Announcement
Collapse
No announcement yet.
MSS6x Flasher - Now released!
Collapse
This is a sticky topic.
X
X
-
Yep, I wish I knew the fix was so simple 6 years ago when I first wrote the application. Oh wellOriginally posted by tdott View Post
That's a pretty big improvement! Hopefully that should prevent all those unaware / careless (even with the warning) still going ahead and flashing, then disabling their car because they 'weren't sure'.
The ediabaslib firmware is definitely still better -- the write speed is much faster and I overall trust it more, especially for program writes. But for someone who's only flashing once, a standard cable is probably reasonable
- Likes 1
Comment
-
Thank you for your continued contributions to many communities.Originally posted by terra View PostApplication updated https://github.com/terraphantm/MSS6x...ses/tag/v1.1.0
Version 1.1.0. Multiple updates since last release:- Updated Ediabaslib to newer release; .Net 4.8.1 now required
- Default port is now COM1 as EdiabasLib dropped support for D2XX on Windows
- RSA Bypass code is improved and notably faster
- Added ability to restore stock (i.e remove RSA bypass and patches)
- Tunes are now automatically flashed after flashing a program instead of having to click the "flash tune" button
- Reads are now done in "programming mode" and should be about twice as fast as before
- Full reads are now saved in both the combined format and in BDM format (separate files)
- If no VIN is found, VIN will be assumed to be AA00000 for file saving purposes
- MSS60 140E and older no longer require an RSA bypass for tune writes (also of note, if you have any software variants between 140E and 220E, please send them to so that I can determine where the exact cutoff is for the RSA bypass requirement)
- Detect if a "pseudo RSA" bypass used by some tuners is present, in which case the loaded file will be flashed without modification (i.e no checksum correction). Recommend manually correcting checksums or disabling checksums if this technique is used
- Decreased size of flash blocks from 254 bytes to 252 bytes - this allows standard D-CAN cables to work without bricking
- More safety checks implemented
- During the RSA bypass, the UC3F censorship routine is now disabled. This does not remove the censorship from the DME (need BDM or mpower32's software for that), but does prevent it from being set again.
- Added ability to request Level 3/4/5 security access to the Advanced Menu. Unclear if there are any uses for level 4/5, but makes it easier to test.
- Now display the "internal" software numbering (i.e v638 for 80E) if it is readable.
- Fixed a few UI issues
Comment
-
Hi.
Massive respect for the MSS6x Flasher work and the SGIDC.AS2 write-ups,
they helped me a lot getting up to speed.
I've been doing some EDC16 reverse engineering work and needed a RAM
dump tool for it, which then turned into a full flasher for EDC16
DDE5/DDE6 and the ZF 6HP TCU over a regular K+DCAN cable. Following
your posts, I got through extracting the 3DES master key from WinKFP,
decoding SGIDC.AS2, and pulling out the RSA-512 keys for level 3 auth.
The auth flow and full write process now match WinKFP captures
byte-for-byte, so I think I have the protocol side worked out.
One thing I still can't place is the 4-byte ASCII token in the
$31 07 03 request, the one right after the service ID.
A few examples I've captured:
6HP TCU: "18f0"
EDC16 DDE: "3aec", "4d85", "3029", and a few others
It doesn't appear to come from SGIDC.AS2, and I can't find an obvious
WinKFP-side lookup table for it either. The same RSA key seems to want
different tokens depending on the ECU and the flash context (full vs
cal-only), so it's clearly tied to some bootloader-side state.
Do you happen to know what this token is called, where the tester
gets it from, and whether it's derived or just a fixed table?
Right now the only reliable way I have to obtain it is sniffing WinKFP.
Thanks again for everything you've put out there - your write-ups made
all of this approachable.
Greetings from Hungary.
Comment
-
Thanks Terra!
I was actually experimenting with this right now after reading your reply.Initially same conclusion here, the vendor pcaps had random looking tokens
(3aec, 4d85, etc.) so a tester side identifier seemed likely. But on EDC16C31 DDE it turns out to be derived ECU side from $1A 89:
DDE503: $1A 89 - 5A 89 30 30 30 30 30 36 33 30 32 39 ASCII 0000063029
DDE509: $1A 89 - 5A 89 30 30 31 30 37 36 34 35 33 ASCII 0010076453
The trailing 4 bytes are the exact $31 07 03 token. Same value also exists
in flash at 0x806029.Looks like a Bosch programming counter incrementing hex-style after each successful flash, which would explain the a-f characters seen in the wild. I switched the tool to runtime-query $1A 89 before each auth and it now
works on every DDE I've tested. That said, I actually suspect the DDE may also accept arbitrary values and not really care either. I just haven't tested random tokens yet because the counter derived value was consistently working from the capturesLast edited by apstuning; Today, 09:17 AM.
Comment
-
Yea the full signed message from what I remember is the “serial number” (which I believe is the last 4 bytes of that 1a89 message), the “user id” which can be any 4 bytes, and then the random number that was previously requested from the dme.
Edit: Below is an excerpt of the logs I took when I was initially figuring all this out with my comments added
Code:#@30964;P00001900h;# Job "11MSD80" "SERIENNUMMER_LESEN" #@30965;P00001900h;# Results: [ 0 ] OBJECT = "11msd80" SAETZE = 1 JOBNAME = "SERIENNUMMER_LESEN" VARIANTE = "11MSD80" JOBSTATUS = "" UBATTCURRENT = -1 UBATTHISTORY = -1 IGNITIONCURRENT = -1 IGNITIONHISTORY = -1 [ 1 ] JOB_STATUS = "OKAY" _TEL_ANTWORT = 15 Bytes: 0000: 8B F1 12 5A 89 30 38 31 ...Z.081 0008: 30 32 31 30 32 34 17 021024. _TEL_AUFTRAG = 5 Bytes: #@30966;P00001900h;# 0000: 82 12 F1 1A 89 ..... SERIENNUMMER = "081021024" //WinKFP gets DME serial number (which is 30 38 31 30 32 31 30 32 34 in hex) #@30967;P00001900h;# Job "11MSD80" "AUTHENTISIERUNG_ZUFALLSZAHL_LESEN" "3;0x31653634" //WinKFP requests authentication level 3 and sends user id "31653634" as a part of the message (exact useid likely doesn't matter) #@30968;P00001900h;# Results: [ 0 ] OBJECT = "11msd80" SAETZE = 1 JOBNAME = "AUTHENTISIERUNG_ZUFALLSZAHL_LESEN" VARIANTE = "11MSD80" JOBSTATUS = "" UBATTCURRENT = -1 UBATTHISTORY = -1 IGNITIONCURRENT = -1 IGNITIONHISTORY = -1 [ 1 ] JOB_STATUS = "OKAY" ZUFALLSZAHL = 8 Bytes: 0000: 62 90 FE 5C 2B 5E 73 25 b..\+^s% //Random number 62 90 FE 5C 2B 5E 73 25 is sent by the DME _TEL_ANTWORT = 14 Bytes: 0000: 8A F1 12 71 07 62 90 FE ...q.b.. #@30969;P00001900h;# 0008: 5C 2B 5E 73 25 34 \+^s%4 _TEL_AUFTRAG = 10 Bytes: 0000: 87 12 F1 31 07 03 31 65 ...1..1e 0008: 36 34 64 AUTHENTISIERUNG = "Asymetrisch" #@30970;P00001900h;# Job "11MSD80" "AUTHENTISIERUNG_START" 90 bytes: 0000: 01 00 00 00 0A 00 00 00 ........ //First few bytes are EDIABAS formatting stuff. Actual signed message (including length) starts at 0x15 0008: 00 00 00 00 00 44 00 00 .....D.. //Signature decrypts to: 9338596f6ce09c477f1dc08f4cb87151 - which is a reversed (stack order) md5 of 31653634313032346290FE5C2B5E7325 0010: 00 00 00 00 00 00 00 00 ........ //31653634313032346290FE5C2B5E7325 -> 31653634 == user ID; 31303234 == Last 4 bytes of serial number; 6290FE5C2B5E7325 == Random Number 0018: 10 5F 4B 1D 24 98 09 69 ._K.$..i //Same general process should apply to other modules and other levels of security access with the appropriate key 0020: 9D 06 44 80 83 72 53 CD ..D..rS. 0028: 76 45 90 24 0B EC E1 47 vE.$...G 0030: 14 B2 4D 4B C1 10 5C F5 ..MK..\. 0038: B2 81 94 83 FF D7 BC 5E .......^ #@30971;P00001900h;# 0040: 6A 29 04 B2 0A 05 E8 68 j).....h 0048: FA 68 57 C1 76 92 9E 5C .hW.v..\ 0050: B8 8F C4 D4 0E 78 D8 3C .....x.< 0058: D0 03 .. 90
Comment

Comment