Hiya LaZaRuS! First let me thank you for your wonderful Hf_crackme_s1. This is a very well written - at least IMHO - crackme which can really be a good challenge for every newbie; and for more experienced too. Here's a short explanation how I find a way (well actually it's one way there are more of course) to get a real serial and how the calculation for this serial is working: First start the Hellforge Crackme II (coded by LaZaRuS). Reading the rules you will find out that there are no rules; you can use any tool you want and try anything you wish to. Good! I decided to work with the exceedingly powerful SoftICE. You will be asked for your name/handle ('Enter your lovely name here':)) and for a serial ('And here is the place to put the correct serial'). So why not? Enter your handle and a fake code (you should always use the same fake code when you're working on those programs because it will be easier to find later when you're fighting through the code jungle). Now enter SoftICE with Ctrl-D and set a breakpoint on hmemcpy ('bpx hmemcpy'). Go back to your Crackme window by leaving SoftICE (Ctrl-D again) and press the 'Click here to check your serial!!!'-button now. SoftIce will immediately pop up - breakpoint on hmemcpy. As we have two boxes (name and serial) we can press F5 ('Go') here once to save us some time. Now we can disable the breakpoint by typing bd0. To come to the interesting places we press F11 ('Go to') once and then F12 ('Return from the procedure call') until we reach the Hf_crackme_s1-code (watch the line between the Code window and the Command window). Some more F12's will bring us to this place: :00426885 E8C6B3FEFF call 00411C50 :0042688A 8B45FC mov eax, dword ptr [ebp-04] ;<---we land here, our handle :0042688D E896CCFDFF call 00403528 ;is copied to eax :00426892 A394864200 mov dword ptr [00428694], eax :00426897 A194864200 mov eax, dword ptr [00428694] :0042689C E86FEDFDFF call 00405610 :004268A1 83F804 cmp eax, 00000004 ;check if name is at least :004268A4 7D1B jge 004268C1 ;4 chars, jump if it is so :004268A6 6A00 push 00000000 * Possible StringData Ref from Code Obj ->"Sorry" | :004268A8 B9DC694200 mov ecx, 004269DC * Possible StringData Ref from Code Obj ->"Wrong Code" ;you come here if you entered | ;a handle with less than :004268AD BAE4694200 mov edx, 004269E4 ;4 chars :004268B2 A124864200 mov eax, dword ptr [00428624] :004268B7 E84CB3FFFF call 00421C08 :004268BC E9E8000000 jmp 004269A9 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004268A4(C) | :004268C1 8D55FC lea edx, dword ptr [ebp-04] ;the relevant parts! :004268C4 8B83B0010000 mov eax, dword ptr [ebx+000001B0] :004268CA E881B3FEFF call 00411C50 :004268CF 8B45FC mov eax, dword ptr [ebp-04] :004268D2 0FB600 movzx eax, byte ptr [eax] :004268D5 8BF0 mov esi, eax :004268D7 C1E602 shl esi, 02 :004268DA 8D3476 lea esi, dword ptr [esi+2*esi] In 004268CF your name/handle is copied to the eax register. Then the first char (Hex value of the Ascii representation of the char) of your name is copied to eax (004268D2). Now it's copied to esi and the math begins; result one is stored in esi. :004268DD 8D55F8 lea edx, dword ptr [ebp-08] :004268E0 8B83B0010000 mov eax, dword ptr [ebx+000001B0] :004268E6 E865B3FEFF call 00411C50 :004268EB 8B45F8 mov eax, dword ptr [ebp-08] :004268EE 0FB64001 movzx eax, byte ptr [eax+01] :004268F2 8D0480 lea eax, dword ptr [eax+4*eax] :004268F5 8D0480 lea eax, dword ptr [eax+4*eax] :004268F8 03F0 add esi, eax Same procedure for the second char of your handle, another (different) calculations and finally the result two (in eax) is added to our result one in esi. :004268FA 8D55F4 lea edx, dword ptr [ebp-0C] :004268FD 8B83B0010000 mov eax, dword ptr [ebx+000001B0] :00426903 E848B3FEFF call 00411C50 :00426908 8B45F4 mov eax, dword ptr [ebp-0C] :0042690B 0FB64002 movzx eax, byte ptr [eax+02] :0042690F 03C0 add eax, eax :00426911 03F0 add esi, eax Third char, math, result three in eax is then added to esi (result one+result two+result three). :00426913 8D55F0 lea edx, dword ptr [ebp-10] :00426916 8B83B0010000 mov eax, dword ptr [ebx+000001B0] :0042691C E82FB3FEFF call 00411C50 :00426921 8B45F0 mov eax, dword ptr [ebp-10] :00426924 0FB64003 movzx eax, byte ptr [eax+03] :00426928 6BC00B imul eax, 0000000B :0042692B 03F0 add esi, eax ...same as before for our fourth char...-->result in eax --> add to esi - so now we have the addition of the results from one to four in esi. :0042692D 893590864200 mov dword ptr [00428690], esi :00426933 A194864200 mov eax, dword ptr [00428694] :00426938 E8D3ECFDFF call 00405610 :0042693D 8B1590864200 mov edx, dword ptr [00428690] Our last result is finally copied to edx and more calculations are following... :00426943 0FAF1590864200 imul edx, dword ptr [00428690] :0042694A F7EA imul edx :0042694C A390864200 mov dword ptr [00428690], eax Important: the latest result is multiplied with the length of your name/handle (0042694A)...afterwards the good code will be in eax...('? eax') :00426951 8D55EC lea edx, dword ptr [ebp-14] :00426954 A190864200 mov eax, dword ptr [00428690] :00426959 E806EBFDFF call 00405464 :0042695E 8B45EC mov eax, dword ptr [ebp-14] :00426961 50 push eax ...good code is pushed to the stack for later use:)... :00426962 8D55FC lea edx, dword ptr [ebp-04] :00426965 8B83B4010000 mov eax, dword ptr [ebx+000001B4] :0042696B E8E0B2FEFF call 00411C50 :00426970 8B55FC mov edx, dword ptr [ebp-04] :00426973 58 pop eax ...your fake code is copied to edx and eax contains the real code again... :00426974 E8FBCAFDFF call 00403474 The 'comparison-call'! Within this call your fake serial is compared to the real serial. You can find out how this works by tracing into the call with F8. :00426979 7518 jne 00426993 ...the good guy/bad guy jump...you better do not jump here eh?! :0042697B 6A00 push 00000000 * Possible StringData Ref from Code Obj ->"Congratulations" | :0042697D B9F0694200 mov ecx, 004269F0 * Possible StringData Ref from Code Obj ->"You did it" Short conclusion: Your name/handle must be at least four chars long because the calculation routine is based on the first four chars. Finally the calculated code is multiplied with the length of your name. Well a very nice Crackme indeed from LaZaRuS. I really hope Hellforge will publish more releases soon. Last words: I just want to thank Jeff for being a real friend...!!! P.S.: Keygen included. Yo that's all for now Keep up the good work and good luck! cheers tnwo_