Number of crackmes:
Number of solutions:
Comments:
Name | Author | Language | Arch | Difficulty | Quality | Platform | Date | Solution | Comments |
---|---|---|---|---|---|---|---|---|---|
VM_Madness2 | survivalizeed | C/C++ | x86-64 | 4.0 | 5.0 | Windows | 4:21 PM 05/09/2024 | 0 | 14 |
VM_Madness | survivalizeed | C/C++ | x86-64 | 4.0 | 4.7 | Windows | 10:51 PM 04/15/2024 | 1 | 33 |
Crackme | Infos |
---|
Comment | Link |
---|---|
And the entire crackmes.one isn't only about cracking. Its also about writing well protected programs yourself to get a deeper understanding of the inner workings. | ==> |
still oreans has a lot of advanced features which arent easily defeated by a single person. Additionally it's nice to have unique stuff instead of 3rd party protectors | ==> |
Nice crackme. Next time i would suggest to make a more complicated obfuscation, as the password routine actually only checks the code in a very few lines of assembly. That way your 1000+ lines of asm turned out to be like 20+ lines of asm to analyze. My suggestion would be to do some more pseudo shifts with the password to cause more confusion. For some odd reason I wasn't able to use memory breakpoints... Could be anti-debugging but not too sure. Setting a first chance exception filter did the job for me :) SPOILER: TheMagicEmpireMayBegin | ==> |
Anyone here has some tips to devirtualized the bytecode/handlers faster and better? | ==> |
What are those comments???? Fucking monkey, ni.... You good? | ==> |
Nice game :). For anyone who wants to learn reverse engineering better, I highly recommend to NOT use UPX here. Do it manually so you learn more! | ==> |
@DosX well there is no obstacle tbh. Packers aren't an obstacle since dumping the executable with Scylla does the job in 99% of the cases... Just throwing protection at an executable wont make it "hard". A nice virtualization would be good i guess but still having a packer wont fix your decompiler problem... And as i've said you dont even need a decompiler for this one here. | ==> |
@imeow256 there is not the ONE way of doing a good obfuscated compare. I highly encourage you to take a look on virtualization tools and how they work. Tigress/VM Protect have some nice devirtualization blogs you can learn a lot from :) | ==> |
@sporta778 can't wait to see the solution. If you guys are interested i will try myself with a way more complicated version. This time really complicated. Obfuscation and all the annoying things will be included :) | ==> |
very nice @dev0. Yeah the core is the same as with the first version. The thing that really changed for this one is that the instruction set gets translated to the instruction set of a different VM which then translates to the instruction set of a different VM etc. It does that a few times until it reaches the "actual" VM which then has to be devirtualized. | ==> |
Why even unpack it at all? If you don't want to patch anything you don't need an unpacked version. Just run it in your debugger and if you really want that decompilation then dump it with scylla. | ==> |
A nice crackme but the difficulty rating is too high imo. The string length check is easy to find (0xB) and after that you dont even need to run it in order to understand the asm. Don't really see any obfuscation except for a heavy packer... Since there is no real solution to post... Here is the password: FLAG{a(#3_} | ==> |
All this strange obfuscation to then do a simple string compare ... password is "lockcmpxchg8beax". | ==> |
0x911 i wouldn't waste time on this if you aint got a decent RE experience :) If do want to try it and need minor help then I'm here | ==> |
no need to apologize. We both do this stuff in our free time so its up to you and me how we spend it. Do the crackme when ever you want to and only if you want to :) | ==> |
"if possible" is only from my dumb point of view. This does a lot of things differently but you should be able to do it :). Again if you got questions or need minor help I always here | ==> |
Oh and last thing: A more difficult version with multilevel VMs is currently waiting for approval. The name is VM_Madness2. So if you are interested and liked this one then the next version should be even more interesting :) | ==> |
As you probably already found out; the instructions are shorts and the values are int64. That way you can calculate where the jumps should go to :) | ==> |
I am not completely sure what you mean to be honest. I will just post the second vm code so you can see for yourself: vm2.opcodes.mov, vm2.opcodes.rbx, vm2.opcodes.val, vm_val((i64)key[5], vm2), vm2.opcodes.mov, vm2.opcodes.rdx, vm2.opcodes.val, vm_val(69, vm2), vm2.opcodes.x_or, vm2.opcodes.rdx, vm2.opcodes.reg, vm2.opcodes.rbx, vm2.opcodes.cmp, vm2.opcodes.reg, vm2.opcodes.rdx, vm2.opcodes.reg, vm2.opcodes.rdx, vm2.opcodes.mov, vm2.opcodes.rcx, vm2.opcodes.val, vm_val(76, vm2), vm2.opcodes.je, vm2.opcodes.reg, vm2.opcodes.rcx, vm2.opcodes.x_or, vm2.opcodes.rax, vm2.opcodes.reg, vm2.opcodes.rax, vm2.opcodes.ret, vm2.opcodes.cmp, vm2.opcodes.val, vm_val((i64)key[6], vm2), vm2.opcodes.val, vm_val((i64)89, vm2), vm2.opcodes.jne, vm2.opcodes.val, vm_val(68, vm2), vm2.opcodes.mov, vm2.opcodes.rax, vm2.opcodes.val, vm_val(1, vm2), vm2.opcodes.ret | ==> |
Sporta the new crackme is now waiting for approval. Good luck :) | ==> |
Yeah IDA is pretty powerful but it sometimes distracts from the actual stuff you should look at. | ==> |
Alright. I should be finished with the new crackme by tomorrow. Would you like an extra layer of obfuscation by some free third party software or just "my" obfuscation? You were a bit too quick with this one here so I would like to level up the difficulty even more :) | ==> |
Damn. Im not even 20 years old haha | ==> |
nice, glad to hear haha. Again i wont use anti debugging or packing... just a VM + some obfuscation. Give me some time to finish it :). I will notify you when everything is finished up. Btw. Where did you learn RE? | ==> |
Would you be interested in a more challenging version? I am currently working on something | ==> |
sporta just saw your solution... Really amazing solution. You really seem to know what you are doing :) | ==> |
You got the key? | ==> |
Idk maybe you are getting some terms wrong or its just a language barrier. With a devirtualizer I mean that the custom instruction set i created which is read by my custom VM has to be decoded in normal x86-64 instructions. So if you e.g have something like 0x12, 0xf3 then your devirtualizer should make a "mov" out of it. | ==> |
Yes the ANY- is correct. Very nice! Second part can be a bit harder but its obviously the same vm used as core. | ==> |
Isnt VM == microcomputer in this context? But yeah it is randomized at the beginning. As a small hint: The code obviously doesnt change at all in its mechanics. Only thing getting more difficult is writing a devirtualizer. If you need a few more little hints you can always ask :) | ==> |
For anyone looking for the complete cleaned up routine (heavy spoiler) int keypart1[8] = {}; int keypart2[8] = {}; for (int i = 0; i 7) { keypart2[i - 8] = input[i]; } else { keypart1[i] = (int)input[i]; } } int sum = keypart1[0] + keypart1[1] + keypart1[2] + keypart1[3] + keypart1[4] + keypart1[5] + keypart1[6] + keypart1[7]; int sum_pow = pow(keypart1[0], 2) + pow(keypart1[1], 2) + pow(keypart1[2], 2) + pow(keypart1[3], 2) + pow(keypart1[4], 2) + pow(keypart1[5], 2) + pow(keypart1[6], 2) + pow(keypart1[7], 2); double added_log = 0; for (int i = 0; i = 0.00000011920929) { std::cout | ==> |
I have the entire routine reversed now. The key is 16 chars long and is split in half and then processed. Only thing which seems rather impossible is inverting it. I will try my best now ... | ==> |
I dont get what you are trying to say | ==> |
Very nice crackme. One thing I would suggest is that you make "smaller" instruction steps so the jumptable becomes bigger and harder to RE. Just four instructions is a bit less. Anyways... Thanks for sharing :) | ==> |