Closed rumator closed 7 months ago
Hey @rumator try to put your 4 bytes seed instead of 1's as on this picture, you can leave zeros as placeholders, since they don't play any role in key calculation. As key you can take highlighted 4 bytes.
Not sure it will work, but please try and let us know, maybe also try to reverse endianess of seed or/and key.
Hello @VladLupashevskyi
I tested it and no luck, sec level goes from 61 11 02
to 61 11 00
I will test different software version
Hi there,
so during the yesterday's night I tested some more alogs, but no luck. I tested simple 27 01
and also 10 F0
for "VDO mode" and then I got seeds by 31 FB 10
. To be honest I don't know the difference between those 2 methods, but both gives 4 bytes, but I was not able to get any successful unlock.
With the CxF viewer I found interesting comment in cbf file:
27 01
function has description as following
!!!Bitte ab BR 211 den parallelen SECURITY-Dienst verwenden!!! Seedbytes fuer die Entriegelungsstufe 1 holen
10 92
has following
!!!Bitte ab BR 211 den parallelen SESSION-Dienst verwenden!!! Diagnosemodus Db-Diagnose einstellen
based on this I think that algo from ki211 suppose to somehow work on those clusters. Any ideas welcomed, thanks!
Hi, small update from my side, I dumped full firmware from the cluster. I did no find root keys yet.
Hey guys, just did a quick lookup. These look like root keys for 7 access levels (so we need just last one to get lvl 7).
Key calculation function is located at: 0xf910b6-0xf91232. I could not find a proper C decompiler for it, but after a quick look it looks like it's the same logic.
Be aware that this CPU is little-endian so you might try both options for root key: 27FC2D10
and 102DFC27
.
And thanks for the dump @rumator :)
Btw... also a key could be accepted in a different endianes. So @rumator you have to try 4 options:
root 27FC2D10
- take 4 bytes from generated key as mentioned above, for example 11 22 33 44
root 27FC2D10
- reverse endianess of key: 44 33 22 11
and then try the same with 102DFC27
as root key
Hello @VladLupashevskyi, thanks for fast answer (and email with advice)!
Unfotunately its not working, I made this:
then tested both root keys as mentioned above (key has been inserted as
11 22 33 44
and 44 33 22 11
). I also tested 27 01 + 27 02
and 31 FB 10 + 31 FA 10
but every combination change my 07
access level gained from eeprom to 00
.
Sorry for basic question, but how did you interpret the hex dump to the screenshot whit the keys which you posted?
thanks!
ok heres my contribution. KI203 ( seed 4 \ key4) key generation algo v1: 203XXXXXXX_0223 ; 0x758A9A61 203XXXXXXX_0287; 0xF8205A4F 203XXXXXXX_0290; 0x054EDE92
key generation algo v2: 203XXXXXXX_0247; 0x5B51DE37 203XXXXXXX_029F; 0x5F1D72EC v3: 203XXXXXXX_0253; 0xEF2DA763 v4: 203XXXXXXX_029D; 0xFFFFFFFF v5: 203XXXXXXX_029E; 0x8EB3DAC5
tell me which version you have in case of KI203M - seed8 \ key7 with other keys and algos
@rumator I did it via Ghidra, found a CPU module for this CPU.
Hmm... it looks like @Feezex knows more about all different algos for these clusters :D
What I would try is also to invert endiannes for seed itself for this algo, so you can try those 4 optioned mentioned earlier.
Otherwise I can try to figure out what it's doing via assembly later, unfortunately that module for CPU does not decompile well assembly to C.
example for version1 :
Seed 28 EC EA E9 > 92 AE 8E CE (pos change) XOR 0x758A9A61 = E7 24 14 AF
12 34 56 78 > 81 63 25 47 > XOR 0x758A9A61 = F4 E9 BF 26
other versions posibbly have other transposition map, can sort it out later.
To say true i dont knew how exactly get Version info, probably with vediamo.
Try 31 FB 00.
heres ki203M example lvl7 reached with version 0014
Here I tried to figure out assembly that I saw first time today, maybe that would be helpful. Some things were not clear to me.
Btw 31 FB 00
and 27
are pointing to the same function, so they should work the same
@VladLupashevskyi
tested 27FC2D10
and 102DFC27
with seed 11 00 22 00 33 00 44 00
and 44 00 33 00 22 00 11
and key XX 11 22 33 44 XX XX XX
and XX 44 33 22 11 XX XX XX
and no luck.
@Feezex
If I understand it correctly, my version is 02 88, is it correct?
Iam not really sure how to use information about the v1 - v5 algo calculation :-)
@rumator yeah, according to assembly it's a bit different algo. Basically it has to be reinterpreted in some high level language and tried out. It's not that hard, but there are some things that were not clear for me (especially at the end), so if someone finds time to read docs of F2MC-16 assembly can try it out, better of course to have a cluster to test it.
I think your 0288 is a v1 with 0xF8205A4F key. So seed 12 34 56 78 > reorder bytes as 81 63 25 47 , XOR it with F8205A4F.
I think I've got it, will try to come up with some test script soon
ki203v1_F8205A4F.zip try this xDD
Just finished decompiling. Quickly did a python script, @rumator try it out.
def rotate_left(v,n):
for _ in range(n):
cond = v & 0x8000_0000
v = (v << 1) & 0xFFFF_FFFF
if cond:
v |= 1
return v
def rotate_right(v,n):
for _ in range(n):
cond = v & 1
v = (v >> 1) & 0xFFFF_FFFF
if cond:
v |= 0x8000_0000
return v
def count_ones(v):
r = 0
for _ in range(32):
if v & 1:
r += 1
v = v >> 1
return r
def seed_key(seed, root):
seed_reorder = (
((seed & 0xFF00_0000) >> 16) |
((seed & 0x00FF_0000) << 8) |
((seed & 0x0000_FF00) >> 8) |
((seed & 0x0000_00FF) << 16)
)
print("Seed reordered", hex(seed_reorder))
rotated_left = rotate_left(seed_reorder, 3)
print("Rotated left 3 times", hex(rotated_left))
xored = rotated_left ^ root
print("Xored", hex(xored))
ones = count_ones(root)
print("Ones", ones)
rotated_right = rotate_right(xored, ones)
print("Rotated right", hex(rotated_right))
result = (
((rotated_right & 0xFF00_0000) >> 16) |
((rotated_right & 0x00FF_0000)) |
((rotated_right & 0x0000_FF00) >> 8) |
((rotated_right & 0x0000_00FF) << 24)
)
print(f"Key result: 0x{result:08X}")
So you give it seed and root key and B912496B
would be your key with seed 11223344
.
@Feezex my algo gives actually the same result as yours, but it has more steps that describe how it was originally implemented.
awesome you)) glad that we got same result, cool to see how its originally implemented.
this is amazing!
@Feezex your algo works like a charm!
@VladLupashevskyi unfortunately PY algo generates different values...
When I had idea almost 1 year ago "hmm would be nice to have some more info about the car on cluster" I would never expect how deep this rabbit hole can be! And I love it!
try PY with 27FC2D10 key, seems there is more than one version of algo and both must work
unbelievable, it works indeed!
so there are 2 different algos with 2 different root keys, which works same.
@Feezex that small exe file is yours? did you extracted root keys same way as Vlad did it?
Woohoo congrats @rumator.
I think the reason there are „different“ versions of algos, is just because one can be derived or simplified with each other.
so you can rotate either seed or root key before xoring, or after. Also the result would be the same if you move bytes or bits in seed value, or in root key.
so @Feezex you algo can be actually more simplified to one xor.
so instead of doing
[12 34 56 78] > reorder bytes as [81 63 25 47]
for seed, you can actually reorder your root key in the same way and use original seed.
then if you use that reordered root key, the algo is just one xor
And I think that’s also the reason they moved to a different more complex logic for algo in w211 later, someone realized that despite all these multiple shifts, the „root“ key can be obtained just if you know one pair of key and seed, just by xoring
as far as i remember ver3 / 4 / 5 is totally another algo, while ver 2 has another bit reordering map. ill try reorder root key , so v1 can be used for v2 also
@VladLupashevskyi the speed which you identified the correct architecture from that dump is impressive. Do you have advice or pointers on how you figured out that arch and that specific address to map the memory into?
@rumator Thanks for starting this thread and following it all the way through. I'm also curious about how you made the dump; I'm assuming that a CFF is unavailable for this cluster?
@Feezex Thanks for building and sharing the exe and supporting this thread (along with all the other discussions and issues too!)
When I started this specific project, I hoped that it would become a small, cozy spot in the internet for random folks to collaborate and work together on seed-key algos (which was traditionally gated knowledge). You guys are doing that right now and it's amazing to watch this algo come to life. Well done, all of you ^^
@jglim hello, I followed Vlad's advices.
The address in EEPROM for ki211 that I checked was 0x0DE, 0x0DF which is for default lvl 2 is 0xA2C4 and for level 7 it's 0x5779
then with Arduino fault-tolerant shield dumped via UDS commands segment by segment.
12 34 56 78 > reorder >81 63 25 47 , xor F8205A4F = 79 43 7F 08 12 34 56 78 xor "reordered xor" FFA28504 (F8205A4F) = ED 96 D3 7C
@VladLupashevskyi дай почту или номер телефона
@jglim I was also surprised that it was so fast, I think it has to do with me doing reverse engineering of ki209/ki211 for more than a year on regular basis :D
I just used the dump that @rumator has provided with memory map and CPU, found it architecture in datasheet and CPU module for Ghidra and started to probe data structures that I know exist in ki211. Eventually I found a diag structure, disassembled it function by function until I noticed some xors and shifts in there. There was of course also a ref to some bytes which were 7 32bit random numbers.
I wonder also that those root keys might not be even random, because remember in ki211 algo there are 4 bytes that are "unused" for key calculation. It turns out that those 4 bytes are generated as follows: 4 bytes of real seed xored with root key of second level (default access lvl) and then rotated 5 times to left.
So you can get a root key for level 2 from 8 bytes seed and then somehow get root for any desired level. Either originally it was done by using some lookup table or generate it deterministically. For example what I noticed is that if root key for some level has F in the end all other root keys for other access levels have also F in the end. Tried to do some bruteforcing with different shifts and xors but no result. I have to say I am not that good in finding those dependancies as @Feezex :D
Very happy that this project is alive :)
@Feezex I will send you my contacts to your GitHub email.
P.S.: For fun I've implemented a snake on w209 cluster :D
@VladLupashevskyi your disassembly level of the cluster firmware is overwhelming! My goal is to reach multiple temps on the cluster display directly. Due to the limited options of the old cluster, I am thinking to move and retrofit W209/W203 FL cluster to preFL203. Both of them suppose to have MB91F. Based on your experience, is available F2MC-16LX plugin to Ghidra mature enough for this job or is it better to move on?
thanks!
Folks, I've added a new provider based on VladLupashevskyi's implementation as it is easier to adapt new keys from dumps if they become available in the future.
There are 3 new definitions, 0223
, 0287
and 0290
. These are using keys that were shared by Sergey here (0287
in rumator's use case). Please let me know if they work (or not)
@VladLupashevskyi That snake implementation is crazy! I'm guessing that it was hand-assembled into the existing firmware blob? It must have been a lot of effort to figure out how to drive the lcd, and the red backlight at the end is a nice touch. Again, very curious about how you did it and the thought process behind it. Time for you to write a long-form article? Would love to read it if you do -- let me know :^)
Thanks guys for your comments :)
@rumator I would say, better put w209 instead of preFL203, it looks nicer. Of course it's a taste thing :D
I have an experience with doing exactly that. We've put ki209 to w203 of my friend. You have to cut casing a bit, or better get a holder for w209 cluster (you'll still need to cut case a bit, but i think it's less there)
We've took a preFL ki209, but I believe fl ki209 should work as well. FW is built in a similar way on both, but if you dont want to have unexpected surprises, just take a preFL ki209. You'll need to move milage and SSID from old cluster. Also get all codings of ki203 and then do coding for ki209.
F2MC-16LX plugin cant do a proper C decompiling, which would slow down a process by a lot, so I would recommend to use friendly RISC FR50 of 209 or fl203 cluster :)
@jglim Yeah, it was hand assembled and patched to existing firmware. Maybe I'll write some article in the future, would be similar to that one: https://alexhude.github.io/2019/01/24/hacking-leica-m240.html (really nice read and also about fujitsu FR family, recommend to read if you haven't yet). Will let you know for sure! But I haven't finished with experimenting yet :D Trying to put MB91F362 CPU instead of 376 one now. That one has an external data and address bus, so I can put all the code into RAM, put breakpoints and do more debugging there. Given it's the same architecture and almost same peripherals on the 362 CPU it's relatively easy to achieve.
For now I can already boot the FW from there already, so let's see how it goes...
Cluster looks like an octopus now...
P.S.: For fun I've implemented a snake on w209 cluster :D
Oh... now i want this game on my ki211)))
@VladLupashevskyi That was a fun read, thanks! And wow that's super cool that you've got your custom board running even with the complexities of external memory; I've tried and failed** in a similar endeavour so I can appreciate the amount of work that goes into that. Can't wait to see what you'll build from there, maybe add a faster coprocessor paired with one of those 1920×480 displays?
** this was my attempt in building a minimal board using the 204's cpu. It didn't show up on the ISP when I tried to bring it online, and I never got to figure out why :(
Ok, i do like original algo usage because it works for version 2, while transposition map there is different in my algo version.
So V2.
203XXXXXXX0247 - 024B; seed 12 34 56 78 > 78 56 12 34 > xor 5B51DE37> result 2307CC03 ;
203XXXXXXX029F; seed 12 34 56 78 > 78 56 12 34 > xor 5F1D72EC> result 274B60D8;
@jglim your condense key converter works amazing.
It does works with V2 and you guys combined them, so you can add definitions.
Going to check another versions
v3_0253; seed 12 34 56 78 >D3 06 AE 79 v4_029D; seed 12 34 56 78 >4E 3F 5C 6D v5_029E; seed 12 34 56 78 >7E 1F FE AD and it works.
@Feezex Nice! Glad to see that they can all fit in the same algo. Thanks for preparing and sharing this, along with the huge list of definitions on #12!
Folks, y'all are still welcome (and encouraged) to continue our conversations here, in this issue -- the "closed" state is simply an indicator that we have all completed our work on the KI203 seed/key, the thread remains unlocked.
@jglim Just happened to notice that a guy is trying to sell this app.
Here on the video he shows installer protected by password and with his name there 😡 :
Hey thanks for pointing that out. Unfortunately this isn't the first individual I've seen who is trying to make a profit off a largely unmodified copy of UnlockECU, and probably won't be the last.
When I first launched this project, I chose the MIT license as it was very permissive and allows for commercial usage, so curious folks who wanted to build something cool (e.g. ecu map editors? research on defeat devices?) could comfortably depend on this project and even monetize their projects at a later date. Commercial entities like workshops and professionals could also use this without worrying about licensing. Whatever "amazing road TV" is doing is legal, but definitely goes against the spirit of this project, and I don't approve of it.
I don't plan on adding any technical countermeasures (e.g. watermarks, urls, popups or packers/protectors) as I find that these tend to work against the end users, and will start a cat-and-mouse chase with less savory people. Rather, I hope that the name of our project here will become familiar enough so that newcomers can find their way here and access the real application for free. So far, this project has been the first organic hit on most search results, thanks to the many fine folks who have shared links on their websites and forums, and I hope it remains this way.
On the lighter note, it's fun to see some of your names appear as he shows off the application:
Hello there, amazing job done in here! I have on the table KI203 (pre facelift cluster).
27 01
provides 4 byte seed size and key size requested (27 02
) is 4. I read all the comments from @VladLupashevskyi and based on his comment, the key is calculated based on the 4 bytes. Is it possible to modifyKiAlgo1
to accept 4 bytes only? Thanks!