-
Notifications
You must be signed in to change notification settings - Fork 55
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
Comments
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 |
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. 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: |
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 and then try the same with |
Hello @VladLupashevskyi, thanks for fast answer (and email with advice)! thanks! |
ok heres my contribution. key generation algo v2: tell me which version you have |
@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. |
Btw |
@VladLupashevskyi @Feezex |
@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. |
I think I've got it, will try to come up with some test script soon |
ki203v1_F8205A4F.zip |
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 |
@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! |
try PY with 27FC2D10 key, seems there is more than one version of algo and both must work |
unbelievable, it works indeed! |
|
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
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. |
@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.
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 |
@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, @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... |
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.
|
v3_0253; seed 12 34 56 78 >D3 06 AE 79
Can be closed now =) |
@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!The text was updated successfully, but these errors were encountered: