Author ManKind
Target BiSHoP's Crackme #9
Public Release  07/10/2000
Author Contact 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
 

Disclaimer: Please note, the information herein is copyright to Hellforge. No portion of this text may be duplicated. Furthermore, damage or problems arising after reading this text is left to the users disposal. Neither Hellforge, nor its members can be held responsible for any direct or indirect result of following this text. The full liability of following this text is on the reader (YOU). The information is provided for educational purposes, misuse of this information is strictly prohibited. If you do not agree with this agreement, then please hit the "back" button on your browser, and go to hell. - Mercution.
 

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 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             ;  - APPC/PC 

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

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



The end.

Any mistakes, corrections, or comments may be mailed to the members individually, or to the group : hellforge@hellforge.org.