Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KI203 algo #30

Closed
rumator opened this issue Sep 6, 2023 · 45 comments
Closed

KI203 algo #30

rumator opened this issue Sep 6, 2023 · 45 comments

Comments

@rumator
Copy link

rumator commented Sep 6, 2023

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 modify KiAlgo1 to accept 4 bytes only? Thanks!

@rumator
Copy link
Author

rumator commented Sep 6, 2023

20230906_200417

@VladLupashevskyi
Copy link
Contributor

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.

image

@rumator
Copy link
Author

rumator commented Sep 7, 2023

Hello @VladLupashevskyi
I tested it and no luck, sec level goes from 61 11 02 to 61 11 00
Screenshot 2023-09-07 184401 I will test different software version

@rumator
Copy link
Author

rumator commented Sep 8, 2023

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
image
!!!Bitte ab BR 211 den parallelen SECURITY-Dienst verwenden!!! Seedbytes fuer die Entriegelungsstufe 1 holen
10 92 has following
image
!!!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!

@rumator
Copy link
Author

rumator commented Jan 8, 2024

Hi, small update from my side, I dumped full firmware from the cluster. I did no find root keys yet.

https://github.com/rumator/ki203

@VladLupashevskyi
Copy link
Contributor

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).

image

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.

@VladLupashevskyi
Copy link
Contributor

And thanks for the dump @rumator :)

@VladLupashevskyi
Copy link
Contributor

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

@rumator
Copy link
Author

rumator commented Jan 8, 2024

Hello @VladLupashevskyi, thanks for fast answer (and email with advice)!
Unfotunately its not working, I made this:
image
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!

@Feezex
Copy link
Contributor

Feezex commented Jan 8, 2024

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

@VladLupashevskyi
Copy link
Contributor

@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.

@Feezex
Copy link
Contributor

Feezex commented Jan 8, 2024

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
KI203_EEP_07

@VladLupashevskyi
Copy link
Contributor

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.

image

image

image

image

image

@VladLupashevskyi
Copy link
Contributor

Btw 31 FB 00 and 27 are pointing to the same function, so they should work the same

@rumator
Copy link
Author

rumator commented Jan 9, 2024

@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?
Screenshot 2024-01-09 183050
Iam not really sure how to use information about the v1 - v5 algo calculation :-)

@VladLupashevskyi
Copy link
Contributor

@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.

@Feezex
Copy link
Contributor

Feezex commented Jan 9, 2024

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.

@VladLupashevskyi
Copy link
Contributor

I think I've got it, will try to come up with some test script soon

@Feezex
Copy link
Contributor

Feezex commented Jan 9, 2024

ki203v1_F8205A4F.zip
try this xDD

@VladLupashevskyi
Copy link
Contributor

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}")
image

So you give it seed and root key and B912496B would be your key with seed 11223344.

@VladLupashevskyi
Copy link
Contributor

VladLupashevskyi commented Jan 10, 2024

@Feezex my algo gives actually the same result as yours, but it has more steps that describe how it was originally implemented.

@Feezex
Copy link
Contributor

Feezex commented Jan 10, 2024

awesome you)) glad that we got same result, cool to see how its originally implemented.

@rumator
Copy link
Author

rumator commented Jan 10, 2024

this is amazing!
@Feezex your algo works like a charm!
Screenshot 2024-01-10 220154
@VladLupashevskyi unfortunately PY algo generates different values...
image
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!

@Feezex
Copy link
Contributor

Feezex commented Jan 10, 2024

try PY with 27FC2D10 key, seems there is more than one version of algo and both must work

@rumator
Copy link
Author

rumator commented Jan 11, 2024

unbelievable, it works indeed!
image
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?

@Feezex
Copy link
Contributor

Feezex commented Jan 11, 2024

  1. Mine, made for you
    2.no, i have another source

@VladLupashevskyi
Copy link
Contributor

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

@VladLupashevskyi
Copy link
Contributor

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

@Feezex
Copy link
Contributor

Feezex commented Jan 11, 2024

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

@jglim
Copy link
Owner

jglim commented Jan 11, 2024

@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 ^^

@rumator
Copy link
Author

rumator commented Jan 11, 2024

@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.

@Feezex
Copy link
Contributor

Feezex commented Jan 11, 2024

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

@Feezex
Copy link
Contributor

Feezex commented Jan 11, 2024

@VladLupashevskyi дай почту или номер телефона

@VladLupashevskyi
Copy link
Contributor

@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

https://www.youtube.com/shorts/D-FUJNtGVPk

@rumator
Copy link
Author

rumator commented Jan 12, 2024

@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!

jglim added a commit that referenced this issue Jan 12, 2024
@jglim
Copy link
Owner

jglim commented Jan 12, 2024

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 :^)

@VladLupashevskyi
Copy link
Contributor

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...

image

@mbw211
Copy link

mbw211 commented Jan 12, 2024

P.S.: For fun I've implemented a snake on w209 cluster :D

https://www.youtube.com/shorts/D-FUJNtGVPk

Oh... now i want this game on my ki211)))

@jglim
Copy link
Owner

jglim commented Jan 14, 2024

@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 :(

image

@Feezex
Copy link
Contributor

Feezex commented Jan 14, 2024

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.
203XXXXXXX_0247 - 024B; seed 12 34 56 78 > 78 56 12 34 > xor 5B51DE37> result 2307CC03 ;
203XXXXXXX_029F; seed 12 34 56 78 > 78 56 12 34 > xor 5F1D72EC> result 274B60D8;
image
@jglim your condense key converter works amazing.
image
image
It does works with V2 and you guys combined them, so you can add definitions.

  • "Origin": "KI203_203_0247-024B_L7_@Feezex-@rumator-@VladLupashevskyi",
      "Value": "BADEF289",
    
  • "Origin": "KI203_203_029F_L7_@Feezex-@rumator-@VladLupashevskyi",
      "Value": "62FB90EF",
    

@Feezex
Copy link
Contributor

Feezex commented Jan 14, 2024

Going to check another versions
image

@Feezex
Copy link
Contributor

Feezex commented Jan 14, 2024

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.

  • "Origin": "KI203_203_0253_L7_@Feezex-@rumator-@VladLupashevskyi",
          "Value": "3EFA72D6",
    
  • "Origin": "KI203_203_029D_L7_@Feezex-@rumator-@VladLupashevskyi",
          "Value": "FFFFFFFF",
    
  • "Origin": "KI203_203_029E_L7_@Feezex-@rumator-@VladLupashevskyi",
          "Value": "163B6ACF",
    

Can be closed now =)
i think Provider can be renamed to KI203Algo, no need to keep version suffix

jglim added a commit that referenced this issue Jan 15, 2024
@jglim
Copy link
Owner

jglim commented Jan 15, 2024

@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 jglim closed this as completed Jan 15, 2024
@VladLupashevskyi
Copy link
Contributor

@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 😡 :

https://youtu.be/gqjtNhlDa1g?si=BFD-M57EXh9BzOjZ

@jglim
Copy link
Owner

jglim commented Jan 22, 2024

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:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants