January 1999
"Paintshop Pro 5"
Don't forget the registry!
Win Code Reversing
by Santa Clawz 
Code Reversing For Beginners 
Program Details
Program Name: psp.exe
Program Type: Popular graphics package
Program Location: Most cover CD's! 
Program Size: 3,612,672 bytes 
Tools Used:
 Regmon - A registry monitor
W32Dasm V8.93 - A Disassembler
Hex workshop - A hex editor
Easy ( X )  Medium ( )  Hard ( )  Pro (    ) 
There is a crack, a crack in everything. That's how the light gets in.
Paintshop Pro 5
Don't forget the registry!
Written by Santa Clawz
By now you probably have at least one copy of Paintshop Pro on a CD in your mass of cover CD's. However, dig around your collection that dates between July and December 98 and you will probably find version 5 - this is our target program. Paintshop pro is essentially the most popular graphics package found on most cover CD's of most computer magazines and is almost definitely available on the web : - )

This tutorial is really set out to be a good lesson in cracking time restricted programs from one newbie to others and to encourage all newbies to study their target's protection (or lack of it! ; - ) as closely as possible before diving into the deep end!
About this protection system
Jasc (the authors of PSP) give no opportunity to register their program directly from the interface, so they are not silly in that respect. However, they stress that this fully functional program is for evaluation purposes only and limit it to be used for 30 days (it will automatically terminate after 60) before asking you to beggar off and buy the full version 8 ¬ P

However, we will destroy the code that tells the program to check somewhere for the limit. Of course if you wish to use this program for ever go and buy it!
The Essay 
Ok, now that you have installed the proggie click on start and have a play for a bit and then come back to this tutorial! Now next time you load it up, before so execute Regmon (remembering to put "regmon;explorer" in the Processes exclude line in the filter) and watch all the calls to and from the registry that PSP makes (and watchout, there's hundreds!).

Hmm, did you want to get any sleep? Didn't think so! Well, we are only concerned with the ones made earlier (upon entry rather than exit) where the program will check the registry for it's installation date and number of times it has been run. However, the programmers here were not stupid enough to put these values in the usual installation or program key of:

HKEY_CURRENT_USER\Software\JASC\Paint Shop Pro 5

Oh no! They put it somewhere were you wouldn't really think of going! I hope you haven't closed Regmon yet - you still need it open (but close PSP5). Search for {84124FF1-5D04-11D1-A575-00A0C96F2B0D} within Regmon and bang! "What?" I hear you say. Well, double click on it and you find out. Firstly though, I will just tell you why and how I discovered this holds our key to freedom.

I simply searched through all the calls for a while making a mental note of all the ones that would seem too obvious to hold a special value. When I came across the ridiculous looking {84124FF1-5D04-11D1-A575-00A0C96F2B0D} I thought to myself hmm. I wonder... so I double clicked on the same line you should have done by now and the registry opened at the right place.

Now back to the registry (don't worry the last paragraph will continue to be explained in this section). You should now collapse this key to reveal a number of other subkeys: AuxUserType; DefaultIcon; InprocHandler32; Insertable; LocalServer32; ProgID; MiscStatus; MS; Verb. If you look through any of them you will find they all have something to do with PSP (funny that!). The one we are concerned with though is MS. Now close Regmon but keep Regedit open at HKEY_CLASSES_ROOT\CLSID\{84124FF1-5D04-11D1-A575-00A0C96F2B0D}\MS (you should be looking at this anyway) and run Paintshop Pro again. After you have clicked "Yes" on the nag screen and close PSP go back to Regedit and refresh the display you will see that the two DWORD values iPID50t and iPID50u have changed. The second value of iPID50u has been incremented by 1 and will be each time you run PSP (try it and watch the number increase). The first value of iPID50t holds the important info of when your period is meant to expire (it doesn't matter how many times you run it within this time). So if you delete these two values your PSP program will go back to day one and run times of 0. However, the clock is still ticking.

Well, we've done the simple bit of finding in the registry where our program looks for the date check ; - ) and now it is time to get into the nitty gritty of byte manipulation and ASM code cracking - the fun part! So load up first of all WinDasm and create your deadlisting making sure you have at least 40meg space for the file (it will be this big!) and in the mean time depending on what time it is mix yourself a good drink because it will take about 15 to 20 mins to disassemble! I recommend, if it is morning a strong coffee, afternoon a cup of tea or if it is evening/late night : - ) either a good beer (bitter) or a Vodka Martini!

Ok, so your back with your all important rations and ready for the trek ahead. If you do a String reference search you won't find much on registering the product although you will find the two DWORD values from the registry I spoke of earlier; iPID50t and iPID50u, how interesting! This does mean that the PSP program accesses the registry around this point. Lets have a look at the disassembled code...

* Possible StringData Ref from Data Obj ->"MS"; Here we can see the last subkey of the registry key opened.
:00585B22 68F4EC6200 push 0062ECF4
:00585B27 8D4C2414 lea ecx, dword ptr [esp+14]

* Reference To: MFC42.MFC42:NoName0848, Ord:03ADh
:00585B2B E8A65C0500 Call 005DB7D6

* Possible Reference to Menu: MenuID_0004
:00585B30 B804000000 mov eax, 00000004
:00585B35 895C2418 mov dword ptr [esp+18], ebx
:00585B39 89442444 mov dword ptr [esp+44], eax
:00585B3D 89442448 mov dword ptr [esp+48], eax
:00585B41 8B442410 mov eax, dword ptr [esp+10]
:00585B45 895C242C mov dword ptr [esp+2C], ebx
:00585B49 50 push eax
:00585B4A 6819000200 push 00020019
:00585B4F 6800000080 push 80000000
:00585B54 E858E5E7FF call 004040B1
:00585B59 83C40C add esp, 0000000C
:00585B5C 3BC3 cmp eax, ebx
:00585B5E 89442428 mov dword ptr [esp+28], eax
:00585B62 7477 je 00585BDB
:00585B64 8D4C2448 lea ecx, dword ptr [esp+48]

* Reference To: ADVAPI32.RegQueryValueExA, Ord:0136h; Where the program calls the dll procedure that checks the values in
                                                                                                          the open registry key.
:00585B68 8B3530AF6300 mov esi, dword ptr [0063AF30]
:00585B6E 51 push ecx
:00585B6F 8D542430 lea edx, dword ptr [esp+30]
:00585B73 8D4C2448 lea ecx, dword ptr [esp+48]
:00585B77 52 push edx
:00585B78 51 push ecx
:00585B79 53 push ebx

* Possible StringData Ref from Data Obj ->"iPID50t"; Our first value.
:00585B7A 68E8EC6200 push 0062ECE8
:00585B7F 50 push eax
:00585B80 FFD6 call esi
:00585B82 85C0 test eax, eax
:00585B84 750E jne 00585B94
:00585B86 8B54242C mov edx, dword ptr [esp+2C]
:00585B8A 8B7C2424 mov edi, dword ptr [esp+24]
:00585B8E 89542418 mov dword ptr [esp+18], edx
:00585B92 EB05 jmp 00585B99

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
:00585B94 BF01000000 mov edi, 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
:00585B99 8D442448 lea eax, dword ptr [esp+48]
:00585B9D 8D4C242C lea ecx, dword ptr [esp+2C]
:00585BA1 50 push eax
:00585BA2 8B44242C mov eax, dword ptr [esp+2C]
:00585BA6 8D542448 lea edx, dword ptr [esp+48]
:00585BAA 51 push ecx
:00585BAB 52 push edx
:00585BAC 53 push ebx

* Possible StringData Ref from Data Obj ->"iPID50u"; Our second value.

:00585BAD 68DCEC6200 push 0062ECDC
:00585BB2 50 push eax
:00585BB3 FFD6 call esi
:00585BB5 85C0 test eax, eax
:00585BB7 750B jne 00585BC4
:00585BB9 8B4C242C mov ecx, dword ptr [esp+2C]
:00585BBD 41 inc ecx
:00585BBE 894C241C mov dword ptr [esp+1C], ecx
:00585BC2 EB0C jmp 00585BD0

We can see from this section of the disassembly that the ADVAPI32.dll opens the key mentioned previously HKEY_CLASSES_ROOT\CLSID\{84124FF1-5D04-11D1-A575-00A0C96F2B0D}\MS), this snippet shows the last subkey "MS" being opened. Further down the code the string references show the two values we also found using Regmon. So far so good, nothing to get lost in 8 ¬ ) There is a real goldmine of code here in this listing and I hope you can spot it! Yup, thats it! Underneath the "iPID50t" and "iPID50u" strings the ASM code for each reference is pretty much the same! Let's take a closer look...

* Possible StringData Ref from Data Obj ->"iPID50t"; This one checks the date/time and limit.
:00585B7A 68E8EC6200 push 0062ECE8
:00585B7F 50 push eax; Saves the data in the eax register.
:00585B80 FFD6 call esi
:00585B82 85C0 test eax, eax; Checks the eax register.
:00585B84 750E jne 00585B94; And the conditional jump.
:00585B86 8B54242C mov edx, dword ptr [esp+2C]
:00585B8A 8B7C2424 mov edi, dword ptr [esp+24]
:00585B8E 89542418 mov dword ptr [esp+18], edx
:00585B92 EB05 jmp 00585B99

* Possible StringData Ref from Data Obj ->"iPID50u"; This one checks how many times the program has been run.
:00585BAD 68DCEC6200 push 0062ECDC
:00585BB2 50 push eax
:00585BB3 FFD6 call esi
:00585BB5 85C0 test eax, eax
:00585BB7 750B jne 00585BC4
:00585BB9 8B4C242C mov ecx, dword ptr [esp+2C]; Copies the dword (iPID50u) into the ecx register.
:00585BBD 41 inc ecx; Increments the ecx register (adding 1 to the number of times the program has been run).
:00585BBE 894C241C mov dword ptr [esp+1C], ecx
:00585BC2 EB0C jmp 00585BD0

Ok, there are two ways you could go from here in *cracking* the program (I have done both and both work). However, one is better than the other.
The Crack
Right now you need your Hex editor, I prefer Hex Workshop ; - ) but as usual any will do that you know how to use! Load it up and be ready to manipulate the bytes = o ]

Before we go any further I will explain the two ways of cracking this program. The first way (the way I discovered first) is to delete the two DWORD values in the registry first and then change the exe file in a Hex editor. In Hex workshop I zeroed the two values i.e. changed "69504944353074" and "69504944353075" (these are iPID50t and iPID50u in hexadecimal) both to "00000000000000". This would then clear the registry of the data PSP looks for (note: these values will never show up in the registry now). Then secondly (the actual crack) change a je to jmp. This can be found at :00585B62 7477 je 00585BDB in your deadlisting. That is it - I will not go any further with that because I feel the next way is better 8 ¬ )

Take two! If you study the last code snippet you will notice to conditional jumps (jne) one in each string reference procedure. All we need to do here is to change them to unconditional jumps.

So load up your Hex editor and search for the bytes 750E8B54242C  

The only byte we want to change in this string of numbers is 75 (the others are simply there to narrow the search down), this is the opcode for jne. As we want to change this to jmp we shall change it to EB this is the hex byte (opcode) for this particular ASM code.

Now search for the bytes 750B8B4C242C  

The only byte we want to change in this string of numbers is 75 again. As before change it to EB. bEfOrE YOU sAvE ANY FILE MAKE A bAcKuP OF IT JUST INCASE. Now save the file (psp.exe) and run it. ** nUff sAid **
From me to you
Well, I hope you understood it all and more than anything I hope it works (I know it does so don't worry!). This was written by a newbie as I said earlier and is meant to help the next generation of crackers become more knowledgeable about the thought behind reversing code not to rip off good software. If for any reason should you want to contact me click on the image below to E-mail me.

Mail Santa Clawz
MY thanx and gratitude to The Sandman for the sheer volume of newbie resources and linkz on code reversing. Jeff and The Sandman for maintaining the Newbie Cracking Forum. +Fravia for his bottomless pit of knowledge provided on the web. +ORC for his intuitive papers on cracking. Icezillions pages on Win32 ASM coding. Anyone else I have forgotten!

Page by: Santa Clawz
Page Created: 2nd February 1999