CRACKING TUTORIAL RELEASE 1 DATE: 13/2/98 AUTHOR: Quantico Mexelite'98 EDITOR: Full screen notepad with wordrap on LEVEL: Intermediate TARGET PROGRAM: Directory toolkit version 2.63 WHERE?: www.funduc.com PROTECTION(s): NAG, 21 day trial, *-Unregistered* in title bar. SOLUTION: A GOOD PATCH JOB :) TOOLS: Good old softice (i used 3.00), w32dasm 8.9, hex editor (hex workshop) and a patch generator like patchit by Qapla or rtd_patch by Mr. Wicked, or write your own. NOTES: Phew, I now have most of my (minor) exams over and only a few next week so I have time to fix this tutorial up a bit. I hope someone learns from this, that's all I want :) PATCHES: patches in pascal, asm, c++ and C have been included in this zip for you to study and learn from. They have been created from a patch generator (rtd_patch & patchit) as I have not yet finished my own patcher source in pascal. The .com file is the complied (and slightly modified asm code.) ================================================================================================= Right, lets get started. You should know by now that you never try to crack something without getting a 'feel' of it first. So run it and see what it does. OK, we notice a nasty nag on startup and if we click OK then we go on into the program. In the title bar, youll see a -Unregistered notice. If you hunt around the menus and look in the help file, you will find that there is no way to turn this into a full version, ie. 'unlock' it and you have to pay $$$ and get it sent to you. You should also find that the program expires in 21 days. Lets change all that, shall we? OK, the first thing, and the most annoying thing to crack is the nag. There are a few ways that a programmer can create a nag but most involve the following calls: 1) messagebox(a) 2) dialogboxparam(a) 3) createdialogindirectparam(a) 4) dialogboxindirectparam(a) The nag does not look like either of the first two styles which are more plain and simple so lets bpx on the 3rd one and the 4th one, createdialogindirectparama and dialogboxindirectparama, i use the 'a' at the end 'cos its a 32bit prog. :bpx createdialogindirectparama :bpx dialogboxindirectparama and then run directory toolkit. Softice will break at createdialogindirectparama Each time softice pops, ctrl-d out again to see when the nag is made. Softice will pop 3 times before the nag is made so it is the 3rd call to createdialogindirectparama that makes the nag so lets run the prog again and look at the 3rd call. Stop on the 3rd break and F12 to return to the function that called it, we are now back in the directory toolkit code; :00455B15 E867FCFFFF call 00455781 :00455B1A 33DB xor ebx, ebx <===== we land here (SIDE NOTE: If you don't have the opcodes to the left of the commands, type 'code on' in softice) press F4 too see if the nag is made yet but it is not and F4 to return again to softice, so it must be made a little further on in the code because it has just started to process it. Keep stepping with F10.... :00455B1C 3BC3 cmp eax, ebx :00455B1E 7457 jz 00455B77 <===== no jump :00455B20 F6462410 test [esi+24], 10 :00455B24 741C jz 00455B42 <===== no jump :00455B26 6A04 push 00000004 :00455B28 8BCE mov ecx, esi :00455B2A 5B pop ebx :00455B2B E8E6030000 call 00455F16 :00455B30 F6C401 test ah, 01 :00455B33 7403 jz 00455B38 <===== jump here ======= :00455B35 6A05 push 00000005 | :00455B37 5B pop ebx | | * Referenced by a (U)nconditional or (C)onditional Jump at Address: | |:00455B33(C) | | | :00455B38 53 push ebx <======================== :00455B39 8BCE mov ecx, esi :00455B3B E8FBF5FFFF call 0045513B *** :00455B40 33DB xor ebx, ebx *** this call actually finishes making the nag and if you trace inside it, you will see a !UPDATEWINDOW call. So we can now presume that this whole section of code is all involved in making the nag and so it must be called from somewhere else. Run the program again, and on the 3rd break, F12 twice (you will have to press the OK button on the nag) and you will see the following code: :0040E334 E821770400 call 00455A5A :0040E339 8D8C2434010000 lea ecx, dword ptr [esp+00000134] <===== we land here :0040E340 C784247801000003000000 mov dword ptr [esp+00000178], 00000003 :0040E34B E818280500 call 00460B68 it is the call at 0040E334 that constructs the nag but if you had studied the program correctly, you would have noticed that the nag and the 'about' dialog are identical. We could take out the above call but it would leave us with no 'about' dialog (believe me, i tried it!) so F12 again to step back another section and you land here: :0040D32D 8986A8070000 mov dword ptr [esi+000007A8], eax :0040D333 E8C80F0000 call 0040E300 :0040D338 8D4C2430 lea ecx, dword ptr [esp+30] <====== you land here :0040D33C 896C2430 mov dword ptr [esp+30], ebp :0040D340 896C2434 mov dword ptr [esp+34], ebp :0040D344 E8B7A20200 call 00437600 Ok, now we've found the call that makes the nag, lets bpx on it and see if we can patch it. :bd * (disable other breakpoints) :bpx 0040D333 (or whatever yours was) and run the program again. You should stop at the line with the nag call on it. Lets try nopping it, (i only nop it when testing, i use a better method when permanently patching) the call is 5 bytes long so lets use 5 nops :a :nop :nop :nop :nop :nop That looks horrible i know. Now ctrl-d and see if it works. DO you see any nag? I dont :) Ok, one part done, lets patch that. Open up a hex editor and load that file, search for 8986A8070000E8C80F0000 (the line b4 the call and the call opcodes) and start patching at the E8 byte (cos it is the start of the nag_you call) changing E8C80F0000 call 0040E300 to 40 inc eax 48 dec eax 90 nop 40 inc eax 48 dec eax save it as a different file (to keep the original intact) and test it. There should be no nag now. Well done. The next part of the program, and a lot easier than the nag, is the 21 day trial part. Set the PC clock 30 days ahead and then run the program. If you are running the original copy, the nag should pop up and if you click OK, a messagebox will tell you that you are past the trial period. Note what that messagebox says; "The evaluation period expired. Do you want to see the ordering information?" If we click no, we are thrown out of the program and if yes then we are shown the helpfile. Either way, the program doesn't run anymore. Im gonna use wdasm for this approach rather than softice 'cos its easier. Wdasm the file and then look in the string reference section for the messagebox text and then double click on it to get to that section. :0040D33C 896C2430 mov dword ptr [esp+30], ebp :0040D340 896C2434 mov dword ptr [esp+34], ebp :0040D344 E8B7A20200 call 00437600 :0040D349 85C0 test eax, eax :0040D34B 743A je 0040D387 <======== important * Possible Reference to String Resource ID=00002: "Directory Toolkit Windows 95/NT Application" | :0040D34D 6A02 push 00000002 :0040D34F E88CC60100 call 004299E0 :0040D354 83C404 add esp, 00000004 :0040D357 8986A8070000 mov dword ptr [esi+000007A8], eax :0040D35D 6AFF push FFFFFFFF :0040D35F 6A04 push 00000004 * Possible Reference to String Resource ID=02106: "The evaluation period expired. Do you want to see the Ordering Information?" | :0040D361 683A080000 push 0000083A :0040D366 E8C6ED0400 call 0045C131 :0040D36B 83F806 cmp eax, 00000006 :0040D36E 750E jne 0040D37E :0040D370 8B16 mov edx, dword ptr [esi] Note that the jump at 0040D34B jumps PAST the 'expired' part. This is obviously the section that decides which path the program should take as inside the call at 0040d344 there is various date gathering information and bad_guy jumps accordingly. (Sorry for the long code snippits) * Referenced by a CALL at Address: |:0040D344 | =====cut a bit to save space===================================================================== :00437628 8D4C2410 lea ecx, dword ptr [esp+10] :0043762C E8F49A0100 call 00451125 <===========go get some date info :00437631 8B4014 mov eax, dword ptr [eax+14] <=== put last 2 figures of year into eax :00437634 056C070000 add eax, 0000076C <==== add 1900 to eax (1900+year) :00437639 3DCC070000 cmp eax, 000007CC <==== compare with 1996 :0043763E 752C jne 0043766C <==== jump not equal ??? :00437640 53 push ebx :00437641 8D4C2410 lea ecx, dword ptr [esp+10] :00437645 E8DB9A0100 call 00451125 :0043764A 8B4010 mov eax, dword ptr [eax+10] <=== put month minus 1 into eax :0043764D 40 inc eax <========= add 1 to eax.....eax=month number :0043764E 83F807 cmp eax, 00000007 <=== compare with 7 (July) :00437651 7519 jne 0043766C <======== bad_dude :00437653 53 push ebx :00437654 8D4C2410 lea ecx, dword ptr [esp+10] :00437658 E8C89A0100 call 00451125 :0043765D 83780C01 cmp dword ptr [eax+0C], 00000001 :00437661 7509 jne 0043766C <====== bad_dude :00437663 33C0 xor eax, eax <====== set good flag (0) :00437665 5F pop edi :00437666 5E pop esi :00437667 5B pop ebx :00437668 83C40C add esp, 0000000C <=== stack correction :0043766B C3 ret If someone can explain a little more to me about this 'strange' call, i would appreciate it because it does not seem to make sense, like jumping if the year is not = to 1996!!! The calls to 00451125 get date information but I don't know what the third call to it does, eax is a really large number and the program always takes the jump there. Someone please tell me :) Anyway, there are 3 jumps to 0043766C which mucks about and generally sets the bad flag before returning to do a test eax,eax. If none of these jumps are taken, eax gets zeroed so we can either take out all the jumps in the call and let the zero flag get set, we can patch the jump after the test eax,eax or we could follow the bad_guy jumps and change the mov eax, 1 instruction to a mov eax, 0. Instead of nopping (for instance) the jumps, we could change them to 'xor eax,eax' which would set the good flag and take out the jumps. I haven't tested that and its just an idea so i'll leave it to you. The same with the flag faking. What im going to do is patch the jump after the RET. Remember this? :0040D344 E8B7A20200 call 00437600 :0040D349 85C0 test eax, eax <======== we come back here :0040D34B 743A je 0040D387 <======== important * Possible Reference to String Resource ID=00002: "Directory Toolkit Windows 95/NT Application" | :0040D34D 6A02 push 00000002 We want the jump at 0040d34b to always be taken so the proggie never expires. Lets change; 85C0 test eax,eax 743A je 0040d387 (jump if still in trial) to the following; 85C0 test eax,eax EB3A jmp 0040d387 (always jump to good_guy bit) And thats the date done. You could also change the call to a xor eax, eax but I haven't tried any other possibilities, I'll just explain a little and leave them for you as an exercise :) You would have to do the following. :0040D344 E8B7A20200 call 00437600 :0040D349 85C0 test eax, eax <======== we come back here :0040D34B 743A je 0040D387 <======== important CHANGE THAT TO :0040D344 40 inc eax :0040D345 90 nop :0040D346 48 dec eax :0040D347 33C0 xor eax, eax :0040D349 85C0 test eax, eax :0040D34B 743A je 0040D387 (SIDE NOTE: you could also crack the time limit by doing a 'bpx messageboxa' and F12 about 3-4 times...again you can try it..I'm not going to explain it here...there are lots of other tuts on messagebox examples.) The last part of this crack is the -Unregistered bit. So you can either look for that in the string references and go to it there or do it this way. After the nag, the windowframe must be the next thing made so it should be soon after that last good_guy jump we just patched. Lets take a look. * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0040D34B(C) | :0040D387 8D442418 lea eax, dword ptr [esp+18] :0040D38B 8BCE mov ecx, esi :0040D38D 50 push eax :0040D38E E8815F0400 call 00453314 :0040D393 8D4C2420 lea ecx, dword ptr [esp+20] :0040D397 E80F940400 call 004567AB :0040D39C B30B mov bl, 0B * Possible Reference to String Resource ID=02173: " - Unregistered" | :0040D39E 687D080000 push 0000087D :0040D3A3 8D4C2424 lea ecx, dword ptr [esp+24] :0040D3A7 885C2478 mov byte ptr [esp+78], bl :0040D3AB E8A79A0400 call 00456E57 Yep, this looks good. All we have to do is fix that 'push' at line 0040D39E. Remember Intel processors handle information a bit strange, its all in reverse so the first byte of the 0000087d thats being pushed will be the last in the opcode. So, remembering that, and remembering that '68' is the opcode for 'push' we can change; 687d080000 push 0000087d (push the -Unregistered sign) TO 6800000000 push 00000000 (push absolutly nothing!) Do these patches like you did the first one in your hexeditor and enjoy the program. These are the only limitations of the program I know of but if you find any others, or have any suggestions or comments (criticisms) on this (please remember im still a newbie :) find me on #cracking4newbies on IRC (Efnet). GREETS: Vizion and Intruder for helping me with nags, Deviant, CoRN2, Norway, _[mP], snipes, Aquadude, Qapla and all the Mexelite and c4n dudes. ***************** ***************** ** ** ** Quantico ** ** Mexelite'98 ** ** 13/2/98 ** ** ** ***************** ***************** http://mex98.home.ml.org http://cracking.home.ml.org http://fantom.home.ml.org http://greythorne.home.ml.org http://quantico.home.ml.org #cracking4newbies (IRC EFNET)