Cracking BiSHoP's Crackme #9 with ManKind Author: ManKind Target: BiSHoP's Crackme #9 -> http://www.hellforge.org Date : 10/10/2000 Author's e-mail: mankind001@bigfoot.com Dedication: Hellforge(sorry for being idle for a while) Difficulty Level: (1..7) 2 Tools Required: SoftICE 3.2x, HIEW 6.1x, IDA or W32Dasm 8.9x ----------------------------------------------------------------------- Introduction =============== The type of protection implemented in this crackme is getting popular though this is the easiest I have seen. So, learn before more protectors implement this kind of protection. I rated the difficulty level as 2 for this crackme but I wondered just how hard it would be if there are loops and others in it... Ahh, what a nightmare. Note that I didn't include too much assistance in here like showing you how to set a breakpoint, telling you how to get the offset of bytes we wanna patch and explaining the other checks which are similar to the one I have explained because I want you to practise by yourself and learn as much as possible... Tutorial ======== Disassembling the crackme in IDA and scrolling down a little the disassembly, I found this important code: 004010E6 loc_4010E6: ; CODE XREF: sub_40102B+14j 004010E6 push 0 004010E8 push offset aSofticeDetecte ; "SoftICE detected..." 004010ED push offset aSofticeDetec_0 ; "SoftICE detected, oh FrogSICE not allow"... 004010F2 push 0 004010F4 call j_MessageBoxA The CODE XREF tells us that this part of codes is referenced or called by another piece of code at address 40102B+14=40103F. Let's look at the code at address 0040103F: 0040102B push ebp 0040102C mov ebp, esp 0040102E cmp [ebp+arg_4], 110h 00401035 jnz short loc_401093 00401037 mov ah, 43h 00401039 int 68h <-- a method of SoftICE detection 0040103B cmp ax, 0F386h 0040103F jz loc_4010E6 <-- the bad_boy jump 00401045 jmp short loc_40105B <-- good_boy jump Obviously, the above is the SoftICE check(the int 68h is the important part, if I am not wrong). Just patch the bad_boy jump with any hex-editor like below: Original Bytes: 0F84A1000000 Patched Bytes: 0F85A100000 This is the quickest way to patch with the most minimum number of byte modified. But then, I guess a problem will arise if we try to start the crackme without SoftICE. This is not a problem for us now, but if you are really concern about that, try nop out the whole bad_boy jump, rather than applying what I asked you to. Now that the crackme runs without problem with a SoftICE loaded system, let's proceed to crack its serial protection. After breaking into SoftICE using your preffered breakpoint(both getdlgitemtexta and hmemcpy works for this crackme) when the crackme is getting your fake serial(don't tell me you didn't put in anything! :D), you should come to this code: * Reference To: USER32.GetDlgItemTextA, Ord:0102h | :004010B4 E8D9000000 Call 00401192 <-- get serial :004010B9 8BC8 mov ecx, eax <-- move eax(serial length) to ecx :004010BB 83F900 cmp ecx, 00000000 <-- test if it is zero :004010BE 747E je 0040113E <-- jump to 0040113E if it is zero :004010C0 E87D000000 call 00401142 <-- important serial verification call :004010C5 3D4B435546 cmp eax, 4655434B <-- compare eax to 4655434B hexadecimal(in which each byte of it will make up the string of "FUCK". BiSHoP, please don't encourage bad influence especially to the kids, hehe :D) :004010CA 7433 je 004010FF <-- jump to good_boy if eax equals to 4655434B hexadecimal :004010CC EB59 jmp 00401127 <-- bad_boy jump :004010CE EB10 jmp 004010E0 <-- jump to bad_boy At this point, you shall know that the length of your serial must be at least 1. We have to attack the call at address 004010C0, so let's step into it with F8: * Referenced by a CALL at Address: |:004010C0 | :00401142 83F90C cmp ecx, 0000000C <-- compare them :00401145 7535 jne 0040117C <-- jump to bad_boy if length of serial not equal to 12 decimal :00401147 33C0 xor eax, eax <-- zero eax :00401149 8D0500304000 lea eax, dword ptr [00403000] <-- eax points to address of serial :0040114F C10009 rol dword ptr [eax], 09 <-- rotate left the first four chars of serial 9 times :00401152 813064727068 xor dword ptr [eax], 68707264 <-- xor them :00401158 7522 jne 0040117C <-- jump to bad_boy if zero flag not set :0040115A 83C004 add eax, 00000004 <-- let eax point to the next four chars of serial :0040115D C10809 ror dword ptr [eax], 09 <-- rotate right the 5th-8th chars of serial 9 times :00401160 81309B989C99 xor dword ptr [eax], 999C989B <-- xor them :00401166 7514 jne 0040117C <-- jump to bad_boy if zero flag not set :00401168 83C004 add eax, 00000004 <-- let eax point to last four chars of serial :0040116B C10809 ror dword ptr [eax], 09 <-- rotate right the last four chars of serial 9 times :0040116E 81301C991918 xor dword ptr [eax], 1819991C <-- xor them :00401174 7506 jne 0040117C <-- jump to bad_boy if zero flag not set :00401176 B84B435546 mov eax, 4655434B <-- move 4655434B hexadecimal to eax, this can help to pass the check at address 004010C5(refer to above) :0040117B C3 ret There are 4 obvious checks in this call. First one is the serial length check and the rest are of similar kind. I will only explain one check and you shall be able to solve the rest of the checks(mail me if you really can't) :00401149 8D0500304000 lea eax, dword ptr [00403000] :0040114F C10009 rol dword ptr [eax], 09 :00401152 813064727068 xor dword ptr [eax], 68707264 :00401158 7522 jne 0040117C The dword value of 00403000 has to be equal to 68707264 hexadecimal(this and other values at the other checks which are to be xored with dword of eax is what BiSHoP means as "hardcoded" serial, hehe. well, sort of :D) after being rotated left 9 times to set the zero flag so that we can proceed to good_boy and not jump to bad_boy. This check only checks for the first 4 chars of serial. Now we have to find the dword value of 00403000 BEFORE rotate left 9 times. Well, to find the supposed dword, we have to calculate BACKWARD. I give you one example: mov eax, dword ptr [ebp-10] <-- get serial add eax, 0A <-- this is 10 in decimal xor eax, 03 cmp eax, 5D <-- this is 93 in decimal jnz bad_boy To calculate the real serial for this(eax shall be 93 decimal at the end), you can't calculate from the front because whatever you enter will affect the end result of eax, so, the only way will be to do the following: (93 xor 3) - 10 = ?? = 84 If you don't believe the result, test it: (84 + 10) xor 3 = ?? = 93 I hope it is clear for you, if not please mail me. We are able to calculate the supposed dword value of 00403000 now according to the above principle(calculate BACKWARD) but it is a pain in the ass if we are to do it manually as we have to convert all the values into bits and stuff, so I suggest we just use our beloved tool, SoftICE. First, we have to find the opposite operator of ROL(as for + the opposite is -). That's not hard because it is seen just a few lines away(ROR, which stands for rotate right). When the white line of indicator of SoftICE land on address 0040114F(make sure you have a serial with a length of 12), do the following command: d 00403000 You shall see something like this in the data window: 0030:00403000 32 33 31 39 39 39 38 31-32 32 32 32 231999812222.... Click on the first 32(after 00403000) and start to insert the AFTER rotate value which is 68707264 hexadecimal but one important thing you must know they must be inserted in a reversed order(don't ask me why, there is something to do with the core of your CPU): 68707264 becomes 64727068 Note that if you can't use mouse in SoftICE, the following command also works: e 00403000 64 72 70 68 When completed the data at 00403000 should look like this: 0030:00403000 64 72 70 68 39 39 38 31-32 32 32 32 drph99812222.... Now use the following command the re-assemble the instruction at address 0040114F: a 0040114F ror dword ptr [eax], 9 Execute the new instruction at address 0040114F and you shall be able to see the first 4 correct chars of serial at address 00403000(do 'd 00403000' if you can't see it), come out of SoftICE, correct the 4 first chars and you shall be able to pass the first check... Do the same for the next two checks and you will get a fully working serial, but don't forget to re-assemble back the original instructions you have modified into its original bytes so that it will work properly(one easy way without the need to re-assemble in SoftICE is to exit the crackme and start it again) and remember that ROR is opposite operator of ROL and opposite operator for ROL is ROR. Hopefully, you will try it out yourself for the next 2 checks if you haven't. Here's the correct serial just for your reference: 984237190823 ------------------------------------------------------------------------- Final Thoughts All in all a good protection. Could be much more better enchanced even by just adding a loop. I personally prefer to crack a single serial protection compared to name/serial ones if both of them are of almost same difficulty level because in single serial it is really not simple to protect and often they are manipulated very well to be challenging and exciting to the cracker. Note that IDA is not needed to crack the SoftICE detection, W32Dasm and SoftICE itself can be used too, it is just that IDA is the first tool I tried out. Greetings to... Personal Messages: Hellforge:Sorry for idling, I will be back soon, wait for me! :D BiSHoP:Nice crackme. Btw, where's #6 & #7? Keep up the good work! +ORC, +HCU, Sandman, HarvestR, tKC, ytc_, Punisher, Kwai_Lo, TORN@DO, CrackZ, cLUSTER, LaZaRuS, mISTER fANATIC, yes123, WhizKiD, Volatility, ACiD BuRN, Eternal Bliss, R!SC, Kwazy Webbit, +Mammon, MisterE, Shadow, Falcon, ^tCM^, WaJ, egis, Borna Janes, CyberBlade, Sheep140/Reclaim, josephCo, Kathras, +tsehp, Predator, tscube, AB4DS(Death), douby, Steinowitz, Lord Soth, seifer666, Latigo, Lucifer48, Mercution, NeuRaL_NoiSE, Fravia+, [dshadow], yAtEs, Duelist, Alpine, hutch, flag eRRatum, Nitrus, LiQUiD8, +Frog's Print, Muad`Dib, Acid_Cool_178, Iczelion, Razzia, wOODY^dRN, Warezpup, Bomber Monkey, XMen, llama and other crackers, individuals and organisations who have helped me, either directly or indirectly, thanks! :D ManKind Service for Mankind mankind001@bigfoot.com