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 18.Cracking Tutorial (28.09.1999) XX tC's CrackMe ID:22 I. Tools you need for my tutorial II. The Crack II.1 Getting rid of the nag-screen II.2 Activating the button II.3 STOP TO JUMP, stupid button II.4 Oh, there's a SICE check II.5 More than 120 seconds would be fine :) II.6 And finally the two serials III. BTW I. Tools you need for my tutorial W32Dasm 8.X (I use 8.9) SICE 3.XX (I use 3.24) HexWorkshop 2.54 II. The Crack: tC's CrackMe ID:22 (called "tC's Revenge") is the last CrackMe of his series :( - Whatever, I have to say it was one of the most motivating CrackMes I ever saw. It is not too easy and not too hard and has some "features" I've never seen before. Well done tC :) II.1 Getting rid of the nag-screen Let's get rid of the Nag-screen at first. (Actually it is no nag-screen, but a pleasure-screen - Look at it, then you know what I'm talking about ;). Nevertheless tC wants to get rid of it. So let's do the job. When you start the CrackMe the nag-screen appears. If you terminate it with [ALT]+[F4] the CrackMe still loads after a couple of seconds. So there must be some kind of timer. If you search for "time" in W32Dasm you find (the important) "SetTimer" and "KillTimer". Those two functions will lead you nowhere (you can try if you want). More important is "GetTickCount". This function returns a value that shows how long Windows runs, yet (in ms). Search for this function and you will find two occurences at the beginning of the file. The CrackMe is written in *big* Delphi, so the two occurences at the beginning will only be important for the runtime module or something like that. At the end of the file there are two more. You will see this: :0044A57C 53 push ebx :0044A57D 56 push esi :0044A57E 8BF2 mov esi, edx * Reference To: kernel32.GetTickCount, Ord:0000h | :0044A580 E847B8FBFF Call 00405DCC :0044A585 8BD8 mov ebx, eax * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0044A59C(C) | :0044A587 A130CD4400 mov eax, dword ptr [0044CD30] ;;Beginning of the nag-loop :0044A58C 8B00 mov eax, dword ptr [eax] :0044A58E E8E163FFFF call 00440974 * Reference To: kernel32.GetTickCount, Ord:0000h | :0044A593 E834B8FBFF Call 00405DCC :0044A598 2BC3 sub eax, ebx :0044A59A 3BC6 cmp eax, esi ;;Is it time to show the main screen ? :0044A59C 72E9 jb 0044A587 ;;If not, the repeat loop :0044A59E 5E pop esi ;;go on with terminating the nag-screen and :0044A59F 5B pop ebx ;;showing the main window :0044A5A0 C3 ret You surely wonder why I found out that this is the correct place for a patch. I tell ya: I just tried it. It is no use to "zen" about a passage for ten minutes when you can find out by trying in 10 seconds. To get rid of the nag-screen just change the 72E9 (jb 0044A587) to 9090 (nop nop). Then the nag-screen has disappeared. Really??? NO!!! It just shows up for about 0.05 seconds. Then the main window is displayed immediately. To get absolutely rid of the nag-screen we have to find out where the nag-screen is called. We can do that in this way (All zen-crackers will hate me for the following passage :( Start the "debug-mode" in W32Dasm and choose "Auto Step Over". When the nag-screen appears, termainate the program and then look at the Call that has called the nag. The first call you will find will be at :0044B160. Trace into that call and set a breakpoint at :00440AA0. Then debug again until the program breaks. Then "Auto Step Over" until the nag appears again. This will be at :00440AD1. Enter this call, set a BP and debug the program again. "Auto Step Over" until the nag-screen appears. This time it will be :00439F31. And so on. When you do this some time you will come to the "final" call. It is at :0044A50F. This one makes the window appear (The bitmap is displayed several lines below). Get rid of the nag-screen by overwriting the E8A036FFFF (call 0043DBB4) with 9090909090 in a hexeditor. Now everything is alright and the "pleasure-screen" is gone :( II.2 Activating the button The second task tC has set up is to enable the disabled "Enable registration" button. At first I thought this will be a pretty hard task, but the I remembered that the CrackMe is written in Borland Delphi. Borland's products have some *very* special way of displaying windows (and buttons, edit boxes...). If you have ever coded with Delphi (or C++ Builder) you know that you can just "Drag 'n' drop" the components (and buttons, edit boxes...) into your main window. You can give them several properties like "Left", "Top" and "Enabled". And - thank god - Delphi stores this properties in (nearly) plain text in the EXE file and creates the windows with the help of this data. The class of a button in Delphi is TButton, the name can be (nearly) anything. So let's search for "Button" in HexWorkshop. You will find the suspicous code around 603C0. There you will see: 000603C0 6572 0204 0000 0754 4275 7474 6F6E 0742 er.....TButton.B ;;Defines Button2 as 000603D0 7574 746F 6E32 044C 6566 7402 0003 546F utton2.Left...To ;;TButton - prop. "Left" 000603E0 7002 0A05 5769 6474 6803 3C01 0648 6569 p...Width.<..Hei ;;"Top","Width","Height" 000603F0 6768 7402 1507 4361 7074 696F 6E06 1645 ght...Caption..E ;;"Caption" 00060400 6E61 626C 6520 7265 6769 7374 7261 7469 nable registrati 00060410 6F6E 2E2E 2E07 456E 6162 6C65 6408 0854 on....Enabled..T ;;"Enabled" This code snippet defines a button of the Class TButton, defines the position in the window and the text that is written at the button. The only property that is important for us is "Enabled". (I replace the unimportant part with X) 00060410 XXXX XXXX XX07 456E 6162 6C65 6408 XXXX XXXXX.Enabled.XX You surely recognize the two dots that surround Enabled. Let me explain the function of them. The dot at the beginning contains the length of the string that will follow (StrLen(Enabled)==07)). You can easily look that I am correct when you look at other properties. The dot at the end is more important: This is the flag, if the button is enabled or disabled (08=disabled; 09=enabled). So change the byte at 6041D to 09 and the button will be enabled at the next start of the CrackMe. II.3 STOP TO JUMP, stupid button Now we have enabled the first button and can activate it to be able to fill text into the edit boxes. When we try to push the "Reg now" button, it jumps away and we are unable to push it. So we have to stop him. The easiest way to push him is to activate the menu of the window using [ALT]. Then the button won't jump away and you can click it. But that's not what tC wanted. Some more Delphi theory: It is obvious that the button jumps away, when we move the cursor above the button. In Delphi this is the "OnMouseMove" method. This is saved in the EXE file, too and we can easily find it (You know that you found the correct passage, when you look at the "Caption" property). 00060440 0007 5442 7574 746F 6E07 4275 7474 6F6E ..TButton.Button 00060450 3104 4C65 6674 0276 0354 6F70 031E 0105 1.Left.v.Top.... 00060460 5769 6474 6802 3C06 4865 6967 6874 021E Width.<.Height.. 00060470 0743 6170 7469 6F6E 0607 5265 6720 6E6F .Caption..Reg no 00060480 7708 5461 624F 7264 6572 0206 0754 6162 w.TabOrder...Tab 00060490 5374 6F70 0807 4F6E 436C 6963 6B07 0C42 Stop..OnClick..B 000604A0 7574 746F 6E31 436C 6963 6B0B 4F6E 4D6F utton1Click.OnMo 000604B0 7573 654D 6F76 6507 0A4D 6F76 6542 7574 useMove..MoveBut 000604C0 746F 6E00 0010 5441 484D 5370 6C61 7368 ton...TAHMSplash Luckily there's another method that has the same length: OnDragStart. So we can just over- write the "OnMouseMove" with "OnDragStart". Now the button won't jump anymore when you move the cursor above the button, but if you drag the button somewhere (if I remember correctly) and this will never happen :) So we tied the button's feet to the ground and we can head for the SICE check. II.4 Oh, there's a SICE check The SICE check is rather easy to defeat. In the general it works like the "MeltIce" protection (see another essay from me). It searches with CreateFileA for a file that is installed when SICE is active. The CrackMe searches for SICE every 20 seconds and (if I remember correctly) when the serial is calculated. Then it terminates with the message "Disable System - Debugger please!!!". Now we could easily patch the values that are written into the different registers when CreateFileA is active. But there's a easier (1-byte-patch) thing we could do. Search for the error message and you should see this: * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0044AF01(C) | :0044AF0B 84DB test bl, bl ;;Is SICE active ??? :0044AF0D 7411 je 0044AF20 ;;if not, then jump * Possible StringData Ref from Code Obj ->"Disable System - Debugger please!!!" | :0044AF0F B844AF4400 mov eax, 0044AF44 ;;next few lines show the message :0044AF14 E8AF8BFFFF call 00443AC8 :0044AF19 8BC7 mov eax, edi ;;and terminate then CrackMe :0044AF1B E8DC2AFFFF call 0043D9FC * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0044AF0D(C) | :0044AF20 5F pop edi ;;if SICE is not active, go on :0044AF21 5E pop esi :0044AF22 5B pop ebx :0044AF23 C3 ret Patching the je 0044AF20 (7411) to jmp 0044AF20 (EB11) should be easy with the hexeditor and the message will never be displayed again and the program will keep running forever. Forever??? Not really. There's a time limit of 120 seconds. II.5 More than 120 seconds would be fine :) After 120 seconds the program will terminate. In Delphi it is easy to set a Timer (class TTimer). tC did this and we can easily locate the important passage in the hexeditor. 000999F0 6566 7403 4801 0354 6F70 0218 0000 0654 eft.H..Top.....T 00099A00 5469 6D65 7205 6368 6563 6B08 496E 7465 Timer.check.Inte 00099A10 7276 616C 0320 4E07 4F6E 5469 6D65 7207 rval. N.OnTimer. 00099A20 0573 6963 6579 044C 6566 7403 4801 0354 .sicey.Left.H..T 00099A30 6F70 0258 0000 0654 5469 6D65 7203 6279 op.X...TTimer.by 00099A40 6508 496E 7465 7276 616C 04A0 8601 0007 e.Interval...... 00099A50 4F6E 5469 6D65 7207 0963 6C6F 7365 5F61 OnTimer..close_a 00099A60 6C6C 044C 6566 7403 4001 0354 6F70 0398 ll.Left.@..Top.. When the given time has gone, the timer calls the OnTimer method which terminates the CrackMe. So just delete this method and the program should run forever (note: Deleting means overwriting with 00h). When you finished, it should look like this. 000999F0 6566 7403 4801 0354 6F70 0218 0000 0654 eft.H..Top.....T 00099A00 5469 6D65 7205 6368 6563 6B08 496E 7465 Timer.check.Inte 00099A10 7276 616C 0320 4E07 4F6E 5469 6D65 7207 rval. N.OnTimer. 00099A20 0573 6963 6579 044C 6566 7403 4801 0354 .sicey.Left.H..T 00099A30 6F70 0258 0000 0654 5469 6D65 7203 6279 op.X...TTimer.by 00099A40 6508 496E 7465 7276 616C 04A0 8601 0000 e.Interval...... 00099A50 0000 0000 0000 0007 0963 6C6F 7365 5F61 .........close_a 00099A60 6C6C 044C 6566 7403 4001 0354 6F70 0398 ll.Left.@..Top.. Look: I have overwritten everything from the length of the string (OnTimer) to the byte in front of the length of the next string (close_all) and the program runs forever, now. II.6 And finally the two serials The last task was the hardest, cause it was no standard serial calculation. In fact: I doubt that tC used more than 10 lines of sourcecode to calculate the two serials, but the way he did it made it quite difficult. At first we should have a look for suspicious strings that could indicate that we cracked it (as there is no message that says something like "wrong serial"). You will find "WELL DONE..." and "Congratulation - you solved it!". That looks heavily like the "you did it" message (and it is so, as we will see later). You should see this: * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0044AD1D(C) | :0044AD23 807DFB00 cmp byte ptr [ebp-05], 00 ;;compare a flag :0044AD27 0F8582000000 jne 0044ADAF ;;if wrong value, then "wrong" :0044AD2D 807DFA00 cmp byte ptr [ebp-06], 00 ;;compare flag :0044AD31 757C jne 0044ADAF ;;if wrong value, then "wrong" :0044AD33 6A00 push 00000000 ;;Show "you did it" message * Possible StringData Ref from Code Obj ->"WELL DONE..." | :0044AD35 68E0AD4400 push 0044ADE0 * Possible StringData Ref from Code Obj ->"Congratulation - you solved it!" | :0044AD3A 68F0AD4400 push 0044ADF0 :0044AD3F A130CD4400 mov eax, dword ptr [0044CD30] :0044AD44 8B00 mov eax, dword ptr [eax] :0044AD46 8B4024 mov eax, dword ptr [eax+24] :0044AD49 50 push eax * Reference To: user32.MessageBoxA, Ord:0000h -- snip snip -- * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |:0044A99F(C), :0044A9C1(C), :0044A9E2(C), :0044AA03(C), :0044AA65(C) ;; all these are |:0044AA74(C), :0044AB3A(C), :0044AD27(C), :0044AD31(C) ;; "beggar off" jumps | :0044ADAF 33C0 xor eax, eax :0044ADB1 5A pop edx :0044ADB2 59 pop ecx :0044ADB3 59 pop ecx :0044ADB4 648910 mov dword ptr fs:[eax], edx As you can see there are quite a lot of "beggar off" jumps. Let's analyze them. The jump at :0044A99F is taken when then length of the entered name is less then 4 chars The jump at :0044A9C1 is taken when then length of the entered company is less then 4 chars The jump at :0044A9E2 is taken when then length of the entered first serial is 0 The jump at :0044AA03 is taken when then length of the entered second serial is 0 The jump at :0044AA65 is taken when the name or company contains chars < 20h The jump at :0044AA74 is taken when the name or company contains chars > 7Ah The jump at :0044AB3A is taken when the length(second serial) < length(company) The jump at :0044AD27 is taken when the first serial is wrong The jump at :0044AD31 is taken when the second serial is wrong So I take: Name : LaZaRuS Company : Hellforge 1st serial: 666999 2nd serial: 123456789 With this combination the first "beggar off" is taken at :004AD27. You should see this: :0044ACEE A150D94400 mov eax, dword ptr [0044D950] :0044ACF3 3B0554D94400 cmp eax, dword ptr [0044D954] ;;something is compared :0044ACF9 7504 jne 0044ACFF ;;if not equal -> "byebye" :0044ACFB C645FB00 mov [ebp-05], 00 ;;else -> set flag * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0044ACF9(C) | :0044ACFF 8D55F4 lea edx, dword ptr [ebp-0C] :0044AD02 8B45FC mov eax, dword ptr [ebp-04] :0044AD05 8B80DC020000 mov eax, dword ptr [eax+000002DC] :0044AD0B E8A09CFDFF call 004249B0 :0044AD10 8B55F4 mov edx, dword ptr [ebp-0C] ;;entered serial :0044AD13 A180D84400 mov eax, dword ptr [0044D880] ;;valid serial :0044AD18 E8038FFBFF call 00403C20 ;;compare :0044AD1D 7504 jne 0044AD23 ;;if not equal -> "byebye" :0044AD1F C645FA00 mov [ebp-06], 00 ;;else -> set flag * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0044AD1D(C) | :0044AD23 807DFB00 cmp byte ptr [ebp-05], 00 ;;1st flag set??? :0044AD27 0F8582000000 jne 0044ADAF ;;if not, "beggar off" :0044AD2D 807DFA00 cmp byte ptr [ebp-06], 00 ;;2nd flag set??? :0044AD31 757C jne 0044ADAF ;;if not, "beggar off" As you can easily see, the two flags are set at :0044ACFB and :0044AD1F. So we have to look that the jump one instruction in front of them mustn't be passed. The second one [ebp-06] is quite easy. When you see that two values are moved to registers followed by a call and then a jump, you can be sure that there is something compared in the serial caluclation routine. The flag that is set then made me absolutely sure :) So set a BP on line :44AD10 and then look what is moved to EDX and EAX. You will recognize that the serial that is moved to edx is the one you entered. So the serial moved to eax *should* be the correct serial. And it is so: In my case 2652326523 Getting the second serial is a bit harder. It is not just a good/bad serial comparison, but the flag is set after the comparison of two completely "strange" values. At first we have to find out how this two values are calculated. After playing around for some time you will see that the first value ([0044D950]) is calculated from the name and the serial you entered and the second value ([0044D954]) is calculated from the first serial you entered. If this two values are the same, then the "good"-flag will be set. The first value is of no interest, but let's find out how the serial is calculated. The important value is stored at ([0044D954]), but let's set a breakpoint like this on the other value fisrt: bpm 44D950 RW (this sets a breakpoint that is taken when something is read from or written to this address. If you try to register it now, SICE will break at :0044A95F first. :0044A95F xor eax, eax ;; eax = 0 :0044A961 mov dword ptr[0044D950], eax ;; set value to 0 This code snippet obviously sets the starting value to 0. The second time SICE will break at the memory access is at :0044AA9B. Here you see this: (You have to know that the CrackMe adds the strings of name and company before) This snippet calculates the first value: :0044AA58 8B157CD84400 mov edx, dword ptr [0044D87C] ;;edx=name+company :0044AA5E 8A541AFF mov dl, byte ptr [edx+ebx-01] ;;dl=1st letter :0044AA62 80FA20 cmp dl, 20 ;;if 1st < 20 :0044AA65 0F8244030000 jb 0044ADAF ;;"beggar off" :0044AA6B 8B0D7CD84400 mov ecx, dword ptr [0044D87C] ;;ecx=name+company :0044AA71 80FA7A cmp dl, 7A ;;if 1st > 7A :0044AA74 0F8735030000 ja 0044ADAF ;;"beggar off" :0044AA7A 8B157CD84400 mov edx, dword ptr [0044D87C] ;;edx=name+company :0044AA80 0FB6541AFF movzx edx, byte ptr [edx+ebx-01];;edx=1st letter :0044AA85 8B0D7CD84400 mov ecx, dword ptr [0044D87C] ;;ecx=name+company :0044AA8B 0FB60C19 movzx ecx, byte ptr [ecx+ebx] ;;ecx=2nd letter :0044AA8F 03D1 add edx, ecx ;;add 1st and 2nd :0044AA91 8910 mov dword ptr [eax], edx :0044AA93 8B10 mov edx, dword ptr [eax] :0044AA95 011550D94400 add dword ptr [0044D950], edx ;;add edx to value :0044AA9B 43 inc ebx ;;inc loop counter :0044AA9C 83C004 add eax, 00000004 :0044AA9F 4E dec esi :0044AAA0 75B6 jne 0044AA58 ;;if letters left,loop To make it short, it goes like this: (1st letter+2nd letter) + (2nd letter + 3rd letter) + (3rd letter + 4th letter)... For LaZaRuSHellforge it is: 0B83 OK, now let's have a look at the other serial calculation. Set this BP: bpm 44D954 RW Now you should break at the point where the value is set to 0, and at :0044AAFA Here you should see this (we found the second loop): * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0044AB02(C) | :0044AAC6 8D55F4 lea edx, dword ptr [ebp-0C] :0044AAC9 8B45FC mov eax, dword ptr [ebp-04] :0044AACC 8B80D8020000 mov eax, dword ptr [eax+000002D8] :0044AAD2 E8D99EFDFF call 004249B0 :0044AAD7 8B45F4 mov eax, dword ptr [ebp-0C] ;;eax=1st serial :0044AADA 0FB67C18FF movzx edi, byte ptr [eax+ebx-01] ;;edi=1st letter :0044AADF 8D55F0 lea edx, dword ptr [ebp-10] :0044AAE2 8B45FC mov eax, dword ptr [ebp-04] :0044AAE5 8B80D8020000 mov eax, dword ptr [eax+000002D8] :0044AAEB E8C09EFDFF call 004249B0 :0044AAF0 8B45F0 mov eax, dword ptr [ebp-10] ;;eax=1st serial :0044AAF3 E81890FBFF call 00403B10 ;;length(first serial) :0044AAF8 03F8 add edi, eax ;;first char + length :0044AAFA 013D54D94400 add dword ptr [0044D954], edi ;;add to value :0044AB00 43 inc ebx :0044AB01 4E dec esi :0044AB02 75C2 jne 0044AAC6 ;; if not last char -> loop OK, to make this one more simple, too: (1st char + len(serial)) + (2nd char + len(serial)) + (3rd char + len(serial))... For 666999 this gives 0171h which is (36h + 06h) + (36h + 06h)+ (36h + 06h)+ (39h + 06h) + (39h + 06h) + (39h + 06h) Now we have the problem to find out how to get a valid value that is equl to the first value. I did it this way: My 1st value: 0B83h = 2947 (36h + 06h)+ (36h + 06h)+ (36h + 06h) + (39h + 06h) + (39h + 06h) + (39h + 06h) is the same as (06h*06h)+(36h+36h+36h+39h+39h+39h) = 24h+(36h+36h+36h+39h+39h+39h) Now I have to find a length that takes much away from the 2947 I have: I took 23. So I can take away 2947-(23*23) = 2418 This I have to divide by 23 (as I have 23 chars in the serial) to get the average ASCII value of all chars of my serial. It is 105,1304347826 = 105. So I know I have 22 * 105 (=iiiiiiiiiiiiiiiiiiiiii) in my serial. 22 * 105 = 2310, so I have 108 left which is "l". So my serial is: iiiiiiiiiiiiiiiiiiiiiil At the end I have the following: Name: LaZaRuS Company: Hellforge 1st serial: iiiiiiiiiiiiiiiiiiiiiil 2nd serial: 2652326523 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, +Sandman, Eternal Bliss, DaVinci, everyone at Fravia+'s MB, everyone at +Sandman's MB and everyone in #cracking4newbies. All Tutorials by LaZaRuS [hf] #| date | name |version|W32Dasm|Soft-Ice|kind of crack | --|--------|------------------|-------|-------|--------|---------------------------| 01|20.01.99|Jaylock |1,0,0,1| (X) | (X) |serial# | 02|31.01.99|Goldwave |4.02 | (X) | (X) |serial#,nag-screens | 03|28.03.99|AxMan |3.00 | (X) | (X) |serial#,remove date-limit | | | | | | |nag-screen, key generator | 04|29.03.99|C++Builder Strings| | (X) | (X) |how to find strings in | | | | | | |C++ Builder that are not | | | | | | |hardcoded | 05|29.03.99|Better Protection | | | |How to protect shareware | | | | | | |better against crackers | 06|04.04.99|Start Clean |1.2 | (X) | (X) |nag-screen/serial/keygen | 07|06.04.99|MP3 TO EXE |1.02 | (X) | (X) |nag-screen/serial | 08|06.04.99|HexDecCharEditor |1.02 | (X) | |make it registered | 09|20.04.99|PowerZip |4.51 | (X) | |serial/time-check/... | 10|24.04.99|eKH CrackMe |1.0 | (X) | |serial | 11|25.04.99|F-Secure |4.02 | (X) | |time limit/nag | 12|29.04.99|Latido's JS |3.0 | | |serial | | |Reverse Me | | | | | 13|24.05.99|Italian Soccer |1.10 | (IDA) | |patch to remove the time | | |Manager | | | |limit | 14|29.05.99|MeltIce | | (X) | (X) |how to defeat this Anti | | | | | | |SICE trick | 15|02.06.99|W32Dasm | | (X) | |Using W32Dasm as a debugger| 16|17.06.99|ID CrackMe 6 | | | (X) |Manual Unpacking | 17|17.06.99|How to start a | | | (X) |My way of starting a crack | | |crack | | (X) | (X) | | 18|29.06.99|tC's Revenge | | (X) | (X) |How to crack this superb | | | | | | |CrackMe | LaZaRuS Visit my page at http://come.to/hellforge for more tutorials and high quality cracking links. If you want to mail me: lazarus_hf@hotmail.com (Yes, the address changed :)