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