L ZZZZZZ RRRRR SSSSS L Z R R S L aaa Z aaa R R u u S L a Z a RRRRR u u SSSSS XX L aaaa Z aaaa R R u u S XXXX L a a Z a a R R u u S XXXXXX LLLLLLL aaaaa ZZZZZZZ aaaaa R R uuuuu SSSSSS XXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXX XXXXXX XXXX proudly presents his 8.Cracking Tutorial (06.04.1999) XX HexDecCharEditor 1.02 I. Tools you need for my tutorial II. Cracking with W32Dasm III. BTW I. Tools you need for my tutorial Win32Dasm 8.9 (get at http://Qserve.8m.com) (perhaps) Soft-Ice for Windows (get at http://Qserve.8m.com) A hex-editor, I prefer Hex Workshop 2.54 HexDecCharEditor 1.02, the target (http://software.webset.de/buschjost/mp3eng.htm mail me if you don't find the version 1.02 there) II. Cracking with Win32Dasm: OK, let's start cracking. Don't try searching for something with Registry Monitor/File Mon. /Helpfile. You won't find anything interesting. Only where the key and the name is saved. But that is of no use (in this case). The target is English and German. I will refer to the english strings. The first waypoint is easily found. The string of the "Wrong serial" window is hardcoded :) The german strings are always in front of the english strings. It's like that: Calculate serial -> Check it -> If language == English then jump to English -> German "Wrong" -> jump to "go on" -> English "Wrong" -> go on Ok, you should see this: :00435846 8B4DF8 mov ecx, dword ptr [ebp-08] :00435849 8B93E0010000 mov edx, dword ptr [ebx+000001E0] :0043584F 8B83DC010000 mov eax, dword ptr [ebx+000001DC] :00435855 E8EEC2FFFF call 00431B48 ;; calculate serial and check it :0043585A 84C0 test al, al ;; is serial-valid flag = 1 :0043585C 7432 je 00435890 ;; then jump to "Beggar off" :0043585E C6052065450001 mov byte ptr [00456520], 01 :00435865 C7832801000001000000 mov dword ptr [ebx+00000128], 00000001 :0043586F 83BBD801000007 cmp dword ptr [ebx+000001D8], 00000007 ;;language = Germ.? :00435876 750C jne 00435884 ;; if not then jump to English * Possible StringData Ref from Code Obj ->"Vielen Dank f" ;; german "Thank you" | :00435878 B8E8584300 mov eax, 004358E8 :0043587D E8EE9DFFFF call 0042F670 :00435882 EB30 jmp 004358B4 ;; jump to "Registered" * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00435876(C) | * Possible StringData Ref from Code Obj ->"Thank you for registering!" ;;english "Thank you" | :00435884 B8185A4300 mov eax, 00435A18 :00435889 E8E29DFFFF call 0042F670 :0043588E EB24 jmp 004358B4 ;; jump to registered * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0043585C(C) ;; here begins the "Beggar off" part | :00435890 E89F23FDFF call 00407C34 :00435895 83BBD801000007 cmp dword ptr [ebx+000001D8], 00000007 ;; language ? :0043589C 750C jne 004358AA ;; if not German then jump * Possible StringData Ref from Code Obj ->"Der eingegebene Name und der eingegebenen " ->"Schl" ;; German "Wrong key" | :0043589E B8D85A4300 mov eax, 00435AD8 :004358A3 E8C89DFFFF call 0042F670 :004358A8 EB0A jmp 004358B4 ;; keep on unregistered * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0043589C(C) | * Possible StringData Ref from Code Obj ->"Sorry, but the name and the key " ;; English ->"you entered cannot be accepted " ;; "Wrong" ->"together. " | :004358AA B8D05B4300 mov eax, 00435BD0 :004358AF E8BC9DFFFF call 0042F670 * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |:00435882(U), :0043588E(U), :004358A8(U) | :004358B4 33C0 xor eax, eax :004358B6 5A pop edx :004358B7 59 pop ecx :004358B8 59 pop ecx :004358B9 648910 mov dword ptr fs:[eax], edx It seems pretty obvious that the valid key must be calculated deep inside the call at :00435855. We will later see, that is so. But what's that. The program will keep on running at the same address no matter if the key is valid or not. What does that mean. No saving in the registry or somewhere ? No, it must be like this (I didn't check, but that's the only way!) 1. Get name and serial from the user --- Enter the call --- 2. Calculate valid serial 3. Check serials 4. Set a "Valid" flag 5. If "Valid" flag set, save into the registry else do nothing --- Leave the call --- 6. If "Valid" flag set, then show "Thank you" else show "Wrong key" 7. Ok, go on We can first check if we can just bypass the jump at :0043585C and perhaps the program saves the correct serial or just a "Flag" in the registry so it will be registered next time. Forget it!!! The programmer made everything right in order to make my life hard. (Hopefully I didn't forget anything real simple) In fact, at the end we will have a crack (2 jumps) that WILL make the target registered, but it will be a damn dirty one. OK, so we have to enter the call. You should see this: * Referenced by a CALL at Address: |:00435855 | :00431B48 55 push ebp SNIP - SNIP :00431BCD E886FEFFFF call 00431A58 :00431BD2 8BF0 mov esi, eax :00431BD4 8B4508 mov eax, dword ptr [ebp+08] :00431BD7 E8EC3EFDFF call 00405AC8 :00431BDC 3BF0 cmp esi, eax :00431BDE 0F8533010000 jne 00431D17 ;; Beggar off :00431BE4 8B45F8 mov eax, dword ptr [ebp-08] :00431BE7 E8A819FDFF call 00403594 :00431BEC 83F80A cmp eax, 0000000A :00431BEF 0F8C22010000 jl 00431D17 ;; Beggar off :00431BF5 B201 mov dl, 01 :00431BF7 B8E8F74200 mov eax, 0042F7E8 :00431BFC E89BDCFFFF call 0042F89C :00431C01 8945E8 mov dword ptr [ebp-18], eax :00431C04 33C0 xor eax, eax SNIP - SNIP :00431CF5 E87617FDFF call 00403470 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00431C46(C) | :00431CFA 33C0 xor eax, eax ;; set "Wrong" flag :00431CFC 5A pop edx :00431CFD 59 pop ecx :00431CFE 59 pop ecx :00431CFF 648910 mov dword ptr fs:[eax], edx :00431D02 68171D4300 push 00431D17 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00431D15(U) | :00431D07 8B45E8 mov eax, dword ptr [ebp-18] :00431D0A E8690EFDFF call 00402B78 :00431D0F C3 ret ;; Return from Call OK, right in front of the first "Beggar off" jump we see a call and a CMP ESI, EAX and this compare sets the "Wrong" flag if they are not the same. When I tell you ESI contains the hex value of the entered serial what do you say contains the EAX. WRONG!!! It doesn't contain the correct serial. I didn't believe it. This obvious compare and no valid serial. That's strange. At least I was able to find out, that the next "Beggar off" is set, when the name contains less than 10 characters :). OK, no idea how to get the valid serial again. So the old bypass-and-hope method. And this time it really works :). When you no-op the jump at :00431BDE and at :00431BEF you can register the target (and even with less than 10-char-names). HexDecCharEditor will write the correct code to the registry and the program will be registered next time you start it. But don't believe the code you can enter in the "Register" box is written to the registry. Everytime you register it another code is written to the registry (even if you don't change the name). For LaZaRuS I got (for example): HKEY_LOCAL_MACHINE\SOFTWARE\Beyersdorf\HexDecCharEditor\Key = 97C5FF823C8B HKEY_LOCAL_MACHINE\SOFTWARE\Beyersdorf\HexDecCharEditor\Key = 5312DDA92340 HKEY_LOCAL_MACHINE\SOFTWARE\Beyersdorf\HexDecCharEditor\Key = 5C738FDB49C5 HKEY_LOCAL_MACHINE\SOFTWARE\Beyersdorf\HexDecCharEditor\Key = 24588FE844E3 ... So, if you see more than I do, why not write a tutorial about it. Or if you don't write one please tell me at least the important facts I found out. III. BTW Hope my tutorial was helpful for you and see you again in my next tutorial. Greets to: Fravia+, tKC, ED!SON, Moral Insanity, The Sandman, Eternal Bliss, DaVinci and all [hf] members All Tutorials by LaZaRuS [hf] #| date | name |version|W32Dasm|Soft-Ice|kind of crack | -|--------|------------------|-------|-------|--------|-------------------------| 1|20.01.99|Jaylock |1,0,0,1| (X) | (X) |serial# | 2|31.01.99|Goldwave |4.02 | (X) | (X) |serial#,nag-screens | 3|28.03.99|AxMan |3.00 | (X) | (X) |serial#,remove date-limit| | | | | | |nag-screen, key generator| 4|29.03.99|C++Builder Strings| | (X) | (X) |how to find strings in | | | | | | |C++ Builder that are not | | | | | | |hardcoded | 5|29.03.99|Better Protection | | | |How to protect shareware | | | | | | |better against crackers | 6|04.04.99|Start Clean |1.2 | (X) | (X) |nag-screen/serial/keygen | 7|06.04.99|MP3 TO EXE |1.02 | (X) | (X) |nag-screen/serial | 8|06.04.99|HexDecCharEditor |1.02 | (X) | |make it registered | LaZaRuS [hf] Visit Hellforge at http://members.xoom.com/hell_crack for more tutorials and high quality cracking links. If you want to mail me: lazarus666@gnwmail.com